Compare commits

..

3 Commits

Author SHA1 Message Date
Matthias Clasen
49e93f6ee4 textview: Don't validate during snapshot
Do it during size_allocate, and go back there
if needed.
2023-02-21 15:04:30 -05:00
Matthias Clasen
4ec2234537 widget: Warn for invalidation during paint 2023-02-21 15:04:30 -05:00
Matthias Clasen
5a3755b233 frameclock: Add a debug helper
Begin able to query the current phase
is useful for debugging purposes.
2023-02-21 15:04:30 -05:00
1480 changed files with 39434 additions and 50378 deletions

View File

@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true" 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" FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3 MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46" FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v41"
workflow: workflow:
rules: rules:
@@ -57,9 +57,11 @@ style-check-diff:
reports: reports:
junit: junit:
- "${CI_PROJECT_DIR}/_build/report-x11.xml" - "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-x11_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml" - "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml" - "${CI_PROJECT_DIR}/_build/report-wayland_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml" - "${CI_PROJECT_DIR}/_build/report-broadway.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway_unstable.xml"
name: "gtk-${CI_COMMIT_REF_NAME}" name: "gtk-${CI_COMMIT_REF_NAME}"
paths: paths:
- "${CI_PROJECT_DIR}/_build/meson-logs" - "${CI_PROJECT_DIR}/_build/meson-logs"
@@ -85,6 +87,7 @@ fedora-x86_64:
script: script:
- .gitlab-ci/show-info-linux.sh - .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH" - export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson subprojects download - meson subprojects download
- meson subprojects update --reset - meson subprojects update --reset
- mkdir _install - mkdir _install
@@ -101,7 +104,7 @@ fedora-x86_64:
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello - 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 x11
- .gitlab-ci/run-tests.sh _build wayland - .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles - .gitlab-ci/run-tests.sh _build waylandgles
- .gitlab-ci/run-tests.sh _build broadway - .gitlab-ci/run-tests.sh _build broadway
release-build: release-build:
@@ -113,6 +116,7 @@ release-build:
script: script:
- .gitlab-ci/show-info-linux.sh - .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH" - export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson subprojects download - meson subprojects download
- meson subprojects update --reset - meson subprojects update --reset
- meson setup - meson setup
@@ -143,11 +147,23 @@ fedora-mingw64:
script: script:
- .gitlab-ci/show-info-linux.sh - .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH" - export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=1.0 - pip3 install --user meson~=0.64
- meson subprojects download - meson subprojects download
- meson subprojects update --reset - meson subprojects update --reset
- meson -Dintrospection=disabled -Dgraphene:introspection=disabled _build # Test that mingw64-meson still fails. If it has stopped failing, the CI
- meson compile -C _build # will fail and now you should remove the hack that follows this.
- FAILED=false
- mingw64-meson --version || FAILED=true
- test $FAILED = false && echo "mingw64-meson works now, remove the hack" && exit 1
# HACK: Running mingw64-meson directly fails on the CI with:
# /usr/bin/mingw64-meson: line 92: fg: no job control
# Because rpm is not evaluating %__meson and it gets interpreted as a job
# specifier. So we fix that and run it ourselves.
- rpm --eval "%{mingw64_meson}" > mingw64-meson.sh
- sed -i -e 's/%__meson/meson/' mingw64-meson.sh
- chmod +x mingw64-meson.sh
- ./mingw64-meson.sh -Dintrospection=disabled -Dgraphene:introspection=disabled _build
- ninja -C _build
.mingw-defaults: .mingw-defaults:
stage: build stage: build
@@ -189,7 +205,7 @@ macos:
needs: [] needs: []
before_script: before_script:
- bash .gitlab-ci/show-info-osx.sh - bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson~=1.0 - pip3 install --user meson~=0.64
- pip3 install --user ninja - pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH - export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1 - export MESON_FORCE_BACKTRACE=1
@@ -347,6 +363,7 @@ static-scan:
EXTRA_MESON_FLAGS: "--buildtype=debug" EXTRA_MESON_FLAGS: "--buildtype=debug"
script: script:
- export PATH="$HOME/.local/bin:$PATH" - export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson setup - meson setup
${COMMON_MESON_FLAGS} ${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
@@ -368,6 +385,7 @@ asan-build:
variables: variables:
script: script:
- export PATH="$HOME/.local/bin:$PATH" - export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build - CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build
- ninja -C _build - ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland - .gitlab-ci/run-tests.sh _build wayland
@@ -382,6 +400,7 @@ reference:
needs: [] needs: []
script: script:
- export PATH="$HOME/.local/bin:$PATH" - export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson setup - meson setup
${COMMON_MESON_FLAGS} ${COMMON_MESON_FLAGS}
--buildtype=release --buildtype=release

View File

@@ -1,4 +1,4 @@
FROM fedora:38 FROM fedora:37
RUN dnf -y install \ RUN dnf -y install \
adwaita-icon-theme \ adwaita-icon-theme \
@@ -32,6 +32,7 @@ RUN dnf -y install \
glib2-static \ glib2-static \
glibc-devel \ glibc-devel \
glibc-headers \ glibc-headers \
gnome-desktop-testing \
gnupg2 \ gnupg2 \
gobject-introspection-devel \ gobject-introspection-devel \
graphene-devel \ graphene-devel \
@@ -72,14 +73,10 @@ RUN dnf -y install \
mesa-dri-drivers \ mesa-dri-drivers \
mesa-libEGL-devel \ mesa-libEGL-devel \
mesa-libGLES-devel \ mesa-libGLES-devel \
meson \
mutter \
ninja-build \ ninja-build \
pango-devel \ pango-devel \
pcre-devel \ pcre-devel \
pcre-static \ pcre-static \
pipewire \
pipewire-gstreamer \
python3 \ python3 \
python3-docutils \ python3-docutils \
python3-gobject \ python3-gobject \
@@ -87,7 +84,6 @@ RUN dnf -y install \
python3-markdown \ python3-markdown \
python3-packaging \ python3-packaging \
python3-pip \ python3-pip \
python3-pydbus \
python3-pygments \ python3-pygments \
python3-typogrify \ python3-typogrify \
python3-wheel \ python3-wheel \
@@ -99,7 +95,6 @@ RUN dnf -y install \
weston \ weston \
weston-libs \ weston-libs \
which \ which \
wireplumber \
xorg-x11-server-Xvfb \ xorg-x11-server-Xvfb \
&& dnf clean all && dnf clean all

View File

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

View File

@@ -138,8 +138,7 @@ if [ $run == 1 ]; then
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}" echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
${CMD} run \ ${CMD} run \
--rm \ --rm \
--userns=keep-id \ --volume "$(pwd)/..:/home/user/app" \
--volume "$(pwd)/..:/home/user/app:rw,z" \
--workdir "/home/user/app" \ --workdir "/home/user/app" \
--tty \ --tty \
--interactive "${TAG}" \ --interactive "${TAG}" \

View File

@@ -6,7 +6,6 @@ set +e
srcdir=$( pwd ) srcdir=$( pwd )
builddir=$1 builddir=$1
backend=$2 backend=$2
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies # Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1 export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1
@@ -16,8 +15,7 @@ case "${backend}" in
x11) x11)
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \ xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \ meson test -C ${builddir} \
--quiet \ --timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \ --print-errorlogs \
--setup=${backend} \ --setup=${backend} \
--suite=gtk \ --suite=gtk \
@@ -28,9 +26,17 @@ case "${backend}" in
# Store the exit code for the CI run, but always # Store the exit code for the CI run, but always
# generate the reports # generate the reports
exit_code=$? exit_code=$?
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
;; ;;
wayland*) wayland)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)" export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 & weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
@@ -38,17 +44,49 @@ case "${backend}" in
export WAYLAND_DISPLAY=wayland-5 export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \ meson test -C ${builddir} \
--quiet \ --timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \ --print-errorlogs \
--setup=${backend} \ --setup=${backend} \
--suite=gtk \ --suite=gtk \
--no-suite=failing \ --no-suite=failing \
--no-suite=flaky \ --no-suite=flaky \
--no-suite=${backend}_failing \
--no-suite=gsk-compare-broadway --no-suite=gsk-compare-broadway
exit_code=$? exit_code=$?
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
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} kill ${compositor}
;; ;;
@@ -60,8 +98,7 @@ case "${backend}" in
export BROADWAY_DISPLAY=:5 export BROADWAY_DISPLAY=:5
meson test -C ${builddir} \ meson test -C ${builddir} \
--quiet \ --timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \ --print-errorlogs \
--setup=${backend} \ --setup=${backend} \
--suite=gtk \ --suite=gtk \
@@ -72,6 +109,13 @@ case "${backend}" in
# don't let Broadway failures fail the run, for now # don't let Broadway failures fail the run, for now
exit_code=0 exit_code=0
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
kill ${server} kill ${server}
;; ;;
@@ -84,19 +128,20 @@ esac
cd ${builddir} cd ${builddir}
$srcdir/.gitlab-ci/meson-junit-report.py \ for suffix in "" "_unstable"; do
$srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \ --project-name=gtk \
--backend="${backend}" \ --backend="${backend}${suffix}" \
--job-id="${CI_JOB_NAME}" \ --job-id="${CI_JOB_NAME}" \
--output="report-${backend}.xml" \ --output="report-${backend}${suffix}.xml" \
"meson-logs/testlog-${backend}.json" "meson-logs/testlog-${backend}${suffix}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
$srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \ --project-name=gtk \
--backend="${backend}" \ --backend="${backend}${suffix}" \
--job-id="${CI_JOB_NAME}" \ --job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${backend}" \ --reftest-output-dir="testsuite/reftests/output/${backend}${suffix}" \
--output="report-${backend}.html" \ --output="report-${backend}${suffix}.html" \
"meson-logs/testlog-${backend}.json" "meson-logs/testlog-${backend}${suffix}.json"
done
exit $exit_code exit $exit_code

255
NEWS
View File

@@ -1,256 +1,5 @@
Overview of Changes in 4.11.2, xx-xx-xxxx Overview of Changes in 4.9.5, xx-xx-xxxx
========================================= ========================================
* GtkGLArea:
- Add an allowed-apis property
* GtkListBox:
- Fix a problem with gtk_list_box_remove_all
* GtkCenterBox:
- Add a shrink-center-last property
* GtkButton, GtkMenuButton:
- Add a can-shrink property
* GtkPopover:
- Fix problems with grabs
* GtkFileChooser:
- Fix a problem with removing files
- Make the date, time and location columns work
- Fix filtering in the save entry popup
- A few memory leak fixes
- Handle webdav in the pathbar
* Dialogs:
- Destroy windows promptly when the async callback finishes
- Detect absence of the OpenURI portal and fall back
* Theme:
- Add explicit style classes to a number of widgets
- Fix some contrast issues in the dark theme
* Accessibility:
- Fix alert dialogs in the a11y tree
* Layout:
- Some fixes to baseline alignment
* GL:
- Add GdkGLTextureBuilder, a more flexible api for creating textures
- Ensure that we work with GLES 2
* Vulkan:
- More fixes to the experimental Vulkan renderer
- Rework glyph caching
* Wayland:
- Don't destroy wl_surfaces on hide
- Plug leaks of compositor-side resources
* Inspector:
- Improve the action list
- Fix a crash
* Tools:
- gtk4-node-editor: Improve scaling
- gtk4-node-editor: Preserve aspect ratio of textures
- gtk4-demo: Make the stylus demo work with mice
* Translation updates
Bulgarian
Chinese (China)
Galician
Hebrew
Polish
Portuguese
Russian
Turkish
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, 12-02-2023
======================================== ========================================

View File

@@ -116,12 +116,19 @@ docs/reference/gtk/html/gtk-building.html
Or [online](https://docs.gtk.org/gtk4/building.html) Or [online](https://docs.gtk.org/gtk4/building.html)
Building from git Default branch renamed to `main`
----------------- --------------------------------
The GTK sources are hosted on [gitlab.gnome.org](http://gitlab.gnome.org). The main The default development branch of GTK has been renamed to `main`.
development branch is called `main`, and stable branches are named after their minor To update your local checkout, use:
version, for example `gtk-4-10`. ```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
How to report bugs How to report bugs
------------------ ------------------

View File

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

View File

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

View File

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

View File

@@ -5,8 +5,7 @@ enum
{ {
PROP_TEXTURE = 1, PROP_TEXTURE = 1,
PROP_FILTER, PROP_FILTER,
PROP_SCALE, PROP_SCALE
PROP_ANGLE,
}; };
struct _Demo3Widget struct _Demo3Widget
@@ -15,7 +14,6 @@ struct _Demo3Widget
GdkTexture *texture; GdkTexture *texture;
float scale; float scale;
float angle;
GskScalingFilter filter; GskScalingFilter filter;
GtkWidget *menu; GtkWidget *menu;
@@ -28,85 +26,10 @@ struct _Demo3WidgetClass
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET) 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 static void
demo3_widget_init (Demo3Widget *self) demo3_widget_init (Demo3Widget *self)
{ {
self->scale = 1.f; self->scale = 1.f;
self->angle = 0.f;
self->filter = GSK_SCALING_FILTER_LINEAR; self->filter = GSK_SCALING_FILTER_LINEAR;
gtk_widget_init_template (GTK_WIDGET (self)); gtk_widget_init_template (GTK_WIDGET (self));
} }
@@ -129,35 +52,26 @@ demo3_widget_snapshot (GtkWidget *widget,
{ {
Demo3Widget *self = DEMO3_WIDGET (widget); Demo3Widget *self = DEMO3_WIDGET (widget);
int x, y, width, height; int x, y, width, height;
double w, h, w2, h2; double w, h;
GskRenderNode *node;
width = gtk_widget_get_width (widget); width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget); height = gtk_widget_get_height (widget);
w2 = w = self->scale * gdk_texture_get_width (self->texture); w = self->scale * gdk_texture_get_width (self->texture);
h2 = h = self->scale * gdk_texture_get_height (self->texture); h = self->scale * gdk_texture_get_height (self->texture);
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) || x = MAX (0, (width - ceil (w)) / 2);
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON)) y = MAX (0, (height - ceil (h)) / 2);
{
double s = w2;
w2 = h2;
h2 = s;
}
x = (width - ceil (w2)) / 2;
y = (height - ceil (h2)) / 2;
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height)); gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_save (snapshot); gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y)); gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (w2 / 2, h2 / 2)); node = gsk_texture_scale_node_new (self->texture,
gtk_snapshot_rotate (snapshot, self->angle); &GRAPHENE_RECT_INIT (0, 0, w, h),
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- w / 2, - h / 2)); self->filter);
gtk_snapshot_append_scaled_texture (snapshot, gtk_snapshot_append_node (snapshot, node);
self->texture, gsk_render_node_unref (node);
self->filter,
&GRAPHENE_RECT_INIT (0, 0, w, h));
gtk_snapshot_restore (snapshot); gtk_snapshot_restore (snapshot);
gtk_snapshot_pop (snapshot); gtk_snapshot_pop (snapshot);
} }
@@ -172,26 +86,14 @@ demo3_widget_measure (GtkWidget *widget,
int *natural_baseline) int *natural_baseline)
{ {
Demo3Widget *self = DEMO3_WIDGET (widget); Demo3Widget *self = DEMO3_WIDGET (widget);
int width, height;
int size; 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) if (orientation == GTK_ORIENTATION_HORIZONTAL)
size = width; size = gdk_texture_get_width (self->texture);
else else
size = height; size = gdk_texture_get_height (self->texture);
*minimum = *natural = (int) ceil (self->scale * size); *minimum = *natural = self->scale * size;
} }
static void static void
@@ -209,8 +111,6 @@ demo3_widget_size_allocate (GtkWidget *widget,
gtk_popover_present (GTK_POPOVER (self->menu)); gtk_popover_present (GTK_POPOVER (self->menu));
} }
static void update_actions (Demo3Widget *self);
static void static void
demo3_widget_set_property (GObject *object, demo3_widget_set_property (GObject *object,
guint prop_id, guint prop_id,
@@ -224,24 +124,11 @@ demo3_widget_set_property (GObject *object,
case PROP_TEXTURE: case PROP_TEXTURE:
g_clear_object (&self->texture); g_clear_object (&self->texture);
self->texture = g_value_dup_object (value); 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)); gtk_widget_queue_resize (GTK_WIDGET (object));
g_object_notify (object, "scale");
g_object_notify (object, "angle");
g_object_notify (object, "filter");
break; break;
case PROP_SCALE: case PROP_SCALE:
self->scale = g_value_get_float (value); 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)); gtk_widget_queue_resize (GTK_WIDGET (object));
break; break;
@@ -274,10 +161,6 @@ demo3_widget_get_property (GObject *object,
g_value_set_float (value, self->scale); g_value_set_float (value, self->scale);
break; break;
case PROP_ANGLE:
g_value_set_float (value, self->angle);
break;
case PROP_FILTER: case PROP_FILTER:
g_value_set_enum (value, self->filter); g_value_set_enum (value, self->filter);
break; break;
@@ -303,14 +186,6 @@ pressed_cb (GtkGestureClick *gesture,
gtk_popover_popup (GTK_POPOVER (self->menu)); 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 static void
zoom_cb (GtkWidget *widget, zoom_cb (GtkWidget *widget,
const char *action_name, const char *action_name,
@@ -320,30 +195,19 @@ zoom_cb (GtkWidget *widget,
float scale; float scale;
if (g_str_equal (action_name, "zoom.in")) 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")) else if (g_str_equal (action_name, "zoom.out"))
scale = MAX (1./1024., self->scale / M_SQRT2); scale = MAX (0.01, self->scale / M_SQRT2);
else if (g_str_equal (action_name, "zoom.reset"))
scale = 1.0;
else 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); 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 static void
demo3_widget_class_init (Demo3WidgetClass *class) 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_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_float ("scale", NULL, NULL, g_param_spec_float ("scale", NULL, NULL,
1./1024., 1024., 1.0, 0.0, 10.0, 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,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_FILTER, 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.in", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.out", 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, "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_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu); 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); texture = gdk_texture_new_from_resource (resource);
self = g_object_new (DEMO3_TYPE_WIDGET, self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
"texture", texture,
"has-tooltip", TRUE,
NULL);
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
g_object_unref (texture); g_object_unref (texture);

View File

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

View File

@@ -109,21 +109,15 @@ static void
apply_transform (CanvasItem *item) apply_transform (CanvasItem *item)
{ {
GskTransform *transform; GskTransform *transform;
graphene_rect_t bounds;
double x, y; double x, y;
/* Add css padding and margin */ x = gtk_widget_get_allocated_width (item->label) / 2.0;
if (!gtk_widget_compute_bounds (item->label, item->label, &bounds)) y = gtk_widget_get_allocated_height (item->label) / 2.0;
return; item->r = sqrt (x*x + y*y);
x = bounds.size.width / 2.;
y = bounds.size.height / 2.;
item->r = sqrt (x * x + y * y);
transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r }); transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r });
transform = gsk_transform_rotate (transform, item->angle + item->delta); transform = gsk_transform_rotate (transform, item->angle + item->delta);
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-x, -y)); transform = gsk_transform_translate (transform, &(graphene_point_t) { -x, -y });
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform); gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
gsk_transform_unref (transform); gsk_transform_unref (transform);
@@ -330,7 +324,7 @@ canvas_item_start_editing (CanvasItem *item)
GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item)); GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item));
GtkWidget *entry; GtkWidget *entry;
GtkWidget *scale; GtkWidget *scale;
graphene_point_t p; double x, y;
if (item->editor) if (item->editor)
return; return;
@@ -356,9 +350,8 @@ canvas_item_start_editing (CanvasItem *item)
gtk_box_append (GTK_BOX (item->editor), scale); gtk_box_append (GTK_BOX (item->editor), scale);
if (!gtk_widget_compute_point (GTK_WIDGET (item), canvas, &GRAPHENE_POINT_INIT (0, 0), &p)) gtk_widget_translate_coordinates (GTK_WIDGET (item), canvas, 0, 0, &x, &y);
graphene_point_init (&p, 0, 0); gtk_fixed_put (GTK_FIXED (canvas), item->editor, x, y + 2 * item->r);
gtk_fixed_put (GTK_FIXED (canvas), item->editor, p.x, p.y + 2 * item->r);
gtk_widget_grab_focus (entry); gtk_widget_grab_focus (entry);
} }
@@ -375,7 +368,6 @@ prepare (GtkDragSource *source,
GtkWidget *canvas; GtkWidget *canvas;
GtkWidget *item; GtkWidget *item;
Hotspot *hotspot; Hotspot *hotspot;
graphene_point_t p;
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source)); canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT); item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
@@ -387,10 +379,7 @@ prepare (GtkDragSource *source,
g_object_set_data (G_OBJECT (canvas), "dragged-item", item); g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
hotspot = g_new (Hotspot, 1); hotspot = g_new (Hotspot, 1);
if (!gtk_widget_compute_point (canvas, item, &GRAPHENE_POINT_INIT (x, y), &p)) gtk_widget_translate_coordinates (canvas, item, x, y, &hotspot->x, &hotspot->y);
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); g_object_set_data_full (G_OBJECT (canvas), "hotspot", hotspot, g_free);
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item); return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);

View File

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

View File

@@ -42,8 +42,8 @@ val_to_xy (GtkFontPlane *plane,
double u, v; double u, v;
int width, height; int width, height;
width = gtk_widget_get_width (GTK_WIDGET (plane)); width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
height = gtk_widget_get_height (GTK_WIDGET (plane)); height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
u = adjustment_get_normalized_value (plane->width_adj); u = adjustment_get_normalized_value (plane->width_adj);
v = adjustment_get_normalized_value (plane->weight_adj); v = adjustment_get_normalized_value (plane->weight_adj);
@@ -62,8 +62,8 @@ plane_snapshot (GtkWidget *widget,
cairo_t *cr; cairo_t *cr;
val_to_xy (plane, &x, &y); val_to_xy (plane, &x, &y);
width = gtk_widget_get_width (widget); width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_height (widget); height = gtk_widget_get_allocated_height (widget);
cr = gtk_snapshot_append_cairo (snapshot, cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height)); &GRAPHENE_RECT_INIT (0, 0, width, height));
@@ -131,8 +131,8 @@ update_value (GtkFontPlane *plane,
GtkWidget *widget = GTK_WIDGET (plane); GtkWidget *widget = GTK_WIDGET (plane);
double u, v; double u, v;
u = CLAMP (x * (1.0 / gtk_widget_get_width (widget)), 0, 1); u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_height (widget)), 0, 1); v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
adjustment_set_normalized_value (plane->width_adj, u); adjustment_set_normalized_value (plane->width_adj, u);
adjustment_set_normalized_value (plane->weight_adj, v); adjustment_set_normalized_value (plane->weight_adj, v);

View File

@@ -221,13 +221,16 @@ static void
realize (GtkWidget *widget) realize (GtkWidget *widget)
{ {
const char *vertex_path, *fragment_path; const char *vertex_path, *fragment_path;
GdkGLContext *context;
gtk_gl_area_make_current (GTK_GL_AREA (widget)); gtk_gl_area_make_current (GTK_GL_AREA (widget));
if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL) if (gtk_gl_area_get_error (GTK_GL_AREA (widget)) != NULL)
return; 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"; vertex_path = "/glarea/glarea-gles.vs.glsl";
fragment_path = "/glarea/glarea-gles.fs.glsl"; fragment_path = "/glarea/glarea-gles.fs.glsl";

View File

@@ -737,6 +737,7 @@ gtk_gears_realize (GtkWidget *widget)
GtkGLArea *glarea = GTK_GL_AREA (widget); GtkGLArea *glarea = GTK_GL_AREA (widget);
GtkGears *gears = GTK_GEARS (widget); GtkGears *gears = GTK_GEARS (widget);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears); GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
GdkGLContext *context;
GLuint vao, v, f, program; GLuint vao, v, f, program;
const char *p; const char *p;
char msg[512]; char msg[512];
@@ -747,6 +748,8 @@ gtk_gears_realize (GtkWidget *widget)
if (gtk_gl_area_get_error (glarea) != NULL) if (gtk_gl_area_get_error (glarea) != NULL)
return; return;
context = gtk_gl_area_get_context (glarea);
glEnable (GL_CULL_FACE); glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
@@ -756,7 +759,7 @@ gtk_gears_realize (GtkWidget *widget)
priv->vao = vao; priv->vao = vao;
/* Compile the vertex shader */ /* 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; p = vertex_shader_gles;
else else
p = vertex_shader_gl; p = vertex_shader_gl;
@@ -767,7 +770,7 @@ gtk_gears_realize (GtkWidget *widget)
g_debug ("vertex shader info: %s\n", msg); g_debug ("vertex shader info: %s\n", msg);
/* Compile the fragment shader */ /* 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; p = fragment_shader_gles;
else else
p = fragment_shader_gl; 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

@@ -64,8 +64,6 @@
</child> </child>
<child> <child>
<object class="GtkLabel" id="short_time_label"> <object class="GtkLabel" id="short_time_label">
<property name="hexpand">1</property>
<property name="xalign">1</property>
<property name="valign">baseline</property> <property name="valign">baseline</property>
<property name="label" translatable="yes">38m</property> <property name="label" translatable="yes">38m</property>
<style> <style>

View File

@@ -29,13 +29,15 @@
</style> </style>
</object> </object>
</child> </child>
<child>
<object class="GtkFrame">
<child> <child>
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<property name="show-separators">1</property>
<signal name="row-activated" handler="row_activated"/> <signal name="row-activated" handler="row_activated"/>
<style> <style>
<class name="rich-list"/> <class name="rich-list"/>
<class name="boxed-list"/>
</style> </style>
<child> <child>
@@ -118,6 +120,8 @@
</child> </child>
</object> </object>
</child> </child>
</object>
</child>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
@@ -130,12 +134,14 @@
</style> </style>
</object> </object>
</child> </child>
<child>
<object class="GtkFrame">
<child> <child>
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<property name="show-separators">1</property>
<style> <style>
<class name="rich-list"/> <class name="rich-list"/>
<class name="boxed-list"/>
</style> </style>
<child> <child>
@@ -275,6 +281,8 @@
</object> </object>
</child> </child>
</object> </object>
</child>
</object>
<object class="GtkSizeGroup"> <object class="GtkSizeGroup">
<property name="mode">horizontal</property> <property name="mode">horizontal</property>
<widgets> <widgets>

View File

@@ -150,7 +150,7 @@ settings_key_new (GSettings *settings,
static void static void
item_value_changed (GtkEditableLabel *label, item_value_changed (GtkEditableLabel *label,
GParamSpec *pspec, GParamSpec *pspec,
GtkColumnViewCell *cell) GtkListItem *item)
{ {
SettingsKey *self; SettingsKey *self;
const char *text; const char *text;
@@ -162,7 +162,8 @@ item_value_changed (GtkEditableLabel *label,
text = gtk_editable_get_text (GTK_EDITABLE (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); type = g_settings_schema_key_get_value_type (self->key);
name = g_settings_schema_key_get_name (self->key); name = g_settings_schema_key_get_name (self->key);

View File

@@ -20,7 +20,6 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<child> <child>
<object class="GtkListView" id="listview"> <object class="GtkListView" id="listview">
<property name="tab-behavior">item</property>
<style> <style>
<class name="navigation-sidebar"/> <class name="navigation-sidebar"/>
</style> </style>
@@ -77,7 +76,6 @@
<property name="vexpand">1</property> <property name="vexpand">1</property>
<child> <child>
<object class="GtkColumnView" id="columnview"> <object class="GtkColumnView" id="columnview">
<property name="tab-behavior">cell</property>
<style> <style>
<class name="data-table"/> <class name="data-table"/>
</style> </style>
@@ -90,13 +88,13 @@
<property name="bytes"><![CDATA[ <property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkColumnViewCell"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="xalign">0</property> <property name="xalign">0</property>
<binding name="label"> <binding name="label">
<lookup name="name" type="SettingsKey"> <lookup name="name" type="SettingsKey">
<lookup name="item">GtkColumnViewCell</lookup> <lookup name="item">GtkListItem</lookup>
</lookup> </lookup>
</binding> </binding>
</object> </object>
@@ -118,12 +116,12 @@
<property name="bytes"><![CDATA[ <property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkColumnViewCell"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkEditableLabel"> <object class="GtkEditableLabel">
<binding name="text"> <binding name="text">
<lookup name="value" type="SettingsKey"> <lookup name="value" type="SettingsKey">
<lookup name="item">GtkColumnViewCell</lookup> <lookup name="item">GtkListItem</lookup>
</lookup> </lookup>
</binding> </binding>
<signal name="notify::label" handler="item_value_changed"/> <signal name="notify::label" handler="item_value_changed"/>
@@ -146,13 +144,13 @@
<property name="bytes"><![CDATA[ <property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkColumnViewCell"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="xalign">0</property> <property name="xalign">0</property>
<binding name="label"> <binding name="label">
<lookup name="type" type="SettingsKey"> <lookup name="type" type="SettingsKey">
<lookup name="item">GtkColumnViewCell</lookup> <lookup name="item">GtkListItem</lookup>
</lookup> </lookup>
</binding> </binding>
</object> </object>
@@ -175,13 +173,13 @@
<property name="bytes"><![CDATA[ <property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkColumnViewCell"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="xalign">0</property> <property name="xalign">0</property>
<binding name="label"> <binding name="label">
<lookup name="default-value" type="SettingsKey"> <lookup name="default-value" type="SettingsKey">
<lookup name="item">GtkColumnViewCell</lookup> <lookup name="item">GtkListItem</lookup>
</lookup> </lookup>
</binding> </binding>
</object> </object>
@@ -205,14 +203,14 @@
<property name="bytes"><![CDATA[ <property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkColumnViewCell"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="wrap">1</property> <property name="wrap">1</property>
<binding name="label"> <binding name="label">
<lookup name="summary" type="SettingsKey"> <lookup name="summary" type="SettingsKey">
<lookup name="item">GtkColumnViewCell</lookup> <lookup name="item">GtkListItem</lookup>
</lookup> </lookup>
</binding> </binding>
</object> </object>
@@ -236,14 +234,14 @@
<property name="bytes"><![CDATA[ <property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkColumnViewCell"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="wrap">1</property> <property name="wrap">1</property>
<binding name="label"> <binding name="label">
<lookup name="description" type="SettingsKey"> <lookup name="description" type="SettingsKey">
<lookup name="item">GtkColumnViewCell</lookup> <lookup name="item">GtkListItem</lookup>
</lookup> </lookup>
</binding> </binding>
</object> </object>

View File

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

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

View File

@@ -24,7 +24,6 @@ typedef struct
GdkRGBA draw_color; GdkRGBA draw_color;
GtkPadController *pad_controller; GtkPadController *pad_controller;
double brush_size; double brush_size;
GtkGesture *gesture;
} DrawingArea; } DrawingArea;
typedef struct typedef struct
@@ -104,11 +103,13 @@ drawing_area_size_allocate (GtkWidget *widget,
static void static void
drawing_area_map (GtkWidget *widget) drawing_area_map (GtkWidget *widget)
{ {
GtkAllocation allocation;
GTK_WIDGET_CLASS (drawing_area_parent_class)->map (widget); GTK_WIDGET_CLASS (drawing_area_parent_class)->map (widget);
gtk_widget_get_allocation (widget, &allocation);
drawing_area_ensure_surface ((DrawingArea *) widget, drawing_area_ensure_surface ((DrawingArea *) widget,
gtk_widget_get_width (widget), allocation.width, allocation.height);
gtk_widget_get_height (widget));
} }
static void static void
@@ -261,7 +262,7 @@ drawing_area_apply_stroke (DrawingArea *area,
double y, double y,
double pressure) double pressure)
{ {
if (tool && gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER) if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
{ {
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size); cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT); cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
@@ -312,9 +313,7 @@ stylus_gesture_motion (GtkGestureStylus *gesture,
drawing_area_apply_stroke (area, tool, drawing_area_apply_stroke (area, tool,
backlog[i].axes[GDK_AXIS_X], backlog[i].axes[GDK_AXIS_X],
backlog[i].axes[GDK_AXIS_Y], backlog[i].axes[GDK_AXIS_Y],
backlog[i].flags & GDK_AXIS_FLAG_PRESSURE backlog[i].axes[GDK_AXIS_PRESSURE]);
? backlog[i].axes[GDK_AXIS_PRESSURE]
: 1);
} }
g_free (backlog); g_free (backlog);
@@ -344,8 +343,6 @@ drawing_area_init (DrawingArea *area)
area->draw_color = (GdkRGBA) { 0, 0, 0, 1 }; area->draw_color = (GdkRGBA) { 0, 0, 0, 1 };
area->brush_size = 1; area->brush_size = 1;
area->gesture = gesture;
} }
static GtkWidget * static GtkWidget *
@@ -384,12 +381,6 @@ drawing_area_color_set (DrawingArea *area,
gtk_color_dialog_button_set_rgba (button, color); gtk_color_dialog_button_set_rgba (button, color);
} }
static GtkGesture *
drawing_area_get_gesture (DrawingArea *area)
{
return area->gesture;
}
GtkWidget * GtkWidget *
do_paint (GtkWidget *toplevel) do_paint (GtkWidget *toplevel)
{ {
@@ -397,7 +388,7 @@ do_paint (GtkWidget *toplevel)
if (!window) if (!window)
{ {
GtkWidget *draw_area, *headerbar, *button; GtkWidget *draw_area, *headerbar, *colorbutton;
window = gtk_window_new (); window = gtk_window_new ();
@@ -406,22 +397,15 @@ do_paint (GtkWidget *toplevel)
headerbar = gtk_header_bar_new (); headerbar = gtk_header_bar_new ();
button = gtk_color_dialog_button_new (gtk_color_dialog_new ()); colorbutton = gtk_color_dialog_button_new (gtk_color_dialog_new ());
g_signal_connect (button, "notify::rgba", g_signal_connect (colorbutton, "notify::rgba",
G_CALLBACK (color_button_color_set), draw_area); G_CALLBACK (color_button_color_set), draw_area);
g_signal_connect (draw_area, "color-set", g_signal_connect (draw_area, "color-set",
G_CALLBACK (drawing_area_color_set), button); G_CALLBACK (drawing_area_color_set), colorbutton);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (button), gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (colorbutton),
&(GdkRGBA) { 0, 0, 0, 1 }); &(GdkRGBA) { 0, 0, 0, 1 });
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), button); gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
button = gtk_check_button_new_with_label ("Stylus only");
g_object_bind_property (button, "active",
drawing_area_get_gesture ((DrawingArea *)draw_area), "stylus-only",
G_BINDING_SYNC_CREATE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), button);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar); gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_title (GTK_WINDOW (window), "Paint"); gtk_window_set_title (GTK_WINDOW (window), "Paint");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);

View File

@@ -13,13 +13,20 @@
static GtkWidget *app_picker; static GtkWidget *app_picker;
static void static void
set_file (GFile *file, file_opened (GObject *source,
gpointer data) GAsyncResult *result,
void *data)
{ {
GFile *file;
GError *error = NULL;
char *name; char *name;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file) if (!file)
{ {
g_print ("%s\n", error->message);
g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE); gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL); g_object_set_data (G_OBJECT (app_picker), "file", NULL);
return; 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); 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 static gboolean
abort_mission (gpointer data) abort_mission (gpointer data)
{ {
@@ -142,28 +130,11 @@ launch_uri (GtkButton *picker)
g_object_unref (launcher); 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 * GtkWidget *
do_pickers (GtkWidget *do_widget) do_pickers (GtkWidget *do_widget)
{ {
static GtkWidget *window = NULL; static GtkWidget *window = NULL;
GtkWidget *table, *label, *picker, *button; GtkWidget *table, *label, *picker, *button;
GtkDropTarget *drop_target;
if (!window) if (!window)
{ {
@@ -208,13 +179,7 @@ do_pickers (GtkWidget *do_widget)
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_button_new_from_icon_name ("document-open-symbolic"); button = gtk_button_new_from_icon_name ("document-open-symbolic");
label = gtk_label_new ("None"); 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_xalign (GTK_LABEL (label), 0.);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE); gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_hexpand (label, TRUE); 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)); gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
g_object_set (overlay, "view-name", view, NULL); g_object_set (overlay, "view-name", view, NULL);
g_object_unref (builder); g_object_unref (builder);
gtk_window_present (GTK_WINDOW (overlay));
} }
G_MODULE_EXPORT void G_MODULE_EXPORT void

View File

@@ -471,7 +471,7 @@ suggestion_entry_size_allocate (GtkWidget *widget,
&(GtkAllocation) { width - arrow_nat, 0, arrow_nat, height }, &(GtkAllocation) { width - arrow_nat, 0, arrow_nat, height },
baseline); baseline);
gtk_widget_set_size_request (self->popup, gtk_widget_get_width (GTK_WIDGET (self)), -1); gtk_widget_set_size_request (self->popup, gtk_widget_get_allocated_width (GTK_WIDGET (self)), -1);
gtk_widget_queue_resize (self->popup); gtk_widget_queue_resize (self->popup);
gtk_popover_present (GTK_POPOVER (self->popup)); gtk_popover_present (GTK_POPOVER (self->popup));
@@ -849,7 +849,7 @@ suggestion_entry_init (SuggestionEntry *self)
GtkCssProvider *provider; GtkCssProvider *provider;
provider = gtk_css_provider_new (); 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_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER (provider),
800); 800);

View File

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

View File

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

View File

@@ -78,8 +78,6 @@ gtk_renderer_paintable_paintable_snapshot (GdkPaintable *paintable,
gdk_paintable_snapshot (GDK_PAINTABLE (texture), snapshot, width, height); gdk_paintable_snapshot (GDK_PAINTABLE (texture), snapshot, width, height);
g_object_unref (texture); g_object_unref (texture);
gsk_render_node_unref (node);
} }
static int static int

View File

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

View File

@@ -32,11 +32,6 @@
#include "gsk/vulkan/gskvulkanrenderer.h" #include "gsk/vulkan/gskvulkanrenderer.h"
#endif #endif
#include <cairo.h>
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
#endif
typedef struct typedef struct
{ {
gsize start_chars; gsize start_chars;
@@ -64,7 +59,6 @@ struct _NodeEditorWindow
GListStore *renderers; GListStore *renderers;
GskRenderNode *node; GskRenderNode *node;
GFile *file;
GFileMonitor *file_monitor; GFileMonitor *file_monitor;
GArray *errors; GArray *errors;
@@ -175,7 +169,6 @@ text_changed (GtkTextBuffer *buffer,
GtkTextIter iter; GtkTextIter iter;
GtkTextIter start, end; GtkTextIter start, end;
float scale; float scale;
GskRenderNode *big_node;
g_array_remove_range (self->errors, 0, self->errors->len); g_array_remove_range (self->errors, 0, self->errors->len);
text = get_current_text (self->text_buffer); text = get_current_text (self->text_buffer);
@@ -188,18 +181,13 @@ text_changed (GtkTextBuffer *buffer,
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self); self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
scale = gtk_scale_button_get_value (GTK_SCALE_BUTTON (self->scale_scale)); 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); GskRenderNode *node;
big_node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
} node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
else if (self->node) gsk_render_node_unref (self->node);
{ self->node = node;
big_node = gsk_render_node_ref (self->node);
}
else
{
big_node = NULL;
} }
g_bytes_unref (bytes); g_bytes_unref (bytes);
@@ -211,27 +199,18 @@ text_changed (GtkTextBuffer *buffer,
graphene_rect_t bounds; graphene_rect_t bounds;
guint i; 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 (); snapshot = gtk_snapshot_new ();
gsk_render_node_get_bounds (self->node, &bounds); gsk_render_node_get_bounds (self->node, &bounds);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y)); gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- bounds.origin.x, - bounds.origin.y));
gtk_snapshot_append_node (snapshot, self->node); gtk_snapshot_append_node (snapshot, self->node);
paintable = gtk_snapshot_free_to_paintable (snapshot, &bounds.size); 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++) 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); gpointer item = g_list_model_get_item (G_LIST_MODEL (self->renderers), i);
gtk_renderer_paintable_set_paintable (item, paintable); gtk_renderer_paintable_set_paintable (item, paintable);
g_object_unref (item); g_object_unref (item);
} }
g_clear_object (&paintable); g_clear_object (&paintable);
} }
else else
@@ -239,8 +218,6 @@ text_changed (GtkTextBuffer *buffer,
gtk_picture_set_paintable (GTK_PICTURE (self->picture), NULL); 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); gtk_text_buffer_get_start_iter (self->text_buffer, &iter);
while (!gtk_text_iter_is_end (&iter)) while (!gtk_text_iter_is_end (&iter))
@@ -545,14 +522,12 @@ node_editor_window_load (NodeEditorWindow *self,
{ {
GError *error = NULL; GError *error = NULL;
g_clear_object (&self->file);
g_clear_object (&self->file_monitor); g_clear_object (&self->file_monitor);
if (!load_file_contents (self, file)) if (!load_file_contents (self, file))
return FALSE; return FALSE;
self->file = g_object_ref (file); self->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
self->file_monitor = g_file_monitor_file (self->file, G_FILE_MONITOR_NONE, NULL, &error);
if (error) if (error)
{ {
@@ -589,21 +564,13 @@ static void
show_open_filechooser (NodeEditorWindow *self) show_open_filechooser (NodeEditorWindow *self)
{ {
GtkFileDialog *dialog; GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new (); dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Open node file"); gtk_file_dialog_set_title (dialog, "Open node file");
if (self->file)
{
gtk_file_dialog_set_initial_file (dialog, self->file);
}
else
{
GFile *cwd;
cwd = g_file_new_for_path ("."); cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd); gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd); g_object_unref (cwd);
}
gtk_file_dialog_open (dialog, GTK_WINDOW (self), gtk_file_dialog_open (dialog, GTK_WINDOW (self),
NULL, open_response_cb, self); NULL, open_response_cb, self);
g_object_unref (dialog); g_object_unref (dialog);
@@ -661,21 +628,14 @@ save_cb (GtkWidget *button,
NodeEditorWindow *self) NodeEditorWindow *self)
{ {
GtkFileDialog *dialog; GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new (); dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Save node"); gtk_file_dialog_set_title (dialog, "Save node");
if (self->file) cwd = g_file_new_for_path (".");
{
gtk_file_dialog_set_initial_file (dialog, self->file);
}
else
{
GFile *cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd); gtk_file_dialog_set_initial_folder (dialog, cwd);
gtk_file_dialog_set_initial_name (dialog, "demo.node"); gtk_file_dialog_set_initial_name (dialog, "demo.node");
g_object_unref (cwd); g_object_unref (cwd);
}
gtk_file_dialog_save (dialog, gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))), GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL, NULL,
@@ -683,34 +643,23 @@ save_cb (GtkWidget *button,
g_object_unref (dialog); g_object_unref (dialog);
} }
static GskRenderNode * static GdkTexture *
create_node (NodeEditorWindow *self) create_texture (NodeEditorWindow *self)
{ {
GdkPaintable *paintable; GdkPaintable *paintable;
GtkSnapshot *snapshot; GtkSnapshot *snapshot;
GskRenderer *renderer;
GskRenderNode *node; GskRenderNode *node;
GdkTexture *texture;
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture)); paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
if (paintable == NULL || if (paintable == NULL ||
gdk_paintable_get_intrinsic_width (paintable) <= 0 || gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
gdk_paintable_get_intrinsic_height (paintable) <= 0) gdk_paintable_get_intrinsic_height (paintable) <= 0)
return NULL; return NULL;
snapshot = gtk_snapshot_new (); snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable)); gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
node = gtk_snapshot_free_to_node (snapshot); 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) if (node == NULL)
return NULL; return NULL;
@@ -721,58 +670,6 @@ create_texture (NodeEditorWindow *self)
return texture; 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 * static GdkTexture *
create_cairo_texture (NodeEditorWindow *self) create_cairo_texture (NodeEditorWindow *self)
{ {
@@ -804,141 +701,51 @@ create_cairo_texture (NodeEditorWindow *self)
return texture; return texture;
} }
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 static void
export_image_response_cb (GObject *source, export_image_response_cb (GObject *source,
GAsyncResult *result, GAsyncResult *result,
void *user_data) void *user_data)
{ {
GtkFileDialog *dialog = GTK_FILE_DIALOG (source); GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GskRenderNode *node = user_data; GdkTexture *texture = user_data;
GFile *file; GFile *file;
char *uri;
GBytes *bytes;
file = gtk_file_dialog_save_finish (dialog, result, NULL); file = gtk_file_dialog_save_finish (dialog, result, NULL);
if (file == NULL) if (file)
{ {
gsk_render_node_unref (node); if (!gdk_texture_save_to_png (texture, g_file_peek_path (file)))
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)
{ {
GtkAlertDialog *alert; GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Exporting to image failed"); alert = gtk_alert_dialog_new ("Exporting to image failed");
gtk_alert_dialog_set_detail (alert, error->message); gtk_alert_dialog_show (alert, GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))));
gtk_alert_dialog_show (alert, NULL);
g_object_unref (alert); 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_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 (file);
}
g_object_unref (texture);
} }
static void static void
export_image_cb (GtkWidget *button, export_image_cb (GtkWidget *button,
NodeEditorWindow *self) NodeEditorWindow *self)
{ {
GskRenderNode *node; GdkTexture *texture;
GtkFileDialog *dialog; GtkFileDialog *dialog;
GtkFileFilter *filter;
GListStore *filters;
node = create_node (self); texture = create_texture (self);
if (node == NULL) if (texture == NULL)
return; 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 (); dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, ""); gtk_file_dialog_set_title (dialog, "");
gtk_file_dialog_set_initial_name (dialog, "example.png"); 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_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))), GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL, NULL,
export_image_response_cb, node); export_image_response_cb, texture);
g_object_unref (filters);
g_object_unref (dialog); g_object_unref (dialog);
} }
@@ -1052,19 +859,6 @@ testcase_save_clicked_cb (GtkWidget *button,
} }
text = get_current_text (self->text_buffer); 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)) if (!g_file_set_contents (node_file, text, -1, &error))
{ {
gtk_label_set_label (GTK_LABEL (self->testcase_error_label), error->message); gtk_label_set_label (GTK_LABEL (self->testcase_error_label), error->message);
@@ -1109,8 +903,6 @@ node_editor_window_finalize (GObject *object)
g_clear_pointer (&self->node, gsk_render_node_unref); g_clear_pointer (&self->node, gsk_render_node_unref);
g_clear_object (&self->renderers); g_clear_object (&self->renderers);
g_clear_object (&self->file_monitor);
g_clear_object (&self->file);
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object); G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
} }

View File

@@ -163,9 +163,9 @@
<property name="valign">center</property> <property name="valign">center</property>
<property name="adjustment"> <property name="adjustment">
<object class="GtkAdjustment"> <object class="GtkAdjustment">
<property name="lower">-4</property> <property name="lower">1</property>
<property name="value">0</property> <property name="value">1</property>
<property name="upper">4</property> <property name="upper">10</property>
<property name="step-increment">0.1</property> <property name="step-increment">0.1</property>
<property name="page-increment">0.5</property> <property name="page-increment">0.5</property>
</object> </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. 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: 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>\*` **document**: `<node>\*`
**node**: container [ "name" ] { <document> } | `<node-type> [ "name" ] { <property>* }` | "name" **node**: container { <document> } | `<node-name> { <property>* }`
**property**: `<property-name>: <node> | <value> ;` **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. 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 \. 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 # Nodes
### container ### container

View File

@@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else else
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources', widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
'widget-factory.gresource.xml', 'widget-factory.gresource.xml',
source_dir: meson.current_source_dir(), source_dir: '.',
) )
endif 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: Private headers should include the public header first, if one exists:
```c ```c
#pragma once #ifndef __GTK_FOO_PRIVATE_H__
#define __GTK_FOO_PRIVATE_H__
/* gtkfooprivate.h */
#include "gtkfoo.h" #include "gtkfoo.h"
@@ -511,8 +510,18 @@ Private headers should include the public header first, if one exists:
#endif /* __GTK_FOO_PRIVATE_H__ */ #endif /* __GTK_FOO_PRIVATE_H__ */
``` ```
All headers should use the `once` pragma to prevent multiple inclusion, All headers should have inclusion guards:
instead of the classic pre-processor 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 ```c
#pragma once #pragma once
@@ -544,8 +553,6 @@ the source file, either the public installed header, or the private header, if
it exists. it exists.
```c ```c
/* gtkfoo.c */
#include "config.h" #include "config.h"
#include "gtkfoo.h" #include "gtkfoo.h"
@@ -587,8 +594,8 @@ Finally, source files should include the system headers last:
#include <string.h> #include <string.h>
``` ```
Cyclic dependencies should be avoided if at all possible; Cyclic dependencies should be avoided if at all possible; for instance, you
for instance, you could use additional headers to break cycles. could use additional headers to break cycles.
### GObject ### 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()` 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()` macros in newly written headers.
for declaring types that can be derived inside GTK, but not in 3rd party code.
Inside your source file, always use the `G_DEFINE_TYPE()`, Inside your source file, always use the `G_DEFINE_TYPE()`,
`G_DEFINE_TYPE_WITH_PRIVATE()`, and `G_DEFINE_TYPE_WITH_CODE()` macros, or their `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_IS_<iface_name>` | `G_TYPE_CHECK_INSTANCE_TYPE` |
| `GTK_<iface_name>_GET_IFACE` | `G_TYPE_INSTANCE_GET_INTERFACE` | | `GTK_<iface_name>_GET_IFACE` | `G_TYPE_INSTANCE_GET_INTERFACE` |
The `G_DECLARE` macros define these as static inline functions instead.
### Memory allocation ### 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, Public structure types should always be returned after being zero-ed,
either explicitly for each member, or by using `g_new0()`. Do not use either explicitly for each member, or by using `g_new0()` or `g_slice_new0()`.
`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.
### Macros ### Macros

View File

@@ -6,15 +6,22 @@ Slug: broadway
The GDK Broadway backend provides support for displaying GTK applications in The GDK Broadway backend provides support for displaying GTK applications in
a web browser, using HTML5 and web sockets. a web browser, using HTML5 and web sockets.
To run your application in this way, first run the broadway server, To run your application in this way, select the Broadway backend by setting
`gtk-broadwayd`, that ships with GTK: `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 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`. Then point your web browser at `http://127.0.0.1:8085`.
Once the Broadway server is running, you can start your applications like 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 GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo
``` ```
Multiple applications can be presented in the same web browser window.
## Broadway-specific environment variables ## Broadway-specific environment variables
### `BROADWAY_DISPLAY` ### `BROADWAY_DISPLAY`

View File

@@ -1,84 +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].
In addition to a size, widgets can optionally have a **_baseline_** to position text on.
Containers such as [class@Gtk.Box] may position their children to match up their baselines.
[method@Gtk.Widget.get_baseline] returns the y position of the baseline in widget coordinates.
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 ) 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 For more information on how to compile a GTK application, please
refer to the [Compiling GTK Applications](compiling.html) refer to the [Compiling GTK Applications](compiling.html)
section in this reference. section in this reference.

View File

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

@@ -68,7 +68,6 @@ ui_files = [
'stackswitcher.ui', 'stackswitcher.ui',
'statusbar.ui', 'statusbar.ui',
'switch.ui', 'switch.ui',
'switch-state.ui',
'toggle-button.ui', 'toggle-button.ui',
'video.ui', 'video.ui',
'volumebutton.ui', 'volumebutton.ui',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkSwitch">
<property name="active">1</property>
<property name="state">0</property>
</object>
</child>
<child>
<object class="GtkSwitch">
<property name="active">0</property>
<property name="state">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

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 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 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 “keyboard navigation”). GTK reserves the Tab key to move the focus
to the next location, and <kbd>Shift</kbd>+<kbd>Tab</kbd> to move it back to the previous to the next location, and Shift-Tab to move it back to the previous
one. In addition many containers allow “directional navigation” with one. In addition many containers allow “directional navigation” with
the arrow keys. the arrow keys.
Many widgets can be “activated” to trigger and action. E.g., you can 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 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 Apart from keyboard navigation, activation and directly typing into
entries or text views, GTK widgets can use key events for activating entries or text views, GTK widgets can use key events for activating

View File

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

View File

@@ -258,7 +258,7 @@ Instead of implementing GtkWidget.destroy, you can implement GObject.dispose.
GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
is not always a replacement for `gtk_container_remove()` in GTK 3, you can is not always a replacement for `gtk_container_remove()` in GTK 3, you can
replace many uses of `gtk_container_add()` with equivalent container-specific replace many uses of `gtk_container_add()` with equivalent container-specific
APIs such as `gtk_grid_attach()`, and thereby reduce APIs such as `gtk_box_pack_start()` or `gtk_grid_attach()`, and thereby reduce
the amount of work you have to do at the time of the switch. the amount of work you have to do at the time of the switch.
### Review your use of icon resources ### Review your use of icon resources
@@ -402,9 +402,9 @@ is open, use the [property@Gtk.Window:modal] property of the dialog.
### Adapt to coordinate API changes ### Adapt to coordinate API changes
A number of coordinate APIs in GTK 3 had variants taking `int` arguments: A number of coordinate APIs in GTK 3 had `double` variants:
`gdk_device_get_surface_at_position()`, `gdk_surface_get_device_position()`. `gdk_device_get_surface_at_position()`, `gdk_surface_get_device_position()`.
These have been changed to use `double` arguments, and the `int` variants These have been changed to use doubles, and the `double` variants
have been removed. Update your code accordingly. have been removed. Update your code accordingly.
Any APIs that deal with global (or root) coordinates have been Any APIs that deal with global (or root) coordinates have been
@@ -875,10 +875,10 @@ reference.
### Adapt to coordinate API changes ### Adapt to coordinate API changes
A number of APIs that are accepting or returning coordinates have A number of APIs that are accepting or returning coordinates have
been changed from `int`s to `double`s: `gtk_widget_translate_coordinates()`, been changed from ints to doubles: `gtk_widget_translate_coordinates()`,
`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent, `gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent,
except for cases where out parameters are involved: you need to except for cases where out parameters are involved: you need to
pass `double*` now, instead of `int*`. pass double* now, instead of int*.
### Adapt to GtkStyleContext API changes ### Adapt to GtkStyleContext API changes

View File

@@ -119,17 +119,3 @@ it no longer has a resize handle for the window.
These are very specialized widgets that should better live with the application These are very specialized widgets that should better live with the application
where they are used. where they are used.
## Widget size api changes
The functions gtk_widget_get_allocated_width() and gtk_widget_get_allocated_height()
are going away. In most cases, [method@Gtk.Widget.get_width] and [method@Gtk.Widget.get_height]
are suitable replacements. Note that the semantics are slightly different though:
the old functions return the size of the CSS border area, while the new functions return
the size of the widgets content area. In places where this difference matters, you can
use `gtk_widget_compute_bounds (widget, widget, &bounds)` instead.
The function gtk_widget_get_allocation() is also going away. It does not have a direct
replacement, but the previously mentioned alternatives can be used for it too.
The function gtk_widget_get_allocated_baseline() has been renamed to [method@Gtk.Widget.get_baseline].

View File

@@ -263,13 +263,10 @@ the question you have, this list is a good place to start.
* How do I load an image or animation from a file? * How do I load an image or animation from a file?
To load an image file straight into a display widget, use To load an image file straight into a display widget, use
[ctor@Gtk.Picture.new_for_file] or [ctor@Gtk.Picture.new_for_filename]. [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 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]. 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? * How do I draw text?
If you just want to put text into your user interface somewhere, it is If you just want to put text into your user interface somewhere, it is
@@ -286,8 +283,8 @@ the question you have, this list is a good place to start.
pango_font_description_free (fontdesc); pango_font_description_free (fontdesc);
g_object_unref (layout); g_object_unref (layout);
See also the [Cairo Rendering](https://docs.gtk.org/PangoCairo/pango_cairo.html) See also the [Cairo Rendering](https://developer.gnome.org/pango/stable/pango-Cairo-Rendering.html)
section of the [Pango documentation](https://docs.gtk.org/Pango/). 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, To draw a piece of text in a widget [vfunc@Gtk.Widget.snapshot] implementation,
use [method@Gtk.Snapshot.append_layout]. use [method@Gtk.Snapshot.append_layout].
@@ -304,8 +301,8 @@ the question you have, this list is a good place to start.
pango_font_description_free (fontdesc); pango_font_description_free (fontdesc);
g_object_unref (layout); g_object_unref (layout);
See also the [Layout Objects](https://docs.gtk.org/Pango/class.Layout.html) See also the [Layout Objects](https://developer.gnome.org/pango/stable/pango-Layout-Objects.html)
section of the [Pango documentation](https://docs.gtk.org/Pango/). section of the [Pango documentation](https://developer.gnome.org/pango/stable/).
* Why are types not registered if I use their `GTK_TYPE_BLAH` macro? * Why are types not registered if I use their `GTK_TYPE_BLAH` macro?

View File

@@ -211,9 +211,6 @@ A number of options affect behavior instead of logging:
`gl-disable` `gl-disable`
: Disable OpenGL support : Disable OpenGL support
`gl-fractional`
: Enable fractional scaling for OpenGL. This is experimental
`gl-legacy` `gl-legacy`
: Use a legacy OpenGL context : 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 workarounds is to try to update your graphics drivers and Nahimic
installation. 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` ### `GTK_CSD`
The default value of this environment variable is `1`. If changed 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_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_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_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 #### 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. in roughly the same way.
Lists are perfectly fine to be used for very short list of only 2 or 3 elements, 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, but generally scale fine to millions of items. Of course, the larger the list
the more care needs to be taken to choose the right data structures to keep things grows, the more care needs to be taken to choose the right data structures to
running well. keep things running well.
Lists are meant to be used with changing data, both with the items itself changing 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 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. **_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`]. 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`] Views display data from a **_model_**. A model is a [`iface@Gio.ListModel`] and
interface and can be provided in a variety of ways: models can be provided in 3 ways or combinations thereof:
* List model implementations for many specific types of data already exist, for * Many list models implementations already exist. There are models that provide
example `GtkDirectoryList` or `GtkStringList`. specific data, like `GtkDirectoryList`. And there are models like `GListStore`
that allow building lists manually.
* There are generic list model implementations like`GListStore` that allow building
lists of arbitrary objects.
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel` * Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
modify, adapt or combine other models. 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 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 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 at position 0. The position of an item can of course change as other items are
removed from the model. added or removed from the model.
It is important to be aware of the difference between items and positions 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 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 for the data displayed, the programming language and development environment
is an important task that can simplify setting up the view tremendously. is an important task that can simplify setting up the view tremendously.
Views support selections via a **_selection model_**. A selection model is Views support selections via a **_selection model_**. A selection model is an
an implementation of the [`iface@Gtk.SelectionModel`] interface on top of the implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
[`iface@Gio.ListModel`] interface that allows marking each item in a model as [`iface@Gio.ListModel`] interface that allows marking each item in a model as either
either selected or not selected. Just like regular models, this can be implemented selected or not selected. Just like regular models, this can be implemented
either by implementing `GtkSelectionModel` directly or by wrapping a model with 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`] one of the GTK models provided for this purposes, such as [`class@Gtk.NoSelection`]
or [`class@Gtk.SingleSelection`]. 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 Views and listitems also support activation. Activation means that double
clicking or pressing enter while inside a focused row will cause the view 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 to emit and activation signal such as [`signal@Gtk.ListView::activate`]. This
easy way to set up lists, but can also be turned off on listitems if undesired. 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 Both selections and activation are supported among other things via widget
[actions](#actions-overview). This allows developers to add widgets to their [actions](#actions-overview). This allows developers to add widgets to their
lists that cause selections to change or to trigger activation via the lists that cause selections to change or to trigger activation via
[`iface@Gtk.Actionable`] interface. For a list of all supported actions the [`iface@Gtk.Actionable`] interface. For a list of all supported actions see
see the relevant documentation. the relevant documentation.
## Behind the scenes ## 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 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 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 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. screen.
While this behavior allows views to scale effortlessly to huge lists, it has a 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 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 one and even if there is, that listitem might soon be recycled for a new
position. 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 use case is displaying lists and not trees and it greatly simplifies the API
interface provided. interface provided.
However, GTK provides functionality to make lists look and behave like trees However, GTK provides functionality to make trees look and behave like lists
for use cases that require trees. This is achieved by using the for the people who still want to display lists. This is achieved by using
[`class@Gtk.TreeListModel`] model to flatten a tree into a list. The 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 [`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 users to expand and collapse rows and provide a similar experience to
`GtkTreeView`. `GtkTreeView`.
@@ -175,26 +174,26 @@ on the topic.
## List styles ## List styles
One of the advantages of the new list widgets over `GtkTreeView` and cell 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 renderers is that they are fully themable using GTK CSS. This provides a
flexibility. The themes that ship with GTK provide a few predefined list lot of flexibility. The themes that ship with GTK provide a few predefined
styles that can be used in many situations: list styles that can be used in many situations:
![Rich list](rich-list.png) ![Rich list](rich-list.png)
This _rich list_ style is low density, spacious and uses an outline focus This style of list is low density, spacious and uses an outline focus ring.
ring. It is suitable for lists of controls, e.g. in preference dialogs or It is suitable for lists of controls, e.g. in preference dialogs or
settings panels. Use the `.rich-list` style class. settings panels. Use the `.rich-list` style class.
![Navigation sidebar](navigation-sidebar.png) ![Navigation sidebar](navigation-sidebar.png)
The _sidebar_ style of list is medium density, using a full background to This style of list is medium density, using a full background to indicate
indicate focus and selection. Use the `.navigation-sidebar` style class. focus and selection. Use the `.navigation-sidebar` style class.
![Data table](data-table.png) ![Data table](data-table.png)
The _data table_ style of list is a high density table, similar in style to a This style of list is a high density table, similar in style to a traditional
traditional treeview. Individual cells can be selectable and editable. Use treeview. Individual cells can be selectable and editable. Use the `.data-table`
the `.data-table` style class. style class.
## Comparison to GtkTreeView ## 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. and differences between the two.
This new approach tries to provide roughly the same functionality as the old 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 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 that items can be displayed using regular widgets and `GtkCellRenderer` is no
machinery is no longer necessary. This allows all benefits that widgets provide, longer necessary. This allows all benefits that widgets provide, such as complex
such as complex layout, animations and CSS styling. 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` 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 was a rather complex interface for a tree data structure and `GListModel` was
deliberately designed to be a very simple data structure for lists only. (See 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.) [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 Another big change is that the new model allows for bulk changes via
`GListModel::items-changed` signal while `GtkTreeModel` only allows a single 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 item to change at once. The goal here is of course to encourage implementation
of custom list models. 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 the selection models. In particular this allows for complex use cases with
specialized requirements. specialized requirements.
Finally here's a quick comparison chart of equivalent functionality to look for Finally here's a quick list of equivalent functionality to look for when
when transitioning code: transitioning code for easy lookup:
| Old | New | | Old | New |
| -------------------- | ------------------------------------------------------- | | -------------------- | ------------------------------------------------------- |

View File

@@ -1,4 +1,4 @@
Title: Using GTK with X11 Title: GTK for the X Window System
Slug: gtk-x11 Slug: gtk-x11
On UNIX, the X backend is enabled by default, so you don't need to do anything 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', app2_resources = gnome.compile_resources('exampleapp2_resources',
'exampleapp.gresource.xml', 'exampleapp.gresource.xml',
source_dir: meson.current_source_dir()) source_dir: '.')
executable('exampleapp2', executable('exampleapp2',
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources, 'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -31,7 +31,8 @@ resize_cb (GtkWidget *widget,
if (gtk_native_get_surface (gtk_widget_get_native (widget))) if (gtk_native_get_surface (gtk_widget_get_native (widget)))
{ {
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 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_width (widget),
gtk_widget_get_height (widget)); gtk_widget_get_height (widget));

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef __BROADWAY_SERVER__
#define __BROADWAY_SERVER__
#include "broadway-protocol.h" #include "broadway-protocol.h"
#include <glib-object.h> #include <glib-object.h>
@@ -92,8 +93,7 @@ guint32 broadway_server_new_surface (BroadwayServer *
int width, int width,
int height); int height);
void broadway_server_destroy_surface (BroadwayServer *server, void broadway_server_destroy_surface (BroadwayServer *server,
int id, int id);
gboolean disconnected);
gboolean broadway_server_surface_show (BroadwayServer *server, gboolean broadway_server_surface_show (BroadwayServer *server,
int id); int id);
gboolean broadway_server_surface_hide (BroadwayServer *server, gboolean broadway_server_surface_hide (BroadwayServer *server,
@@ -135,3 +135,4 @@ void broadway_server_surface_set_modal_hint (BroadwayServer *s
gboolean modal_hint); 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) 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); g_list_free (client->surfaces);
client->surfaces = NULL; client->surfaces = NULL;
@@ -267,7 +268,7 @@ client_handle_request (BroadwayClient *client,
client->surfaces = client->surfaces =
g_list_remove (client->surfaces, g_list_remove (client->surfaces,
GUINT_TO_POINTER (request->destroy_surface.id)); 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; break;
case BROADWAY_REQUEST_SHOW_SURFACE: case BROADWAY_REQUEST_SHOW_SURFACE:
broadway_server_surface_show (server, request->show_surface.id); 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> #include <gdk/gdktypes.h>
@@ -81,3 +82,4 @@ void _gdk_broadway_server_surface_set_modal_hint (GdkBroadwaySer
int id, int id,
gboolean modal_hint); gboolean modal_hint);
#endif /* __GDK_BROADWAY_SERVER__ */

View File

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

View File

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

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#pragma once #ifndef __GDK_BROADWAY_SURFACE_H__
#define __GDK_BROADWAY_SURFACE_H__
#include <gdk/gdk.h> #include <gdk/gdk.h>
@@ -47,3 +48,4 @@ GType gdk_broadway_surface_get_type (void);
G_END_DECLS 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/>. * 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" #include "gdkconfig.h"
@@ -51,3 +52,4 @@ GType gdk_broadway_cairo_context_get_type (void) G_GNUC_CONST;
G_END_DECLS 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/>. * 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> #include <gdk/gdkdeviceprivate.h>
@@ -52,3 +53,4 @@ void gdk_broadway_device_query_state (GdkDevice *device,
G_END_DECLS G_END_DECLS
#endif /* __GDK_DEVICE_BROADWAY_H__ */

View File

@@ -477,8 +477,6 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
object_class->dispose = gdk_broadway_display_dispose; object_class->dispose = gdk_broadway_display_dispose;
object_class->finalize = gdk_broadway_display_finalize; object_class->finalize = gdk_broadway_display_finalize;
display_class->toplevel_type = GDK_TYPE_BROADWAY_TOPLEVEL;
display_class->popup_type = GDK_TYPE_BROADWAY_POPUP;
display_class->cairo_context_type = GDK_TYPE_BROADWAY_CAIRO_CONTEXT; display_class->cairo_context_type = GDK_TYPE_BROADWAY_CAIRO_CONTEXT;
display_class->get_name = gdk_broadway_display_get_name; display_class->get_name = gdk_broadway_display_get_name;
@@ -490,6 +488,7 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
display_class->get_next_serial = gdk_broadway_display_get_next_serial; display_class->get_next_serial = gdk_broadway_display_get_next_serial;
display_class->notify_startup_complete = gdk_broadway_display_notify_startup_complete; display_class->notify_startup_complete = gdk_broadway_display_notify_startup_complete;
display_class->create_surface = _gdk_broadway_display_create_surface;
display_class->get_keymap = _gdk_broadway_display_get_keymap; display_class->get_keymap = _gdk_broadway_display_get_keymap;
display_class->get_monitors = gdk_broadway_display_get_monitors; display_class->get_monitors = gdk_broadway_display_get_monitors;

View File

@@ -19,7 +19,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * 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" #include "gdkbroadwaydisplay.h"
@@ -69,3 +70,4 @@ struct _GdkBroadwayDisplayClass
G_END_DECLS 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/>. * 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" #include "gdkconfig.h"
@@ -54,3 +55,4 @@ GdkBroadwayDrawContext *gdk_broadway_draw_context_context (GdkSurface *surface);
G_END_DECLS 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/>. * 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" #include "gdkprivate-broadway.h"
@@ -28,3 +29,4 @@ GSource * _gdk_broadway_event_source_new (GdkDisplay *display);
G_END_DECLS 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/>. * 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 <glib.h>
#include <gio/gio.h> #include <gio/gio.h>
@@ -34,3 +35,4 @@ struct _GdkBroadwayMonitorClass {
GdkMonitorClass parent_class; GdkMonitorClass parent_class;
}; };
#endif

View File

@@ -26,7 +26,8 @@
* Private uninstalled header defining things local to X windowing code * 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 <gdk/gdkcursor.h>
#include "gdksurface-broadway.h" #include "gdksurface-broadway.h"
@@ -103,6 +104,13 @@ void _gdk_broadway_display_get_default_cursor_size (GdkDisplay *display,
void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display, void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
guint *width, guint *width,
guint *height); guint *height);
GdkSurface * _gdk_broadway_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkKeymap* _gdk_broadway_display_get_keymap (GdkDisplay *display); GdkKeymap* _gdk_broadway_display_get_keymap (GdkDisplay *display);
void _gdk_broadway_display_consume_all_input (GdkDisplay *display); void _gdk_broadway_display_consume_all_input (GdkDisplay *display);
BroadwayInputMsg * _gdk_broadway_display_block_for_input (GdkDisplay *display, BroadwayInputMsg * _gdk_broadway_display_block_for_input (GdkDisplay *display,
@@ -116,3 +124,4 @@ void _gdk_broadway_surface_resize_surface (GdkSurface *surface);
void _gdk_broadway_cursor_update_theme (GdkCursor *cursor); void _gdk_broadway_cursor_update_theme (GdkCursor *cursor);
void _gdk_broadway_cursor_display_finalize (GdkDisplay *display); void _gdk_broadway_cursor_display_finalize (GdkDisplay *display);
#endif /* __GDK_PRIVATE_BROADWAY_H__ */

View File

@@ -47,8 +47,19 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
/* Forward declarations */
static void gdk_broadway_surface_finalize (GObject *object);
G_DEFINE_TYPE (GdkBroadwaySurface, gdk_broadway_surface, GDK_TYPE_SURFACE) G_DEFINE_TYPE (GdkBroadwaySurface, gdk_broadway_surface, GDK_TYPE_SURFACE)
GType gdk_broadway_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_broadway_popup_get_type (void) G_GNUC_CONST;
GType gdk_broadway_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_BROADWAY_TOPLEVEL (gdk_broadway_toplevel_get_type ())
#define GDK_TYPE_BROADWAY_POPUP (gdk_broadway_popup_get_type ())
#define GDK_TYPE_BROADWAY_DRAG_SURFACE (gdk_broadway_drag_surface_get_type ())
/* We need to flush in an idle rather than AFTER_PAINT, as the clock /* We need to flush in an idle rather than AFTER_PAINT, as the clock
is frozen during e.g. surface resizes so the paint will not happen is frozen during e.g. surface resizes so the paint will not happen
and the surface resize request is never flushed. */ and the surface resize request is never flushed. */
@@ -63,93 +74,6 @@ gdk_broadway_surface_init (GdkBroadwaySurface *impl)
{ {
} }
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
_gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial (display));
gdk_display_flush (display);
}
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
if (surface->update_freeze_count > 0)
return;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static void
connect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
static void
disconnect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
static void
gdk_broadway_surface_constructed (GObject *object)
{
GdkBroadwaySurface *self = GDK_BROADWAY_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (object);
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, self);
self->id = _gdk_broadway_server_new_surface (broadway_display->server,
self->root_x,
self->root_y,
1, 1);
g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER (self->id), surface);
g_object_ref (self);
G_OBJECT_CLASS (gdk_broadway_surface_parent_class)->constructed (object);
connect_frame_clock (surface);
}
static void static void
gdk_broadway_surface_finalize (GObject *object) gdk_broadway_surface_finalize (GObject *object)
{ {
@@ -219,6 +143,164 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
} }
} }
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
_gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial (display));
gdk_display_flush (display);
}
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
if (surface->update_freeze_count > 0)
return;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static void
connect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
static void
disconnect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
GdkSurface *
_gdk_broadway_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkBroadwayDisplay *broadway_display;
GdkFrameClock *frame_clock;
GdkSurface *surface;
GdkBroadwaySurface *impl;
GType type;
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
type = GDK_TYPE_BROADWAY_TOPLEVEL;
break;
case GDK_SURFACE_POPUP:
type = GDK_TYPE_BROADWAY_POPUP;
break;
case GDK_SURFACE_DRAG:
type = GDK_TYPE_BROADWAY_DRAG_SURFACE;
break;
default:
g_assert_not_reached ();
break;
}
surface = g_object_new (type,
"display", display,
"frame-clock", frame_clock,
NULL);
g_object_unref (frame_clock);
surface->parent = parent;
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
broadway_display = GDK_BROADWAY_DISPLAY (display);
impl = GDK_BROADWAY_SURFACE (surface);
impl->root_x = x;
impl->root_y = y;
if (parent)
{
impl->root_x += GDK_BROADWAY_SURFACE (parent)->root_x;
impl->root_y += GDK_BROADWAY_SURFACE (parent)->root_y;
}
impl->id = _gdk_broadway_server_new_surface (broadway_display->server,
impl->root_x,
impl->root_y,
surface->width,
surface->height);
g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), surface);
g_object_ref (surface);
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
connect_frame_clock (surface);
/* We treat the real parent as a default transient for to get stacking right */
if (parent)
{
impl->transient_for = GDK_BROADWAY_SURFACE (parent)->id;
_gdk_broadway_server_surface_set_transient_for (broadway_display->server, impl->id, impl->transient_for);
}
return surface;
}
static cairo_surface_t *
gdk_broadway_surface_ref_cairo_surface (GdkSurface *surface)
{
if (GDK_IS_BROADWAY_SURFACE (surface) &&
GDK_SURFACE_DESTROYED (surface))
return NULL;
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
}
static void static void
_gdk_broadway_surface_destroy (GdkSurface *surface, _gdk_broadway_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy) gboolean foreign_destroy)
@@ -325,10 +407,17 @@ gdk_broadway_surface_hide (GdkSurface *surface)
_gdk_surface_clear_update_area (surface); _gdk_surface_clear_update_area (surface);
} }
static double static int
gdk_broadway_surface_get_scale (GdkSurface *surface) 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 static void
@@ -1025,14 +1114,6 @@ _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
return TRUE; return TRUE;
} }
static GdkSurface *
gdk_broadway_drag_surface_new (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DRAG_SURFACE,
"display", display,
NULL);
}
static void static void
create_moveresize_surface (MoveResizeData *mv_resize, create_moveresize_surface (MoveResizeData *mv_resize,
guint32 timestamp) guint32 timestamp)
@@ -1044,9 +1125,11 @@ create_moveresize_surface (MoveResizeData *mv_resize,
g_assert (mv_resize->moveresize_emulation_surface == NULL); g_assert (mv_resize->moveresize_emulation_surface == NULL);
mv_resize->moveresize_emulation_surface = mv_resize->moveresize_emulation_surface =
gdk_broadway_drag_surface_new (mv_resize->display); _gdk_broadway_display_create_surface (mv_resize->display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 1, 1);
gdk_broadway_surface_move_resize_internal (mv_resize->moveresize_emulation_surface, TRUE, -100, -100, 1, 1);
gdk_broadway_surface_show (mv_resize->moveresize_emulation_surface, FALSE); gdk_broadway_surface_show (mv_resize->moveresize_emulation_surface, FALSE);
seat = gdk_display_get_default_seat (mv_resize->display); seat = gdk_display_get_default_seat (mv_resize->display);
@@ -1176,9 +1259,9 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass); GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = gdk_broadway_surface_constructed;
object_class->finalize = gdk_broadway_surface_finalize; object_class->finalize = gdk_broadway_surface_finalize;
impl_class->ref_cairo_surface = gdk_broadway_surface_ref_cairo_surface;
impl_class->hide = gdk_broadway_surface_hide; impl_class->hide = gdk_broadway_surface_hide;
impl_class->get_geometry = gdk_broadway_surface_get_geometry; impl_class->get_geometry = gdk_broadway_surface_get_geometry;
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords; impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
@@ -1188,7 +1271,7 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
impl_class->beep = gdk_broadway_surface_beep; impl_class->beep = gdk_broadway_surface_beep;
impl_class->destroy_notify = gdk_broadway_surface_destroy_notify; impl_class->destroy_notify = gdk_broadway_surface_destroy_notify;
impl_class->drag_begin = _gdk_broadway_surface_drag_begin; 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 #define LAST_PROP 1
@@ -1214,25 +1297,6 @@ gdk_broadway_popup_init (GdkBroadwayPopup *popup)
{ {
} }
static void
gdk_broadway_popup_constructed (GObject *object)
{
GdkBroadwaySurface *self = GDK_BROADWAY_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
self->root_x = GDK_BROADWAY_SURFACE (surface->parent)->root_x;
self->root_y = GDK_BROADWAY_SURFACE (surface->parent)->root_y;
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (surface->parent));
G_OBJECT_CLASS (gdk_broadway_popup_parent_class)->constructed (object);
/* We treat the real parent as a default transient for to get stacking right */
self->transient_for = GDK_BROADWAY_SURFACE (surface->parent)->id;
_gdk_broadway_server_surface_set_transient_for (broadway_display->server, self->id, self->transient_for);
}
static void static void
gdk_broadway_popup_get_property (GObject *object, gdk_broadway_popup_get_property (GObject *object,
guint prop_id, guint prop_id,
@@ -1288,7 +1352,6 @@ gdk_broadway_popup_class_init (GdkBroadwayPopupClass *class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (class); GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_popup_constructed;
object_class->get_property = gdk_broadway_popup_get_property; object_class->get_property = gdk_broadway_popup_get_property;
object_class->set_property = gdk_broadway_popup_set_property; object_class->set_property = gdk_broadway_popup_set_property;
@@ -1359,19 +1422,6 @@ gdk_broadway_toplevel_init (GdkBroadwayToplevel *toplevel)
{ {
} }
static void
gdk_broadway_toplevel_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_broadway_toplevel_parent_class)->constructed (object);
}
static void static void
gdk_broadway_toplevel_set_property (GObject *object, gdk_broadway_toplevel_set_property (GObject *object,
guint prop_id, guint prop_id,
@@ -1475,7 +1525,6 @@ gdk_broadway_toplevel_class_init (GdkBroadwayToplevelClass *class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (class); GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_toplevel_constructed;
object_class->get_property = gdk_broadway_toplevel_get_property; object_class->get_property = gdk_broadway_toplevel_get_property;
object_class->set_property = gdk_broadway_toplevel_set_property; object_class->set_property = gdk_broadway_toplevel_set_property;
@@ -1636,25 +1685,9 @@ gdk_broadway_drag_surface_init (GdkBroadwayDragSurface *surface)
{ {
} }
static void
gdk_broadway_drag_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_broadway_drag_surface_parent_class)->constructed (object);
}
static void static void
gdk_broadway_drag_surface_class_init (GdkBroadwayDragSurfaceClass *class) gdk_broadway_drag_surface_class_init (GdkBroadwayDragSurfaceClass *class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_drag_surface_constructed;
} }
static gboolean static gboolean

View File

@@ -22,7 +22,8 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * 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 <gdk/gdksurfaceprivate.h>
#include "gdkbroadwaysurface.h" #include "gdkbroadwaysurface.h"
@@ -32,14 +33,6 @@ G_BEGIN_DECLS
/* Surface implementation for Broadway /* Surface implementation for Broadway
*/ */
GType gdk_broadway_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_broadway_popup_get_type (void) G_GNUC_CONST;
GType gdk_broadway_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_BROADWAY_TOPLEVEL (gdk_broadway_toplevel_get_type ())
#define GDK_TYPE_BROADWAY_POPUP (gdk_broadway_popup_get_type ())
#define GDK_TYPE_BROADWAY_DRAG_SURFACE (gdk_broadway_drag_surface_get_type ())
struct _GdkBroadwaySurface struct _GdkBroadwaySurface
{ {
GdkSurface parent_instance; GdkSurface parent_instance;
@@ -87,3 +80,4 @@ GType gdk_surface_broadway_get_type (void);
G_END_DECLS 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/>. * 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); void file_transfer_portal_register (void);
@@ -36,3 +37,4 @@ gboolean file_transfer_portal_retrieve_files_finish (GAsyncResult *resu
GError **error); GError **error);
#endif

View File

@@ -121,7 +121,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE }, { "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable 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-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-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", 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 }, { "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/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#pragma once #ifndef __GDK_H__
#define __GDK_H__
#define __GDK_H_INSIDE__ #define __GDK_H_INSIDE__
@@ -44,7 +45,6 @@
#include <gdk/gdkdisplaymanager.h> #include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdrag.h> #include <gdk/gdkdrag.h>
#include <gdk/gdkdragsurface.h> #include <gdk/gdkdragsurface.h>
#include <gdk/gdkdragsurfacesize.h>
#include <gdk/gdkdrawcontext.h> #include <gdk/gdkdrawcontext.h>
#include <gdk/gdkdrop.h> #include <gdk/gdkdrop.h>
#include <gdk/gdkenums.h> #include <gdk/gdkenums.h>
@@ -54,7 +54,6 @@
#include <gdk/gdkframetimings.h> #include <gdk/gdkframetimings.h>
#include <gdk/gdkglcontext.h> #include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexture.h> #include <gdk/gdkgltexture.h>
#include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdkkeys.h> #include <gdk/gdkkeys.h>
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
#include <gdk/gdkmemorytexture.h> #include <gdk/gdkmemorytexture.h>
@@ -80,3 +79,4 @@
#undef __GDK_H_INSIDE__ #undef __GDK_H_INSIDE__
#endif /* __GDK_H__ */

View File

@@ -18,7 +18,8 @@
* Author: Alexander Larsson <alexl@redhat.com> * 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) #if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly." #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 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/>. * 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 "gdkapplaunchcontext.h"
#include "gdktypes.h" #include "gdktypes.h"
@@ -42,3 +43,4 @@ struct _GdkAppLaunchContext
G_END_DECLS G_END_DECLS
#endif

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * 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) #if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly." #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 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/>. * 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) #if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly." #error "Only <gdk/gdk.h> can be included directly."
@@ -45,3 +46,4 @@ cairo_t * gdk_cairo_context_cairo_create (GdkCair
G_END_DECLS 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/>. * 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" #include "gdkcairocontext.h"
@@ -48,3 +49,4 @@ struct _GdkCairoContextClass
G_END_DECLS 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/>. * 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" #include "gdkcairo.h"
@@ -35,3 +36,4 @@ cairo_region_t *gdk_cairo_region_from_clip (cairo_t *cr);
G_END_DECLS G_END_DECLS
#endif /* __GDK_CAIRO_PRIVATE_H__ */

View File

@@ -750,7 +750,7 @@ static void
free_value (gpointer value) free_value (gpointer value)
{ {
g_value_unset (value); g_value_unset (value);
g_free (value); g_slice_free (GValue, value);
} }
static void static void
@@ -771,7 +771,7 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
task = g_task_new (clipboard, cancellable, callback, user_data); task = g_task_new (clipboard, cancellable, callback, user_data);
g_task_set_priority (task, io_priority); g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, source_tag); g_task_set_source_tag (task, source_tag);
value = g_new0 (GValue, 1); value = g_slice_new0 (GValue);
g_value_init (value, type); g_value_init (value, type);
g_task_set_task_data (task, value, free_value); 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/>. * 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) #if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly." #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 G_END_DECLS
#endif /* __GDK_CLIPBOARD_H__ */

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