Compare commits

..

12 Commits

Author SHA1 Message Date
Matthias Clasen
406a32d825 Fix the build 2023-02-12 16:31:40 -05:00
Matthias Clasen
beabe8c33b gsk: Drop an unnecessary call
The renderer should make all the necessary
make_current calls.
2023-02-12 15:12:43 -05:00
Matthias Clasen
90500519d6 gst: Add a comment about context confusion 2023-02-12 15:12:43 -05:00
Matthias Clasen
06921674a9 gsk: Only wait if we need to
If the texture was created in the same context
we are using it in, then waiting on the sync
will be a no-op.
2023-02-12 15:12:43 -05:00
Matthias Clasen
a91fa9a680 gltexture: Only wait if we need to
If the texture was created in the same context
we are downloading it from, then waiting on the
sync will be a no-op.
2023-02-12 15:12:43 -05:00
Matthias Clasen
ead40dc834 gldriver: Add a sync when creating textures 2023-02-12 15:12:43 -05:00
Matthias Clasen
2be928b569 gstreamer: Defer the sync
Don't sync right when we receive the buffer,
pass it along with the texture to be executed
later in the renderer.
2023-02-12 15:12:43 -05:00
Matthias Clasen
621ba6d67c Export gdk_gl_texture_new_with_sync
Otherwise we can't use it in the loadable modules,
like the GStreamer media stream.

This change puts gdk_gl_texture_new_with_sync into
the private, but exported bucket for now. We will
make new public APIs for textures (including
synchronization) when we add color management support.
2023-02-12 15:12:43 -05:00
Matthias Clasen
af929a8787 glarea: Synchronize
Create a fence object and pass it along when
creating the GL texture, so that the GL renderer
can wait for the texture to be ready.
2023-02-12 15:12:43 -05:00
Matthias Clasen
ef986f4256 gsk: Synchronize when using textures
Pass the GLsync object from texture into our
command queue, and when executing the queue,
wait on the sync object the first time we
use its associated texture.
2023-02-12 15:12:41 -05:00
Matthias Clasen
ab36c275cf gltexture: Synchronize when downloading
If the GL texture has a sync object, wait
on it before downloading the data.
2023-02-12 15:09:21 -05:00
Matthias Clasen
720327bc00 gltexture: Optionally take a sync object
Add a new (private, for now) constructor takes
a GLsync together with a texture id, for synchronization.
2023-02-12 15:09:21 -05:00
1405 changed files with 37615 additions and 50972 deletions

View File

@@ -26,31 +26,25 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v42"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v40"
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
workflow:
rules:
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
default:
retry:
max: 2
when:
- 'runner_system_failure'
- 'stuck_or_timeout_failure'
- 'scheduler_failure'
- 'api_failure'
interruptible: true
.only-default:
only:
- branches
except:
- tags
style-check-diff:
extends: .only-default
image: $FEDORA_IMAGE
stage: check
when: manual
allow_failure: true
script:
- .gitlab-ci/run-style-check-diff.sh
.build-fedora-default:
extends: .only-default
image: $FEDORA_IMAGE
artifacts:
when: always
@@ -60,10 +54,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report-x11_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway_unstable.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
@@ -108,8 +98,7 @@ fedora-x86_64:
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build wayland_smalltexture
- .gitlab-ci/run-tests.sh _build waylandgles
- .gitlab-ci/run-tests.sh _build broadway
release-build:
@@ -171,6 +160,7 @@ fedora-mingw64:
- ninja -C _build
.mingw-defaults:
extends: .only-default
stage: build
tags:
- win32-ps
@@ -202,8 +192,9 @@ msys2-mingw64:
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
rules:
- if: $CI_PROJECT_NAMESPACE == "GNOME"
extends: .only-default
only:
- branches@GNOME/gtk
stage: build
tags:
- macos
@@ -236,9 +227,10 @@ macos:
- "${CI_PROJECT_DIR}/_build/meson-logs"
vs2017-x64:
extends: .only-default
# TODO: Uncomment this when ready to merge.
# rules:
# - if: $CI_PROJECT_NAMESPACE == "GNOME"
#only:
# - branches@GNOME/gtk
stage: build
tags:
- win32-ps
@@ -251,7 +243,7 @@ vs2017-x64:
- "${CI_PROJECT_DIR}/_build/meson-logs"
.flatpak-defaults:
image: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
image: $FLATPAK_IMAGE
stage: flatpak
allow_failure: true
tags:
@@ -261,67 +253,65 @@ vs2017-x64:
- "${APPID}-dev.flatpak"
- 'repo.tar'
expire_in: 1 day
rules:
# Only build Flatpak bundles automatically on main
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH != "main"
when: "manual"
script:
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
flatpak:demo:
extends: '.flatpak-defaults'
# Manual jobs, for branches and MRs
.flatpak-manual:
extends: .flatpak-defaults
when: manual
# Only build Flatpak bundles automatically on main
.flatpak-main:
extends: .flatpak-defaults
only:
- main
flatpak-manual:demo:
extends: .flatpak-manual
needs: []
variables:
APPID: org.gtk.Demo4
flatpak:demo:aarch64:
extends: '.flatpak-defaults'
flatpak-main:demo:
extends: .flatpak-main
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.Demo4
flatpak:widget-factory:
extends: '.flatpak-defaults'
flatpak-manual:widget-factory:
extends: .flatpak-manual
needs: []
variables:
APPID: org.gtk.WidgetFactory4
flatpak:widget-factory:aarch64:
extends: '.flatpak-defaults'
flatpak-main:widget-factory:
extends: .flatpak-main
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.WidgetFactory4
flatpak:icon-browser:
extends: '.flatpak-defaults'
flatpak-manual:icon-browser:
extends: .flatpak-manual
needs: []
variables:
APPID: org.gtk.IconBrowser4
flatpak:icon-browser:aarch64:
extends: '.flatpak-defaults'
flatpak-main:icon-browser:
extends: .flatpak-main
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.IconBrowser4
flatpak:node-editor:
extends: '.flatpak-defaults'
flatpak-manual:node-editor:
extends: .flatpak-manual
needs: []
variables:
APPID: org.gtk.gtk4.NodeEditor
flatpak:node-editor:aarch64:
extends: '.flatpak-defaults'
flatpak-main:node-editor:
extends: .flatpak-main
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.gtk4.NodeEditor
@@ -330,35 +320,23 @@ flatpak:node-editor:aarch64:
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
nightly demo:
extends: '.publish_nightly'
needs: ['flatpak:demo']
nightly demo aarch64:
extends: '.publish_nightly'
needs: ['flatpak:demo:aarch64']
dependencies: ['flatpak-main:demo']
needs: ['flatpak-main:demo']
nightly factory:
extends: '.publish_nightly'
needs: ['flatpak:widget-factory']
nightly factory aarch64:
extends: '.publish_nightly'
needs: ['flatpak:widget-factory:aarch64']
dependencies: ['flatpak-main:widget-factory']
needs: ['flatpak-main:widget-factory']
nightly icon-browser:
extends: '.publish_nightly'
needs: ['flatpak:icon-browser']
nightly icon-browser aarch64:
extends: '.publish_nightly'
needs: ['flatpak:icon-browser:aarch64']
dependencies: ['flatpak-main:icon-browser']
needs: ['flatpak-main:icon-browser']
nightly node-editor:
extends: '.publish_nightly'
needs: ['flatpak:node-editor']
nightly node-editor aarch64:
extends: '.publish_nightly'
needs: ['flatpak:node-editor:aarch64']
dependencies: ['flatpak-main:node-editor']
needs: ['flatpak-main:node-editor']
static-scan:
image: $FEDORA_IMAGE
@@ -441,9 +419,9 @@ reference:
publish-docs:
image: fedora:latest
stage: publish
interruptible: false
needs: ['reference']
script:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
rules:
- if: $CI_COMMIT_REF_NAME == "main"
only:
refs:
- main

View File

@@ -1,4 +1,4 @@
FROM fedora:38
FROM fedora:37
RUN dnf -y install \
adwaita-icon-theme \
@@ -82,7 +82,6 @@ RUN dnf -y install \
python3-gobject \
python3-jinja2 \
python3-markdown \
python3-packaging \
python3-pip \
python3-pygments \
python3-typogrify \

View File

@@ -20,7 +20,6 @@ flatpak build ${builddir} meson \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dbuild-tests=false \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \

View File

@@ -23,7 +23,6 @@ push=0
list=0
print_help=0
no_login=0
no_cache=0
while (($# > 0)); do
case "${1%%=*}" in
@@ -35,7 +34,6 @@ while (($# > 0)); do
--base|-b) read_arg base "$@" || shift;;
--version|-v) read_arg base_version "$@" || shift;;
--no-login) no_login=1;;
--no-cache) no_cache=1;;
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
esac
shift
@@ -105,21 +103,11 @@ TAG="${REGISTRY}/gnome/gtk/${base}:${base_version}"
if [ $build == 1 ]; then
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
if [ $no_cache == 0 ]; then
${CMD} build \
${format} \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
else
${CMD} build \
${format} \
--no-cache \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
fi
${CMD} build \
${format} \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
exit $?
fi

View File

@@ -36,7 +36,7 @@ case "${backend}" in
--suite=failing || true
;;
wayland*)
wayland)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
@@ -63,6 +63,33 @@ case "${backend}" in
kill ${compositor}
;;
waylandgles)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-6 --idle-time=0 &
compositor=$!
export WAYLAND_DISPLAY=wayland-6
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--no-suite=gsk-compare-broadway
exit_code=$?
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
kill ${compositor}
;;
broadway)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"

199
NEWS
View File

@@ -1,195 +1,8 @@
Overview of Changes in 4.11.2, xx-xx-xxxx
=========================================
Overview of Changes in 4.11.1, 03-04-2023
=========================================
* GtkLabel, GtkLinkButton:
- Make file:// uris work again
* GtkListView/GtkColumnView/GtkGridView:
- Fix clipping issues
- Handle focus movement better
- Introduce ::tab-behavior properties
- Introduce GtkListItem::focusable
- Introduce GtkColumnViewCell
- Introduce row factories in GtkColumnView
- Make list grid and column views inert when not rendering
* Drag-and-Drop:
- Support resizing drag surfaces, using the new
GdkDragSurface::compute-size signal
* Theme:
- Port .boxed-list style from Adwaita
- Make insensitive pictures appear grayed out
* Accessibility:
- Fix memory leaks
- Fix a crash
* GDK:
- Add gdk_surface_get_scale to get the fractional scale
- Use fractional scales on Wayland with cairo
- Use fractional scales on Wayland with GL if GDK_DEBUG=gl-fractional
is set. This support is still experimental
* GSK:
- Allow limiting texture sizes with GSK_MAX_TEXTURE_SIZE
- Use samplers for GL texture filtering
- Fix problems with texture slicing
- Avoid re-uploading textures when possible
- Use mipmaps when it is beneficial
* Wayland:
- Fix handling of Drag hotspots
- Fix a crash with cursor size 0
- Support absolute paths in WAYLAND_DISPLAY
- Use the fractional scale protocol
- Use a viewporter to set buffer scale
* Windows:
- Fix problems with WGL
* Vulkan:
- Some fixes to the experimental Vulkan renderer
- Support fractional scaling
* Debugging:
- Show more Wayland-specific information in the inspector
* Deprecations:
- gtk_widget_translate_coordinates
- gdk_surface_create_similar_surface
* Documentation:
- Add a section on coordinate systems
* Build:
- Require wayland-protocols 1.31
* Translation updates
- British English
- Bulgarian
- Chinese (China)
- Dutch
- French
- Persian
- Russian
Overview of Changes in 4.10.1, 14-03-2023
=========================================
* GtkFileChooser
- Improve search performance
- Be safe against pathless files
- Fix memory leaks
- Only show local files in recent files
- Show most recent files first
- Make files non-selectable in selet_folder mode
* GtkListView / GtkColumnView / GtkGridView
- Fix scrolling problems
- Support CSS border-spacing
* GtkComboBox
- Fix a size allocation problem
* gtk
- Size allocation fixes
* Accessibility
- Miscellaneous property fixes and improvements
* Wayland
- Fix an ordering problem in surface disposal
* Windows
- Fix Visual Studio build with older GLib
* Translation updates
Basque
Bulgarian
Catalan
Czech
Danish
Finnish
Friulian
Galician
Georgian
Hungarian
Lithuanian
Polish
Portuguese
Swedish
Turkish
Ukrainian
Overview of Changes in 4.10.0, 04-03-2023
=========================================
* GtkTextView
- Document hanging indentation
* GtkListView
- Fix a size allocation problem
* GtkFileChooser
- Fix paned behavior
- Fix a crash
* GtkText
- Fix various problems with undo
* Accessibility
- Make some getters transfer-full
- Allow setting accessible parents and siblings
- Add a role for toggle buttons
- Miscellaneous property fixes and improvements
* gtk
- Improve the handling resize-during-size-allocate
* gdk
- Introduce GdkTextureDownloader and use it
- Make gdk_texture_get_format public
* gsk
- Make mask nodes more versatile
- Improve the GL implementation for texture scale nodes
* X11
- Fix key handling during DND
* Tools
- gtk-builder-tool: Try harder to handle templates
- gtk-builder-tool: Prefer properties over <child>
* Translation updates
Basque
Belarusian
Bulgarian
Indonesian
Galician
Georgian
German
Hebrew
Lithuanian
Portuguese
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.9.4, 12-02-2023
Overview of Changes in 4.9.4, xx-xx-xxxx
========================================
* Printing:
- Add a CPDB backend
- Drop the lpr backend
- Add a CPDB print backend
* GtkFileDialog:
- Robustness fixes
@@ -197,28 +10,20 @@ Overview of Changes in 4.9.4, 12-02-2023
* GtkScaleButton:
- Add an 'active' property
* GtkSearchEntry:
- Add placeholder text
* Fix conflicting type names between gtk and gio
* Gsk:
- Settable filtering for scaled textures
- Add mask nodes
- Some robustness and crash fixes
* Wayland:
- Handle dispatch failing in more places
* Deprecations:
- GtkVolumeButton
* Translation updates:
Belarusian
Chinese (Taiwan)
Georgian
Turkish
Ukrainian
Overview of Changes in 4.9.3, 04-02-2023

View File

@@ -9,7 +9,7 @@ constraint_editor_sources = [
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
executable('gtk4-constraint-editor',

View File

@@ -297,13 +297,12 @@ blur_overlay_snapshot (GtkWidget *widget,
GtkWidget *main_widget;
GskRenderNode *main_widget_node = NULL;
GtkWidget *child;
int width, height;
GtkAllocation main_alloc;
cairo_region_t *clip = NULL;
int i;
main_widget = BLUR_OVERLAY (widget)->main_widget;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_widget_get_allocation (widget, &main_alloc);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
@@ -316,7 +315,7 @@ blur_overlay_snapshot (GtkWidget *widget,
if (blur > 0)
{
cairo_rectangle_int_t rect;
GtkAllocation alloc;
graphene_rect_t bounds;
if (main_widget_node == NULL)
@@ -328,8 +327,8 @@ blur_overlay_snapshot (GtkWidget *widget,
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
}
if (!gtk_widget_compute_bounds (child, gtk_widget_get_parent (child), &bounds))
graphene_rect_init (&bounds, 0, 0, 0, 0);
gtk_widget_get_allocation (child, &alloc);
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
gtk_snapshot_push_blur (snapshot, blur);
gtk_snapshot_push_clip (snapshot, &bounds);
gtk_snapshot_append_node (snapshot, main_widget_node);
@@ -338,17 +337,13 @@ blur_overlay_snapshot (GtkWidget *widget,
if (clip == NULL)
{
cairo_rectangle_int_t rect;
rect.x = rect.y = 0;
rect.width = width;
rect.height = height;
rect.width = main_alloc.width;
rect.height = main_alloc.height;
clip = cairo_region_create_rectangle (&rect);
}
rect.x = floor (bounds.origin.x);
rect.y = floor (bounds.origin.y);
rect.width = ceil (bounds.origin.x + bounds.size.width - rect.x);
rect.height = ceil (bounds.origin.y + bounds.size.height - rect.y);
cairo_region_subtract_rectangle (clip, &rect);
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
}
}

View File

@@ -43,7 +43,7 @@
<file>cssview.css</file>
<file>reset.css</file>
</gresource>
<gresource prefix="/listview_selections">
<gresource prefix="/dropdown">
<file>suggestionentry.h</file>
<file>suggestionentry.c</file>
<file>suggestionentry.css</file>
@@ -274,6 +274,7 @@
<file>cursors.c</file>
<file>dialog.c</file>
<file>drawingarea.c</file>
<file>dropdown.c</file>
<file>dnd.c</file>
<file>editable_cells.c</file>
<file>entry_completion.c</file>
@@ -297,7 +298,6 @@
<file>iconscroll.c</file>
<file>iconview.c</file>
<file>iconview_edit.c</file>
<file>image_scaling.c</file>
<file>images.c</file>
<file>infobar.c</file>
<file>layoutmanager.c</file>
@@ -310,7 +310,6 @@
<file>listview_clocks.c</file>
<file>listview_filebrowser.c</file>
<file>listview_minesweeper.c</file>
<file>listview_selections.c</file>
<file>listview_settings.c</file>
<file>listview_ucd.c</file>
<file>listview_weather.c</file>
@@ -319,6 +318,7 @@
<file>main.c</file>
<file>markup.c</file>
<file>mask.c</file>
<file>menu.c</file>
<file>overlay.c</file>
<file>overlay_decorative.c</file>
<file>paint.c</file>

View File

@@ -5,8 +5,7 @@ enum
{
PROP_TEXTURE = 1,
PROP_FILTER,
PROP_SCALE,
PROP_ANGLE,
PROP_SCALE
};
struct _Demo3Widget
@@ -15,7 +14,6 @@ struct _Demo3Widget
GdkTexture *texture;
float scale;
float angle;
GskScalingFilter filter;
GtkWidget *menu;
@@ -28,85 +26,10 @@ struct _Demo3WidgetClass
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
static gboolean
query_tooltip (GtkWidget *widget,
int x,
int y,
gboolean keyboard_mode,
GtkTooltip *tooltip,
gpointer data)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
GtkWidget *grid;
GtkWidget *label;
char *s, *s2;
const char *filter[] = { "Linear", "Nearest", "Trilinear" };
int precision, l;
grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
label = gtk_label_new ("Texture");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
s = g_strdup_printf ("%d\342\200\206\303\227\342\200\206%d",
gdk_texture_get_width (self->texture),
gdk_texture_get_height (self->texture));
label = gtk_label_new (s);
g_free (s);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
label = gtk_label_new ("Rotation");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
s = g_strdup_printf ("%.1f", self->angle);
if (g_str_has_suffix (s, ".0"))
s[strlen (s) - 2] = '\0';
s2 = g_strconcat (s, "\302\260", NULL);
label = gtk_label_new (s2);
g_free (s2);
g_free (s);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
label = gtk_label_new ("Scale");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
precision = 1;
do {
s = g_strdup_printf ("%.*f", precision, self->scale);
l = strlen (s) - 1;
while (s[l] == '0')
l--;
if (s[l] == '.')
s[l] = '\0';
precision++;
} while (strcmp (s, "0") == 0);
label = gtk_label_new (s);
g_free (s);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
label = gtk_label_new ("Filter");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
label = gtk_label_new (filter[self->filter]);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
gtk_tooltip_set_custom (tooltip, grid);
return TRUE;
}
static void
demo3_widget_init (Demo3Widget *self)
{
self->scale = 1.f;
self->angle = 0.f;
self->filter = GSK_SCALING_FILTER_LINEAR;
gtk_widget_init_template (GTK_WIDGET (self));
}
@@ -129,35 +52,26 @@ demo3_widget_snapshot (GtkWidget *widget,
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int x, y, width, height;
double w, h, w2, h2;
double w, h;
GskRenderNode *node;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
w2 = w = self->scale * gdk_texture_get_width (self->texture);
h2 = h = self->scale * gdk_texture_get_height (self->texture);
w = self->scale * gdk_texture_get_width (self->texture);
h = self->scale * gdk_texture_get_height (self->texture);
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
{
double s = w2;
w2 = h2;
h2 = s;
}
x = (width - ceil (w2)) / 2;
y = (height - ceil (h2)) / 2;
x = MAX (0, (width - ceil (w)) / 2);
y = MAX (0, (height - ceil (h)) / 2);
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (w2 / 2, h2 / 2));
gtk_snapshot_rotate (snapshot, self->angle);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- w / 2, - h / 2));
gtk_snapshot_append_scaled_texture (snapshot,
self->texture,
self->filter,
&GRAPHENE_RECT_INIT (0, 0, w, h));
node = gsk_texture_scale_node_new (self->texture,
&GRAPHENE_RECT_INIT (0, 0, w, h),
self->filter);
gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
gtk_snapshot_restore (snapshot);
gtk_snapshot_pop (snapshot);
}
@@ -172,26 +86,14 @@ demo3_widget_measure (GtkWidget *widget,
int *natural_baseline)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int width, height;
int size;
width = gdk_texture_get_width (self->texture);
height = gdk_texture_get_height (self->texture);
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
{
int s = width;
width = height;
height = s;
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
size = width;
size = gdk_texture_get_width (self->texture);
else
size = height;
size = gdk_texture_get_height (self->texture);
*minimum = *natural = (int) ceil (self->scale * size);
*minimum = *natural = self->scale * size;
}
static void
@@ -209,8 +111,6 @@ demo3_widget_size_allocate (GtkWidget *widget,
gtk_popover_present (GTK_POPOVER (self->menu));
}
static void update_actions (Demo3Widget *self);
static void
demo3_widget_set_property (GObject *object,
guint prop_id,
@@ -224,24 +124,11 @@ demo3_widget_set_property (GObject *object,
case PROP_TEXTURE:
g_clear_object (&self->texture);
self->texture = g_value_dup_object (value);
self->scale = 1.f;
self->angle = 0.f;
self->filter = GSK_SCALING_FILTER_LINEAR;
update_actions (self);
gtk_widget_queue_resize (GTK_WIDGET (object));
g_object_notify (object, "scale");
g_object_notify (object, "angle");
g_object_notify (object, "filter");
break;
case PROP_SCALE:
self->scale = g_value_get_float (value);
update_actions (self);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
case PROP_ANGLE:
self->angle = fmodf (g_value_get_float (value), 360.f);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
@@ -274,10 +161,6 @@ demo3_widget_get_property (GObject *object,
g_value_set_float (value, self->scale);
break;
case PROP_ANGLE:
g_value_set_float (value, self->angle);
break;
case PROP_FILTER:
g_value_set_enum (value, self->filter);
break;
@@ -303,14 +186,6 @@ pressed_cb (GtkGestureClick *gesture,
gtk_popover_popup (GTK_POPOVER (self->menu));
}
static void
update_actions (Demo3Widget *self)
{
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
}
static void
zoom_cb (GtkWidget *widget,
const char *action_name,
@@ -320,30 +195,19 @@ zoom_cb (GtkWidget *widget,
float scale;
if (g_str_equal (action_name, "zoom.in"))
scale = MIN (1024., self->scale * M_SQRT2);
scale = MIN (10, self->scale * M_SQRT2);
else if (g_str_equal (action_name, "zoom.out"))
scale = MAX (1./1024., self->scale / M_SQRT2);
else if (g_str_equal (action_name, "zoom.reset"))
scale = 1.0;
scale = MAX (0.01, self->scale / M_SQRT2);
else
g_assert_not_reached ();
scale = 1.0;
gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
g_object_set (widget, "scale", scale, NULL);
}
static void
rotate_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int angle;
g_variant_get (parameter, "i", &angle);
g_object_set (widget, "angle", fmodf (self->angle + angle, 360.f), NULL);
}
static void
demo3_widget_class_init (Demo3WidgetClass *class)
{
@@ -365,12 +229,7 @@ demo3_widget_class_init (Demo3WidgetClass *class)
g_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_float ("scale", NULL, NULL,
1./1024., 1024., 1.0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_ANGLE,
g_param_spec_float ("angle", NULL, NULL,
0.0, 360.0, 0.0,
0.0, 10.0, 1.0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_FILTER,
@@ -382,7 +241,6 @@ demo3_widget_class_init (Demo3WidgetClass *class)
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.reset", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "rotate", "i", rotate_cb);
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
@@ -397,12 +255,7 @@ demo3_widget_new (const char *resource)
texture = gdk_texture_new_from_resource (resource);
self = g_object_new (DEMO3_TYPE_WIDGET,
"texture", texture,
"has-tooltip", TRUE,
NULL);
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
g_object_unref (texture);

View File

@@ -12,11 +12,6 @@
<attribute name="label">11</attribute>
<attribute name="action">zoom.reset</attribute>
</item>
<item>
<attribute name="label">Rotate</attribute>
<attribute name="action">rotate</attribute>
<attribute name="target" type="i">90</attribute>
</item>
</menu>
<template class="Demo3Widget">
<child>

View File

@@ -2,19 +2,12 @@
#include "demo4widget.h"
#include "hsla.h"
enum
{
PROP_0,
PROP_PROGRESS,
};
struct _Demo4Widget
{
GtkWidget parent_instance;
PangoLayout *layout;
GskColorStop stops[8];
gsize n_stops;
double progress;
guint tick;
};
@@ -56,8 +49,6 @@ demo4_widget_init (Demo4Widget *self)
{
PangoFontDescription *desc;
self->progress = 0.5;
self->n_stops = 8;
self->stops[0].offset = 0;
self->stops[0].color = (GdkRGBA) { 1, 0, 0, 1 };
@@ -92,24 +83,16 @@ demo4_widget_dispose (GObject *object)
}
static void
demo4_widget_snapshot_content (GtkWidget *widget,
GtkSnapshot *snapshot,
GskMaskMode mode)
demo4_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
Demo4Widget *self = DEMO4_WIDGET (widget);
int width, height, layout_width, layout_height;
double scale;
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_mask (snapshot, mode);
pango_layout_get_pixel_size (self->layout, &layout_width, &layout_height);
scale = MIN ((double) width / layout_width, (double) height / layout_height);
gtk_snapshot_translate (snapshot,
&GRAPHENE_POINT_INIT ((width - scale * layout_width) / 2,
(height - scale * layout_height) / 2));
gtk_snapshot_scale (snapshot, scale, scale);
gtk_snapshot_push_mask (snapshot);
gtk_snapshot_append_layout (snapshot, self->layout, &(GdkRGBA) { 0, 0, 0, 1 });
gtk_snapshot_pop (snapshot);
@@ -122,84 +105,6 @@ demo4_widget_snapshot_content (GtkWidget *widget,
gtk_snapshot_pop (snapshot);
}
static void
demo4_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
Demo4Widget *self = DEMO4_WIDGET (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_INVERTED_LUMINANCE);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, 0),
(GskColorStop[2]) {
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
}, 2);
gtk_snapshot_pop (snapshot);
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_INVERTED_ALPHA);
gtk_snapshot_pop (snapshot);
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_LUMINANCE);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, 0),
(GskColorStop[2]) {
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
}, 2);
gtk_snapshot_pop (snapshot);
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_ALPHA);
gtk_snapshot_pop (snapshot);
}
static void
demo4_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
Demo4Widget *self = DEMO4_WIDGET (object);
switch (prop_id)
{
case PROP_PROGRESS:
self->progress = g_value_get_double (value);
gtk_widget_queue_draw (GTK_WIDGET (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo4_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
Demo4Widget *self = DEMO4_WIDGET (object);
switch (prop_id)
{
case PROP_PROGRESS:
g_value_set_double (value, self->progress);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo4_widget_class_init (Demo4WidgetClass *class)
{
@@ -207,15 +112,8 @@ demo4_widget_class_init (Demo4WidgetClass *class)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = demo4_widget_dispose;
object_class->get_property = demo4_widget_get_property;
object_class->set_property = demo4_widget_set_property;
widget_class->snapshot = demo4_widget_snapshot;
g_object_class_install_property (object_class, PROP_PROGRESS,
g_param_spec_double ("progress", NULL, NULL,
0.0, 1.0, 0.5,
G_PARAM_READWRITE));
}
GtkWidget *
@@ -223,4 +121,3 @@ demo4_widget_new (void)
{
return g_object_new (DEMO4_TYPE_WIDGET, NULL);
}

View File

@@ -324,7 +324,7 @@ canvas_item_start_editing (CanvasItem *item)
GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item));
GtkWidget *entry;
GtkWidget *scale;
graphene_point_t p;
double x, y;
if (item->editor)
return;
@@ -350,17 +350,12 @@ canvas_item_start_editing (CanvasItem *item)
gtk_box_append (GTK_BOX (item->editor), scale);
if (!gtk_widget_compute_point (GTK_WIDGET (item), canvas, &GRAPHENE_POINT_INIT (0, 0), &p))
graphene_point_init (&p, 0, 0);
gtk_fixed_put (GTK_FIXED (canvas), item->editor, p.x, p.y + 2 * item->r);
gtk_widget_translate_coordinates (GTK_WIDGET (item), canvas, 0, 0, &x, &y);
gtk_fixed_put (GTK_FIXED (canvas), item->editor, x, y + 2 * item->r);
gtk_widget_grab_focus (entry);
}
typedef struct {
double x, y;
} Hotspot;
static GdkContentProvider *
prepare (GtkDragSource *source,
double x,
@@ -368,8 +363,6 @@ prepare (GtkDragSource *source,
{
GtkWidget *canvas;
GtkWidget *item;
Hotspot *hotspot;
graphene_point_t p;
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
@@ -380,13 +373,6 @@ prepare (GtkDragSource *source,
g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
hotspot = g_new (Hotspot, 1);
if (!gtk_widget_compute_point (canvas, item, &GRAPHENE_POINT_INIT (x, y), &p))
graphene_point_init (&p, x, y);
hotspot->x = p.x;
hotspot->y = p.y;
g_object_set_data_full (G_OBJECT (canvas), "hotspot", hotspot, g_free);
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);
}
@@ -397,14 +383,12 @@ drag_begin (GtkDragSource *source,
GtkWidget *canvas;
CanvasItem *item;
GdkPaintable *paintable;
Hotspot *hotspot;
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item"));
hotspot = (Hotspot *) g_object_get_data (G_OBJECT (canvas), "hotspot");
paintable = canvas_item_get_drag_icon (item);
gtk_drag_source_set_icon (source, paintable, hotspot->x, hotspot->y);
gtk_drag_source_set_icon (source, paintable, item->r, item->r);
g_object_unref (paintable);
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);

View File

@@ -369,7 +369,7 @@ match_func (MatchObject *obj,
}
GtkWidget *
do_listview_selections (GtkWidget *do_widget)
do_dropdown (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *button, *box, *spin, *check, *hbox, *label, *entry;

View File

@@ -221,13 +221,16 @@ static void
realize (GtkWidget *widget)
{
const char *vertex_path, *fragment_path;
GdkGLContext *context;
gtk_gl_area_make_current (GTK_GL_AREA (widget));
if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL)
return;
if (gtk_gl_area_get_api (GTK_GL_AREA (widget)) == GDK_GL_API_GLES)
context = gtk_gl_area_get_context (GTK_GL_AREA (widget));
if (gdk_gl_context_get_use_es (context))
{
vertex_path = "/glarea/glarea-gles.vs.glsl";
fragment_path = "/glarea/glarea-gles.fs.glsl";

View File

@@ -48,16 +48,14 @@
#define VERTICES_PER_TOOTH 34
#define GEAR_VERTEX_STRIDE 6
static inline void
_sincos (double x, double *_sin, double *_cos)
#ifndef HAVE_SINCOS
static void
sincos (double x, double *_sin, double *_cos)
{
#ifdef HAVE_SINCOS
sincos (x, _sin, _cos);
#else
*_sin = sin (x);
*_cos = cos (x);
#endif
}
#endif
/**
* Struct describing the vertices in triangle strip
@@ -309,11 +307,11 @@ create_gear (GLfloat inner_radius,
struct point p[7];
/* Calculate needed sin/cos for various angles */
_sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
_sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
_sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
_sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
_sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
GEAR_POINT(p[0], r2, 1);
GEAR_POINT(p[1], r2, 2);
@@ -522,7 +520,7 @@ void perspective(GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloa
identity(tmp);
deltaZ = zFar - zNear;
_sincos(radians, &sine, &cosine);
sincos(radians, &sine, &cosine);
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
return;
@@ -737,6 +735,7 @@ gtk_gears_realize (GtkWidget *widget)
GtkGLArea *glarea = GTK_GL_AREA (widget);
GtkGears *gears = GTK_GEARS (widget);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
GdkGLContext *context;
GLuint vao, v, f, program;
const char *p;
char msg[512];
@@ -747,6 +746,8 @@ gtk_gears_realize (GtkWidget *widget)
if (gtk_gl_area_get_error (glarea) != NULL)
return;
context = gtk_gl_area_get_context (glarea);
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
@@ -756,7 +757,7 @@ gtk_gears_realize (GtkWidget *widget)
priv->vao = vao;
/* Compile the vertex shader */
if (gtk_gl_area_get_api (glarea) == GDK_GL_API_GLES)
if (gdk_gl_context_get_use_es (context))
p = vertex_shader_gles;
else
p = vertex_shader_gl;
@@ -767,7 +768,7 @@ gtk_gears_realize (GtkWidget *widget)
g_debug ("vertex shader info: %s\n", msg);
/* Compile the fragment shader */
if (gtk_gl_area_get_api (glarea) == GDK_GL_API_GLES)
if (gdk_gl_context_get_use_es (context))
p = fragment_shader_gles;
else
p = fragment_shader_gl;

View File

@@ -1,191 +0,0 @@
/* Image Scaling
* #Keywords: zoom, scale, filter, action, menu
*
* The custom widget we create here is similar to a GtkPicture,
* but allows setting a zoom level and filtering mode for the
* displayed paintable.
*
* It also demonstrates how to add a context menu to a custom
* widget and connect it with widget actions.
*
* The context menu has items to change the zoom level.
*/
#include <gtk/gtk.h>
#include "demo3widget.h"
static void
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
GdkTexture *texture;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
texture = gdk_texture_new_from_file (file, &error);
g_object_unref (file);
if (!texture)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
g_object_set (G_OBJECT (data), "texture", texture, NULL);
g_object_unref (texture);
}
static void
open_file (GtkWidget *picker,
GtkWidget *demo)
{
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (picker));
GtkFileDialog *dialog;
GtkFileFilter *filter;
GListStore *filters;
dialog = gtk_file_dialog_new ();
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, "Images");
gtk_file_filter_add_pixbuf_formats (filter);
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
g_list_store_append (filters, filter);
g_object_unref (filter);
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
g_object_unref (filters);
gtk_file_dialog_open (dialog, parent, NULL, file_opened, demo);
g_object_unref (dialog);
}
static void
rotate (GtkWidget *button,
GtkWidget *demo)
{
float angle;
g_object_get (demo, "angle", &angle, NULL);
angle = fmodf (angle + 90.f, 360.f);
g_object_set (demo, "angle", angle, NULL);
}
static gboolean
transform_to (GBinding *binding,
const GValue *src,
GValue *dest,
gpointer user_data)
{
double from;
float to;
from = g_value_get_double (src);
to = (float) pow (2., from);
g_value_set_float (dest, to);
return TRUE;
}
static gboolean
transform_from (GBinding *binding,
const GValue *src,
GValue *dest,
gpointer user_data)
{
float to;
double from;
to = g_value_get_float (src);
from = log2 (to);
g_value_set_double (dest, from);
return TRUE;
}
GtkWidget *
do_image_scaling (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *box;
GtkWidget *box2;
GtkWidget *sw;
GtkWidget *widget;
GtkWidget *scale;
GtkWidget *dropdown;
GtkWidget *button;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
sw = gtk_scrolled_window_new ();
gtk_widget_set_vexpand (sw, TRUE);
gtk_box_append (GTK_BOX (box), sw);
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (box), box2);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
gtk_widget_set_tooltip_text (button, "Open File");
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
gtk_widget_set_tooltip_text (button, "Rotate");
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
gtk_box_append (GTK_BOX (box2), button);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
gtk_widget_set_tooltip_text (scale, "Zoom");
gtk_range_set_value (GTK_RANGE (scale), 0.);
gtk_widget_set_hexpand (scale, TRUE);
gtk_box_append (GTK_BOX (box2), scale);
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
gtk_widget_set_tooltip_text (dropdown, "Filter");
gtk_box_append (GTK_BOX (box2), dropdown);
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL,
transform_to,
transform_from,
NULL, NULL);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -30,86 +30,90 @@
</object>
</child>
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<signal name="row-activated" handler="row_activated"/>
<style>
<class name="rich-list"/>
<class name="boxed-list"/>
</style>
<object class="GtkFrame">
<child>
<object class="GtkListBoxRow">
<object class="GtkListBox">
<property name="selection-mode">none</property>
<property name="show-separators">1</property>
<signal name="row-activated" handler="row_activated"/>
<style>
<class name="rich-list"/>
</style>
<child>
<object class="GtkBox">
<object class="GtkListBoxRow">
<child>
<object class="GtkLabel" id="switch_label">
<property name="label" translatable="yes">Switch</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="switch">
<property name="halign">end</property>
<property name="valign">center</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="switch_label">
<property name="label" translatable="yes">Switch</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="switch">
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<child>
<object class="GtkBox">
<object class="GtkListBoxRow">
<child>
<object class="GtkLabel" id="check_label">
<property name="label" translatable="yes">Check</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="check">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="active">1</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="check_label">
<property name="label" translatable="yes">Check</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="check">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="active">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<child>
<object class="GtkBox">
<object class="GtkListBoxRow">
<child>
<object class="GtkLabel" id="image_label">
<property name="label" translatable="yes">Click here!</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkImage" id="image">
<property name="icon-name">object-select-symbolic</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="opacity">0</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="image_label">
<property name="label" translatable="yes">Click here!</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkImage" id="image">
<property name="icon-name">object-select-symbolic</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="opacity">0</property>
</object>
</child>
</object>
</child>
</object>
@@ -130,142 +134,146 @@
</style>
</object>
</child>
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<style>
<class name="rich-list"/>
<class name="boxed-list"/>
</style>
<child>
<object class="GtkFrame">
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<property name="show-separators">1</property>
<style>
<class name="rich-list"/>
</style>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="scale_label">
<property name="label" translatable="yes">Scale</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">0</property>
<property name="width-request">150</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="scale_label">
<property name="label" translatable="yes">Scale</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">0</property>
<property name="width-request">150</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="spin_label">
<property name="label" translatable="yes">Spinbutton</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSpinButton">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="dropdown_label">
<property name="label" translatable="yes">Dropdown</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkDropDown">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Choice 1</item>
<item>Choice 2</item>
<item>Choice 3</item>
<item>Choice 4</item>
</items>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="spin_label">
<property name="label" translatable="yes">Spinbutton</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSpinButton">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="dropdown_label">
<property name="label" translatable="yes">Dropdown</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkDropDown">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Choice 1</item>
<item>Choice 2</item>
<item>Choice 3</item>
<item>Choice 4</item>
</items>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="entry_label">
<property name="label" translatable="yes">Entry</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="placeholder-text">Type here…</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="entry_label">
<property name="label" translatable="yes">Entry</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="placeholder-text">Type here…</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>

View File

@@ -29,7 +29,6 @@ struct _SettingsKey
enum {
PROP_0,
PROP_NAME,
PROP_SETTINGS,
PROP_SUMMARY,
PROP_DESCRIPTION,
PROP_VALUE,
@@ -90,10 +89,6 @@ settings_key_get_property (GObject *object,
}
break;
case PROP_SETTINGS:
g_value_set_object (value, self->settings);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -123,8 +118,6 @@ settings_key_class_init (SettingsKeyClass *klass)
g_param_spec_string ("description", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_SETTINGS] =
g_param_spec_object ("settings", NULL, NULL, G_TYPE_SETTINGS, G_PARAM_READABLE);
properties[PROP_SUMMARY] =
g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_VALUE] =
@@ -154,27 +147,10 @@ settings_key_new (GSettings *settings,
return result;
}
static char *
settings_key_get_search_string (SettingsKey *self)
{
char *schema, *result;
g_object_get (self->settings, "schema-id", &schema, NULL);
result = g_strconcat (g_settings_schema_key_get_name (self->key), " ",
g_settings_schema_key_get_summary (self->key), " ",
schema,
NULL);
g_free (schema);
return result;
}
static void
item_value_changed (GtkEditableLabel *label,
GParamSpec *pspec,
GtkColumnViewCell *cell)
item_value_changed (GtkEditableLabel *label,
GParamSpec *pspec,
GtkListItem *item)
{
SettingsKey *self;
const char *text;
@@ -186,7 +162,8 @@ item_value_changed (GtkEditableLabel *label,
text = gtk_editable_get_text (GTK_EDITABLE (label));
self = gtk_column_view_cell_get_item (cell);
g_object_get (item, "item", &self, NULL);
g_object_unref (self);
type = g_settings_schema_key_get_value_type (self->key);
name = g_settings_schema_key_get_name (self->key);
@@ -227,16 +204,28 @@ strvcmp (gconstpointer p1,
return strcmp (*s1, *s2);
}
static gpointer
map_settings_to_keys (gpointer item,
gpointer unused)
static GtkFilter *current_filter;
static gboolean
transform_settings_to_keys (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer data)
{
GSettings *settings = item;
GtkTreeListRow *treelistrow;
GSettings *settings;
GSettingsSchema *schema;
GListStore *store;
GtkSortListModel *sort_model;
GtkFilterListModel *filter_model;
GtkFilter *filter;
char **keys;
guint i;
treelistrow = g_value_get_object (from_value);
if (treelistrow == NULL)
return TRUE;
settings = gtk_tree_list_row_get_item (treelistrow);
g_object_get (settings, "settings-schema", &schema, NULL);
store = g_list_store_new (SETTINGS_TYPE_KEY);
@@ -256,7 +245,16 @@ map_settings_to_keys (gpointer item,
g_settings_schema_unref (schema);
g_object_unref (settings);
return store;
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (store),
g_object_ref (gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data))));
filter = GTK_FILTER (gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name")));
g_set_object (&current_filter, filter);
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
g_value_take_object (to_value, gtk_no_selection_new (G_LIST_MODEL (filter_model)));
return TRUE;
}
static GListModel *
@@ -313,11 +311,24 @@ search_enabled (GtkSearchEntry *entry)
gtk_editable_set_text (GTK_EDITABLE (entry), "");
}
static void
search_changed (GtkSearchEntry *entry,
gpointer data)
{
const char *text = gtk_editable_get_text (GTK_EDITABLE (entry));
if (current_filter)
gtk_string_filter_set_search (GTK_STRING_FILTER (current_filter), text);
}
static void
stop_search (GtkSearchEntry *entry,
gpointer data)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
if (current_filter)
gtk_string_filter_set_search (GTK_STRING_FILTER (current_filter), "");
}
static GtkWidget *window = NULL;
@@ -327,53 +338,94 @@ do_listview_settings (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkListView *listview;
GtkWidget *listview, *columnview;
GListModel *model;
GtkTreeListModel *treemodel;
GtkNoSelection *selection;
GtkSingleSelection *selection;
GtkBuilderScope *scope;
GtkBuilder *builder;
GError *error = NULL;
GtkFilter *filter;
GtkColumnViewColumn *name_column;
GtkColumnViewColumn *type_column;
GtkColumnViewColumn *default_column;
GtkColumnViewColumn *summary_column;
GtkColumnViewColumn *description_column;
GtkSorter *sorter;
GActionGroup *actions;
GAction *action;
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, search_enabled);
gtk_builder_cscope_add_callback (scope, search_changed);
gtk_builder_cscope_add_callback (scope, stop_search);
gtk_builder_cscope_add_callback (scope, settings_key_get_search_string);
gtk_builder_cscope_add_callback (scope, item_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
gtk_builder_add_from_resource (builder, "/listview_settings/listview_settings.ui", &error);
g_assert_no_error (error);
gtk_builder_add_from_resource (builder, "/listview_settings/listview_settings.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
listview = GTK_LIST_VIEW (gtk_builder_get_object (builder, "listview"));
filter = GTK_FILTER (gtk_builder_get_object (builder, "filter"));
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
columnview = GTK_WIDGET (gtk_builder_get_object (builder, "columnview"));
type_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "type_column"));
default_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "default_column"));
summary_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "summary_column"));
description_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "description_column"));
actions = G_ACTION_GROUP (g_simple_action_group_new ());
action = G_ACTION (g_property_action_new ("show-type", type_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
action = G_ACTION (g_property_action_new ("show-default", default_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
action = G_ACTION (g_property_action_new ("show-summary", summary_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
action = G_ACTION (g_property_action_new ("show-description", description_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
gtk_widget_insert_action_group (columnview, "columnview", actions);
g_object_unref (actions);
model = create_settings_model (NULL, NULL);
treemodel = gtk_tree_list_model_new (model,
TRUE,
FALSE,
TRUE,
create_settings_model,
NULL,
NULL);
model = G_LIST_MODEL (gtk_map_list_model_new (G_LIST_MODEL (treemodel), map_settings_to_keys, NULL, NULL));
model = G_LIST_MODEL (gtk_flatten_list_model_new (model));
model = G_LIST_MODEL (gtk_filter_list_model_new (model, g_object_ref (filter)));
selection = gtk_no_selection_new (model);
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_object_bind_property_full (selection, "selected-item",
columnview, "model",
G_BINDING_SYNC_CREATE,
transform_settings_to_keys,
NULL,
columnview, NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), GTK_SELECTION_MODEL (selection));
g_object_unref (selection);
name_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "name_column"));
sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name")));
gtk_column_view_column_set_sorter (name_column, sorter);
g_object_unref (sorter);
sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "type")));
gtk_column_view_column_set_sorter (type_column, sorter);
g_object_unref (sorter);
g_object_unref (builder);
}

View File

@@ -1,11 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkStringFilter" id="filter">
<property name="expression">
<closure type="gchararray" function="settings_key_get_search_string" />
</property>
<property name="search" bind-source="entry" bind-property="text" />
</object>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Settings</property>
<property name="default-width">640</property>
@@ -20,26 +14,14 @@
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional"/>
<signal name="notify::search-mode-enabled" handler="search_enabled" object="entry"/>
<child>
<object class="GtkSearchEntry" id="entry">
<signal name="stop-search" handler="stop_search"/>
</object>
</child>
</object>
</child>
<object class="GtkPaned">
<property name="position">300</property>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView" id="listview">
<property name="vexpand">1</property>
<style>
<class name="rich-list"/>
<class name="navigation-sidebar"/>
</style>
<property name="factory">
<object class="GtkBuilderListItemFactory">
@@ -48,48 +30,20 @@
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<style>
<class name="dim-label"/>
</style>
<property name="xalign">0</property>
<property name="ellipsize">end</property>
<binding name="label">
<lookup name="summary" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="hexpand">1</property>
<property name="halign">end</property>
<binding name="text">
<lookup name="value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="schema" type="GSettings">
<lookup name="item">expander</lookup>
</lookup>
</binding>
<signal name="notify::label" handler="item_value_changed"/>
</object>
</child>
</property>
</object>
</property>
</template>
@@ -97,29 +51,210 @@
]]></property>
</object>
</property>
<property name="header-factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional"/>
<signal name="notify::search-mode-enabled" handler="search_enabled" object="entry"/>
<child>
<object class="GtkSearchEntry" id="entry">
<signal name="search-changed" handler="search_changed"/>
<signal name="stop-search" handler="stop_search"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkColumnView" id="columnview">
<style>
<class name="data-table"/>
</style>
<child>
<object class="GtkColumnViewColumn" id="name_column">
<property name="title">Name</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListHeader">
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="schema" type="GSettings">
<lookup name="settings" type="SettingsKey">
<lookup name="item">GtkListHeader</lookup>
</lookup>
<lookup name="name" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn">
<property name="title">Value</property>
<property name="resizable">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkEditableLabel">
<binding name="text">
<lookup name="value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<signal name="notify::label" handler="item_value_changed"/>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="type_column">
<property name="title">Type</property>
<property name="resizable">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="type" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="default_column">
<property name="title">Default</property>
<property name="resizable">1</property>
<property name="expand">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="default-value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="summary_column">
<property name="title">Summary</property>
<property name="resizable">1</property>
<property name="visible">0</property>
<property name="expand">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="wrap">1</property>
<binding name="label">
<lookup name="summary" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="description_column">
<property name="title">Description</property>
<property name="resizable">1</property>
<property name="visible">0</property>
<property name="expand">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="wrap">1</property>
<binding name="label">
<lookup name="description" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</property>
</child>
</object>
</child>
</object>
@@ -127,4 +262,24 @@
</object>
</child>
</object>
<menu id="header_menu">
<section>
<item>
<attribute name="label" translatable="yes">Type</attribute>
<attribute name="action">columnview.show-type</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Default value</attribute>
<attribute name="action">columnview.show-default</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Summary</attribute>
<attribute name="action">columnview.show-summary</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Description</attribute>
<attribute name="action">columnview.show-description</attribute>
</item>
</section>
</menu>
</interface>

View File

@@ -63,19 +63,6 @@ ucd_item_get_name (UcdItem *item)
return item->name;
}
static int
compare_script (gconstpointer a, gconstpointer b, gpointer data)
{
const UcdItem *ai = a;
const UcdItem *bi = b;
int s1, s2;
s1 = (int) g_unichar_get_script (ai->codepoint);
s2 = (int) g_unichar_get_script (bi->codepoint);
return s2 - s1;
}
static GListModel *
ucd_model_new (void)
{
@@ -85,7 +72,6 @@ ucd_model_new (void)
GListStore *store;
guint u;
char *name;
GtkSortListModel *sortmodel;
bytes = g_resources_lookup_data ("/listview_ucd_data/ucdnames.data", 0, NULL);
v = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(us)"), bytes, TRUE));
@@ -107,10 +93,7 @@ ucd_model_new (void)
g_variant_unref (v);
g_bytes_unref (bytes);
sortmodel = gtk_sort_list_model_new (G_LIST_MODEL (store), NULL);
gtk_sort_list_model_set_section_sorter (sortmodel, GTK_SORTER (gtk_custom_sorter_new (compare_script, NULL, NULL)));
return G_LIST_MODEL (sortmodel);
return G_LIST_MODEL (store);
}
static void
@@ -240,16 +223,6 @@ bind_combining_class (GtkSignalListItemFactory *factory,
gtk_label_set_label (GTK_LABEL (label), get_combining_class_name (g_unichar_combining_class (codepoint)));
}
static void
setup_header (GtkSignalListItemFactory *factory,
GObject *listitem)
{
GtkWidget *label;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_list_header_set_child (GTK_LIST_HEADER (listitem), label);
}
static void
bind_script (GtkSignalListItemFactory *factory,
GObject *listitem)
@@ -259,8 +232,8 @@ bind_script (GtkSignalListItemFactory *factory,
gunichar codepoint;
GUnicodeScript script;
label = gtk_list_header_get_child (GTK_LIST_HEADER (listitem));
item = gtk_list_header_get_item (GTK_LIST_HEADER (listitem));
label = gtk_list_item_get_child (GTK_LIST_ITEM (listitem));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
codepoint = ucd_item_get_codepoint (UCD_ITEM (item));
script = g_unichar_get_script (codepoint);
@@ -352,10 +325,12 @@ create_ucd_view (GtkWidget *label)
g_object_unref (column);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_header), NULL);
g_signal_connect (factory, "setup", G_CALLBACK (setup_label), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_script), NULL);
gtk_column_view_set_header_factory (GTK_COLUMN_VIEW (cv), factory);
g_object_unref (factory);
column = gtk_column_view_column_new ("Script", factory);
gtk_column_view_column_set_resizable (column, TRUE);
gtk_column_view_append_column (GTK_COLUMN_VIEW (cv), column);
g_object_unref (column);
return cv;
}

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="focusable">0</property>
<property name="child">
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">

View File

@@ -18,8 +18,7 @@ do_mask (GtkWidget *do_widget)
if (!window)
{
GtkWidget *box;
GtkWidget *demo;
GtkWidget *scale;
GtkWidget *widget;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Mask Nodes");
@@ -31,17 +30,11 @@ do_mask (GtkWidget *do_widget)
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
demo = demo4_widget_new ();
gtk_widget_set_hexpand (demo, TRUE);
gtk_widget_set_vexpand (demo, TRUE);
widget = demo4_widget_new ();
gtk_widget_set_hexpand (widget, TRUE);
gtk_widget_set_vexpand (widget, TRUE);
gtk_box_append (GTK_BOX (box), demo);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 1, 0.1);
gtk_range_set_value (GTK_RANGE (scale), 0.5);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value", demo, "progress", 0);
gtk_box_append (GTK_BOX (box), scale);
gtk_box_append (GTK_BOX (box), widget);
}
if (!gtk_widget_get_visible (window))

72
demos/gtk-demo/menu.c Normal file
View File

@@ -0,0 +1,72 @@
/* Menu
* #Keywords: action, zoom
*
* Demonstrates how to add a context menu to a custom widget
* and connect it with widget actions.
*
* The custom widget we create here is similar to a GtkPicture,
* but allows setting a zoom level for the displayed paintable.
*
* Our context menu has items to change the zoom level.
*/
#include <gtk/gtk.h>
#include "demo3widget.h"
GtkWidget *
do_menu (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *box;
GtkWidget *box2;
GtkWidget *sw;
GtkWidget *widget;
GtkWidget *scale;
GtkWidget *dropdown;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Menu");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
sw = gtk_scrolled_window_new ();
gtk_widget_set_vexpand (sw, TRUE);
gtk_box_append (GTK_BOX (box), sw);
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (box), box2);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
gtk_range_set_value (GTK_RANGE (scale), 1.0);
gtk_widget_set_hexpand (scale, TRUE);
gtk_box_append (GTK_BOX (box2), scale);
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
gtk_box_append (GTK_BOX (box2), dropdown);
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -39,7 +39,6 @@ demos = files([
'iconscroll.c',
'iconview.c',
'iconview_edit.c',
'image_scaling.c',
'images.c',
'infobar.c',
'layoutmanager.c',
@@ -48,6 +47,7 @@ demos = files([
'listbox.c',
'listbox_controls.c',
'mask.c',
'menu.c',
'flowbox.c',
'list_store.c',
'listview_applauncher.c',
@@ -55,7 +55,7 @@ demos = files([
'listview_colors.c',
'listview_filebrowser.c',
'listview_minesweeper.c',
'listview_selections.c',
'dropdown.c',
'listview_settings.c',
'listview_ucd.c',
'listview_weather.c',
@@ -225,7 +225,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
'demo.gresource.xml',
source_dir: meson.current_source_dir()
source_dir: '.',
)
endif

View File

@@ -103,11 +103,13 @@ drawing_area_size_allocate (GtkWidget *widget,
static void
drawing_area_map (GtkWidget *widget)
{
GtkAllocation allocation;
GTK_WIDGET_CLASS (drawing_area_parent_class)->map (widget);
gtk_widget_get_allocation (widget, &allocation);
drawing_area_ensure_surface ((DrawingArea *) widget,
gtk_widget_get_width (widget),
gtk_widget_get_height (widget));
allocation.width, allocation.height);
}
static void

View File

@@ -13,13 +13,20 @@
static GtkWidget *app_picker;
static void
set_file (GFile *file,
gpointer data)
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
char *name;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
return;
@@ -33,25 +40,6 @@ set_file (GFile *file,
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
}
static void
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
}
set_file (file, data);
}
static gboolean
abort_mission (gpointer data)
{
@@ -142,28 +130,11 @@ launch_uri (GtkButton *picker)
g_object_unref (launcher);
}
static gboolean
on_drop (GtkDropTarget *target,
const GValue *value,
double x,
double y,
gpointer data)
{
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
set_file (g_value_get_object (value), data);
return TRUE;
}
return FALSE;
}
GtkWidget *
do_pickers (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *table, *label, *picker, *button;
GtkDropTarget *drop_target;
if (!window)
{
@@ -208,13 +179,7 @@ do_pickers (GtkWidget *do_widget)
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
label = gtk_label_new ("None");
drop_target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
g_signal_connect (drop_target, "drop", G_CALLBACK (on_drop), label);
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (drop_target));
gtk_label_set_xalign (GTK_LABEL (label), 0.);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_hexpand (label, TRUE);

View File

@@ -22,7 +22,6 @@ show_shortcuts (GtkWidget *window,
gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
g_object_set (overlay, "view-name", view, NULL);
g_object_unref (builder);
gtk_window_present (GTK_WINDOW (overlay));
}
G_MODULE_EXPORT void

View File

@@ -849,7 +849,7 @@ suggestion_entry_init (SuggestionEntry *self)
GtkCssProvider *provider;
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/listview_selections/suggestionentry.css");
gtk_css_provider_load_from_resource (provider, "/dropdown/suggestionentry.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);

View File

@@ -1,5 +1,5 @@
/* Overlay/Transparency
* #Keywords: GtkOverlay, GtkSnapshot, blur
* #Keywords: GtkOverlay, GtkSnapshot
*
* Blur the background behind an overlay.
*/

View File

@@ -8,7 +8,7 @@ iconbrowser_sources = [
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
'iconbrowser.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
executable('gtk4-icon-browser',

View File

@@ -7,7 +7,7 @@ node_editor_sources = [
node_editor_resources = gnome.compile_resources('node_editor_resources',
'node-editor.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
executable('gtk4-node-editor',

View File

@@ -32,11 +32,6 @@
#include "gsk/vulkan/gskvulkanrenderer.h"
#endif
#include <cairo.h>
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
#endif
typedef struct
{
gsize start_chars;
@@ -174,7 +169,6 @@ text_changed (GtkTextBuffer *buffer,
GtkTextIter iter;
GtkTextIter start, end;
float scale;
GskRenderNode *big_node;
g_array_remove_range (self->errors, 0, self->errors->len);
text = get_current_text (self->text_buffer);
@@ -187,18 +181,13 @@ text_changed (GtkTextBuffer *buffer,
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
scale = gtk_scale_button_get_value (GTK_SCALE_BUTTON (self->scale_scale));
if (self->node && scale != 0.)
if (self->node && scale != 1.0)
{
scale = pow (2., scale);
big_node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
}
else if (self->node)
{
big_node = gsk_render_node_ref (self->node);
}
else
{
big_node = NULL;
GskRenderNode *node;
node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
gsk_render_node_unref (self->node);
self->node = node;
}
g_bytes_unref (bytes);
@@ -210,27 +199,18 @@ text_changed (GtkTextBuffer *buffer,
graphene_rect_t bounds;
guint i;
snapshot = gtk_snapshot_new ();
gsk_render_node_get_bounds (big_node, &bounds);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y));
gtk_snapshot_append_node (snapshot, big_node);
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
gtk_picture_set_paintable (GTK_PICTURE (self->picture), paintable);
g_clear_object (&paintable);
snapshot = gtk_snapshot_new ();
gsk_render_node_get_bounds (self->node, &bounds);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y));
gtk_snapshot_append_node (snapshot, self->node);
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size);
gtk_picture_set_paintable (GTK_PICTURE (self->picture), paintable);
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->renderers)); i++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
gtk_renderer_paintable_set_paintable (item, paintable);
g_object_unref (item);
}
g_clear_object (&paintable);
}
else
@@ -238,8 +218,6 @@ text_changed (GtkTextBuffer *buffer,
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL);
}
g_clear_pointer (&big_node, gsk_render_node_unref);
gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
while (!gtk_text_iter_is_end (&iter))
@@ -665,34 +643,23 @@ save_cb (GtkWidget *button,
g_object_unref (dialog);
}
static GskRenderNode *
create_node (NodeEditorWindow *self)
static GdkTexture *
create_texture (NodeEditorWindow *self)
{
GdkPaintable *paintable;
GtkSnapshot *snapshot;
GskRenderer *renderer;
GskRenderNode *node;
GdkTexture *texture;
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
if (paintable == NULL ||
gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
gdk_paintable_get_intrinsic_height (paintable) <= 0)
return NULL;
snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
node = gtk_snapshot_free_to_node (snapshot);
return node;
}
static GdkTexture *
create_texture (NodeEditorWindow *self)
{
GskRenderer *renderer;
GskRenderNode *node;
GdkTexture *texture;
node = create_node (self);
if (node == NULL)
return NULL;
@@ -703,58 +670,6 @@ create_texture (NodeEditorWindow *self)
return texture;
}
#ifdef CAIRO_HAS_SVG_SURFACE
static cairo_status_t
cairo_serializer_write (gpointer user_data,
const unsigned char *data,
unsigned int length)
{
g_byte_array_append (user_data, data, length);
return CAIRO_STATUS_SUCCESS;
}
static GBytes *
create_svg (GskRenderNode *node,
GError **error)
{
cairo_surface_t *surface;
cairo_t *cr;
graphene_rect_t bounds;
GByteArray *array;
gsk_render_node_get_bounds (node, &bounds);
array = g_byte_array_new ();
surface = cairo_svg_surface_create_for_stream (cairo_serializer_write,
array,
bounds.size.width,
bounds.size.height);
cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX);
cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_finish (surface);
if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
{
cairo_surface_destroy (surface);
return g_byte_array_free_to_bytes (array);
}
else
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"%s", cairo_status_to_string (cairo_surface_status (surface)));
cairo_surface_destroy (surface);
g_byte_array_unref (array);
return NULL;
}
}
#endif
static GdkTexture *
create_cairo_texture (NodeEditorWindow *self)
{
@@ -787,140 +702,50 @@ create_cairo_texture (NodeEditorWindow *self)
}
static void
export_image_saved_cb (GObject *source,
GAsyncResult *result,
void *user_data)
{
GError *error = NULL;
if (!g_file_replace_contents_finish (G_FILE (source), result, NULL, &error))
{
GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Exporting to image failed");
gtk_alert_dialog_set_detail (alert, error->message);
gtk_alert_dialog_show (alert, NULL);
g_object_unref (alert);
g_clear_error (&error);
}
}
static void
export_image_response_cb (GObject *source,
export_image_response_cb (GObject *source,
GAsyncResult *result,
void *user_data)
void *user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GskRenderNode *node = user_data;
GdkTexture *texture = user_data;
GFile *file;
char *uri;
GBytes *bytes;
file = gtk_file_dialog_save_finish (dialog, result, NULL);
if (file == NULL)
if (file)
{
gsk_render_node_unref (node);
return;
}
uri = g_file_get_uri (file);
#ifdef CAIRO_HAS_SVG_SURFACE
if (g_str_has_suffix (uri, "svg"))
{
GError *error = NULL;
bytes = create_svg (node, &error);
if (bytes == NULL)
if (!gdk_texture_save_to_png (texture, g_file_peek_path (file)))
{
GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Exporting to image failed");
gtk_alert_dialog_set_detail (alert, error->message);
gtk_alert_dialog_show (alert, NULL);
gtk_alert_dialog_show (alert, GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))));
g_object_unref (alert);
g_clear_error (&error);
}
}
else
#endif
{
GdkTexture *texture;
GskRenderer *renderer;
renderer = gsk_gl_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
g_object_unref (renderer);
renderer = gsk_cairo_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
g_assert_not_reached ();
}
}
texture = gsk_renderer_render_texture (renderer, node, NULL);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
if (g_str_has_suffix (uri, "tiff"))
bytes = gdk_texture_save_to_tiff_bytes (texture);
else
bytes = gdk_texture_save_to_png_bytes (texture);
g_object_unref (texture);
g_object_unref (file);
}
g_free (uri);
if (bytes)
{
g_file_replace_contents_bytes_async (file,
bytes,
NULL,
FALSE,
0,
NULL,
export_image_saved_cb,
NULL);
g_bytes_unref (bytes);
}
gsk_render_node_unref (node);
g_object_unref (file);
g_object_unref (texture);
}
static void
export_image_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GskRenderNode *node;
GdkTexture *texture;
GtkFileDialog *dialog;
GtkFileFilter *filter;
GListStore *filters;
node = create_node (self);
if (node == NULL)
texture = create_texture (self);
if (texture == NULL)
return;
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/png");
g_list_store_append (filters, filter);
g_object_unref (filter);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/svg+xml");
g_list_store_append (filters, filter);
g_object_unref (filter);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/tiff");
g_list_store_append (filters, filter);
g_object_unref (filter);
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "");
gtk_file_dialog_set_initial_name (dialog, "example.png");
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL,
export_image_response_cb, node);
g_object_unref (filters);
export_image_response_cb, texture);
g_object_unref (dialog);
}
@@ -1034,19 +859,6 @@ testcase_save_clicked_cb (GtkWidget *button,
}
text = get_current_text (self->text_buffer);
{
GBytes *bytes;
GskRenderNode *node;
gsize size;
bytes = g_bytes_new_take (text, strlen (text) + 1);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
bytes = gsk_render_node_serialize (node);
gsk_render_node_unref (node);
text = g_bytes_unref_to_data (bytes, &size);
}
if (!g_file_set_contents (node_file, text, -1, &error))
{
gtk_label_set_label (GTK_LABEL (self->testcase_error_label), error->message);

View File

@@ -163,9 +163,9 @@
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="lower">-4</property>
<property name="value">0</property>
<property name="upper">4</property>
<property name="lower">1</property>
<property name="value">1</property>
<property name="upper">10</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.5</property>
</object>

View File

@@ -2,29 +2,19 @@
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the parsing APIs.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the aprsing APIs.
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
**document**: `<node>\*`
**node**: container [ "name" ] { <document> } | `<node-type> [ "name" ] { <property>* }` | "name"
**node**: container { <document> } | `<node-name> { <property>* }`
**property**: `<property-name>: <node> | <value> ;`
Each node has its own `<node-type>` and supports a custom set of properties, each with their own `<property-name>` and syntax. The following paragraphs document each of the nodes and their properties.
Each node has its own `<node-name>` and supports a custom set of properties, each with their own `<property-name>` and syntax. The following paragraphs document each of the nodes and their properties.
When serializing and the value of a property equals the default value, this value will not be serialized. Serialization aims to produce an output as small as possible.
To embed newlines in strings, use \A. To break a long string into multiple lines, escape the newline with a \.
# Names
### Nodes
Nodes can be given a name by adding a string after the `<node-type>` in their definition. That same node can then be used further down in the document by specifying just the name identifying the node.
### Textures
Just like nodes, textures can be referenced by name. When defining a named texture, the name has to be placed in front of the URL.
# Nodes
### container
@@ -188,16 +178,6 @@ Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
### mask
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| source | `<node>` | color { } | always |
| mode | `<blend-mode>` | alpha | non-default |
| mask | `<node>` | color { } | always |
Creates a node like `gsk_mask_node_new()` with the given properties.
### opacity
| property | syntax | default | printed |

View File

@@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
'widget-factory.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
endif

View File

@@ -500,9 +500,8 @@ Public headers should never be included directly:
Private headers should include the public header first, if one exists:
```c
#pragma once
/* gtkfooprivate.h */
#ifndef __GTK_FOO_PRIVATE_H__
#define __GTK_FOO_PRIVATE_H__
#include "gtkfoo.h"
@@ -511,8 +510,18 @@ Private headers should include the public header first, if one exists:
#endif /* __GTK_FOO_PRIVATE_H__ */
```
All headers should use the `once` pragma to prevent multiple inclusion,
instead of the classic pre-processor guards:
All headers should have inclusion guards:
```c
#ifndef __GTK_FOO_H__
#define __GTK_FOO_H__
...
#endif /* __GTK_FOO_H__ */
```
You can also use the `once` pragma instead of the classic pre-processor guard:
```c
#pragma once
@@ -544,8 +553,6 @@ the source file, either the public installed header, or the private header, if
it exists.
```c
/* gtkfoo.c */
#include "config.h"
#include "gtkfoo.h"
@@ -587,8 +594,8 @@ Finally, source files should include the system headers last:
#include <string.h>
```
Cyclic dependencies should be avoided if at all possible;
for instance, you could use additional headers to break cycles.
Cyclic dependencies should be avoided if at all possible; for instance, you
could use additional headers to break cycles.
### GObject
@@ -629,8 +636,7 @@ Instance structures should only contain the parent type:
```
You should use the `G_DECLARE_DERIVABLE_TYPE()` and `G_DECLARE_FINAL_TYPE()`
macros in newly written headers. There is also a `GDK_DECLARE_INTERNAL_TYPE()`
for declaring types that can be derived inside GTK, but not in 3rd party code.
macros in newly written headers.
Inside your source file, always use the `G_DEFINE_TYPE()`,
`G_DEFINE_TYPE_WITH_PRIVATE()`, and `G_DEFINE_TYPE_WITH_CODE()` macros, or their
@@ -670,20 +676,13 @@ Interfaces must have the following macros:
| `GTK_IS_<iface_name>` | `G_TYPE_CHECK_INSTANCE_TYPE` |
| `GTK_<iface_name>_GET_IFACE` | `G_TYPE_INSTANCE_GET_INTERFACE` |
The `G_DECLARE` macros define these as static inline functions instead.
### Memory allocation
When dynamically allocating data on the heap use `g_new()`.
When dynamically allocating data on the heap either use `g_new()` or,
if allocating multiple small data structures, `g_slice_new()`.
Public structure types should always be returned after being zero-ed,
either explicitly for each member, or by using `g_new0()`. Do not use
`g_slice` in new code.
Memory that is only needed within the scope of a function can be
stack-allocated using `g_newa()` or `g_alloca()`. But limit the amount
of stack memory that you consume this way, in particular in recursive
functions.
either explicitly for each member, or by using `g_new0()` or `g_slice_new0()`.
### Macros

View File

@@ -6,15 +6,22 @@ Slug: broadway
The GDK Broadway backend provides support for displaying GTK applications in
a web browser, using HTML5 and web sockets.
To run your application in this way, first run the broadway server,
`gtk-broadwayd`, that ships with GTK:
To run your application in this way, select the Broadway backend by setting
`GDK_BACKEND=broadway`. Then you can make your application appear in a web
browser by pointing it at `http://127.0.0.1:8080`. Note that you need to
enable web sockets in your web browser.
You can choose a different port from the default 8080 by setting the
`BROADWAY_DISPLAY` environment variable to the port that you want to use.
It is also possible to use multiple GTK applications in the same web browser
window, by using the Broadway server, `gtk4-broadwayd`, that ships with GTK.
To start the Broadway server use:
```
gtk4-broadwayd :5
```
The server expects the colon-prefixed display number as a commandline argument.
Then point your web browser at `http://127.0.0.1:8085`.
Once the Broadway server is running, you can start your applications like
@@ -24,8 +31,6 @@ this:
GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo
```
Multiple applications can be presented in the same web browser window.
## Broadway-specific environment variables
### `BROADWAY_DISPLAY`

View File

@@ -239,14 +239,14 @@ control whether Vulkan should be used.
### `media-gstreamer` and `media-ffmpeg`
By default, GTK will try to build the gstreamer backend for
media playback support. These options can be used to explicitly
media playback support. These option can be used to explicitly
control which media backends should be built.
### `print-cups` and `print-cpdb`
### `print-cups`
By default, GTK will try to build the cups and file print backends
if their dependencies are found. These options can be used to
explicitly control which print backends should be built.
By default, GTK will try to build various print backends
if their dependencies are found. This option can be used
to explicitly control whether the cups print backend should be built.
### `cloudproviders`

View File

@@ -1,80 +0,0 @@
Title: Coordinate systems
Slug: gtk-coordinates
## Coordinate systems in GTK
All coordinate systems in GTK have the origin at the top left, with the X axis
pointing right, and the Y axis pointing down. This matches the convention used
in X11, Wayland and cairo, but differs from OpenGL and PostScript, where the origin
is in the lower left, and the Y axis is pointing up.
Every widget in a window has its own coordinate system that it uses to place its
child widgets and to interpret events. Most of the time, this fact can be safely
ignored. The section will explain the details for the few cases when it is important.
## The box model
When it comes to rendering, GTK follows the CSS box model as far as practical.
<picture>
<source srcset="box-model-dark.png" media="(prefers-color-scheme: dark)">
<img alt="Box Model" src="box-model-light.png">
</picture>
The CSS stylesheet that is in use determines the sizes (and appearance) of the
margin, border and padding areas for each widget. The size of the content area
is determined by GTKs layout algorithm using each widgets [vfunc@Gtk.Widget.measure]
and [vfunc@Gtk.Widget.size_allocate] vfuncs.
You can learn more about the CSS box model by reading the
[CSS specification](https://www.w3.org/TR/css-box-3/#box-model) or the
Mozilla [documentation](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model).
To learn more about where GTK CSS differs from CSS on the web, see the
[CSS overview](css-overview.html).
## Widgets
The content area in the CSS box model is the region that the widget considers its own.
The origin of the widgets coordinate system is the top left corner of the content area,
and its size is the widgets size. The size can be queried with [method@Gtk.Widget.get_width]
and [method@Gtk.Widget.get_height]. GTK allows general 3D transformations to position
widgets (although most of the time, the transformation will be a simple 2D translation).
The transform to go from one widgets coordinate system to another one can be obtained
with [method@Gtk.Widget.compute_transform].
When widget APIs expect positions or areas, they need to be expressed in this coordinate
system, typically called **_widget coordinates_**. GTK provides a number of APIs to translate
between different widgets' coordinate systems, such as [method@Gtk.Widget.compute_point]
or [method@Gtk.Widget.compute_bounds]. These methods can fail (either because the widgets
don't share a common ancestor, or because of a singular transformation), and callers need
to handle this eventuality.
Another area that is occasionally relevant are the widgets **_bounds_**, which is the area
that a widgets rendering is typically confined to (technically, widgets can draw outside
of this area, unless clipping is enforced via the [property@Gtk.Widget:overflow] property).
In CSS terms, the bounds of a widget correspond to the border area.
During GTK's layout algorithm, a parent widget needs to measure each visible child and
allocate them at least as much size as measured. These functions take care of respecting
the CSS box model and widget properties such as align and margin. This happens in the
parent's coordinate system.
Note that the **_text direction_** of a widget does not influence its coordinate
system, but simply determines whether text flows in the direction of increasing
or decreasing X coordinates.
## Events
Event controllers and gestures report positions in the coordinate system of the widget
they are attached to.
If you are dealing with raw events in the form of [class@Gdk.Event] that have positions
associated with them (e.g. the pointer position), such positions are expressed in
**_surface coordinates_**, which have their origin at the top left corner of the
[class@Gdk.Surface].
To translate from surface to widget coordinates, you have to apply the offset from the
top left corner of the surface to the top left corner of the topmost widget, which can
be obtained with [method@Gtk.Native.get_surface_transform].

View File

@@ -66,10 +66,6 @@ You can compile the program above with GCC using:
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
```
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
others in this documentation.
For more information on how to compile a GTK application, please
refer to the [Compiling GTK Applications](compiling.html)
section in this reference.

View File

@@ -33,11 +33,6 @@ Validation
The ``validate`` command validates the given UI definition file and reports
errors to ``stderr``.
Note that there are limitations to the validation that can be done for templates,
since they are closely tied to the class_init function they are used in.
If your UI file uses types from third-party libraries, it may help to add those
libraries to the `LD_PRELOAD` environment variable.
``--deprecations``
Warn about uses of deprecated types in the UI definition file.

View File

@@ -68,7 +68,6 @@ content_files = [
"input-handling.md",
"drag-and-drop.md",
"drawing-model.md",
"coordinates.md",
"css-overview.md",
"css-properties.md",
"section-accessibility.md",
@@ -242,7 +241,5 @@ content_images = [
"images/rich-list.png",
"images/data-table.png",
"images/navigation-sidebar.png",
"images/box-model-light.png",
"images/box-model-dark.png",
]
urlmap_file = "urlmap.js"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,193 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="box-model.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.84096521"
inkscape:cx="265.76605"
inkscape:cy="312.14133"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<marker
style="overflow:visible"
id="Arrow2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L" />
</marker>
<marker
style="overflow:visible"
id="Arrow2-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Arrow2"
markerWidth="7.6999998"
markerHeight="5.5999999"
viewBox="0 0 7.7 5.6"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.7)"
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
id="arrow2L-7" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:10.58333333;stroke-dasharray:none"
id="rect234-0"
width="112.51476"
height="70.089249"
x="38.634876"
y="49.512993" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.487868;stroke-dasharray:none"
id="rect234"
width="146.21118"
height="103.37679"
x="21.283342"
y="33.173706" />
<rect
style="fill:none;stroke:#000000;stroke-width:0.54387;stroke-dasharray:none"
id="rect234-3"
width="79.543648"
height="37.520485"
x="55.724121"
y="65.367287" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5834px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none"
x="76.878265"
y="100.819"
id="text3935"><tspan
sodipodi:role="line"
id="tspan3933"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5834px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.264583"
x="76.878265"
y="100.819">content</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5834px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none"
x="77.072464"
y="111.58885"
id="text4767"><tspan
sodipodi:role="line"
id="tspan4765"
style="fill:#000000;fill-opacity:1;stroke-width:0.264583"
x="77.072464"
y="111.58885">padding</tspan><tspan
sodipodi:role="line"
style="fill:#000000;fill-opacity:1;stroke-width:0.264583"
x="77.072464"
y="124.8181"
id="tspan4769" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5834px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none"
x="77.337868"
y="133.01045"
id="text4767-1"><tspan
sodipodi:role="line"
id="tspan8053"
x="77.337868"
y="133.01045">margin</tspan><tspan
sodipodi:role="line"
id="tspan8055"
x="77.337868"
y="146.2397"></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5834px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1"
x="77.311295"
y="123.22021"
id="text7028"><tspan
sodipodi:role="line"
id="tspan7026"
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1"
x="77.311295"
y="123.22021">border</tspan></text>
<path
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2)"
d="M 58.115912,67.846321 71.79645,67.813301"
id="path9563" />
<path
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2-4)"
d="m 58.054931,67.806272 -0.03031,13.680545"
id="path9563-6"
inkscape:transform-center-x="0.99122989"
inkscape:transform-center-y="-10.282891" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52785px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1"
x="74.660751"
y="69.01046"
id="text10129"><tspan
sodipodi:role="line"
id="tspan10127"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52785px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
x="74.660751"
y="69.01046">X</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52785px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1"
x="56.974892"
y="86.498825"
id="text10133"><tspan
sodipodi:role="line"
id="tspan10131"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52785px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
x="56.974892"
y="86.498825">Y</tspan></text>
<circle
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-dasharray:none;stroke-opacity:1"
id="path10187"
cx="58.076889"
cy="67.895195"
r="0.2" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -103,14 +103,14 @@ fields, but e.g. buttons can take the focus too.
Input widgets can be given the focus by clicking on them, but focus
can also be moved around with certain key events (this is known as
“keyboard navigation”). GTK reserves the <kbd>Tab</kbd> key to move the focus
to the next location, and <kbd>Shift</kbd>+<kbd>Tab</kbd> to move it back to the previous
“keyboard navigation”). GTK reserves the Tab key to move the focus
to the next location, and Shift-Tab to move it back to the previous
one. In addition many containers allow “directional navigation” with
the arrow keys.
Many widgets can be “activated” to trigger and action. E.g., you can
activate a button or switch by clicking on them, but you can also
activate them with the keyboard, by using the <kbd>Enter</kbd> or <kbd>␣</kbd> keys.
activate them with the keyboard, by using the Enter or Space keys.
Apart from keyboard navigation, activation and directly typing into
entries or text views, GTK widgets can use key events for activating

View File

@@ -17,7 +17,6 @@ expand_content_md_files = [
'actions.md',
'input-handling.md',
'drawing-model.md',
'coordinates.md',
'css-overview.md',
'css-properties.md',
'section-accessibility.md',

View File

@@ -7,50 +7,37 @@ the question you have, this list is a good place to start.
## General Questions
* How do I get started with GTK?
1. How do I get started with GTK?
The GTK [website](https://www.gtk.org) offers some
[tutorials](https://www.gtk.org/documentation.php) and other documentation
This reference manual also contains a introductory
(most of it about GTK 2.x and 3.x, but still somewhat applicable). This
reference manual also contains a introductory
[Getting Started](#gtk-getting-started) part.
More documentation ranging from whitepapers to online books can be found at
the [GNOME developer's site](https://developer.gnome.org). After studying these
materials you should be well prepared to come back to this reference manual for details.
* Where can I get help with GTK, submit a bug report, or make a feature request?
2. Where can I get help with GTK, submit a bug report, or make a feature request?
See the [documentation](#gtk-resources) on this topic.
* How do I port from one GTK version to another?
3. How do I port from one GTK version to another?
Every major version of GTK comes with a [migration guide](#migrating). You may also
find useful information in the documentation for specific widgets and functions. If
you have a question not covered in the manual, feel free to ask, and please
See the [migration guide](#migrating). You may also find useful information in
the documentation for specific widgets and functions. If you have a question not
covered in the manual, feel free to ask, and please
[file a bug report](https://gitlab.gnome.org/GNOME/gtk/issues/new) against the
documentation.
* Should I maintain parallel versions of my UI in GTK x and GTK y?
At the end of the day, that is up to you.
Our experience is that it is a lot of work, and usually not a good idea.
If you are not ready to make the jump to the next major version of GTK,
it is perfectly fine to stick with the stable release. We maintain them
for that reason.
* How does memory management work in GTK? Should I free data returned from functions?
4. How does memory management work in GTK? Should I free data returned from functions?
See the documentation for `GObject` and `GInitiallyUnowned`. For `GObject` note
specifically `g_object_ref()` and `g_object_unref()`. `GInitiallyUnowned` is a
subclass of `GObject` so the same points apply, except that it has a "floating"
state (explained in its documentation).
In a widget tree, each container owns a reference to its children. The root
object (typically a `GtkWindow`) is owned by GTK. GTK will drop its reference
when you call [method@Gtk.Window.destroy].
For strings returned from functions, they will be declared "const" if they should
not be freed. Non-const strings should be freed with `g_free()`. Arrays follow the
same rule. If you find an undocumented exception to the rules, please
@@ -59,7 +46,7 @@ the question you have, this list is a good place to start.
The transfer annotations for gobject-introspection that are part of the
documentation can provide useful hints for memory handling semantics as well.
* Why does my program leak memory, if I destroy a widget immediately
5. Why does my program leak memory, if I destroy a widget immediately
after creating it?
If `GtkFoo` isn't a toplevel window, then
@@ -82,7 +69,7 @@ the question you have, this list is a good place to start.
the initial floating reference and you don't have to worry about reference
counting at all ... just remove the widget from the container to get rid of it.
* How do I use GTK with threads?
6. How do I use GTK with threads?
GTK requires that all GTK API calls are made from the same thread in which
the `GtkApplication` was created, or `gtk_init()` was called (the _main thread_).
@@ -92,7 +79,7 @@ the question you have, this list is a good place to start.
the results back to the main thread using `g_idle_add()` or `GAsyncQueue`. GIO
offers useful tools for such an approach such as `GTask`.
* How do I internationalize a GTK program?
7. How do I internationalize a GTK program?
Most people use [GNU gettext](https://www.gnu.org/software/gettext/),
already required in order to install GLib. On a UNIX or Linux system with
@@ -147,7 +134,7 @@ the question you have, this list is a good place to start.
#define _(x) dgettext (GETTEXT_PACKAGE, x)
* How do I use non-ASCII characters in GTK programs ?
8. How do I use non-ASCII characters in GTK programs ?
GTK uses [Unicode](http://www.unicode.org) (more exactly UTF-8) for all text.
UTF-8 encodes each Unicode codepoint as a sequence of one to six bytes and
@@ -230,7 +217,7 @@ the question you have, this list is a good place to start.
to call bind_textdomain_codeset() to ensure that translated strings
are returned in UTF-8 encoding.
* How do I use GTK with C++?
9. How do I use GTK with C++?
There are two ways to approach this. The GTK header files use the subset
of C that's also valid C++, so you can simply use the normal GTK API
@@ -255,26 +242,19 @@ the question you have, this list is a good place to start.
There are very few functions that require this cast, however.
* How do I use GTK with other non-C languages?
10. How do I use GTK with other non-C languages?
See the list of [language bindings](https://www.gtk.org/language-bindings.php)
on the GTK [website](https://www.gtk.org).
* How do I load an image or animation from a file?
11. How do I load an image or animation from a file?
To load an image file straight into a display widget, use
[ctor@Gtk.Picture.new_for_file] or [ctor@Gtk.Picture.new_for_filename].
To load an image for another purpose, use [ctor@Gdk.Texture.new_from_file].
To load a video from a file, use [ctor@Gtk.MediaFile.new_for_file].
[ctor@Gtk.Image.new_from_file]. To load an image for another purpose, use
[ctor@Gdk.Texture.new_from_file]. To load a video from a file, use
[ctor@Gtk.MediaFile.new_for_file].
Note that [class@Gtk.Image] is meant for fixed-size icons. For arbitrary
image files, you should use [class@Gtk.Picture].
* How do I draw text?
If you just want to put text into your user interface somewhere, it is
usually easiest to just use one of ready-made widgets for this purpose,
such as [class@Gtk.Label].
12. How do I draw text?
To draw a piece of text onto a cairo surface, use a Pango layout and
[func@PangoCairo.show_layout].
@@ -286,13 +266,13 @@ the question you have, this list is a good place to start.
pango_font_description_free (fontdesc);
g_object_unref (layout);
See also the [Cairo Rendering](https://docs.gtk.org/PangoCairo/pango_cairo.html)
section of the [Pango documentation](https://docs.gtk.org/Pango/).
See also the [Cairo Rendering](https://developer.gnome.org/pango/stable/pango-Cairo-Rendering.html)
section of the [Pango documentation](https://developer.gnome.org/pango/stable/).
To draw a piece of text in a widget [vfunc@Gtk.Widget.snapshot] implementation,
use [method@Gtk.Snapshot.append_layout].
* How do I measure the size of a piece of text?
13. How do I measure the size of a piece of text?
To obtain the size of a piece of text, use a Pango layout and
[method@Pango.Layout.get_pixel_size], using code like the following:
@@ -304,10 +284,10 @@ the question you have, this list is a good place to start.
pango_font_description_free (fontdesc);
g_object_unref (layout);
See also the [Layout Objects](https://docs.gtk.org/Pango/class.Layout.html)
section of the [Pango documentation](https://docs.gtk.org/Pango/).
See also the [Layout Objects](https://developer.gnome.org/pango/stable/pango-Layout-Objects.html)
section of the [Pango documentation](https://developer.gnome.org/pango/stable/).
* Why are types not registered if I use their `GTK_TYPE_BLAH` macro?
14. Why are types not registered if I use their `GTK_TYPE_BLAH` macro?
The %GTK_TYPE_BLAH macros are defined as calls to gtk_blah_get_type(), and
the `_get_type()` functions are declared as %G_GNUC_CONST which allows the
@@ -318,14 +298,14 @@ the question you have, this list is a good place to start.
g_type_ensure (GTK_TYPE_BLAH);
* How do I create a transparent toplevel window?
15. How do I create a transparent toplevel window?
Any toplevel window can be transparent. It is just a matter of setting a
transparent background in the CSS style for it.
## Which widget should I use...
* ...for lists and trees?
16. ...for lists and trees?
This question has different answers, depending on the size of the dataset
and the required formatting flexibility.
@@ -341,7 +321,7 @@ the question you have, this list is a good place to start.
and widgetry inside the list, then you probably want to use a [class@Gtk.ListBox],
which uses regular widgets for display.
* ...for multi-line text display or editing?
17. ...for multi-line text display or editing?
See the [text widget overview](#TextWidget) -- you should use the
[class@Gtk.TextView] widget.
@@ -350,7 +330,7 @@ the question you have, this list is a good place to start.
of course. It can be made selectable with [method@Gtk.Label.set_selectable]. For a
single-line text entry, see [class@Gtk.Entry].
* ...to display an image or animation?
18. ...to display an image or animation?
GTK has two widgets that are dedicated to displaying images. [class@Gtk.Image], for
small, fixed-size icons and [class@Gtk.Picture] for content images.
@@ -366,14 +346,17 @@ the question you have, this list is a good place to start.
mediafile = gtk_media_file_new_for_filename ("example.webm");
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (mediafile));
* ...for presenting a set of mutually-exclusive choices, where Windows
19. ...for presenting a set of mutually-exclusive choices, where Windows
would use a combo box?
With GTK, a [class@Gtk.DropDown] is the recommended widget to use for this use case.
With GTK, a [class@Gtk.ComboBox] is the recommended widget to use for this use case.
If you need an editable text entry, use the [property@Gtk.ComboBox:has-entry] property.
A newer alternative is [class@Gtk.DropDown].
## Questions about GtkWidget
* How do I change the color of a widget?
20. How do I change the color of a widget?
The background color of a widget is determined by the CSS style that applies
to it. To change that, you can set style classes on the widget, and provide
@@ -381,7 +364,7 @@ the question you have, this list is a good place to start.
[method@Gtk.CssProvider.load_from_file] and its variants.
See [method@Gtk.StyleContext.add_provider].
* How do I change the font of a widget?
21. How do I change the font of a widget?
If you want to make the text of a label larger, you can use
gtk_label_set_markup():
@@ -405,14 +388,14 @@ the question you have, this list is a good place to start.
of this approach is that users can then override the font you have chosen.
See the `GtkStyleContext` documentation for more discussion.
* How do I disable/ghost/desensitize a widget?
22. How do I disable/ghost/desensitize a widget?
In GTK a disabled widget is termed _insensitive_.
See [method@Gtk.Widget.set_sensitive].
## GtkTextView questions
* How do I get the contents of the entire text widget as a string?
23. How do I get the contents of the entire text widget as a string?
See [method@Gtk.TextBuffer.get_bounds] and [method@Gtk.TextBuffer.get_text]
or [method@Gtk.TextIter.get_text].
@@ -427,14 +410,14 @@ the question you have, this list is a good place to start.
/* use text */
g_free (text);
* How do I make a text widget display its complete contents in a specific font?
24. How do I make a text widget display its complete contents in a specific font?
If you use [method@Gtk.TextBuffer.insert_with_tags] with appropriate tags to
select the font, the inserted text will have the desired appearance, but
text typed in by the user before or after the tagged block will appear in
the default style.
* How do I make a text view scroll to the end of the buffer automatically ?
25. How do I make a text view scroll to the end of the buffer automatically ?
A good way to keep a text buffer scrolled to the end is to place a
[mark](#GtkTextMark) at the end of the buffer, and give it right gravity.
@@ -449,21 +432,21 @@ the question you have, this list is a good place to start.
## GtkTreeView questions
* How do I associate some data with a row in the tree?
26. How do I associate some data with a row in the tree?
Remember that the [iface@Gtk.TreeModel] columns don't necessarily have to be
displayed. So you can put non-user-visible data in your model just
like any other data, and retrieve it with [method@Gtk.TreeModel.get].
See the [tree widget overview](#TreeWidget).
* How do I put an image and some text in the same column?
27. How do I put an image and some text in the same column?
You can pack more than one [class@Gtk.CellRenderer] into a single [class@Gtk.TreeViewColumn]
using [method@Gtk.TreeViewColumn.pack_start] or [method@Gtk.TreeViewColumn.pack_end].
So pack both a [class@Gtk.CellRendererPixbuf] and a [class@Gtk.CellRendererText] into the
column.
* I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
28. I can set data easily on my [class@Gtk.TreeStore] or [class@Gtk.ListStore] models using
[method@Gtk.ListStore.set] and [method@Gtk.TreeStore.set], but can't read it back?
Both the [class@Gtk.TreeStore] and the [class@Gtk.ListStore] implement the [iface@Gtk.TreeModel]
@@ -471,7 +454,7 @@ the question you have, this list is a good place to start.
implements. The easiest way to read a set of data back is to use
[method@Gtk.TreeModel.get].
* How do I change the way that numbers are formatted by `GtkTreeView`?
29. How do I change the way that numbers are formatted by `GtkTreeView`?
Use [method@Gtk.TreeView.insert_column_with_data_func] or
[method@Gtk.TreeViewColumn.set_cell_data_func] and do the conversion
@@ -545,21 +528,19 @@ the question you have, this list is a good place to start.
(gpointer)DOUBLE_COLUMN, NULL);
}
* How do I hide the expander arrows in my tree view?
30. How do I hide the expander arrows in my tree view?
Set the expander-column property of the tree view to a hidden column.
See [method@Gtk.TreeView.set_expander_column] and [method@Gtk.TreeViewColumn.set_visible].
## Using cairo with GTK
* How do I use cairo to draw in GTK applications?
31. How do I use cairo to draw in GTK applications?
[class@Gtk.DrawingArea] is a ready-made widget for drawing with cairo.
Use [method@Gtk.Snapshot.append_cairo] in your [vfunc@Gtk.Widget.snapshot] vfunc
to obtain a cairo context and draw with that.
If you implement a custom widget, use [method@Gtk.Snapshot.append_cairo]
in your [vfunc@Gtk.Widget.snapshot] vfunc to obtain a cairo context and draw with that.
* Can I improve the performance of my application by using another backend
32. Can I improve the performance of my application by using another backend
of cairo (such as GL)?
No. Most drawing in GTK is not done via cairo anymore (but instead
@@ -570,7 +551,7 @@ the question you have, this list is a good place to start.
If you are interested in using GL for your own drawing, see [class@Gtk.GLArea].
* Can I use cairo to draw on a `GdkPixbuf`?
33. Can I use cairo to draw on a `GdkPixbuf`?
No. The cairo image surface does not support the pixel format used by `GdkPixbuf`.

View File

@@ -211,9 +211,6 @@ A number of options affect behavior instead of logging:
`gl-disable`
: Disable OpenGL support
`gl-fractional`
: Enable fractional scaling for OpenGL. This is experimental
`gl-legacy`
: Use a legacy OpenGL context
@@ -371,13 +368,6 @@ to rememdy this on the GTK side; the best bet before trying the above
workarounds is to try to update your graphics drivers and Nahimic
installation.
### `GSK_MAX_TEXTURE_SIZE`
Limit texture size to the minimum of this value and the OpenGL limit
for texture sizes. This can be used to debug issues with texture slicing
on systems where the OpenGL texture size limit would otherwise make
texture slicing difficult to test.
### `GTK_CSD`
The default value of this environment variable is `1`. If changed

View File

@@ -128,7 +128,6 @@ Each state name is part of the `GtkAccessibleState` enumeration.
| %GTK_ACCESSIBLE_STATE_INVALID | “aria-invalid” | `GtkAccessibleInvalidState` | Set when a widget is showing an error |
| %GTK_ACCESSIBLE_STATE_PRESSED | “aria-pressed” | `GtkAccessibleTristate` | Indicates the current state of a [class@Gtk.ToggleButton] |
| %GTK_ACCESSIBLE_STATE_SELECTED | “aria-selected” | boolean or undefined | Set when a widget is selected |
| %GTK_ACCESSIBLE_STATE_VISITED | N/A | boolean or undefined | Set when a link-like widget is visited |
#### List of accessible properties

View File

@@ -9,9 +9,9 @@ Lists are intended to be used whenever developers want to display many objects
in roughly the same way.
Lists are perfectly fine to be used for very short list of only 2 or 3 elements,
but generally scale to millions of items. Of course, the larger the list grows,
the more care needs to be taken to choose the right data structures to keep things
running well.
but generally scale fine to millions of items. Of course, the larger the list
grows, the more care needs to be taken to choose the right data structures to
keep things running well.
Lists are meant to be used with changing data, both with the items itself changing
as well as the list adding and removing items. Of course, they work just as well
@@ -26,14 +26,12 @@ have a specific meaning in this context.
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists.
Examples of these widgets would be [`class@Gtk.ListView`] or [`class@Gtk.GridView`].
Views display data from a **_model_**. Models implement the [`iface@Gio.ListModel`]
interface and can be provided in a variety of ways:
Views display data from a **_model_**. A model is a [`iface@Gio.ListModel`] and
models can be provided in 3 ways or combinations thereof:
* List model implementations for many specific types of data already exist, for
example `GtkDirectoryList` or `GtkStringList`.
* There are generic list model implementations like`GListStore` that allow building
lists of arbitrary objects.
* Many list models implementations already exist. There are models that provide
specific data, like `GtkDirectoryList`. And there are models like `GListStore`
that allow building lists manually.
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
modify, adapt or combine other models.
@@ -49,8 +47,8 @@ The elements in a model are called **_items_**. All items are
Every item in a model has a **_position_** which is the unsigned integer that
describes where in the model the item is located. The first item in a model is
at position 0. The position of an item can change as other items are added or
removed from the model.
at position 0. The position of an item can of course change as other items are
added or removed from the model.
It is important to be aware of the difference between items and positions
because the mapping from position to item is not permanent, so developers
@@ -73,10 +71,10 @@ with the item managed by the listitem. Finding a suitable factory implementation
for the data displayed, the programming language and development environment
is an important task that can simplify setting up the view tremendously.
Views support selections via a **_selection model_**. A selection model is
an implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
[`iface@Gio.ListModel`] interface that allows marking each item in a model as
either selected or not selected. Just like regular models, this can be implemented
Views support selections via a **_selection model_**. A selection model is an
implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
[`iface@Gio.ListModel`] interface that allows marking each item in a model as either
selected or not selected. Just like regular models, this can be implemented
either by implementing `GtkSelectionModel` directly or by wrapping a model with
one of the GTK models provided for this purposes, such as [`class@Gtk.NoSelection`]
or [`class@Gtk.SingleSelection`].
@@ -89,18 +87,19 @@ item is exposed in the listitem via the [`property@Gtk.ListItem:selected`] prope
Views and listitems also support activation. Activation means that double
clicking or pressing enter while inside a focused row will cause the view
to emit a signal such as [`signal@Gtk.ListView::activate`]. This provides an
easy way to set up lists, but can also be turned off on listitems if undesired.
to emit and activation signal such as [`signal@Gtk.ListView::activate`]. This
provides an easy way to set up lists, but can also be turned off on listitems
if undesired.
Both selections and activation are supported among other things via widget
[actions](#actions-overview). This allows developers to add widgets to their
lists that cause selections to change or to trigger activation via the
[`iface@Gtk.Actionable`] interface. For a list of all supported actions
see the relevant documentation.
lists that cause selections to change or to trigger activation via
the [`iface@Gtk.Actionable`] interface. For a list of all supported actions see
the relevant documentation.
## Behind the scenes
While it is not a problem for short lists to instantiate widgets for every
While for short lists it is not a problem to instantiate widgets for every
item in the model, once lists grow to thousands or millions of elements, this
gets less feasible. Because of this, the views only create a limited amount of
listitems and recycle them by binding them to new items. In general, views try
@@ -108,7 +107,7 @@ to keep listitems available only for the items that can actually be seen on
screen.
While this behavior allows views to scale effortlessly to huge lists, it has a
few implications for what can be done with views. For example, it is not possible
few implication on what can be done with views. For example, it is not possible
to query a view for a listitem used for a certain position - there might not be
one and even if there is, that listitem might soon be recycled for a new
position.
@@ -162,9 +161,9 @@ in particular `GListModel` do not. This was a design choice because the common
use case is displaying lists and not trees and it greatly simplifies the API
interface provided.
However, GTK provides functionality to make lists look and behave like trees
for use cases that require trees. This is achieved by using the
[`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
However, GTK provides functionality to make trees look and behave like lists
for the people who still want to display lists. This is achieved by using
the [`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
[`class@Gtk.TreeExpander`] widget can then be used inside a listitem to allow
users to expand and collapse rows and provide a similar experience to
`GtkTreeView`.
@@ -175,26 +174,26 @@ on the topic.
## List styles
One of the advantages of the new list widgets over `GtkTreeView` and cell
renderers is that they are styleable using GTK CSS. This provides a lot of
flexibility. The themes that ship with GTK provide a few predefined list
styles that can be used in many situations:
renderers is that they are fully themable using GTK CSS. This provides a
lot of flexibility. The themes that ship with GTK provide a few predefined
list styles that can be used in many situations:
![Rich list](rich-list.png)
This _rich list_ style is low density, spacious and uses an outline focus
ring. It is suitable for lists of controls, e.g. in preference dialogs or
This style of list is low density, spacious and uses an outline focus ring.
It is suitable for lists of controls, e.g. in preference dialogs or
settings panels. Use the `.rich-list` style class.
![Navigation sidebar](navigation-sidebar.png)
The _sidebar_ style of list is medium density, using a full background to
indicate focus and selection. Use the `.navigation-sidebar` style class.
This style of list is medium density, using a full background to indicate
focus and selection. Use the `.navigation-sidebar` style class.
![Data table](data-table.png)
The _data table_ style of list is a high density table, similar in style to a
traditional treeview. Individual cells can be selectable and editable. Use
the `.data-table` style class.
This style of list is a high density table, similar in style to a traditional
treeview. Individual cells can be selectable and editable. Use the `.data-table`
style class.
## Comparison to GtkTreeView
@@ -203,19 +202,20 @@ compares to the way they know. This section will try to outline the similarities
and differences between the two.
This new approach tries to provide roughly the same functionality as the old
approach but often uses a very different way to achieve these goals.
approach but often uses a very different approach to achieve these goals.
The main difference and one of the primary reasons for this new development is
that items can be displayed using regular widgets and the separate cell renderer
machinery is no longer necessary. This allows all benefits that widgets provide,
such as complex layout, animations and CSS styling.
that items can be displayed using regular widgets and `GtkCellRenderer` is no
longer necessary. This allows all benefits that widgets provide, such as complex
layout and animating widgets and not only makes cell renderers obsolete, but
also `GtkCellArea`.
The other big difference is the massive change to the data model. `GtkTreeModel`
was a rather complex interface for a tree data structure. `GListModel` is
deliberately designed to be a very simple data structure for lists only. (See
was a rather complex interface for a tree data structure and `GListModel` was
deliberately designed to be a simple data structure for lists only. (See
[above](#displaying-trees)) for how to still do trees with this new model.)
Another big change is that the new model allows for bulk changes via the
`GListModel::items-changed` signal while `GtkTreeModel` only allows a single
Another big change is that the new model allows for bulk changes via
the `GListModel::items-changed` signal while `GtkTreeModel` only allows a single
item to change at once. The goal here is of course to encourage implementation
of custom list models.
@@ -231,8 +231,8 @@ via custom code in each widget, selection state is now meant to be managed by
the selection models. In particular this allows for complex use cases with
specialized requirements.
Finally here's a quick comparison chart of equivalent functionality to look for
when transitioning code:
Finally here's a quick list of equivalent functionality to look for when
transitioning code for easy lookup:
| Old | New |
| -------------------- | ------------------------------------------------------- |

View File

@@ -1,4 +1,4 @@
Title: Using GTK with X11
Title: GTK for the X Window System
Slug: gtk-x11
On UNIX, the X backend is enabled by default, so you don't need to do anything

View File

@@ -1,6 +1,6 @@
app2_resources = gnome.compile_resources('exampleapp2_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('exampleapp2',
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,

View File

@@ -1,6 +1,6 @@
app3_resources = gnome.compile_resources('exampleapp3_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('exampleapp3',
'exampleapp.c', 'exampleappwin.c', 'main.c', app3_resources,

View File

@@ -1,6 +1,6 @@
app4_resources = gnome.compile_resources('exampleapp4_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('exampleapp4',
'exampleapp.c', 'exampleappwin.c', 'main.c', app4_resources,

View File

@@ -1,6 +1,6 @@
app5_resources = gnome.compile_resources('exampleapp5_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app5_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app6_resources = gnome.compile_resources('exampleapp6_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app6_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app7_resources = gnome.compile_resources('exampleapp7_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app7_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app8_resources = gnome.compile_resources('exampleapp8 resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app8_schemas = gnome.compile_schemas()

View File

@@ -1,6 +1,6 @@
app9_resources = gnome.compile_resources('exampleapp9_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app9_schemas = gnome.compile_schemas()

View File

@@ -1,5 +1,5 @@
bp_resources = gnome.compile_resources('bloatpad_resources',
'bloatpad.gresources.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('bloatpad', 'bloatpad.c', bp_resources, dependencies: libgtk_dep, c_args: common_cflags)

View File

@@ -31,9 +31,10 @@ resize_cb (GtkWidget *widget,
if (gtk_native_get_surface (gtk_widget_get_native (widget)))
{
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
gtk_widget_get_width (widget),
gtk_widget_get_height (widget));
surface = gdk_surface_create_similar_surface (gtk_native_get_surface (gtk_widget_get_native (widget)),
CAIRO_CONTENT_COLOR,
gtk_widget_get_width (widget),
gtk_widget_get_height (widget));
/* Initialize the surface to white */
clear_surface ();

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __BROADWAY_H__
#define __BROADWAY_H__
#include <glib.h>
#include <gio/gio.h>
@@ -73,3 +74,4 @@ void broadway_output_pong (BroadwayOutput *output);
void broadway_output_set_show_keyboard (BroadwayOutput *output,
gboolean show);
#endif /* __BROADWAY_H__ */

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __BROADWAY_PROTOCOL_H__
#define __BROADWAY_PROTOCOL_H__
#include <glib.h>
@@ -369,3 +370,4 @@ typedef union {
BroadwayReplyUngrabPointer ungrab_pointer;
} BroadwayReply;
#endif /* __BROADWAY_PROTOCOL_H__ */

View File

@@ -1574,8 +1574,7 @@ broadway_server_query_mouse (BroadwayServer *server,
void
broadway_server_destroy_surface (BroadwayServer *server,
int id,
gboolean disconnected)
int id)
{
BroadwaySurface *surface;
gint32 transient_for = -1;
@@ -1590,7 +1589,8 @@ broadway_server_destroy_surface (BroadwayServer *server,
server->pointer_grab_surface_id = -1;
if (server->output)
broadway_output_destroy_surface (server->output, id);
broadway_output_destroy_surface (server->output,
id);
surface = broadway_server_lookup_surface (server, id);
if (surface != NULL)
@@ -1604,7 +1604,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
broadway_surface_free (server, surface);
}
if (transient_for != -1 && !disconnected)
if (transient_for != -1)
{
surface = broadway_server_lookup_surface (server, transient_for);
if (surface != NULL)

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __BROADWAY_SERVER__
#define __BROADWAY_SERVER__
#include "broadway-protocol.h"
#include <glib-object.h>
@@ -92,8 +93,7 @@ guint32 broadway_server_new_surface (BroadwayServer *
int width,
int height);
void broadway_server_destroy_surface (BroadwayServer *server,
int id,
gboolean disconnected);
int id);
gboolean broadway_server_surface_show (BroadwayServer *server,
int id);
gboolean broadway_server_surface_hide (BroadwayServer *server,
@@ -135,3 +135,4 @@ void broadway_server_surface_set_modal_hint (BroadwayServer *s
gboolean modal_hint);
#endif /* __BROADWAY_SERVER__ */

View File

@@ -101,7 +101,8 @@ client_disconnected (BroadwayClient *client)
}
for (l = client->surfaces; l != NULL; l = l->next)
broadway_server_destroy_surface (server, GPOINTER_TO_UINT (l->data), TRUE);
broadway_server_destroy_surface (server,
GPOINTER_TO_UINT (l->data));
g_list_free (client->surfaces);
client->surfaces = NULL;
@@ -267,7 +268,7 @@ client_handle_request (BroadwayClient *client,
client->surfaces =
g_list_remove (client->surfaces,
GUINT_TO_POINTER (request->destroy_surface.id));
broadway_server_destroy_surface (server, request->destroy_surface.id, FALSE);
broadway_server_destroy_surface (server, request->destroy_surface.id);
break;
case BROADWAY_REQUEST_SHOW_SURFACE:
broadway_server_surface_show (server, request->show_surface.id);

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __GDK_BROADWAY_SERVER__
#define __GDK_BROADWAY_SERVER__
#include <gdk/gdktypes.h>
@@ -81,3 +82,4 @@ void _gdk_broadway_server_surface_set_modal_hint (GdkBroadwaySer
int id,
gboolean modal_hint);
#endif /* __GDK_BROADWAY_SERVER__ */

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#pragma once
#ifndef __GDK_BROADWAY_H__
#define __GDK_BROADWAY_H__
#include <gdk/gdk.h>
@@ -35,3 +36,4 @@
#undef __GDKBROADWAY_H_INSIDE__
#endif /* __GDK_BROADWAY_H__ */

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#pragma once
#ifndef __GDK_BROADWAY_CURSOR_H__
#define __GDK_BROADWAY_CURSOR_H__
#if !defined (__GDKBROADWAY_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/broadway/gdkbroadway.h> can be included directly."
@@ -51,3 +52,4 @@ GType gdk_broadway_cursor_get_type (void);
G_END_DECLS
#endif /* __GDK_BROADWAY_CURSOR_H__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_DISPLAY_H__
#define __GDK_BROADWAY_DISPLAY_H__
#if !defined (__GDKBROADWAY_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/broadway/gdkbroadway.h> can be included directly."
@@ -55,3 +56,4 @@ void gdk_broadway_display_set_surface_scale (GdkDisplay *di
G_END_DECLS
#endif /* __GDK_BROADWAY_DISPLAY_H__ */

View File

@@ -17,7 +17,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_DISPLAY_MANAGER_H__
#define __GDK_BROADWAY_DISPLAY_MANAGER_H__
#if !defined(__GDKBROADWAY_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/broadway/gdkbroadway.h> can be included directly."
@@ -42,3 +43,4 @@ GType gdk_broadway_display_manager_get_type (void);
G_END_DECLS
#endif /* __GDK_BROADWAY_DISPLAY_MANAGER_H__ */

View File

@@ -19,7 +19,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_MONITOR_H__
#define __GDK_BROADWAY_MONITOR_H__
#if !defined (__GDKBROADWAY_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/broadway/gdkbroadway.h> can be included directly."
@@ -41,4 +42,5 @@ GType gdk_broadway_monitor_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GDK_BROADWAY_MONITOR_H__ */

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#pragma once
#ifndef __GDK_BROADWAY_SURFACE_H__
#define __GDK_BROADWAY_SURFACE_H__
#include <gdk/gdk.h>
@@ -47,3 +48,4 @@ GType gdk_broadway_surface_get_type (void);
G_END_DECLS
#endif /* __GDK_BROADWAY_SURFACE_H__ */

View File

@@ -16,7 +16,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_CAIRO_CONTEXT__
#define __GDK_BROADWAY_CAIRO_CONTEXT__
#include "gdkconfig.h"
@@ -51,3 +52,4 @@ GType gdk_broadway_cairo_context_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GDK_BROADWAY_CAIRO_CONTEXT__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_DEVICE_BROADWAY_H__
#define __GDK_DEVICE_BROADWAY_H__
#include <gdk/gdkdeviceprivate.h>
@@ -52,3 +53,4 @@ void gdk_broadway_device_query_state (GdkDevice *device,
G_END_DECLS
#endif /* __GDK_DEVICE_BROADWAY_H__ */

View File

@@ -19,7 +19,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_DISPLAY__
#define __GDK_BROADWAY_DISPLAY__
#include "gdkbroadwaydisplay.h"
@@ -69,3 +70,4 @@ struct _GdkBroadwayDisplayClass
G_END_DECLS
#endif /* __GDK_BROADWAY_DISPLAY__ */

View File

@@ -16,7 +16,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_DRAW_CONTEXT__
#define __GDK_BROADWAY_DRAW_CONTEXT__
#include "gdkconfig.h"
@@ -54,3 +55,4 @@ GdkBroadwayDrawContext *gdk_broadway_draw_context_context (GdkSurface *surface);
G_END_DECLS
#endif /* __GDK_BROADWAY_DRAW_CONTEXT__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_EVENT_SOURCE_H__
#define __GDK_BROADWAY_EVENT_SOURCE_H__
#include "gdkprivate-broadway.h"
@@ -28,3 +29,4 @@ GSource * _gdk_broadway_event_source_new (GdkDisplay *display);
G_END_DECLS
#endif /* __GDK_BROADWAY_EVENT_SOURCE_H__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_BROADWAY_MONITOR_PRIVATE_H__
#define __GDK_BROADWAY_MONITOR_PRIVATE_H__
#include <glib.h>
#include <gio/gio.h>
@@ -34,3 +35,4 @@ struct _GdkBroadwayMonitorClass {
GdkMonitorClass parent_class;
};
#endif

View File

@@ -26,7 +26,8 @@
* Private uninstalled header defining things local to X windowing code
*/
#pragma once
#ifndef __GDK_PRIVATE_BROADWAY_H__
#define __GDK_PRIVATE_BROADWAY_H__
#include <gdk/gdkcursor.h>
#include "gdksurface-broadway.h"
@@ -123,3 +124,4 @@ void _gdk_broadway_surface_resize_surface (GdkSurface *surface);
void _gdk_broadway_cursor_update_theme (GdkCursor *cursor);
void _gdk_broadway_cursor_display_finalize (GdkDisplay *display);
#endif /* __GDK_PRIVATE_BROADWAY_H__ */

View File

@@ -407,10 +407,17 @@ gdk_broadway_surface_hide (GdkSurface *surface)
_gdk_surface_clear_update_area (surface);
}
static double
gdk_broadway_surface_get_scale (GdkSurface *surface)
static int
gdk_broadway_surface_get_scale_factor (GdkSurface *surface)
{
return GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface))->scale_factor;
GdkBroadwayDisplay *broadway_display;
if (GDK_SURFACE_DESTROYED (surface))
return 1;
broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
return broadway_display->scale_factor;
}
static void
@@ -1264,7 +1271,7 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
impl_class->beep = gdk_broadway_surface_beep;
impl_class->destroy_notify = gdk_broadway_surface_destroy_notify;
impl_class->drag_begin = _gdk_broadway_surface_drag_begin;
impl_class->get_scale = gdk_broadway_surface_get_scale;
impl_class->get_scale_factor = gdk_broadway_surface_get_scale_factor;
}
#define LAST_PROP 1

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#pragma once
#ifndef __GDK_SURFACE_BROADWAY_H__
#define __GDK_SURFACE_BROADWAY_H__
#include <gdk/gdksurfaceprivate.h>
#include "gdkbroadwaysurface.h"
@@ -79,3 +80,4 @@ GType gdk_surface_broadway_get_type (void);
G_END_DECLS
#endif /* __GDK_SURFACE_BROADWAY_H__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __FILE_TRANSFER_PROTOCOL_H__
#define __FILE_TRANSFER_PROTOCOL_H__
void file_transfer_portal_register (void);
@@ -36,3 +37,4 @@ gboolean file_transfer_portal_retrieve_files_finish (GAsyncResult *resu
GError **error);
#endif

View File

@@ -121,7 +121,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE },
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)", TRUE },
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE },
{ "gl-gles", GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API", TRUE },

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#pragma once
#ifndef __GDK_H__
#define __GDK_H__
#define __GDK_H_INSIDE__
@@ -44,7 +45,6 @@
#include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdrag.h>
#include <gdk/gdkdragsurface.h>
#include <gdk/gdkdragsurfacesize.h>
#include <gdk/gdkdrawcontext.h>
#include <gdk/gdkdrop.h>
#include <gdk/gdkenums.h>
@@ -69,7 +69,6 @@
#include <gdk/gdksnapshot.h>
#include <gdk/gdksurface.h>
#include <gdk/gdktexture.h>
#include <gdk/gdktexturedownloader.h>
#include <gdk/gdktoplevel.h>
#include <gdk/gdktoplevellayout.h>
#include <gdk/gdktoplevelsize.h>
@@ -79,3 +78,4 @@
#undef __GDK_H_INSIDE__
#endif /* __GDK_H__ */

View File

@@ -18,7 +18,8 @@
* Author: Alexander Larsson <alexl@redhat.com>
*/
#pragma once
#ifndef __GDK_APP_LAUNCH_CONTEXT_H__
#define __GDK_APP_LAUNCH_CONTEXT_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
@@ -57,3 +58,4 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkAppLaunchContext, g_object_unref)
G_END_DECLS
#endif /* __GDK_APP_LAUNCH_CONTEXT_H__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_APP_LAUNCH_CONTEXT_PRIVATE_H__
#define __GDK_APP_LAUNCH_CONTEXT_PRIVATE_H__
#include "gdkapplaunchcontext.h"
#include "gdktypes.h"
@@ -42,3 +43,4 @@ struct _GdkAppLaunchContext
G_END_DECLS
#endif

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_CAIRO_H__
#define __GDK_CAIRO_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
@@ -62,3 +63,4 @@ void gdk_cairo_draw_from_gl (cairo_t *cr,
G_END_DECLS
#endif /* __GDK_CAIRO_H__ */

View File

@@ -18,7 +18,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_CAIRO_CONTEXT__
#define __GDK_CAIRO_CONTEXT__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
@@ -45,3 +46,4 @@ cairo_t * gdk_cairo_context_cairo_create (GdkCair
G_END_DECLS
#endif /* __GDK_CAIRO_CONTEXT__ */

View File

@@ -18,7 +18,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_CAIRO_CONTEXT_PRIVATE__
#define __GDK_CAIRO_CONTEXT_PRIVATE__
#include "gdkcairocontext.h"
@@ -48,3 +49,4 @@ struct _GdkCairoContextClass
G_END_DECLS
#endif /* __GDK__CAIRO_CONTEXT_PRIVATE__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_CAIRO_PRIVATE_H__
#define __GDK_CAIRO_PRIVATE_H__
#include "gdkcairo.h"
@@ -35,3 +36,4 @@ cairo_region_t *gdk_cairo_region_from_clip (cairo_t *cr);
G_END_DECLS
#endif /* __GDK_CAIRO_PRIVATE_H__ */

View File

@@ -750,7 +750,7 @@ static void
free_value (gpointer value)
{
g_value_unset (value);
g_free (value);
g_slice_free (GValue, value);
}
static void
@@ -771,7 +771,7 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
task = g_task_new (clipboard, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, source_tag);
value = g_new0 (GValue, 1);
value = g_slice_new0 (GValue);
g_value_init (value, type);
g_task_set_task_data (task, value, free_value);

View File

@@ -16,7 +16,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_CLIPBOARD_H__
#define __GDK_CLIPBOARD_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
@@ -123,3 +124,4 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkClipboard, g_object_unref)
G_END_DECLS
#endif /* __GDK_CLIPBOARD_H__ */

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GDK_CLIPBOARD_PRIVATE_H__
#define __GDK_CLIPBOARD_PRIVATE_H__
#include <gdk/gdkclipboard.h>
@@ -81,3 +82,4 @@ gboolean gdk_clipboard_write_finish (GdkClipboard
G_END_DECLS
#endif /* __GDK_CLIPBOARD_PRIVATE_H__ */

View File

@@ -410,7 +410,7 @@ gdk_content_register_deserializer (const char *mime_type,
g_return_if_fail (mime_type != NULL);
g_return_if_fail (deserialize != NULL);
deserializer = g_new0 (Deserializer, 1);
deserializer = g_slice_new0 (Deserializer);
deserializer->mime_type = g_intern_string (mime_type);
deserializer->type = type;

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GTK_CONTENT_DESERIALIZER_H__
#define __GTK_CONTENT_DESERIALIZER_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
@@ -102,3 +103,4 @@ gboolean gdk_content_deserialize_finish (GAsyncR
G_END_DECLS
#endif /* __GDK_CONTENT_DESERIALIZER_H__ */

View File

@@ -112,7 +112,7 @@ gdk_content_formats_new_take (GType * gtypes,
const char **mime_types,
gsize n_mime_types)
{
GdkContentFormats *result = g_new0 (GdkContentFormats, 1);
GdkContentFormats *result = g_slice_new0 (GdkContentFormats);
result->ref_count = 1;
result->gtypes = gtypes;
@@ -287,7 +287,7 @@ gdk_content_formats_unref (GdkContentFormats *formats)
g_free (formats->gtypes);
g_free (formats->mime_types);
g_free (formats);
g_slice_free (GdkContentFormats, formats);
}
/**
@@ -611,7 +611,7 @@ gdk_content_formats_builder_new (void)
{
GdkContentFormatsBuilder *builder;
builder = g_new0 (GdkContentFormatsBuilder, 1);
builder = g_slice_new0 (GdkContentFormatsBuilder);
builder->ref_count = 1;
return builder;
@@ -665,7 +665,7 @@ gdk_content_formats_builder_unref (GdkContentFormatsBuilder *builder)
return;
gdk_content_formats_builder_clear (builder);
g_free (builder);
g_slice_free (GdkContentFormatsBuilder, builder);
}
/**

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GTK_CONTENT_FORMATS_H__
#define __GTK_CONTENT_FORMATS_H__
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
@@ -131,3 +132,4 @@ GdkFileList * gdk_file_list_new_from_array (GFile **files,
G_END_DECLS
#endif /* __GTK_CONTENT_FORMATS_H__ */

Some files were not shown because too many files have changed in this diff Show More