Compare commits

..

4 Commits

Author SHA1 Message Date
Emmanuele Bassi
e8d497b83a Do not leak the shaders cache
When finalizing the shader cache object we need to delete the shaders
and programs we are caching as well.
2018-03-30 13:59:06 +01:00
Emmanuele Bassi
37767e056f Cache linked programs
If we're trying to link the same vertex and fragment shaders together
then we can simply reuse the program object and avoid linking
altogether.
2018-03-30 13:55:50 +01:00
Emmanuele Bassi
c7e1ab67c6 Cache individual GLSL shaders
When compiling fragment or vertex shaders, we can store the shader
object id for later use, if the shader source is identical.
2018-03-30 13:55:01 +01:00
Emmanuele Bassi
4a2e73a07c Move GL shader compilation to a separate object
We want to cache the compiled and linked programs, so the first step is
to create an object in charge of compiling and linking GLSL programs.

We only create one per GL context, for the time being, but in the
following commits we're going to store it per display connection, and
introduce the cache.
2018-03-30 02:24:53 +01:00
908 changed files with 71891 additions and 92791 deletions

View File

@@ -1,82 +1,43 @@
stages: stages:
- build - build
- flatpak - flatpak
- deploy
.cache-paths: &cache-paths gtk:
image: ebassi/gitlab-gtk:latest
stage: build
before_script:
- export CCACHE_DISABLE=true_
script:
- bash -x ./.gitlab-ci/test-docker.sh
cache:
paths: paths:
- _ccache/
- subprojects/gdk-pixbuf/ - subprojects/gdk-pixbuf/
- subprojects/glib/ - subprojects/glib/
- subprojects/graphene/ - subprojects/graphene/
- subprojects/libepoxy/ - subprojects/libepoxy/
- subprojects/pango/ - subprojects/pango/
fedora-x86_64:
image: registry.gitlab.gnome.org/gnome/gtk/master:v1
stage: build
script:
- bash -x ./.gitlab-ci/test-docker.sh
artifacts: artifacts:
when: on_failure when: on_failure
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"
cache:
key: "$CI_JOB_NAME"
<<: *cache-paths
.mingw-defaults: &mingw-defaults
stage: build
tags:
- win32
script:
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
cache:
key: "%CI_JOB_NAME%"
<<: *cache-paths
msys2-mingw32:
variables:
MSYSTEM: "MINGW32"
CHERE_INVOKING: "yes"
<<: *mingw-defaults
.flatpak-defaults: &flatpak-defaults
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
stage: flatpak
artifacts:
paths:
- "${APPID}-dev.flatpak"
expire_in: 1 day
script:
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
flatpak:demo: flatpak:demo:
variables: image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
APPID: org.gtk.Demo stage: flatpak
<<: *flatpak-defaults
flatpak:widget-factory:
variables:
APPID: org.gtk.WidgetFactory
<<: *flatpak-defaults
pages:
image: registry.gitlab.gnome.org/gnome/gtk/master:v1
stage: deploy
script: script:
- meson -Ddocumentation=true _build . - bash -x ./.gitlab-ci/flatpak-build.sh org.gtk.Demo
- ninja -C _build
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
- mkdir -p public/
- mv _build/docs/reference/gtk/html/ public/gtk/
- mv _build/docs/reference/gdk/html/ public/gdk/
- mv _build/docs/reference/gsk/html/ public/gsk/
artifacts: artifacts:
paths: paths:
- public - org.gtk.Demo-dev.flatpak
only: expire_in: 1 day
- master
flatpak:widget-factory:
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
stage: flatpak
script:
- bash -x ./.gitlab-ci/flatpak-build.sh org.gtk.WidgetFactory
artifacts:
paths:
- org.gtk.WidgetFactory-dev.flatpak
expire_in: 1 day

View File

@@ -1,7 +1,6 @@
FROM fedora:28 FROM fedora:27
RUN dnf -y install \ RUN dnf -y install \
hicolor-icon-theme \
adwaita-icon-theme \ adwaita-icon-theme \
atk-devel \ atk-devel \
at-spi2-atk-devel \ at-spi2-atk-devel \
@@ -29,7 +28,6 @@ RUN dnf -y install \
gstreamer1-plugins-good \ gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \ gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \ gstreamer1-plugins-base-devel \
gtk-doc \
iso-codes \ iso-codes \
itstool \ itstool \
json-glib-devel \ json-glib-devel \

View File

@@ -2,7 +2,7 @@
set -e set -e
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v1" TAG="ebassi/gitlab-gtk:latest"
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \ sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
--file "Dockerfile" . --file "Dockerfile" .

View File

@@ -4,25 +4,16 @@ set -e
srcdir=$(pwd) srcdir=$(pwd)
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
ccache --zero-stats
ccache --show-stats
export CCACHE_DISABLE=true
meson \ meson \
-Dx11-backend=true \ -Dx11-backend=true \
-Dwayland-backend=true \ -Dwayland-backend=true \
-Dbroadway-backend=true \ -Dbroadway-backend=true \
-Dvulkan=yes \ -Dvulkan=yes \
_build $srcdir _build $srcdir
unset CCACHE_DISABLE
cd _build cd _build
ninja ninja
ccache --show-stats
xvfb-run -a -s "-screen 0 1024x768x24" \ xvfb-run -a -s "-screen 0 1024x768x24" \
meson test \ meson test \

View File

@@ -1,53 +0,0 @@
#!/bin/bash
set -e
if [[ "$MSYSTEM" == "MINGW32" ]]; then
export MSYS2_ARCH="i686"
else
export MSYS2_ARCH="x86_64"
fi
# Update everything
pacman --noconfirm -Suy
# Install the required packages
pacman --noconfirm -S --needed \
base-devel \
git \
mingw-w64-$MSYS2_ARCH-toolchain \
mingw-w64-$MSYS2_ARCH-ccache \
mingw-w64-$MSYS2_ARCH-pkg-config \
mingw-w64-$MSYS2_ARCH-gobject-introspection \
mingw-w64-$MSYS2_ARCH-meson \
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
mingw-w64-$MSYS2_ARCH-atk \
mingw-w64-$MSYS2_ARCH-cairo \
mingw-w64-$MSYS2_ARCH-gdk-pixbuf2 \
mingw-w64-$MSYS2_ARCH-glib2 \
mingw-w64-$MSYS2_ARCH-graphene \
mingw-w64-$MSYS2_ARCH-json-glib \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
mingw-w64-$MSYS2_ARCH-shared-mime-info
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
# Build
ccache --zero-stats
ccache --show-stats
export CCACHE_DISABLE=true
meson \
-Denable-x11-backend=false \
-Denable-wayland-backend=false \
-Denable-win32-backend=true \
-Dvulkan=no \
_build
unset CCACHE_DISABLE
ninja -C _build
ccache --show-stats

View File

@@ -23,14 +23,17 @@
## Version information ## Version information
<!-- <!--
- Which version of GTK+ you are using - which version of GTK+ you are using
- What operating system and version - what operating system and version
- For Linux, which distribution - for Linux, which distribution
- If you built GTK+ yourself, the list of options used to configure the build - if you built GTK+ yourself, the list of options used to configure the build
--> -->
## Additional information ## Additional information
<!-- <!--
- Screenshots or screen recordings are useful for visual errors - If the bug was a crash, the exact text that was printed out
- Please report any warning or message printed on the terminal when the crash occurred.
- If the bug was a crash, attaching a stack trace obtained using
GDB is appreciated; follow the instructions on the wiki:
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces
--> -->

View File

@@ -1,34 +0,0 @@
## Steps to reproduce
1. ...
2. ...
3. ...
<!--
You should try and reproduce with the demos applications available
under the `demos` directory, or the test programs in the `tests` directory.
Alternatively, please attach a *small and self-contained* example that
exhibits the issue.
-->
## Version information
<!--
- Which version of GTK+ you are using
- What operating system and version
- for Linux, which distribution
- If you built GTK+ yourself, the list of options used to configure the build
-->
## Warnings
<!--
- If the application generates warning messages before crashing please
report them here
-->
## Backtrace
<!--
- Attaching a stack trace obtained using GDB is appreciated; follow the
instructions on the wiki:
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces
-->

View File

@@ -60,6 +60,4 @@ $ git checkout -b your-branch
Once you've finished working on the bug fix or feature, push the branch Once you've finished working on the bug fix or feature, push the branch
to the Git repository and open a new merge request, to let the GTK to the Git repository and open a new merge request, to let the GTK
maintainers review your contribution. The [CODE-OWNERS](./docs-CODE-OWNERS) maintainers review your contribution.
document contains the list of core contributors to GTK and the areas for
which they are responsible.

88
NEWS
View File

@@ -1,91 +1,3 @@
Overview of Changes in GTK+ 3.94.0
==================================
* GdkPaintable is a new, powerful abstraction for drawable content.
gtk4-demo has a new "Paint" demo to show some of its capabilities.
* There is support for displaying media, with
GtkVideo
GtkMediaFile
GtkMediaStream
GtkMediaControls
* GtkFontChooser now supports OpenType font variations and features.
* The Ctrl-Shift-E support in the simple IM context has been replaced
by an optional completion popup for Emoji alpha codes. This can be
enabled with the GtkEntry::enable-emoji-completion property.
* Wayland has an input method based on the text protocol now
* Input methods, print backends and media backends have been converted
to GIOModules and extension points, and support for generic loadable
modules has been dropped. Platform im modules are always included.
* GdkWindow has been renamed to GdkSurface.
* Applications can now create their own GtkSnapshot objects for
intermediate rendering.
* Widget event signals have been replaced by event controllers,
and some new event controllers have been introduced for this:
GtkEventControllerMotion
GtkEventControllerKey
GtkGestureStylus
* Event controllers can now be created in .ui files.
* Invalidation tracking has been changed, only gtk_widget_queue_draw is left.
* Observing widget contents and size is now done by using the
GtkWidgetPaintable object instead of connecting to widget signals.
* The GtkWidget::draw signal has been removed, widgets need
to implement GtkWidget::snapshot.
* GdkTexture now has GdkMemoryTexture and GdkGLTexture subclasses.
* The Vulkan support in GDK can now use a particular device that is
specified by the GDK_VULKAN_DEVICE environment variable. use
GDK_VULKAN_DEVICE=list to see them all.
* GTK+ Inspector
- has logging support, and the logging settings have been cleaned up
- has an fps overlay
* Removed APIs and features:
Individual event signals such as ::proximity-in-event
The ::draw signal
threading support
non-platform IM modules
papi and test print backends
GtkPlacesSidebar
GtkRecentChooser
GtkToolPalette
GdkStatus
gtk_true, gtk_false
gtk_widget_show_now
gtk_widget_draw
gtk_render_icon_surface
* Incomplete transitions:
The ::event signal is not still there, but it will be removed
The DND apis are not finalized yet
* Translation updates:
Croatian
Esperanto
Estonian
French
Friulian
Icelandic
Latvian
Polish
Russian
Scottish Gaelic
Spanish
Overview of Changes in GTK+ 3.93.0 Overview of Changes in GTK+ 3.93.0
================================== ==================================

View File

@@ -31,11 +31,6 @@ Information about mailing lists can be found at
- http://www.gtk.org/mailing-lists.php - http://www.gtk.org/mailing-lists.php
Nightly documentation can be found at
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
Building and installing Building and installing
----------------------- -----------------------

View File

@@ -5,6 +5,7 @@
"sdk": "org.gnome.Sdk", "sdk": "org.gnome.Sdk",
"command": "gtk4-demo", "command": "gtk4-demo",
"tags": ["devel", "development", "nightly"], "tags": ["devel", "development", "nightly"],
"rename-desktop-file": "gtk4-demo.desktop",
"rename-icon": "gtk4-demo", "rename-icon": "gtk4-demo",
"desktop-file-name-prefix": "(Development) ", "desktop-file-name-prefix": "(Development) ",
"finish-args": [ "finish-args": [
@@ -26,28 +27,12 @@
"/share/doc" "/share/doc"
], ],
"modules": [ "modules": [
{
"name" : "wayland",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{ {
"name": "graphene", "name": "graphene",
"buildsystem": "meson", "buildsystem": "meson",
"builddir": true, "builddir": true,
"config-opts": [ "config-opts": [
"--libdir=/app/lib", "--libdir=/app/lib"
"-Dtests=false",
"-Dbenchmarks=false"
], ],
"sources": [ "sources": [
{ {

View File

@@ -5,6 +5,7 @@
"sdk": "org.gnome.Sdk", "sdk": "org.gnome.Sdk",
"command": "gtk4-widget-factory", "command": "gtk4-widget-factory",
"tags": ["devel", "development", "nightly"], "tags": ["devel", "development", "nightly"],
"rename-desktop-file": "gtk4-widget-factory.desktop",
"rename-icon": "gtk4-widget-factory", "rename-icon": "gtk4-widget-factory",
"desktop-file-name-prefix": "(Development) ", "desktop-file-name-prefix": "(Development) ",
"finish-args": [ "finish-args": [
@@ -26,28 +27,12 @@
"/share/doc" "/share/doc"
], ],
"modules": [ "modules": [
{
"name" : "wayland",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{ {
"name": "graphene", "name": "graphene",
"buildsystem": "meson", "buildsystem": "meson",
"builddir": true, "builddir": true,
"config-opts": [ "config-opts": [
"--libdir=/app/lib", "--libdir=/app/lib"
"-Dtests=false",
"-Dbenchmarks=false"
], ],
"sources": [ "sources": [
{ {

View File

@@ -286,10 +286,6 @@
/* Define to 1 if linux/memfd.h exists */ /* Define to 1 if linux/memfd.h exists */
#mesondefine HAVE_LINUX_MEMFD_H #mesondefine HAVE_LINUX_MEMFD_H
#mesondefine HAVE_LINUX_INPUT_H
#mesondefine HAVE_DEV_EVDEV_INPUT_H
#mesondefine GTK_SYSCONFDIR #mesondefine GTK_SYSCONFDIR
#mesondefine GTK_LOCALEDIR #mesondefine GTK_LOCALEDIR
@@ -305,13 +301,3 @@
#mesondefine HAVE_PANGOFT #mesondefine HAVE_PANGOFT
#mesondefine ISO_CODES_PREFIX #mesondefine ISO_CODES_PREFIX
#mesondefine MALLOC_IS_ALIGNED16
#mesondefine HAVE_POSIX_MEMALIGN
#mesondefine HAVE_MEMALIGN
#mesondefine HAVE_ALIGNED_ALLOC
#mesondefine HAVE__ALIGNED_MALLOC

View File

@@ -457,12 +457,13 @@ demo_application_window_constructed (GObject *object)
static void static void
demo_application_window_size_allocate (GtkWidget *widget, demo_application_window_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation, const GtkAllocation *allocation,
int baseline) int baseline,
GtkAllocation *out_clip)
{ {
DemoApplicationWindow *window = (DemoApplicationWindow *)widget; DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation, GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
baseline); baseline, out_clip);
if (!window->maximized && !window->fullscreen) if (!window->maximized && !window->fullscreen)
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height); gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);

View File

@@ -87,14 +87,14 @@ find_toplevel_at_pointer (GdkDisplay *display)
return widget ? gtk_widget_get_toplevel (widget) : NULL; return widget ? gtk_widget_get_toplevel (widget) : NULL;
} }
static void static gboolean
released_cb (GtkGestureMultiPress *gesture, release_event_cb (GtkWidget *widget,
guint n_press, GdkEvent *event,
gdouble x,
gdouble y,
gboolean *clicked) gboolean *clicked)
{ {
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
*clicked = TRUE; *clicked = TRUE;
return TRUE;
} }
/* Asks the user to click on a window, then waits for them click /* Asks the user to click on a window, then waits for them click
@@ -132,12 +132,10 @@ query_for_toplevel (GdkDisplay *display,
GDK_SEAT_CAPABILITY_ALL_POINTING, GDK_SEAT_CAPABILITY_ALL_POINTING,
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS) FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
{ {
GtkGesture *gesture = gtk_gesture_multi_press_new ();
gboolean clicked = FALSE; gboolean clicked = FALSE;
g_signal_connect (gesture, "released", g_signal_connect (popup, "event",
G_CALLBACK (released_cb), &clicked); G_CALLBACK (release_event_cb), &clicked);
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
/* Process events until clicked is set by our button release event handler. /* Process events until clicked is set by our button release event handler.
* We pass in may_block=TRUE since we want to wait if there * We pass in may_block=TRUE since we want to wait if there
@@ -146,8 +144,6 @@ query_for_toplevel (GdkDisplay *display,
while (!clicked) while (!clicked)
g_main_context_iteration (NULL, TRUE); g_main_context_iteration (NULL, TRUE);
gdk_seat_ungrab (gdk_device_get_seat (device));
toplevel = find_toplevel_at_pointer (display); toplevel = find_toplevel_at_pointer (display);
if (toplevel == popup) if (toplevel == popup)
toplevel = NULL; toplevel = NULL;

View File

@@ -120,7 +120,7 @@ get_image_paintable (GtkImage *image)
static void static void
drag_begin (GtkWidget *widget, drag_begin (GtkWidget *widget,
GdkDrag *drag, GdkDragContext *context,
gpointer data) gpointer data)
{ {
GdkPaintable *paintable; GdkPaintable *paintable;
@@ -128,16 +128,17 @@ drag_begin (GtkWidget *widget,
paintable = get_image_paintable (GTK_IMAGE (widget)); paintable = get_image_paintable (GTK_IMAGE (widget));
if (paintable) if (paintable)
{ {
gtk_drag_set_icon_paintable (drag, paintable, -2, -2); gtk_drag_set_icon_paintable (context, paintable, -2, -2);
g_object_unref (paintable); g_object_unref (paintable);
} }
} }
void void
drag_data_get (GtkWidget *widget, drag_data_get (GtkWidget *widget,
GdkDrag *drag, GdkDragContext *context,
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint info, guint info,
guint time,
gpointer data) gpointer data)
{ {
GdkPaintable *paintable; GdkPaintable *paintable;
@@ -149,8 +150,9 @@ drag_data_get (GtkWidget *widget,
static void static void
drag_data_received (GtkWidget *widget, drag_data_received (GtkWidget *widget,
GdkDrop *drop, GdkDragContext *context,
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint32 time,
gpointer data) gpointer data)
{ {
if (gtk_selection_data_get_length (selection_data) > 0) if (gtk_selection_data_get_length (selection_data) > 0)
@@ -319,10 +321,10 @@ do_clipboard (GtkWidget *do_widget)
G_CALLBACK (drag_data_received), image); G_CALLBACK (drag_data_received), image);
/* context menu on image */ /* context menu on image */
gesture = gtk_gesture_multi_press_new (); gesture = gtk_gesture_multi_press_new (image);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_object_set_data_full (G_OBJECT (image), "gesture", gesture, g_object_unref);
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image); g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
/* Create the second image */ /* Create the second image */
image = gtk_image_new_from_icon_name ("process-stop"); image = gtk_image_new_from_icon_name ("process-stop");
@@ -344,10 +346,10 @@ do_clipboard (GtkWidget *do_widget)
G_CALLBACK (drag_data_received), image); G_CALLBACK (drag_data_received), image);
/* context menu on image */ /* context menu on image */
gesture = gtk_gesture_multi_press_new (); gesture = gtk_gesture_multi_press_new (image);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_object_set_data_full (G_OBJECT (image), "gesture", gesture, g_object_unref);
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image); g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))

View File

@@ -105,6 +105,9 @@
<file>gnome-fs-directory.png</file> <file>gnome-fs-directory.png</file>
<file>gnome-fs-regular.png</file> <file>gnome-fs-regular.png</file>
</gresource> </gresource>
<gresource prefix="/stack">
<file>stack.ui</file>
</gresource>
<gresource prefix="/shortcuts"> <gresource prefix="/shortcuts">
<file>shortcuts.ui</file> <file>shortcuts.ui</file>
<file>shortcuts-builder.ui</file> <file>shortcuts-builder.ui</file>
@@ -112,14 +115,6 @@
<file>shortcuts-clocks.ui</file> <file>shortcuts-clocks.ui</file>
<file>shortcuts-boxes.ui</file> <file>shortcuts-boxes.ui</file>
</gresource> </gresource>
<gresource prefix="/sliding_puzzle">
<file>puzzlepiece.c</file>
<file>puzzlepiece.h</file>
<file>portland-rose.jpg</file>
</gresource>
<gresource prefix="/stack">
<file>stack.ui</file>
</gresource>
<gresource prefix="/revealer"> <gresource prefix="/revealer">
<file>revealer.ui</file> <file>revealer.ui</file>
</gresource> </gresource>
@@ -161,9 +156,11 @@
<file>editable_cells.c</file> <file>editable_cells.c</file>
<file>entry_buffer.c</file> <file>entry_buffer.c</file>
<file>entry_completion.c</file> <file>entry_completion.c</file>
<file>event_axes.c</file>
<file>expander.c</file> <file>expander.c</file>
<file>filtermodel.c</file> <file>filtermodel.c</file>
<file>fishbowl.c</file> <file>fishbowl.c</file>
<file>widgetbowl.c</file>
<file>flowbox.c</file> <file>flowbox.c</file>
<file>foreigndrawing.c</file> <file>foreigndrawing.c</file>
<file>font_features.c</file> <file>font_features.c</file>
@@ -184,7 +181,6 @@
<file>modelbutton.c</file> <file>modelbutton.c</file>
<file>overlay.c</file> <file>overlay.c</file>
<file>overlay2.c</file> <file>overlay2.c</file>
<file>paint.c</file>
<file>pagesetup.c</file> <file>pagesetup.c</file>
<file>paintable.c</file> <file>paintable.c</file>
<file>paintable_animated.c</file> <file>paintable_animated.c</file>
@@ -202,7 +198,6 @@
<file>shortcuts.c</file> <file>shortcuts.c</file>
<file>sizegroup.c</file> <file>sizegroup.c</file>
<file>sidebar.c</file> <file>sidebar.c</file>
<file>sliding_puzzle.c</file>
<file>stack.c</file> <file>stack.c</file>
<file>spinbutton.c</file> <file>spinbutton.c</file>
<file>spinner.c</file> <file>spinner.c</file>

View File

@@ -356,11 +356,10 @@ do_dnd (GtkWidget *do_widget)
gtk_widget_set_hexpand (fixed, TRUE); gtk_widget_set_hexpand (fixed, TRUE);
gtk_widget_set_vexpand (fixed, TRUE); gtk_widget_set_vexpand (fixed, TRUE);
multipress = gtk_gesture_multi_press_new (); multipress = gtk_gesture_multi_press_new (fixed);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0);
g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL); g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL);
g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL); g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL);
gtk_widget_add_controller (fixed, GTK_EVENT_CONTROLLER (multipress));
provider = gtk_css_provider_new (); provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css"); gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");

View File

@@ -86,7 +86,7 @@ draw_brush (GtkWidget *widget,
cairo_destroy (cr); cairo_destroy (cr);
gtk_widget_queue_draw (widget); gtk_widget_queue_draw_area (widget, update_rect.x, update_rect.y, update_rect.width, update_rect.height);
} }
static double start_x; static double start_x;
@@ -244,14 +244,13 @@ do_drawingarea (GtkWidget *do_widget)
g_signal_connect (da, "size-allocate", g_signal_connect (da, "size-allocate",
G_CALLBACK (scribble_size_allocate), NULL); G_CALLBACK (scribble_size_allocate), NULL);
drag = gtk_gesture_drag_new (); drag = gtk_gesture_drag_new (da);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag)); g_object_set_data_full (G_OBJECT (da), "drag", drag, g_object_unref);
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da); g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), da); g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), da);
g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), da); g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), da);
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))

668
demos/gtk-demo/event_axes.c Normal file
View File

@@ -0,0 +1,668 @@
/* Touch and Drawing Tablets
*
* Demonstrates advanced handling of event information from exotic
* input devices.
*
* On one hand, this snippet demonstrates management of drawing tablets,
* those contain additional information for the pointer other than
* X/Y coordinates. Tablet pads events are mapped to actions, which
* are both defined and interpreted by the application.
*
* Input axes are dependent on hardware devices, on linux/unix you
* can see the device axes through xinput list <device>. Each time
* a different hardware device is used to move the pointer, the
* master device will be updated to match the axes it provides,
* these changes can be tracked through GdkDevice::changed, or
* checking gdk_event_get_source_device().
*
* On the other hand, this demo handles basic multitouch events,
* each event coming from an specific touchpoint will contain a
* GdkEventSequence that's unique for its lifetime, so multiple
* touchpoints can be tracked.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
typedef struct {
GdkDevice *last_source;
GdkDeviceTool *last_tool;
gdouble *axes;
GdkRGBA color;
gdouble x;
gdouble y;
} AxesInfo;
typedef struct {
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
} EventData;
const gchar *colors[] = {
"black",
"orchid",
"fuchsia",
"indigo",
"thistle",
"sienna",
"azure",
"plum",
"lime",
"navy",
"maroon",
"burlywood"
};
static GtkPadActionEntry pad_actions[] = {
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike"), "pad.nuke" },
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves"), "pad.heat" },
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare"), "pad.fry" },
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud"), "pad.fall" },
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104"), "pad.burst" },
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button"), "pad.lart" },
{ GTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt"), "pad.tilt" },
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force"), "pad.dissolve" },
};
static const gchar *pad_action_results[] = {
"",
"",
"",
"",
"",
"💫",
"",
""
};
static guint cur_color = 0;
static guint pad_action_timeout_id = 0;
static AxesInfo *
axes_info_new (void)
{
AxesInfo *info;
info = g_new0 (AxesInfo, 1);
gdk_rgba_parse (&info->color, colors[cur_color]);
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
return info;
}
static EventData *
event_data_new (void)
{
EventData *data;
data = g_new0 (EventData, 1);
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free);
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free);
return data;
}
static void
event_data_free (EventData *data)
{
g_hash_table_destroy (data->pointer_info);
g_hash_table_destroy (data->touch_info);
g_free (data);
}
static void
update_axes_from_event (GdkEvent *event,
EventData *data)
{
GdkDevice *device, *source_device;
GdkEventSequence *sequence;
GdkDeviceTool *tool;
GdkEventType type;
gdouble x, y;
AxesInfo *info;
device = gdk_event_get_device (event);
source_device = gdk_event_get_source_device (event);
sequence = gdk_event_get_event_sequence (event);
tool = gdk_event_get_device_tool (event);
type = gdk_event_get_event_type (event);
if (type == GDK_TOUCH_END ||
type == GDK_TOUCH_CANCEL)
{
g_hash_table_remove (data->touch_info, sequence);
return;
}
else if (type == GDK_LEAVE_NOTIFY)
{
g_hash_table_remove (data->pointer_info, device);
return;
}
if (!source_device)
return;
if (!sequence)
{
info = g_hash_table_lookup (data->pointer_info, device);
if (!info)
{
info = axes_info_new ();
g_hash_table_insert (data->pointer_info, device, info);
}
}
else
{
info = g_hash_table_lookup (data->touch_info, sequence);
if (!info)
{
info = axes_info_new ();
g_hash_table_insert (data->touch_info, sequence, info);
}
}
if (info->last_source != source_device)
info->last_source = source_device;
if (info->last_tool != tool)
info->last_tool = tool;
g_clear_pointer (&info->axes, g_free);
if (type == GDK_TOUCH_BEGIN ||
type == GDK_TOUCH_UPDATE)
{
gboolean emulating_pointer;
gdk_event_get_touch_emulating_pointer (event, &emulating_pointer);
if (sequence && emulating_pointer)
g_hash_table_remove (data->pointer_info, device);
}
if (type == GDK_MOTION_NOTIFY ||
type == GDK_BUTTON_PRESS ||
type == GDK_BUTTON_RELEASE)
{
gdouble *axes;
guint n_axes;
gdk_event_get_axes (event, &axes, &n_axes);
info->axes = g_memdup (axes, sizeof (double) * n_axes);
}
if (gdk_event_get_coords (event, &x, &y))
{
info->x = x;
info->y = y;
}
}
static gboolean
event_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
update_axes_from_event (event, user_data);
gtk_widget_queue_draw (widget);
return FALSE;
}
static void
render_arrow (cairo_t *cr,
gdouble x_diff,
gdouble y_diff,
const gchar *label)
{
cairo_save (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_new_path (cr);
cairo_move_to (cr, 0, 0);
cairo_line_to (cr, x_diff, y_diff);
cairo_stroke (cr);
cairo_move_to (cr, x_diff, y_diff);
cairo_show_text (cr, label);
cairo_restore (cr);
}
static void
draw_axes_info (cairo_t *cr,
AxesInfo *info,
int width,
int height)
{
gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
cairo_save (cr);
cairo_set_line_width (cr, 1);
gdk_cairo_set_source_rgba (cr, &info->color);
cairo_move_to (cr, 0, info->y);
cairo_line_to (cr, width, info->y);
cairo_move_to (cr, info->x, 0);
cairo_line_to (cr, info->x, height);
cairo_stroke (cr);
cairo_translate (cr, info->x, info->y);
if (!info->axes)
{
cairo_restore (cr);
return;
}
if (axes & GDK_AXIS_FLAG_PRESSURE)
{
cairo_pattern_t *pattern;
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
&pressure);
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
cairo_set_source (cr, pattern);
cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI);
cairo_fill (cr);
cairo_pattern_destroy (pattern);
}
if (axes & GDK_AXIS_FLAG_XTILT &&
axes & GDK_AXIS_FLAG_YTILT)
{
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
&tilt_x);
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
&tilt_y);
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
}
if (axes & GDK_AXIS_FLAG_DISTANCE)
{
double dashes[] = { 5.0, 5.0 };
cairo_text_extents_t extents;
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
&distance);
cairo_save (cr);
cairo_move_to (cr, distance * 100, 0);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_set_dash (cr, dashes, 2, 0.0);
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
cairo_stroke (cr);
cairo_move_to (cr, 0, -distance * 100);
cairo_text_extents (cr, "Distance", &extents);
cairo_rel_move_to (cr, -extents.width / 2, 0);
cairo_show_text (cr, "Distance");
cairo_move_to (cr, 0, 0);
cairo_restore (cr);
}
if (axes & GDK_AXIS_FLAG_WHEEL)
{
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
&wheel);
cairo_save (cr);
cairo_set_line_width (cr, 10);
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
cairo_new_sub_path (cr);
cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI);
cairo_stroke (cr);
cairo_restore (cr);
}
if (axes & GDK_AXIS_FLAG_ROTATION)
{
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_ROTATION,
&rotation);
rotation *= 2 * G_PI;
cairo_save (cr);
cairo_rotate (cr, - G_PI / 2);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_width (cr, 5);
cairo_new_sub_path (cr);
cairo_arc (cr, 0, 0, 100, 0, rotation);
cairo_stroke (cr);
cairo_restore (cr);
}
if (axes & GDK_AXIS_FLAG_SLIDER)
{
cairo_pattern_t *pattern, *mask;
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_SLIDER,
&slider);
cairo_save (cr);
cairo_move_to (cr, 0, -10);
cairo_rel_line_to (cr, 0, -50);
cairo_rel_line_to (cr, 10, 0);
cairo_rel_line_to (cr, -5, 50);
cairo_close_path (cr);
cairo_clip_preserve (cr);
pattern = cairo_pattern_create_linear (0, -10, 0, -60);
cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
mask = cairo_pattern_create_linear (0, -10, 0, -60);
cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
cairo_mask (cr, mask);
cairo_pattern_destroy (mask);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_stroke (cr);
cairo_restore (cr);
}
cairo_restore (cr);
}
static const gchar *
tool_type_to_string (GdkDeviceToolType tool_type)
{
switch (tool_type)
{
case GDK_DEVICE_TOOL_TYPE_PEN:
return "Pen";
case GDK_DEVICE_TOOL_TYPE_ERASER:
return "Eraser";
case GDK_DEVICE_TOOL_TYPE_BRUSH:
return "Brush";
case GDK_DEVICE_TOOL_TYPE_PENCIL:
return "Pencil";
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
return "Airbrush";
case GDK_DEVICE_TOOL_TYPE_MOUSE:
return "Mouse";
case GDK_DEVICE_TOOL_TYPE_LENS:
return "Lens cursor";
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
default:
return "Unknown";
}
}
static void
draw_device_info (GtkWidget *widget,
cairo_t *cr,
GdkEventSequence *sequence,
gint *y,
AxesInfo *info)
{
PangoLayout *layout;
GString *string;
gint height;
cairo_save (cr);
string = g_string_new (NULL);
g_string_append_printf (string, "Source: %s",
gdk_device_get_name (info->last_source));
if (sequence)
g_string_append_printf (string, "\nSequence: %d",
GPOINTER_TO_UINT (sequence));
if (info->last_tool)
{
const gchar *tool_type;
guint64 serial;
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
serial = gdk_device_tool_get_serial (info->last_tool);
g_string_append_printf (string, "\nTool: %s", tool_type);
if (serial != 0)
g_string_append_printf (string, ", Serial: %lx", serial);
}
cairo_move_to (cr, 10, *y);
layout = gtk_widget_create_pango_layout (widget, string->str);
pango_cairo_show_layout (cr, layout);
cairo_stroke (cr);
pango_layout_get_pixel_size (layout, NULL, &height);
gdk_cairo_set_source_rgba (cr, &info->color);
cairo_set_line_width (cr, 10);
cairo_move_to (cr, 0, *y);
*y = *y + height;
cairo_line_to (cr, 0, *y);
cairo_stroke (cr);
cairo_restore (cr);
g_object_unref (layout);
g_string_free (string, TRUE);
}
static void
draw_cb (GtkDrawingArea *da,
cairo_t *cr,
int width,
int height,
gpointer user_data)
{
GtkWidget *widget = GTK_WIDGET (da);
EventData *data = user_data;
AxesInfo *info;
GHashTableIter iter;
gpointer key, value;
gint y = 0;
/* Draw Abs info */
g_hash_table_iter_init (&iter, data->pointer_info);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
info = value;
draw_axes_info (cr, info, width, height);
}
g_hash_table_iter_init (&iter, data->touch_info);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
info = value;
draw_axes_info (cr, info, width, height);
}
/* Draw name, color legend and misc data */
g_hash_table_iter_init (&iter, data->pointer_info);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
info = value;
draw_device_info (widget, cr, NULL, &y, info);
}
g_hash_table_iter_init (&iter, data->touch_info);
while (g_hash_table_iter_next (&iter, &key, &value))
{
info = value;
draw_device_info (widget, cr, key, &y, info);
}
}
static void
update_label_text (GtkWidget *label,
const gchar *text)
{
gchar *markup = NULL;
if (text)
markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
gtk_label_set_markup (GTK_LABEL (label), markup);
g_free (markup);
}
static gboolean
reset_label_text_timeout_cb (gpointer user_data)
{
GtkWidget *label = user_data;
update_label_text (label, NULL);
pad_action_timeout_id = 0;
return G_SOURCE_REMOVE;
}
static void
update_label_and_timeout (GtkWidget *label,
const gchar *text)
{
if (pad_action_timeout_id)
g_source_remove (pad_action_timeout_id);
update_label_text (label, text);
pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
}
static void
on_action_activate (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkWidget *label = user_data;
const gchar *result;
gchar *str;
result = g_object_get_data (G_OBJECT (action), "action-result");
if (!parameter)
update_label_and_timeout (label, result);
else
{
str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
update_label_and_timeout (label, str);
g_free (str);
}
}
static void
init_pad_controller (GtkWidget *window,
GtkWidget *label)
{
GtkPadController *pad_controller;
GSimpleActionGroup *action_group;
GSimpleAction *action;
gint i;
action_group = g_simple_action_group_new ();
pad_controller = gtk_pad_controller_new (GTK_WINDOW (window),
G_ACTION_GROUP (action_group),
NULL);
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
{
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
{
action = g_simple_action_new (pad_actions[i].action_name, NULL);
}
else
{
action = g_simple_action_new_stateful (pad_actions[i].action_name,
G_VARIANT_TYPE_DOUBLE, NULL);
}
g_signal_connect (action, "activate",
G_CALLBACK (on_action_activate), label);
g_object_set_data (G_OBJECT (action), "action-result",
(gpointer) pad_action_results[i]);
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
g_object_unref (action);
}
gtk_pad_controller_set_action_entries (pad_controller, pad_actions,
G_N_ELEMENTS (pad_actions));
g_object_set_data_full (G_OBJECT (window), "pad-controller",
pad_controller, g_object_unref);
g_object_unref (action_group);
}
GtkWidget *
do_event_axes (GtkWidget *toplevel)
{
static GtkWidget *window = NULL;
EventData *event_data;
GtkWidget *label;
GtkWidget *overlay;
GtkWidget *da;
if (!window)
{
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Touch and Drawing Tablets");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_set_support_multidevice (window, TRUE);
event_data = event_data_new ();
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
event_data, (GDestroyNotify) event_data_free);
da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 400);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 400);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_cb, event_data, NULL);
gtk_widget_set_can_focus (da, TRUE);
gtk_widget_grab_focus (da);
g_signal_connect (da, "event",
G_CALLBACK (event_cb), event_data);
label = gtk_label_new ("");
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_START);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
overlay = gtk_overlay_new ();
gtk_container_add (GTK_CONTAINER (window), overlay);
gtk_container_add (GTK_CONTAINER (overlay), da);
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), label);
init_pad_controller (da, label);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -8,268 +8,165 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "gtkfishbowl.h" #include "gtkfishbowl.h"
#include "gtkgears.h"
const char *const css = GtkWidget *allow_changes;
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
"}"
"";
char **icon_names = NULL; #define N_STATS 5
gsize n_icon_names = 0;
static void #define STATS_UPDATE_TIME G_USEC_PER_SEC
init_icon_names (GtkIconTheme *theme)
{
GPtrArray *icons;
GList *l, *icon_list;
if (icon_names) typedef struct _Stats Stats;
return; struct _Stats {
gint64 last_stats;
gint64 last_frame;
gint last_suggestion;
guint frame_counter_max;
icon_list = gtk_icon_theme_list_icons (theme, NULL); guint stats_index;
icons = g_ptr_array_new (); guint frame_counter[N_STATS];
guint item_counter[N_STATS];
for (l = icon_list; l; l = l->next)
{
if (g_str_has_suffix (l->data, "symbolic"))
continue;
g_ptr_array_add (icons, g_strdup (l->data));
}
n_icon_names = icons->len;
g_ptr_array_add (icons, NULL); /* NULL-terminate the array */
icon_names = (char **) g_ptr_array_free (icons, FALSE);
/* don't free strings, we assigned them to the array */
g_list_free_full (icon_list, g_free);
}
static const char *
get_random_icon_name (GtkIconTheme *theme)
{
init_icon_names (theme);
return icon_names[g_random_int_range(0, n_icon_names)];
}
GtkWidget *
create_icon (void)
{
GtkWidget *image;
image = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
return image;
}
static GtkWidget *
create_button (void)
{
return gtk_button_new_with_label ("Button");
}
static GtkWidget *
create_blurred_button (void)
{
GtkWidget *w = gtk_button_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (w), "blurred-button");
return w;
}
static GtkWidget *
create_font_button (void)
{
return gtk_font_button_new ();
}
static GtkWidget *
create_level_bar (void)
{
GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
/* Force them to be a bit larger */
gtk_widget_set_size_request (w, 200, -1);
return w;
}
static GtkWidget *
create_spinner (void)
{
GtkWidget *w = gtk_spinner_new ();
gtk_spinner_start (GTK_SPINNER (w));
return w;
}
static GtkWidget *
create_spinbutton (void)
{
GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
return w;
}
static GtkWidget *
create_label (void)
{
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
return w;
}
static GtkWidget *
create_video (void)
{
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
GtkWidget *w = gtk_image_new_from_paintable (GDK_PAINTABLE (stream));
gtk_media_stream_set_loop (stream, TRUE);
gtk_media_stream_play (stream);
g_object_unref (stream);
return w;
}
static GtkWidget *
create_gears (void)
{
GtkWidget *w = gtk_gears_new ();
gtk_widget_set_size_request (w, 100, 100);
return w;
}
static GtkWidget *
create_switch (void)
{
GtkWidget *w = gtk_switch_new ();
gtk_switch_set_state (GTK_SWITCH (w), TRUE);
return w;
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
} widget_types[] = {
{ "Icon", create_icon },
{ "Button", create_button },
{ "Blurbutton", create_blurred_button },
{ "Fontbutton", create_font_button },
{ "Levelbar", create_level_bar },
{ "Label", create_label },
{ "Spinner", create_spinner },
{ "Spinbutton", create_spinbutton },
{ "Video", create_video },
{ "Gears", create_gears },
{ "Switch", create_switch },
}; };
static int selected_widget_type = -1; static Stats *
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types); get_stats (GtkWidget *widget)
{
static GQuark stats_quark = 0;
Stats *stats;
if (G_UNLIKELY (stats_quark == 0))
stats_quark = g_quark_from_static_string ("stats");
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
if (stats == NULL)
{
stats = g_new0 (Stats, 1);
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
stats->last_stats = stats->last_frame;
}
return stats;
}
static void static void
set_widget_type (GtkFishbowl *fishbowl, do_stats (GtkWidget *widget,
int widget_type_index) GtkWidget *info_label,
gint *suggested_change)
{ {
GtkWidget *window, *headerbar; Stats *stats;
gint64 frame_time;
if (widget_type_index == selected_widget_type) stats = get_stats (widget);
return; frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
selected_widget_type = widget_type_index; if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
{
char *new_label;
guint i, n_frames;
gtk_fishbowl_set_creation_func (fishbowl, n_frames = 0;
widget_types[selected_widget_type].create_func); for (i = 0; i < N_STATS; i++)
{
window = gtk_widget_get_toplevel (GTK_WIDGET (fishbowl)); n_frames += stats->frame_counter[i];
headerbar = gtk_window_get_titlebar (GTK_WINDOW (window));
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
widget_types[selected_widget_type].name);
} }
void new_label = g_strdup_printf ("icons - %.1f fps",
next_button_clicked_cb (GtkButton *source, (double) G_USEC_PER_SEC * n_frames
gpointer user_data) / (N_STATS * STATS_UPDATE_TIME));
{ gtk_label_set_label (GTK_LABEL (info_label), new_label);
GtkFishbowl *fishbowl = user_data; g_free (new_label);
int new_index;
if (selected_widget_type + 1 >= N_WIDGET_TYPES) if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
new_index = 0; {
if (stats->last_suggestion > 0)
stats->last_suggestion *= 2;
else else
new_index = selected_widget_type + 1; stats->last_suggestion = 1;
set_widget_type (fishbowl, new_index);
} }
void
prev_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkFishbowl *fishbowl = user_data;
int new_index;
if (selected_widget_type - 1 < 0)
new_index = N_WIDGET_TYPES - 1;
else else
new_index = selected_widget_type - 1; {
if (stats->last_suggestion < 0)
set_widget_type (fishbowl, new_index); stats->last_suggestion--;
else
stats->last_suggestion = -1;
stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) stats->item_counter[stats->stats_index]);
} }
stats->stats_index = (stats->stats_index + 1) % N_STATS;
stats->frame_counter[stats->stats_index] = 0;
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
stats->last_stats = frame_time;
if (suggested_change)
*suggested_change = stats->last_suggestion;
else
stats->last_suggestion = 0;
}
else
{
if (suggested_change)
*suggested_change = 0;
}
stats->last_frame = frame_time;
stats->frame_counter[stats->stats_index]++;
stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
}
static void
stats_update (GtkWidget *widget)
{
Stats *stats;
stats = get_stats (widget);
stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
}
static gboolean
move_fish (GtkWidget *bowl,
GdkFrameClock *frame_clock,
gpointer info_label)
{
gint suggested_change = 0;
do_stats (bowl,
info_label,
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
gtk_fishbowl_set_count (GTK_FISHBOWL (bowl),
gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change);
stats_update (bowl);
return G_SOURCE_CONTINUE;
}
GtkWidget * GtkWidget *
do_fishbowl (GtkWidget *do_widget) do_fishbowl (GtkWidget *do_widget)
{ {
static GtkWidget *window = NULL; static GtkWidget *window = NULL;
static GtkCssProvider *provider = NULL;
if (provider == NULL)
{
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
if (!window) if (!window)
{ {
GtkBuilder *builder; GtkBuilder *builder;
GtkWidget *bowl; GtkWidget *bowl, *info_label;
g_type_ensure (GTK_TYPE_FISHBOWL); g_type_ensure (GTK_TYPE_FISHBOWL);
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui"); builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
gtk_builder_add_callback_symbols (builder,
"next_button_clicked_cb", G_CALLBACK (next_button_clicked_cb),
"prev_button_clicked_cb", G_CALLBACK (prev_button_clicked_cb),
NULL);
gtk_builder_connect_signals (builder, NULL); gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl")); bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
set_widget_type (GTK_FISHBOWL (bowl), 0); gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
gtk_window_set_display (GTK_WINDOW (window), gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy", g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window); G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window); gtk_widget_realize (window);
gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))

View File

@@ -7,43 +7,7 @@
<object class="GtkHeaderBar" id=""> <object class="GtkHeaderBar" id="">
<property name="show-title-buttons">1</property> <property name="show-title-buttons">1</property>
<child> <child>
<object class="GtkBox"> <object class="GtkLabel" id="info_label">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkButton">
<property name="icon-name">pan-start-symbolic</property>
<signal name="clicked" handler="prev_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="next_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">fps</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="framerate"/>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label">Icons, </property>
</object> </object>
<packing> <packing>
<property name="pack-type">end</property> <property name="pack-type">end</property>
@@ -84,7 +48,6 @@
<object class="GtkFishbowl" id="bowl"> <object class="GtkFishbowl" id="bowl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="animating">True</property> <property name="animating">True</property>
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean">True</property>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -42,7 +42,6 @@
<property name="can-focus">1</property> <property name="can-focus">1</property>
<property name="receives-default">1</property> <property name="receives-default">1</property>
<property name="font">Sans 12</property> <property name="font">Sans 12</property>
<property name="level">family|style|size|variations|features</property>
<signal name="font-set" handler="font_changed" swapped="no"/> <signal name="font-set" handler="font_changed" swapped="no"/>
</object> </object>
</child> </child>
@@ -133,6 +132,7 @@
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр! Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property> Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
<signal name="key-press-event" handler="entry_key_press"/>
<signal name="activate" handler="stop_edit"/> <signal name="activate" handler="stop_edit"/>
<property name="valign">start</property> <property name="valign">start</property>
<property name="width-chars">50</property> <property name="width-chars">50</property>

View File

@@ -1669,12 +1669,12 @@ stop_edit (void)
} }
static gboolean static gboolean
entry_key_press (GtkEventController *controller, entry_key_press (GtkEntry *entry, GdkEventKey *event)
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkEntry *entry)
{ {
guint keyval;
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
if (keyval == GDK_KEY_Escape) if (keyval == GDK_KEY_Escape)
{ {
gtk_entry_set_text (GTK_ENTRY (entry), text); gtk_entry_set_text (GTK_ENTRY (entry), text);
@@ -1694,7 +1694,6 @@ do_font_features (GtkWidget *do_widget)
{ {
GtkBuilder *builder; GtkBuilder *builder;
GtkWidget *feature_list; GtkWidget *feature_list;
GtkEventController *controller;
builder = gtk_builder_new_from_resource ("/font_features/font-features.ui"); builder = gtk_builder_new_from_resource ("/font_features/font-features.ui");
@@ -1704,6 +1703,7 @@ do_font_features (GtkWidget *do_widget)
gtk_builder_add_callback_symbol (builder, "reset", reset_features); gtk_builder_add_callback_symbol (builder, "reset", reset_features);
gtk_builder_add_callback_symbol (builder, "stop_edit", G_CALLBACK (stop_edit)); gtk_builder_add_callback_symbol (builder, "stop_edit", G_CALLBACK (stop_edit));
gtk_builder_add_callback_symbol (builder, "toggle_edit", G_CALLBACK (toggle_edit)); gtk_builder_add_callback_symbol (builder, "toggle_edit", G_CALLBACK (toggle_edit));
gtk_builder_add_callback_symbol (builder, "entry_key_press", G_CALLBACK (entry_key_press));
gtk_builder_connect_signals (builder, NULL); gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
@@ -1718,11 +1718,6 @@ do_font_features (GtkWidget *do_widget)
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry")); entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle")); edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle"));
controller = gtk_event_controller_key_new ();
g_object_set_data_full (G_OBJECT (entry), "controller", controller, g_object_unref);
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), entry);
gtk_widget_add_controller (entry, controller);
add_check_group (feature_list, _("Kerning"), (const char *[]){ "kern", NULL }); add_check_group (feature_list, _("Kerning"), (const char *[]){ "kern", NULL });
add_check_group (feature_list, _("Ligatures"), (const char *[]){ "liga", add_check_group (feature_list, _("Ligatures"), (const char *[]){ "liga",
"dlig", "dlig",

View File

@@ -68,7 +68,8 @@ plane_snapshot (GtkWidget *widget,
height = gtk_widget_get_allocated_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),
"FontPlane");
cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_source_rgb (cr, 0, 0, 0);
cairo_rectangle (cr, 0, 0, width, height); cairo_rectangle (cr, 0, 0, width, height);
@@ -207,27 +208,23 @@ plane_drag_gesture_end (GtkGestureDrag *gesture,
static void static void
gtk_font_plane_init (GtkFontPlane *plane) gtk_font_plane_init (GtkFontPlane *plane)
{ {
GtkGesture *gesture;
gtk_widget_set_has_surface (GTK_WIDGET (plane), FALSE); gtk_widget_set_has_surface (GTK_WIDGET (plane), FALSE);
gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE); gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
gesture = gtk_gesture_drag_new (); plane->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (plane));
g_signal_connect (gesture, "drag-begin", g_signal_connect (plane->drag_gesture, "drag-begin",
G_CALLBACK (plane_drag_gesture_begin), plane); G_CALLBACK (plane_drag_gesture_begin), plane);
g_signal_connect (gesture, "drag-update", g_signal_connect (plane->drag_gesture, "drag-update",
G_CALLBACK (plane_drag_gesture_update), plane); G_CALLBACK (plane_drag_gesture_update), plane);
g_signal_connect (gesture, "drag-end", g_signal_connect (plane->drag_gesture, "drag-end",
G_CALLBACK (plane_drag_gesture_end), plane); G_CALLBACK (plane_drag_gesture_end), plane);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (plane->drag_gesture), 0);
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
gesture = gtk_gesture_long_press_new (); plane->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
g_signal_connect (gesture, "pressed", g_signal_connect (plane->long_press_gesture, "pressed",
G_CALLBACK (hold_action), plane); G_CALLBACK (hold_action), plane);
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->long_press_gesture),
TRUE); TRUE);
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
} }
static void static void
@@ -238,6 +235,9 @@ plane_finalize (GObject *object)
g_clear_object (&plane->weight_adj); g_clear_object (&plane->weight_adj);
g_clear_object (&plane->width_adj); g_clear_object (&plane->width_adj);
g_clear_object (&plane->drag_gesture);
g_clear_object (&plane->long_press_gesture);
G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object); G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object);
} }

View File

@@ -41,6 +41,7 @@ struct _GtkFontPlane
GtkAdjustment *width_adj; GtkAdjustment *width_adj;
GtkGesture *drag_gesture; GtkGesture *drag_gesture;
GtkGesture *long_press_gesture;
}; };
struct _GtkFontPlaneClass struct _GtkFontPlaneClass

View File

@@ -157,15 +157,16 @@ do_gestures (GtkWidget *do_widget)
NULL, NULL); NULL, NULL);
/* Swipe */ /* Swipe */
gesture = gtk_gesture_swipe_new (); gesture = gtk_gesture_swipe_new (drawing_area);
g_signal_connect (gesture, "swipe", g_signal_connect (gesture, "swipe",
G_CALLBACK (swipe_gesture_swept), drawing_area); G_CALLBACK (swipe_gesture_swept), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); GTK_PHASE_BUBBLE);
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture)); g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
/* 3fg swipe for touchpads */ /* 3fg swipe for touchpads */
gesture = g_object_new (GTK_TYPE_GESTURE_SWIPE, gesture = g_object_new (GTK_TYPE_GESTURE_SWIPE,
"widget", drawing_area,
"n-points", 3, "n-points", 3,
NULL); NULL);
g_signal_connect (gesture, "begin", g_signal_connect (gesture, "begin",
@@ -174,34 +175,33 @@ do_gestures (GtkWidget *do_widget)
G_CALLBACK (swipe_gesture_swept), drawing_area); G_CALLBACK (swipe_gesture_swept), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); GTK_PHASE_BUBBLE);
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture)); g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
/* Long press */ /* Long press */
gesture = gtk_gesture_long_press_new (); gesture = gtk_gesture_long_press_new (drawing_area);
g_signal_connect (gesture, "pressed", g_signal_connect (gesture, "pressed",
G_CALLBACK (long_press_gesture_pressed), drawing_area); G_CALLBACK (long_press_gesture_pressed), drawing_area);
g_signal_connect (gesture, "end", g_signal_connect (gesture, "end",
G_CALLBACK (long_press_gesture_end), drawing_area); G_CALLBACK (long_press_gesture_end), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); GTK_PHASE_BUBBLE);
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture)); g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
/* Rotate */ /* Rotate */
rotate = gesture = gtk_gesture_rotate_new (); rotate = gesture = gtk_gesture_rotate_new (drawing_area);
g_signal_connect (gesture, "angle-changed", g_signal_connect (gesture, "angle-changed",
G_CALLBACK (rotation_angle_changed), drawing_area); G_CALLBACK (rotation_angle_changed), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); GTK_PHASE_BUBBLE);
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture)); g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
/* Zoom */ /* Zoom */
zoom = gesture = gtk_gesture_zoom_new (); zoom = gesture = gtk_gesture_zoom_new (drawing_area);
g_signal_connect (gesture, "scale-changed", g_signal_connect (gesture, "scale-changed",
G_CALLBACK (zoom_scale_changed), drawing_area); G_CALLBACK (zoom_scale_changed), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); GTK_PHASE_BUBBLE);
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture)); g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))

View File

@@ -24,18 +24,13 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
struct _GtkFishbowlPrivate struct _GtkFishbowlPrivate
{ {
GtkFishCreationFunc creation_func;
GList *children; GList *children;
guint count; guint count;
gint64 last_frame_time; gint64 last_frame_time;
gint64 update_delay;
guint tick_id; guint tick_id;
double framerate; guint use_icons: 1;
int last_benchmark_change;
guint benchmark : 1;
}; };
struct _GtkFishbowlChild struct _GtkFishbowlChild
@@ -50,25 +45,18 @@ struct _GtkFishbowlChild
enum { enum {
PROP_0, PROP_0,
PROP_ANIMATING, PROP_ANIMATING,
PROP_BENCHMARK,
PROP_COUNT, PROP_COUNT,
PROP_FRAMERATE,
PROP_UPDATE_DELAY,
NUM_PROPERTIES NUM_PROPERTIES
}; };
static GParamSpec *props[NUM_PROPERTIES] = { NULL, }; static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_WIDGET) G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_CONTAINER)
static void static void
gtk_fishbowl_init (GtkFishbowl *fishbowl) gtk_fishbowl_init (GtkFishbowl *fishbowl)
{ {
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE); gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE);
priv->update_delay = G_USEC_PER_SEC;
} }
/** /**
@@ -84,6 +72,15 @@ gtk_fishbowl_new (void)
return g_object_new (GTK_TYPE_FISHBOWL, NULL); return g_object_new (GTK_TYPE_FISHBOWL, NULL);
} }
void
gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
gboolean use_icons)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
priv->use_icons = use_icons;
}
static void static void
gtk_fishbowl_measure (GtkWidget *widget, gtk_fishbowl_measure (GtkWidget *widget,
GtkOrientation orientation, GtkOrientation orientation,
@@ -130,7 +127,8 @@ gtk_fishbowl_measure (GtkWidget *widget,
static void static void
gtk_fishbowl_size_allocate (GtkWidget *widget, gtk_fishbowl_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation, const GtkAllocation *allocation,
int baseline) int baseline,
GtkAllocation *out_clip)
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget); GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
@@ -141,6 +139,8 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
for (children = priv->children; children; children = children->next) for (children = priv->children; children; children = children->next)
{ {
GtkAllocation child_clip;
child = children->data; child = children->data;
if (!gtk_widget_get_visible (child->widget)) if (!gtk_widget_get_visible (child->widget))
@@ -152,7 +152,7 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
child_allocation.width = child_requisition.width; child_allocation.width = child_requisition.width;
child_allocation.height = child_requisition.height; child_allocation.height = child_requisition.height;
gtk_widget_size_allocate (child->widget, &child_allocation, -1); gtk_widget_size_allocate (child->widget, &child_allocation, -1, &child_clip);
} }
} }
@@ -164,9 +164,10 @@ new_speed (void)
} }
static void static void
gtk_fishbowl_add (GtkFishbowl *fishbowl, gtk_fishbowl_add (GtkContainer *container,
GtkWidget *widget) GtkWidget *widget)
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child_info; GtkFishbowlChild *child_info;
@@ -188,12 +189,13 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
} }
static void static void
gtk_fishbowl_remove (GtkFishbowl *fishbowl, gtk_fishbowl_remove (GtkContainer *container,
GtkWidget *widget) GtkWidget *widget)
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child; GtkFishbowlChild *child;
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl); GtkWidget *widget_container = GTK_WIDGET (container);
GList *children; GList *children;
for (children = priv->children; children; children = children->next) for (children = priv->children; children; children = children->next)
@@ -210,8 +212,8 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
g_list_free (children); g_list_free (children);
g_free (child); g_free (child);
if (was_visible && gtk_widget_get_visible (widget_bowl)) if (was_visible && gtk_widget_get_visible (widget_container))
gtk_widget_queue_resize (widget_bowl); gtk_widget_queue_resize (widget_container);
priv->count--; priv->count--;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]); g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
@@ -220,6 +222,26 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
} }
} }
static void
gtk_fishbowl_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data)
{
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child;
GList *children;
children = priv->children;
while (children)
{
child = children->data;
children = children->next;
(* callback) (child->widget, callback_data);
}
}
static void static void
gtk_fishbowl_dispose (GObject *object) gtk_fishbowl_dispose (GObject *object)
{ {
@@ -245,18 +267,10 @@ gtk_fishbowl_set_property (GObject *object,
gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value)); gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value));
break; break;
case PROP_BENCHMARK:
gtk_fishbowl_set_benchmark (fishbowl, g_value_get_boolean (value));
break;
case PROP_COUNT: case PROP_COUNT:
gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value)); gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value));
break; break;
case PROP_UPDATE_DELAY:
gtk_fishbowl_set_update_delay (fishbowl, g_value_get_int64 (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -277,22 +291,10 @@ gtk_fishbowl_get_property (GObject *object,
g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl)); g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl));
break; break;
case PROP_BENCHMARK:
g_value_set_boolean (value, gtk_fishbowl_get_benchmark (fishbowl));
break;
case PROP_COUNT: case PROP_COUNT:
g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl)); g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl));
break; break;
case PROP_FRAMERATE:
g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl));
break;
case PROP_UPDATE_DELAY:
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -304,6 +306,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->dispose = gtk_fishbowl_dispose; object_class->dispose = gtk_fishbowl_dispose;
object_class->set_property = gtk_fishbowl_set_property; object_class->set_property = gtk_fishbowl_set_property;
@@ -312,6 +315,10 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
widget_class->measure = gtk_fishbowl_measure; widget_class->measure = gtk_fishbowl_measure;
widget_class->size_allocate = gtk_fishbowl_size_allocate; widget_class->size_allocate = gtk_fishbowl_size_allocate;
container_class->add = gtk_fishbowl_add;
container_class->remove = gtk_fishbowl_remove;
container_class->forall = gtk_fishbowl_forall;
props[PROP_ANIMATING] = props[PROP_ANIMATING] =
g_param_spec_boolean ("animating", g_param_spec_boolean ("animating",
"animating", "animating",
@@ -319,37 +326,14 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
FALSE, FALSE,
G_PARAM_READWRITE); G_PARAM_READWRITE);
props[PROP_BENCHMARK] =
g_param_spec_boolean ("benchmark",
"Benchmark",
"Adapt the count property to hit the maximum framerate",
FALSE,
G_PARAM_READWRITE);
props[PROP_COUNT] = props[PROP_COUNT] =
g_param_spec_uint ("count", g_param_spec_uint ("count",
"Count", "Count",
"Number of widgets", "Number of widgets",
0, G_MAXUINT, 0, G_MAXUINT,
0, 0,
G_PARAM_READWRITE);
props[PROP_FRAMERATE] =
g_param_spec_double ("framerate",
"Framerate",
"Framerate of this widget in frames per second",
0, G_MAXDOUBLE,
0,
G_PARAM_READABLE); G_PARAM_READABLE);
props[PROP_UPDATE_DELAY] =
g_param_spec_int64 ("update-delay",
"Update delay",
"Number of usecs between updates",
0, G_MAXINT64,
G_USEC_PER_SEC,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, props); g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
} }
@@ -361,58 +345,96 @@ gtk_fishbowl_get_count (GtkFishbowl *fishbowl)
return priv->count; return priv->count;
} }
char **icon_names = NULL;
gsize n_icon_names = 0;
static void
init_icon_names (GtkIconTheme *theme)
{
GPtrArray *icons;
GList *l, *icon_list;
if (icon_names)
return;
icon_list = gtk_icon_theme_list_icons (theme, NULL);
icons = g_ptr_array_new ();
for (l = icon_list; l; l = l->next)
{
if (g_str_has_suffix (l->data, "symbolic"))
continue;
g_ptr_array_add (icons, g_strdup (l->data));
}
n_icon_names = icons->len;
g_ptr_array_add (icons, NULL); /* NULL-terminate the array */
icon_names = (char **) g_ptr_array_free (icons, FALSE);
/* don't free strings, we assigned them to the array */
g_list_free_full (icon_list, g_free);
}
static const char *
get_random_icon_name (GtkIconTheme *theme)
{
init_icon_names (theme);
return icon_names[g_random_int_range(0, n_icon_names)];
}
static GType
get_random_widget_type ()
{
GType types[] = {
GTK_TYPE_SWITCH,
GTK_TYPE_BUTTON,
GTK_TYPE_ENTRY,
GTK_TYPE_SPIN_BUTTON,
GTK_TYPE_FONT_BUTTON,
GTK_TYPE_SCROLLBAR,
GTK_TYPE_SCALE,
GTK_TYPE_LEVEL_BAR,
GTK_TYPE_PROGRESS_BAR,
GTK_TYPE_RADIO_BUTTON,
GTK_TYPE_CHECK_BUTTON
};
return types[g_random_int_range (0, G_N_ELEMENTS (types))];
}
void void
gtk_fishbowl_set_count (GtkFishbowl *fishbowl, gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count) guint count)
{ {
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
if (priv->count == count)
return;
g_object_freeze_notify (G_OBJECT (fishbowl)); g_object_freeze_notify (G_OBJECT (fishbowl));
while (priv->count > count) while (priv->count > count)
{ {
gtk_fishbowl_remove (fishbowl, gtk_widget_get_first_child (GTK_WIDGET (fishbowl))); gtk_container_remove (GTK_CONTAINER (fishbowl),
((GtkFishbowlChild *) priv->children->data)->widget);
} }
while (priv->count < count) while (priv->count < count)
{ {
GtkWidget *new_widget; GtkWidget *new_widget;
new_widget = priv->creation_func (); if (priv->use_icons)
{
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
gtk_image_set_icon_size (GTK_IMAGE (new_widget), GTK_ICON_SIZE_LARGE);
}
else
new_widget = g_object_new (get_random_widget_type (), NULL);
gtk_fishbowl_add (fishbowl, new_widget); gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
} }
g_object_thaw_notify (G_OBJECT (fishbowl)); g_object_thaw_notify (G_OBJECT (fishbowl));
} }
gboolean
gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
return priv->benchmark;
}
void
gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
gboolean benchmark)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
if (priv->benchmark == benchmark)
return;
priv->benchmark = benchmark;
if (!benchmark)
priv->last_benchmark_change = 0;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_BENCHMARK]);
}
gboolean gboolean
gtk_fishbowl_get_animating (GtkFishbowl *fishbowl) gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
{ {
@@ -421,111 +443,6 @@ gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
return priv->tick_id != 0; return priv->tick_id != 0;
} }
static gint64
guess_refresh_interval (GdkFrameClock *frame_clock)
{
gint64 interval;
gint64 i;
interval = G_MAXINT64;
for (i = gdk_frame_clock_get_history_start (frame_clock);
i < gdk_frame_clock_get_frame_counter (frame_clock);
i++)
{
GdkFrameTimings *t, *before;
gint64 ts, before_ts;
t = gdk_frame_clock_get_timings (frame_clock, i);
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
if (t == NULL || before == NULL)
continue;
ts = gdk_frame_timings_get_frame_time (t);
before_ts = gdk_frame_timings_get_frame_time (before);
if (ts == 0 || before_ts == 0)
continue;
interval = MIN (interval, ts - before_ts);
}
if (interval == G_MAXINT64)
return 0;
return interval;
}
static void
gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GdkFrameClock *frame_clock;
GdkFrameTimings *start, *end;
gint64 start_counter, end_counter;
gint64 n_frames, expected_frames;
gint64 start_timestamp, end_timestamp;
gint64 interval;
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (fishbowl));
if (frame_clock == NULL)
return;
start_counter = gdk_frame_clock_get_history_start (frame_clock);
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
end_counter--;
if (end_counter - start_counter < 4)
return;
start_timestamp = gdk_frame_timings_get_presentation_time (start);
end_timestamp = gdk_frame_timings_get_presentation_time (end);
if (start_timestamp == 0 || end_timestamp == 0)
{
start_timestamp = gdk_frame_timings_get_frame_time (start);
end_timestamp = gdk_frame_timings_get_frame_time (end);
}
n_frames = end_counter - start_counter;
priv->framerate = ((double) n_frames) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
if (!priv->benchmark)
return;
interval = gdk_frame_timings_get_refresh_interval (end);
if (interval == 0)
{
interval = guess_refresh_interval (frame_clock);
if (interval == 0)
return;
}
expected_frames = round ((double) (end_timestamp - start_timestamp) / interval);
if (n_frames >= expected_frames)
{
if (priv->last_benchmark_change > 0)
priv->last_benchmark_change *= 2;
else
priv->last_benchmark_change = 1;
}
else if (n_frames + 1 < expected_frames)
{
if (priv->last_benchmark_change < 0)
priv->last_benchmark_change--;
else
priv->last_benchmark_change = -1;
}
else
{
priv->last_benchmark_change = 0;
}
gtk_fishbowl_set_count (fishbowl, MAX (1, (int) priv->count + priv->last_benchmark_change));
}
static gboolean static gboolean
gtk_fishbowl_tick (GtkWidget *widget, gtk_fishbowl_tick (GtkWidget *widget,
GdkFrameClock *frame_clock, GdkFrameClock *frame_clock,
@@ -536,11 +453,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
GtkFishbowlChild *child; GtkFishbowlChild *child;
GList *l; GList *l;
gint64 frame_time, elapsed; gint64 frame_time, elapsed;
gboolean do_update;
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget)); frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
elapsed = frame_time - priv->last_frame_time; elapsed = frame_time - priv->last_frame_time;
do_update = frame_time / priv->update_delay != priv->last_frame_time / priv->update_delay;
priv->last_frame_time = frame_time; priv->last_frame_time = frame_time;
/* last frame was 0, so we're just starting to animate */ /* last frame was 0, so we're just starting to animate */
@@ -579,9 +494,6 @@ gtk_fishbowl_tick (GtkWidget *widget,
gtk_widget_queue_allocate (widget); gtk_widget_queue_allocate (widget);
if (do_update)
gtk_fishbowl_do_update (fishbowl);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
@@ -606,57 +518,8 @@ gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
priv->last_frame_time = 0; priv->last_frame_time = 0;
gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id); gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id);
priv->tick_id = 0; priv->tick_id = 0;
priv->framerate = 0;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
} }
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_ANIMATING]); g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_ANIMATING]);
} }
double
gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
return priv->framerate;
}
gint64
gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
return priv->update_delay;
}
void
gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
gint64 update_delay)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
if (priv->update_delay == update_delay)
return;
priv->update_delay = update_delay;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_UPDATE_DELAY]);
}
void
gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
GtkFishCreationFunc creation_func)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
g_object_freeze_notify (G_OBJECT (fishbowl));
gtk_fishbowl_set_count (fishbowl, 0);
priv->last_benchmark_change = 0;
priv->creation_func = creation_func;
gtk_fishbowl_set_count (fishbowl, 1);
g_object_thaw_notify (G_OBJECT (fishbowl));
}

View File

@@ -32,37 +32,29 @@ G_BEGIN_DECLS
typedef struct _GtkFishbowl GtkFishbowl; typedef struct _GtkFishbowl GtkFishbowl;
typedef struct _GtkFishbowlClass GtkFishbowlClass; typedef struct _GtkFishbowlClass GtkFishbowlClass;
typedef GtkWidget * (* GtkFishCreationFunc) (void);
struct _GtkFishbowl struct _GtkFishbowl
{ {
GtkWidget parent; GtkContainer container;
}; };
struct _GtkFishbowlClass struct _GtkFishbowlClass
{ {
GtkWidgetClass parent_class; GtkContainerClass parent_class;
}; };
GType gtk_fishbowl_get_type (void) G_GNUC_CONST; GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_fishbowl_new (void); GtkWidget* gtk_fishbowl_new (void);
void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
gboolean use_icons);
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl); guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl, void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count); guint count);
gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl); gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl, void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
gboolean animating); gboolean animating);
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
gboolean animating);
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
gint64 update_delay);
void gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
GtkFishCreationFunc creation_func);
G_END_DECLS G_END_DECLS

View File

@@ -105,14 +105,14 @@ follow_if_link (GtkWidget *text_view,
/* Links can be activated by pressing Enter. /* Links can be activated by pressing Enter.
*/ */
static gboolean static gboolean
key_pressed (GtkEventController *controller, key_press_event (GtkWidget *text_view,
guint keyval, GdkEventKey *event)
guint keycode,
GdkModifierType modifiers,
GtkWidget *text_view)
{ {
GtkTextIter iter; GtkTextIter iter;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
guint keyval;
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
switch (keyval) switch (keyval)
{ {
@@ -128,49 +128,62 @@ key_pressed (GtkEventController *controller,
break; break;
} }
return GDK_EVENT_PROPAGATE; return FALSE;
} }
static void set_cursor_if_appropriate (GtkTextView *text_view, static void set_cursor_if_appropriate (GtkTextView *text_view,
gint x, gint x,
gint y); gint y);
static void /* Links can also be activated by clicking or tapping.
released_cb (GtkGestureMultiPress *gesture, */
guint n_press, static gboolean
gdouble x, event_cb (GtkWidget *text_view,
gdouble y, GdkEvent *ev)
GtkWidget *text_view)
{ {
GtkTextIter start, end, iter; GtkTextIter start, end, iter;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
int tx, ty; gdouble ex, ey;
int x, y;
GdkEventType type;
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1) type = gdk_event_get_event_type (ev);
return;
gdk_event_get_coords (ev, &ex, &ey);
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
GTK_TEXT_WINDOW_WIDGET, GTK_TEXT_WINDOW_WIDGET,
x, y, &tx, &ty); ex, ey, &x, &y);
if (type == GDK_BUTTON_RELEASE)
{
guint button;
gdk_event_get_button (ev, &button);
if (button != GDK_BUTTON_PRIMARY)
return FALSE;
}
else if (type == GDK_MOTION_NOTIFY)
{
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
return FALSE;
}
else if (type == GDK_TOUCH_END)
{
}
else
return FALSE;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
/* we shouldn't follow a link if the user has selected something */ /* we shouldn't follow a link if the user has selected something */
gtk_text_buffer_get_selection_bounds (buffer, &start, &end); gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
return; return FALSE;
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y)) if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
follow_if_link (text_view, &iter); follow_if_link (text_view, &iter);
}
static void return TRUE;
motion_cb (GtkEventControllerMotion *controller,
gdouble x,
gdouble y,
GtkTextView *text_view)
{
set_cursor_if_appropriate (text_view, x, y);
} }
static gboolean hovering_over_link = FALSE; static gboolean hovering_over_link = FALSE;
@@ -228,7 +241,6 @@ do_hypertext (GtkWidget *do_widget)
GtkWidget *view; GtkWidget *view;
GtkWidget *sw; GtkWidget *sw;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
GtkEventController *controller;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Hypertext"); gtk_window_set_title (GTK_WINDOW (window), "Hypertext");
@@ -243,19 +255,10 @@ do_hypertext (GtkWidget *do_widget)
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20); gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20);
controller = gtk_event_controller_key_new (); g_signal_connect (view, "key-press-event",
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view); G_CALLBACK (key_press_event), NULL);
gtk_widget_add_controller (view, controller); g_signal_connect (view, "event",
G_CALLBACK (event_cb), NULL);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
g_signal_connect (controller, "released",
G_CALLBACK (released_cb), view);
gtk_widget_add_controller (view, controller);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion",
G_CALLBACK (motion_cb), view);
gtk_widget_add_controller (view, controller);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));

View File

@@ -1,15 +1,15 @@
/* Images /* Images
* *
* GtkImage and GtkPicture are used to display an image; the image can be * GtkImage is used to display an image; the image can be in a number of formats.
* in a number of formats. * Typically, you load an image into a GdkPixbuf, then display the pixbuf.
*
* GtkImage is the widget used to display icons or images that should be
* sized and styled like an icon, while GtkPicture is used for images
* that should be displayed as-is.
* *
* This demo code shows some of the more obscure cases, in the simple * This demo code shows some of the more obscure cases, in the simple
* case a call to gtk_picture_new_for_file() or * case a call to gtk_image_new_from_file() is all you need.
* gtk_image_new_from_icon_name() is all you need. *
* If you want to put image data in your program as a C variable,
* use the make-inline-pixbuf program that comes with GTK+.
* This way you won't need to depend on loading external files, your
* application binary can be self-contained.
*/ */
#include <gtk/gtk.h> #include <gtk/gtk.h>
@@ -27,9 +27,9 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
gpointer data) gpointer data)
{ {
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
GtkWidget *picture; GtkWidget *image;
picture = GTK_WIDGET (data); image = GTK_WIDGET (data);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
@@ -38,7 +38,7 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
*/ */
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff); gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf); gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
} }
static void static void
@@ -49,21 +49,21 @@ progressive_updated_callback (GdkPixbufLoader *loader,
gint height, gint height,
gpointer data) gpointer data)
{ {
GtkWidget *picture; GtkWidget *image;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
picture = GTK_WIDGET (data); image = GTK_WIDGET (data);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf); gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
} }
static gint static gint
progressive_timeout (gpointer data) progressive_timeout (gpointer data)
{ {
GtkWidget *picture; GtkWidget *image;
picture = GTK_WIDGET (data); image = GTK_WIDGET (data);
/* This shows off fully-paranoid error handling, so looks scary. /* This shows off fully-paranoid error handling, so looks scary.
* You could factor out the error handling code into a nice separate * You could factor out the error handling code into a nice separate
@@ -241,10 +241,10 @@ progressive_timeout (gpointer data)
pixbuf_loader = gdk_pixbuf_loader_new (); pixbuf_loader = gdk_pixbuf_loader_new ();
g_signal_connect (pixbuf_loader, "area-prepared", g_signal_connect (pixbuf_loader, "area-prepared",
G_CALLBACK (progressive_prepared_callback), picture); G_CALLBACK (progressive_prepared_callback), image);
g_signal_connect (pixbuf_loader, "area-updated", g_signal_connect (pixbuf_loader, "area-updated",
G_CALLBACK (progressive_updated_callback), picture); G_CALLBACK (progressive_updated_callback), image);
} }
/* leave timeout installed */ /* leave timeout installed */
@@ -252,7 +252,7 @@ progressive_timeout (gpointer data)
} }
static void static void
start_progressive_loading (GtkWidget *picture) start_progressive_loading (GtkWidget *image)
{ {
/* This is obviously totally contrived (we slow down loading /* This is obviously totally contrived (we slow down loading
* on purpose to show how incremental loading works). * on purpose to show how incremental loading works).
@@ -261,7 +261,7 @@ start_progressive_loading (GtkWidget *picture)
* The timeout simply simulates a slow data source by inserting * The timeout simply simulates a slow data source by inserting
* pauses in the reading process. * pauses in the reading process.
*/ */
load_timeout = g_timeout_add (150, progressive_timeout, picture); load_timeout = g_timeout_add (150, progressive_timeout, image);
g_source_set_name_by_id (load_timeout, "[gtk+] progressive_timeout"); g_source_set_name_by_id (load_timeout, "[gtk+] progressive_timeout");
} }
@@ -323,10 +323,8 @@ do_images (GtkWidget *do_widget)
GtkWidget *hbox; GtkWidget *hbox;
GtkWidget *base_vbox; GtkWidget *base_vbox;
GtkWidget *image; GtkWidget *image;
GtkWidget *picture;
GtkWidget *label; GtkWidget *label;
GtkWidget *button; GtkWidget *button;
GdkPaintable *paintable;
GIcon *gicon; GIcon *gicon;
if (!window) if (!window)
@@ -381,9 +379,9 @@ do_images (GtkWidget *do_widget)
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
picture = gtk_picture_new_for_resource ("/images/floppybuddy.gif"); image = gtk_image_new_from_resource ("/images/floppybuddy.gif");
gtk_container_add (GTK_CONTAINER (frame), picture); gtk_container_add (GTK_CONTAINER (frame), image);
/* Symbolic icon */ /* Symbolic icon */
@@ -423,10 +421,10 @@ do_images (GtkWidget *do_widget)
/* Create an empty image for now; the progressive loader /* Create an empty image for now; the progressive loader
* will create the pixbuf and fill it in. * will create the pixbuf and fill it in.
*/ */
picture = gtk_picture_new (); image = gtk_image_new_from_pixbuf (NULL);
gtk_container_add (GTK_CONTAINER (frame), picture); gtk_container_add (GTK_CONTAINER (frame), image);
start_progressive_loading (picture); start_progressive_loading (image);
/* Video */ /* Video */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
@@ -447,21 +445,6 @@ do_images (GtkWidget *do_widget)
gtk_media_stream_set_loop (gtk_video_get_media_stream (GTK_VIDEO (video)), TRUE); gtk_media_stream_set_loop (gtk_video_get_media_stream (GTK_VIDEO (video)), TRUE);
gtk_container_add (GTK_CONTAINER (frame), video); gtk_container_add (GTK_CONTAINER (frame), video);
/* Widget paintables */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_container_add (GTK_CONTAINER (hbox), vbox);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),
"<u>GtkWidgetPaintable</u>");
gtk_box_pack_start (GTK_BOX (vbox), label);
paintable = gtk_widget_paintable_new (do_widget);
picture = gtk_picture_new_for_paintable (paintable);
gtk_widget_set_size_request (picture, 100, 100);
gtk_widget_set_valign (picture, GTK_ALIGN_START);
gtk_container_add (GTK_CONTAINER (vbox), picture);
/* Sensitivity control */ /* Sensitivity control */
button = gtk_toggle_button_new_with_mnemonic ("_Insensitive"); button = gtk_toggle_button_new_with_mnemonic ("_Insensitive");
gtk_box_pack_start (GTK_BOX (base_vbox), button); gtk_box_pack_start (GTK_BOX (base_vbox), button);

View File

@@ -2,13 +2,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <dirent.h>
#include <locale.h> #include <locale.h>
#include <langinfo.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <glib.h> #include <glib.h>
@@ -174,9 +173,9 @@ languages_variant_init (const char *variant)
{ {
gboolean res; gboolean res;
gsize buf_len; gsize buf_len;
char *buf = NULL; g_autofree char *buf = NULL;
char *filename = NULL; g_autofree char *filename = NULL;
GError *error = NULL; g_autoptr (GError) error = NULL;
bindtextdomain (variant, ISO_CODES_LOCALESDIR); bindtextdomain (variant, ISO_CODES_LOCALESDIR);
bind_textdomain_codeset (variant, "UTF-8"); bind_textdomain_codeset (variant, "UTF-8");
@@ -186,25 +185,19 @@ languages_variant_init (const char *variant)
res = g_file_get_contents (filename, &buf, &buf_len, &error); res = g_file_get_contents (filename, &buf, &buf_len, &error);
if (res) if (res)
{ {
GMarkupParseContext *ctx = NULL; g_autoptr (GMarkupParseContext) ctx = NULL;
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL }; GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL); ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
g_free (error);
error = NULL; error = NULL;
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error); res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
g_free (ctx);
if (!res) if (!res)
g_warning ("Failed to parse '%s': %s\n", filename, error->message); g_warning ("Failed to parse '%s': %s\n", filename, error->message);
} }
else else
g_warning ("Failed to load '%s': %s\n", filename, error->message); g_warning ("Failed to load '%s': %s\n", filename, error->message);
g_free (error);
g_free (filename);
g_free (buf);
} }
static void static void

View File

@@ -154,7 +154,6 @@
</child> </child>
<child> <child>
<object class="GtkBox" id="extra_buttons_box"> <object class="GtkBox" id="extra_buttons_box">
<property name="visible">0</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child> <child>
<object class="GtkButton" id="reply-button"> <object class="GtkButton" id="reply-button">

View File

@@ -532,106 +532,7 @@ fontify (GtkTextBuffer *source_buffer)
} }
} }
static GtkWidget * static GtkWidget *create_text (GtkWidget **text_view, gboolean is_source);
display_image (const char *resource)
{
GtkWidget *sw, *image;
image = gtk_image_new_from_resource (resource);
gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (sw), image);
return sw;
}
static GtkWidget *
display_text (const char *resource)
{
GtkTextBuffer *buffer;
GtkWidget *textview, *sw;
GBytes *bytes;
bytes = g_resources_lookup_data (resource, 0, NULL);
g_assert (bytes);
g_assert (g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL));
textview = gtk_text_view_new ();
g_object_set (textview,
"left-margin", 20,
"right-margin", 20,
"top-margin", 20,
"bottom-margin", 20,
NULL);
gtk_text_view_set_editable (GTK_TEXT_VIEW (textview), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (textview), FALSE);
/* Make it a bit nicer for text. */
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview), GTK_WRAP_WORD);
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (textview), 2);
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (textview), 2);
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
if (g_str_has_suffix (resource, ".c"))
fontify (buffer);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
g_bytes_unref (bytes);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
GTK_SHADOW_NONE);
gtk_container_add (GTK_CONTAINER (sw), textview);
return sw;
}
static GtkWidget *
display_video (const char *resource)
{
GtkWidget *video;
video = gtk_video_new_for_resource (resource);
gtk_video_set_loop (GTK_VIDEO (video), TRUE);
return video;
}
static GtkWidget *
display_nothing (const char *resource)
{
GtkWidget *widget;
char *str;
str = g_strdup_printf ("The lazy GTK developers forgot to add a way to display the resource '%s'", resource);
widget = gtk_label_new (str);
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
g_free (str);
return widget;
}
static struct {
const char *extension;
GtkWidget * (* display_func) (const char *resource);
} display_funcs[] = {
{ ".gif", display_image },
{ ".jpg", display_image },
{ ".png", display_image },
{ ".c", display_text },
{ ".css", display_text },
{ ".glsl", display_text },
{ ".h", display_text },
{ ".txt", display_text },
{ ".ui", display_text },
{ ".webm", display_video }
};
static void static void
add_data_tab (const gchar *demoname) add_data_tab (const gchar *demoname)
@@ -639,7 +540,7 @@ add_data_tab (const gchar *demoname)
gchar *resource_dir, *resource_name; gchar *resource_dir, *resource_name;
gchar **resources; gchar **resources;
GtkWidget *widget, *label; GtkWidget *widget, *label;
guint i, j; guint i;
resource_dir = g_strconcat ("/", demoname, NULL); resource_dir = g_strconcat ("/", demoname, NULL);
resources = g_resources_enumerate_children (resource_dir, 0, NULL); resources = g_resources_enumerate_children (resource_dir, 0, NULL);
@@ -653,22 +554,58 @@ add_data_tab (const gchar *demoname)
{ {
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL); resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
for (j = 0; j < G_N_ELEMENTS(display_funcs); j++) widget = gtk_image_new_from_resource (resource_name);
if (gtk_image_get_paintable (GTK_IMAGE (widget)) == NULL)
{ {
if (g_str_has_suffix (resource_name, display_funcs[j].extension)) GBytes *bytes;
break;
/* So we've used the best API available to figure out it's
* not an image. Let's try something else then.
*/
g_object_ref_sink (widget);
g_object_unref (widget);
bytes = g_resources_lookup_data (resource_name, 0, NULL);
g_assert (bytes);
if (g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
{
/* Looks like it parses as text. Dump it into a textview then! */
GtkTextBuffer *buffer;
GtkWidget *textview;
widget = create_text (&textview, FALSE);
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
if (g_str_has_suffix (resource_name, ".c"))
fontify (buffer);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
}
else
{
g_warning ("Don't know how to display resource '%s'", resource_name);
widget = NULL;
} }
if (j < G_N_ELEMENTS(display_funcs)) g_bytes_unref (bytes);
widget = display_funcs[j].display_func (resource_name); }
else
widget = display_nothing (resource_name); if (GTK_IS_IMAGE (widget))
{
GtkWidget *sw;
gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (sw), widget);
widget = sw;
}
label = gtk_label_new (resources[i]); label = gtk_label_new (resources[i]);
gtk_widget_show (label); gtk_widget_show (label);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label); gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
gtk_container_child_set (GTK_CONTAINER (notebook), gtk_container_child_set (GTK_CONTAINER (notebook),
widget, GTK_WIDGET (widget),
"tab-expand", TRUE, "tab-expand", TRUE,
NULL); NULL);
@@ -888,6 +825,49 @@ selection_cb (GtkTreeSelection *selection,
g_free (filename); g_free (filename);
} }
static GtkWidget *
create_text (GtkWidget **view,
gboolean is_source)
{
GtkWidget *scrolled_window;
GtkWidget *text_view;
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_SHADOW_NONE);
*view = text_view = gtk_text_view_new ();
g_object_set (text_view,
"left-margin", 20,
"right-margin", 20,
"top-margin", 20,
"bottom-margin", 20,
NULL);
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_view), FALSE);
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
if (is_source)
{
gtk_text_view_set_monospace (GTK_TEXT_VIEW (text_view), TRUE);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_NONE);
}
else
{
/* Make it a bit nicer for text. */
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (text_view), 2);
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (text_view), 2);
}
return scrolled_window;
}
static void static void
populate_model (GtkTreeModel *model) populate_model (GtkTreeModel *model)
{ {

View File

@@ -22,9 +22,11 @@ demos = files([
'editable_cells.c', 'editable_cells.c',
'entry_buffer.c', 'entry_buffer.c',
'entry_completion.c', 'entry_completion.c',
'event_axes.c',
'expander.c', 'expander.c',
'filtermodel.c', 'filtermodel.c',
'fishbowl.c', 'fishbowl.c',
'widgetbowl.c',
'foreigndrawing.c', 'foreigndrawing.c',
'gestures.c', 'gestures.c',
'glarea.c', 'glarea.c',
@@ -43,7 +45,6 @@ demos = files([
'modelbutton.c', 'modelbutton.c',
'overlay.c', 'overlay.c',
'overlay2.c', 'overlay2.c',
'paint.c',
'paintable.c', 'paintable.c',
'paintable_animated.c', 'paintable_animated.c',
'paintable_mediastream.c', 'paintable_mediastream.c',
@@ -60,7 +61,6 @@ demos = files([
'shortcuts.c', 'shortcuts.c',
'sidebar.c', 'sidebar.c',
'sizegroup.c', 'sizegroup.c',
'sliding_puzzle.c',
'spinbutton.c', 'spinbutton.c',
'spinner.c', 'spinner.c',
'stack.c', 'stack.c',
@@ -76,11 +76,8 @@ demos = files([
gtkdemo_deps = [ libgtk_dep, ] gtkdemo_deps = [ libgtk_dep, ]
extra_demo_sources = files(['main.c', 'gtkfishbowl.c', 'fontplane.c', 'gtkgears.c', 'puzzlepiece.c'])
if harfbuzz_dep.found() and pangoft_dep.found() if harfbuzz_dep.found() and pangoft_dep.found()
demos += files('font_features.c') demos += files('font_features.c')
extra_demo_sources += files(['script-names.c', 'language-names.c'])
gtkdemo_deps += [ harfbuzz_dep, ] gtkdemo_deps += [ harfbuzz_dep, ]
endif endif
@@ -100,12 +97,13 @@ gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
source_dir: '.') source_dir: '.')
executable('gtk4-demo', executable('gtk4-demo',
demos, demos_h, extra_demo_sources, gtkdemo_resources, 'main.c', 'gtkfishbowl.c', 'fontplane.c', 'script-names.c', 'language-names.c',
'gtkgears.c',
demos, demos_h, gtkdemo_resources,
c_args: gtkdemo_args, c_args: gtkdemo_args,
dependencies: gtkdemo_deps, dependencies: gtkdemo_deps,
include_directories: confinc, include_directories: confinc,
gui_app: true, gui_app: true,
link_args: extra_demo_ldflags,
install: true) install: true)
executable('gtk4-demo-application', executable('gtk4-demo-application',
@@ -114,7 +112,6 @@ executable('gtk4-demo-application',
dependencies: gtkdemo_deps, dependencies: gtkdemo_deps,
include_directories: confinc, include_directories: confinc,
gui_app: true, gui_app: true,
link_args: extra_demo_ldflags,
install: true) install: true)
# icons # icons
@@ -129,7 +126,7 @@ foreach icon_size: [ '16x16', '22x22', '24x24', '32x32', '48x48', '256x256', ]
endforeach endforeach
# desktop file # desktop file
install_data('org.gtk.Demo.desktop', install_dir: gtk_applicationsdir) install_data('gtk4-demo.desktop', install_dir: gtk_applicationsdir)
# GSettings # GSettings
install_data('org.gtk.Demo.gschema.xml', install_dir: gtk_schemasdir) install_data('org.gtk.Demo.gschema.xml', install_dir: gtk_schemasdir)

View File

@@ -56,7 +56,6 @@
<child> <child>
<object class="GtkModelButton"> <object class="GtkModelButton">
<property name="action-name">win.color</property> <property name="action-name">win.color</property>
<property name="action-target">'red'</property>
<property name="text">Red</property> <property name="text">Red</property>
<property name="inverted">1</property> <property name="inverted">1</property>
</object> </object>
@@ -64,7 +63,6 @@
<child> <child>
<object class="GtkModelButton"> <object class="GtkModelButton">
<property name="action-name">win.color</property> <property name="action-name">win.color</property>
<property name="action-target">'green'</property>
<property name="text">Green</property> <property name="text">Green</property>
<property name="inverted">1</property> <property name="inverted">1</property>
</object> </object>
@@ -72,7 +70,6 @@
<child> <child>
<object class="GtkModelButton"> <object class="GtkModelButton">
<property name="action-name">win.color</property> <property name="action-name">win.color</property>
<property name="action-target">'blue'</property>
<property name="text">Blue</property> <property name="text">Blue</property>
<property name="inverted">1</property> <property name="inverted">1</property>
</object> </object>

View File

@@ -1,411 +0,0 @@
/* Paint
*
* Demonstrates practical handling of drawing tablets in a real world
* usecase.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
enum {
COLOR_SET,
N_SIGNALS
};
static guint area_signals[N_SIGNALS] = { 0, };
typedef struct
{
GtkWidget parent_instance;
cairo_surface_t *surface;
cairo_t *cr;
GdkRGBA draw_color;
GtkPadController *pad_controller;
gdouble brush_size;
} DrawingArea;
typedef struct
{
GtkWidgetClass parent_class;
} DrawingAreaClass;
static GtkPadActionEntry pad_actions[] = {
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Black"), "pad.black" },
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Pink"), "pad.pink" },
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Green"), "pad.green" },
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("Red"), "pad.red" },
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Purple"), "pad.purple" },
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Orange"), "pad.orange" },
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Brush size"), "pad.brush_size" },
};
static const gchar *pad_colors[] = {
"black",
"pink",
"green",
"red",
"purple",
"orange"
};
G_DEFINE_TYPE (DrawingArea, drawing_area, GTK_TYPE_WIDGET)
static void drawing_area_set_color (DrawingArea *area,
GdkRGBA *color);
static void
drawing_area_ensure_surface (DrawingArea *area,
gint width,
gint height)
{
if (!area->surface ||
cairo_image_surface_get_width (area->surface) != width ||
cairo_image_surface_get_height (area->surface) != height)
{
cairo_surface_t *surface;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
width, height);
if (area->surface)
{
cairo_t *cr;
cr = cairo_create (surface);
cairo_set_source_surface (cr, area->surface, 0, 0);
cairo_paint (cr);
cairo_surface_destroy (area->surface);
cairo_destroy (area->cr);
cairo_destroy (cr);
}
area->surface = surface;
area->cr = cairo_create (surface);
}
}
static void
drawing_area_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline)
{
DrawingArea *area = (DrawingArea *) widget;
drawing_area_ensure_surface (area, allocation->width, allocation->height);
GTK_WIDGET_CLASS (drawing_area_parent_class)->size_allocate (widget, allocation, baseline);
}
static void
drawing_area_map (GtkWidget *widget)
{
GtkAllocation allocation;
GTK_WIDGET_CLASS (drawing_area_parent_class)->map (widget);
gtk_widget_get_allocation (widget, &allocation);
drawing_area_ensure_surface ((DrawingArea *) widget,
allocation.width, allocation.height);
}
static void
drawing_area_unmap (GtkWidget *widget)
{
DrawingArea *area = (DrawingArea *) widget;
g_clear_pointer (&area->cr, cairo_destroy);
g_clear_pointer (&area->surface, cairo_surface_destroy);
GTK_WIDGET_CLASS (drawing_area_parent_class)->unmap (widget);
}
static void
drawing_area_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
DrawingArea *area = (DrawingArea *) widget;
GtkAllocation allocation;
cairo_t *cr;
gtk_widget_get_allocation (widget, &allocation);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (
0, 0,
allocation.width,
allocation.height
));
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_set_source_surface (cr, area->surface, 0, 0);
cairo_paint (cr);
cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_stroke (cr);
cairo_destroy (cr);
}
static void
on_pad_button_activate (GSimpleAction *action,
GVariant *parameter,
DrawingArea *area)
{
const gchar *color = g_object_get_data (G_OBJECT (action), "color");
GdkRGBA rgba;
gdk_rgba_parse (&rgba, color);
drawing_area_set_color (area, &rgba);
}
static void
on_pad_knob_change (GSimpleAction *action,
GVariant *parameter,
DrawingArea *area)
{
gdouble value = g_variant_get_double (parameter);
area->brush_size = value;
}
static void
drawing_area_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel)
{
DrawingArea *area = (DrawingArea *) widget;
GSimpleActionGroup *action_group;
GSimpleAction *action;
GtkWidget *toplevel;
gint i;
if (previous_toplevel && area->pad_controller)
{
gtk_widget_remove_controller (previous_toplevel,
GTK_EVENT_CONTROLLER (area->pad_controller));
area->pad_controller = NULL;
}
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (area));
if (!GTK_IS_WINDOW (toplevel))
return;
action_group = g_simple_action_group_new ();
area->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
NULL);
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
{
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
{
action = g_simple_action_new (pad_actions[i].action_name, NULL);
g_object_set_data (G_OBJECT (action), "color",
(gpointer) pad_colors[i]);
g_signal_connect (action, "activate",
G_CALLBACK (on_pad_button_activate), area);
}
else
{
action = g_simple_action_new_stateful (pad_actions[i].action_name,
G_VARIANT_TYPE_DOUBLE, NULL);
g_signal_connect (action, "activate",
G_CALLBACK (on_pad_knob_change), area);
}
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
g_object_unref (action);
}
gtk_pad_controller_set_action_entries (area->pad_controller, pad_actions,
G_N_ELEMENTS (pad_actions));
gtk_widget_add_controller (toplevel,
GTK_EVENT_CONTROLLER (area->pad_controller));
}
static void
drawing_area_class_init (DrawingAreaClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
widget_class->size_allocate = drawing_area_size_allocate;
widget_class->snapshot = drawing_area_snapshot;
widget_class->map = drawing_area_map;
widget_class->unmap = drawing_area_unmap;
widget_class->hierarchy_changed = drawing_area_hierarchy_changed;
area_signals[COLOR_SET] =
g_signal_new ("color-set",
G_TYPE_FROM_CLASS (widget_class),
G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1, GDK_TYPE_RGBA);
}
static void
drawing_area_apply_stroke (DrawingArea *area,
GdkDeviceTool *tool,
gdouble x,
gdouble y,
gdouble pressure)
{
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_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
}
else
{
cairo_set_line_width (area->cr, 4 * pressure * area->brush_size);
cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE);
}
cairo_set_source_rgba (area->cr, area->draw_color.red,
area->draw_color.green, area->draw_color.blue,
area->draw_color.alpha * pressure);
cairo_line_to (area->cr, x, y);
cairo_stroke (area->cr);
cairo_move_to (area->cr, x, y);
}
static void
stylus_gesture_down (GtkGestureStylus *gesture,
gdouble x,
gdouble y,
DrawingArea *area)
{
cairo_new_path (area->cr);
}
static void
stylus_gesture_motion (GtkGestureStylus *gesture,
gdouble x,
gdouble y,
DrawingArea *area)
{
GdkTimeCoord *backlog;
GdkDeviceTool *tool;
gdouble pressure;
guint n_items;
tool = gtk_gesture_stylus_get_device_tool (gesture);
if (gtk_gesture_stylus_get_backlog (gesture, &backlog, &n_items))
{
guint i;
for (i = 0; i < n_items; i++)
{
drawing_area_apply_stroke (area, tool,
backlog[i].axes[GDK_AXIS_X],
backlog[i].axes[GDK_AXIS_Y],
backlog[i].axes[GDK_AXIS_PRESSURE]);
}
g_free (backlog);
}
else
{
if (!gtk_gesture_stylus_get_axis (gesture, GDK_AXIS_PRESSURE, &pressure))
pressure = 1;
drawing_area_apply_stroke (area, tool, x, y, pressure);
}
gtk_widget_queue_draw (GTK_WIDGET (area));
}
static void
drawing_area_init (DrawingArea *area)
{
GtkGesture *gesture;
gtk_widget_set_has_surface (GTK_WIDGET (area), FALSE);
gesture = gtk_gesture_stylus_new ();
g_signal_connect (gesture, "down",
G_CALLBACK (stylus_gesture_down), area);
g_signal_connect (gesture, "motion",
G_CALLBACK (stylus_gesture_motion), area);
gtk_widget_add_controller (GTK_WIDGET (area), GTK_EVENT_CONTROLLER (gesture));
area->draw_color = (GdkRGBA) { 0, 0, 0, 1 };
}
GtkWidget *
drawing_area_new (void)
{
return g_object_new (drawing_area_get_type (), NULL);
}
static void
drawing_area_set_color (DrawingArea *area,
GdkRGBA *color)
{
if (gdk_rgba_equal (&area->draw_color, color))
return;
area->draw_color = *color;
g_signal_emit (area, area_signals[COLOR_SET], 0, &area->draw_color);
}
static void
color_button_color_set (GtkColorButton *button,
DrawingArea *draw_area)
{
GdkRGBA color;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (button), &color);
drawing_area_set_color (draw_area, &color);
}
static void
drawing_area_color_set (DrawingArea *area,
GdkRGBA *color,
GtkColorButton *button)
{
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), color);
}
GtkWidget *
do_paint (GtkWidget *toplevel)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *draw_area, *headerbar, *colorbutton;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
draw_area = drawing_area_new ();
gtk_container_add (GTK_CONTAINER (window), draw_area);
headerbar = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), "Paint");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
colorbutton = gtk_color_button_new ();
g_signal_connect (colorbutton, "color-set",
G_CALLBACK (color_button_color_set), draw_area);
g_signal_connect (draw_area, "color-set",
G_CALLBACK (drawing_area_color_set), colorbutton);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton),
&(GdkRGBA) { 0, 0, 0, 1 });
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -56,13 +56,15 @@ gtk_nuclear_snapshot (GtkSnapshot *snapshot,
gtk_snapshot_append_color (snapshot, gtk_snapshot_append_color (snapshot,
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 }, &(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 },
&GRAPHENE_RECT_INIT (0, 0, width, height)); &GRAPHENE_RECT_INIT (0, 0, width, height),
"Yellow background");
size = MIN (width, height); size = MIN (width, height);
cr = gtk_snapshot_append_cairo (snapshot, cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT ((width - size) / 2.0, &GRAPHENE_RECT_INIT ((width - size) / 2.0,
(height - size) / 2.0, (height - size) / 2.0,
size, size)); size, size),
"Radioactive Icon");
cairo_translate (cr, width / 2.0, height / 2.0); cairo_translate (cr, width / 2.0, height / 2.0);
cairo_scale (cr, size, size); cairo_scale (cr, size, size);
cairo_rotate (cr, rotation); cairo_rotate (cr, rotation);

View File

@@ -58,6 +58,7 @@ static void
entry_size_allocate_cb (GtkEntry *entry, entry_size_allocate_cb (GtkEntry *entry,
const GtkAllocation *allocation, const GtkAllocation *allocation,
int baseline, int baseline,
GtkAllocation *out_clip,
gpointer user_data) gpointer user_data)
{ {
GtkEntryIconPosition popover_pos; GtkEntryIconPosition popover_pos;
@@ -77,6 +78,7 @@ entry_size_allocate_cb (GtkEntry *entry,
static void static void
entry_icon_press_cb (GtkEntry *entry, entry_icon_press_cb (GtkEntry *entry,
GtkEntryIconPosition icon_pos, GtkEntryIconPosition icon_pos,
GdkEvent *event,
gpointer user_data) gpointer user_data)
{ {
GtkWidget *popover = user_data; GtkWidget *popover = user_data;
@@ -118,7 +120,7 @@ day_selected_cb (GtkCalendar *calendar,
gtk_widget_show (popover); gtk_widget_show (popover);
g_object_unref (event); gdk_event_free (event);
} }
GtkWidget * GtkWidget *

View File

@@ -1,220 +0,0 @@
/* Paintable/A simple paintable
*
* GdkPaintable is an interface used by GTK for drawings of any sort
* that do not require layouting or positioning.
*
* This demo code gives a simple example on how a paintable can
* be created.
*
* Paintables can be used in many places inside GTK widgets, but the
* most common usage is inside GtkImage and that's what we're going
* to do here.
*/
#include <gtk/gtk.h>
#include "puzzlepiece.h"
/* Declare the struct. */
struct _GtkPuzzlePiece
{
GObject parent_instance;
GdkPaintable *puzzle;
guint x;
guint y;
guint width;
guint height;
};
struct _GtkPuzzlePieceClass
{
GObjectClass parent_class;
};
/* This is the function that draws the puzzle piece.
* It just draws a rectangular cutout of the puzzle by clipping
* away the rest.
*/
static void
gtk_puzzle_piece_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_offset (snapshot,
- width * self->x,
- height * self->y);
gdk_paintable_snapshot (self->puzzle,
snapshot,
width * self->width,
height * self->height);
gtk_snapshot_pop (snapshot);
}
static GdkPaintableFlags
gtk_puzzle_piece_get_flags (GdkPaintable *paintable)
{
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
/* The flags are the same as the ones of the puzzle.
* If the puzzle changes in some way, so do the pieces.
*/
return gdk_paintable_get_flags (self->puzzle);
}
static int
gtk_puzzle_piece_get_intrinsic_width (GdkPaintable *paintable)
{
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
/* We can compute our width relative to the puzzle.
* This logic even works for the case where the puzzle
* has no width, because the 0 return value is unchanged.
* Round up the value.
*/
return (gdk_paintable_get_intrinsic_width (self->puzzle) + self->width - 1) / self->width;
}
static int
gtk_puzzle_piece_get_intrinsic_height (GdkPaintable *paintable)
{
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
/* Do the same thing we did for the width with the height.
*/
return (gdk_paintable_get_intrinsic_height (self->puzzle) + self->height - 1) / self->height;
}
static double
gtk_puzzle_piece_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
/* We can compute our aspect ratio relative to the puzzle.
* This logic again works for the case where the puzzle
* has no aspect ratio, because the 0 return value is unchanged.
*/
return gdk_paintable_get_intrinsic_aspect_ratio (self->puzzle) * self->height / self->width;
}
static void
gtk_puzzle_piece_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_puzzle_piece_snapshot;
iface->get_flags = gtk_puzzle_piece_get_flags;
iface->get_intrinsic_width = gtk_puzzle_piece_get_intrinsic_width;
iface->get_intrinsic_height = gtk_puzzle_piece_get_intrinsic_height;
iface->get_intrinsic_aspect_ratio = gtk_puzzle_piece_get_intrinsic_aspect_ratio;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkPuzzlePiece, gtk_puzzle_piece, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_puzzle_piece_paintable_init))
/* We need to declare a destructor to release our reference to the
* puzzle paintable and disconnect our signal handlers.
*/
static void
gtk_puzzle_piece_dispose (GObject *object)
{
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (object);
if (self->puzzle)
{
g_signal_handlers_disconnect_by_func (self->puzzle, gdk_paintable_invalidate_contents, self);
g_signal_handlers_disconnect_by_func (self->puzzle, gdk_paintable_invalidate_size, self);
g_clear_object (&self->puzzle);
}
G_OBJECT_CLASS (gtk_puzzle_piece_parent_class)->dispose (object);
}
/* Here's the boilerplate for the GObject declaration.
*/
static void
gtk_puzzle_piece_class_init (GtkPuzzlePieceClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gtk_puzzle_piece_dispose;
}
static void
gtk_puzzle_piece_init (GtkPuzzlePiece *self)
{
}
/* And finally, we add a constructor.
* It is declared in the header so that the other examples
* can use it.
*/
GdkPaintable *
gtk_puzzle_piece_new (GdkPaintable *puzzle,
guint x,
guint y,
guint width,
guint height)
{
GtkPuzzlePiece *self;
/* These are sanity checks, so that we get warnings if we accidentally
* do anything stupid. */
g_return_val_if_fail (GDK_IS_PAINTABLE (puzzle), NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
g_return_val_if_fail (x < width, NULL);
g_return_val_if_fail (y < height, NULL);
self = g_object_new (GTK_TYPE_PUZZLE_PIECE, NULL);
self->puzzle = g_object_ref (puzzle);
g_signal_connect_swapped (puzzle, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
g_signal_connect_swapped (puzzle, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
self->x = x;
self->y = y;
self->width = width;
self->height = height;
return GDK_PAINTABLE (self);
}
/* Here are the accessors that we need to inspect the puzzle
* pieces in other code.
*/
GdkPaintable *
gtk_puzzle_piece_get_puzzle (GtkPuzzlePiece *self)
{
/* Add sanity checks here, too.
* If you make a habit out of this, you can always rely
* on your code having sanity checks, which makes it
* way easier to debug.
*/
g_return_val_if_fail (GTK_IS_PUZZLE_PIECE (self), NULL);
return self->puzzle;
}
guint
gtk_puzzle_piece_get_x (GtkPuzzlePiece *self)
{
g_return_val_if_fail (GTK_IS_PUZZLE_PIECE (self), 0);
return self->x;
}
guint
gtk_puzzle_piece_get_y (GtkPuzzlePiece *self)
{
g_return_val_if_fail (GTK_IS_PUZZLE_PIECE (self), 0);
return self->y;
}

View File

@@ -1,23 +0,0 @@
#ifndef __PUZZLE_PIECE_H__
#define __PUZZLE_PIECE_H__
#include <gtk/gtk.h>
/* First, add the boilerplate for the object itself.
*/
#define GTK_TYPE_PUZZLE_PIECE (gtk_puzzle_piece_get_type ())
G_DECLARE_FINAL_TYPE (GtkPuzzlePiece, gtk_puzzle_piece, GTK, PUZZLE_PIECE, GObject)
/* Then, declare all constructors */
GdkPaintable * gtk_puzzle_piece_new (GdkPaintable *puzzle,
guint x,
guint y,
guint width,
guint height);
/* Next, add the getters and setters for object properties */
GdkPaintable * gtk_puzzle_piece_get_puzzle (GtkPuzzlePiece *self);
guint gtk_puzzle_piece_get_x (GtkPuzzlePiece *self);
guint gtk_puzzle_piece_get_y (GtkPuzzlePiece *self);
#endif /* __PUZZLE_PIECE_H__ */

View File

@@ -151,10 +151,11 @@ create_search_menu (GtkWidget *entry)
static void static void
icon_press_cb (GtkEntry *entry, icon_press_cb (GtkEntry *entry,
gint position, gint position,
GdkEventButton *event,
gpointer data) gpointer data)
{ {
if (position == GTK_ENTRY_ICON_PRIMARY) if (position == GTK_ENTRY_ICON_PRIMARY)
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL); gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *) event);
} }
static void static void

View File

@@ -26,6 +26,14 @@ changed_cb (GtkEditable *editable)
g_message ("changed: %s", text); g_message ("changed: %s", text);
} }
static gboolean
window_key_press_event_cb (GtkWidget *widget,
GdkEvent *event,
GtkSearchBar *bar)
{
return gtk_search_bar_handle_event (bar, event);
}
static void static void
search_changed (GtkSearchEntry *entry, search_changed (GtkSearchEntry *entry,
GtkLabel *label) GtkLabel *label)
@@ -91,7 +99,8 @@ do_search_entry2 (GtkWidget *do_widget)
gtk_box_pack_start (GTK_BOX (vbox), searchbar); gtk_box_pack_start (GTK_BOX (vbox), searchbar);
/* Hook the search bar to key presses */ /* Hook the search bar to key presses */
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (searchbar), window); g_signal_connect (window, "key-press-event",
G_CALLBACK (window_key_press_event_cb), searchbar);
/* Help */ /* Help */
label = gtk_label_new ("Start Typing to search"); label = gtk_label_new ("Start Typing to search");

View File

@@ -1,486 +0,0 @@
/* Sliding puzzle
*
* This demo demonstrates how to use gestures and paintables to create a
* small sliding puzzle game.
*
*/
#include <gtk/gtk.h>
/* Include the header for the puzzle piece */
#include "puzzlepiece.h"
#include "paintable.h"
static GtkWidget *window = NULL;
static GtkWidget *frame = NULL;
static GtkWidget *choices = NULL;
static GtkWidget *size_spin = NULL;
static GdkPaintable *puzzle = NULL;
static gboolean solved = TRUE;
static guint width = 3;
static guint height = 3;
static guint pos_x;
static guint pos_y;
static gboolean
move_puzzle (GtkWidget *grid,
int dx,
int dy)
{
GtkWidget *pos, *next;
GdkPaintable *piece;
guint next_x, next_y;
/* We don't move anything if the puzzle is solved */
if (solved)
return FALSE;
/* Return FALSE if we can't move to where the call
* wants us to move.
*/
if ((dx < 0 && pos_x < -dx) ||
dx + pos_x >= width ||
(dy < 0 && pos_y < -dy) ||
dy + pos_y >= height)
return FALSE;
/* Compute the new position */
next_x = pos_x + dx;
next_y = pos_y + dy;
/* Get the current and next image */
pos = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
next = gtk_grid_get_child_at (GTK_GRID (grid), next_x, next_y);
/* Move the displayed piece. */
piece = gtk_picture_get_paintable (GTK_PICTURE (next));
gtk_picture_set_paintable (GTK_PICTURE (pos), piece);
gtk_picture_set_paintable (GTK_PICTURE (next), NULL);
/* Update the current position */
pos_x = next_x;
pos_y = next_y;
/* Return TRUE because we successfully moved the piece */
return TRUE;
}
static void
shuffle_puzzle (GtkWidget *grid)
{
guint i, n_steps;
/* Do this many random moves */
n_steps = width * height * 50;
for (i = 0; i < n_steps; i++)
{
/* Get a random number for the direction to move in */
switch (g_random_int_range (0, 4))
{
case 0:
/* left */
move_puzzle (grid, -1, 0);
break;
case 1:
/* up */
move_puzzle (grid, 0, -1);
break;
case 2:
/* right */
move_puzzle (grid, 1, 0);
break;
case 3:
/* down */
move_puzzle (grid, 0, 1);
break;
default:
g_assert_not_reached ();
continue;
}
}
}
static gboolean
check_solved (GtkWidget *grid)
{
GtkWidget *picture;
GdkPaintable *piece;
guint x, y;
/* Nothing to check if the puzzle is already solved */
if (solved)
return TRUE;
/* If the empty cell isn't in the bottom right,
* the puzzle is obviously not solved */
if (pos_x != width - 1 ||
pos_y != height - 1)
return FALSE;
/* Check that all pieces are in the right position */
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
picture = gtk_grid_get_child_at (GTK_GRID (grid), x, y);
piece = gtk_picture_get_paintable (GTK_PICTURE (picture));
/* empty cell */
if (piece == NULL)
continue;
if (gtk_puzzle_piece_get_x (GTK_PUZZLE_PIECE (piece)) != x ||
gtk_puzzle_piece_get_y (GTK_PUZZLE_PIECE (piece)) != y)
return FALSE;
}
}
/* We solved the puzzle!
*/
solved = TRUE;
/* Fill the empty cell to show that we're done.
*/
picture = gtk_grid_get_child_at (GTK_GRID (grid), 0, 0);
piece = gtk_picture_get_paintable (GTK_PICTURE (picture));
piece = gtk_puzzle_piece_new (gtk_puzzle_piece_get_puzzle (GTK_PUZZLE_PIECE (piece)),
pos_x, pos_y,
width, height);
picture = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
gtk_picture_set_paintable (GTK_PICTURE (picture), piece);
return TRUE;
}
static gboolean
puzzle_key_pressed (GtkEventControllerKey *controller,
guint keyval,
guint keycode,
GdkModifierType state,
GtkWidget *grid)
{
int dx, dy;
dx = 0;
dy = 0;
switch (keyval)
{
case GDK_KEY_KP_Left:
case GDK_KEY_Left:
/* left */
dx = -1;
break;
case GDK_KEY_KP_Up:
case GDK_KEY_Up:
/* up */
dy = -1;
break;
case GDK_KEY_KP_Right:
case GDK_KEY_Right:
/* right */
dx = 1;
break;
case GDK_KEY_KP_Down:
case GDK_KEY_Down:
/* down */
dy = 1;
break;
default:
/* We return FALSE here because we didn't handle the key that was pressed */
return FALSE;
}
if (!move_puzzle (grid, dx, dy))
{
/* Make the error sound and then return TRUE.
* We handled this key, even though we didn't
* do anything to the puzzle.
*/
gtk_widget_error_bell (grid);
return TRUE;
}
check_solved (grid);
return TRUE;
}
static void
puzzle_button_pressed (GtkGestureMultiPress *gesture,
int n_press,
double x,
double y,
GtkWidget *grid)
{
GtkWidget *child;
int l, t, i;
int pos;
child = gtk_widget_pick (grid, x, y);
if (!child)
{
gtk_widget_error_bell (grid);
return;
}
gtk_container_child_get (GTK_CONTAINER (grid), child,
"left-attach", &l,
"top-attach", &t,
NULL);
if (l == pos_x && t == pos_y)
{
gtk_widget_error_bell (grid);
}
else if (l == pos_x)
{
pos = pos_y;
for (i = t; i < pos; i++)
{
if (!move_puzzle (grid, 0, -1))
gtk_widget_error_bell (grid);
}
for (i = pos; i < t; i++)
{
if (!move_puzzle (grid, 0, 1))
gtk_widget_error_bell (grid);
}
}
else if (t == pos_y)
{
pos = pos_x;
for (i = l; i < pos; i++)
{
if (!move_puzzle (grid, -1, 0))
gtk_widget_error_bell (grid);
}
for (i = pos; i < l; i++)
{
if (!move_puzzle (grid, 1, 0))
gtk_widget_error_bell (grid);
}
}
else
{
gtk_widget_error_bell (grid);
}
}
static void
start_puzzle (GdkPaintable *puzzle)
{
GtkWidget *picture, *grid;
GtkEventController *controller;
guint x, y;
/* Remove the old grid (if there is one) */
grid = gtk_bin_get_child (GTK_BIN (frame));
if (grid)
gtk_container_remove (GTK_CONTAINER (frame), grid);
/* Create a new grid */
grid = gtk_grid_new ();
gtk_widget_set_can_focus (grid, TRUE);
gtk_container_add (GTK_CONTAINER (frame), grid);
gtk_aspect_frame_set (GTK_ASPECT_FRAME (frame), 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
/* Add a key event controller so people can use the arrow
* keys to move the puzzle */
controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed",
G_CALLBACK (puzzle_key_pressed),
grid);
gtk_widget_add_controller (GTK_WIDGET (grid), controller);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
g_signal_connect (controller, "pressed",
G_CALLBACK (puzzle_button_pressed),
grid);
gtk_widget_add_controller (GTK_WIDGET (grid), controller);
/* Make sure the cells have equal size */
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
/* Reset the variables */
solved = FALSE;
pos_x = width - 1;
pos_y = height - 1;
/* add a picture for every cell */
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
GdkPaintable *piece;
/* Don't paint anything for the lsiding part of the video */
if (x == pos_x && y == pos_y)
piece = NULL;
else
piece = gtk_puzzle_piece_new (puzzle,
x, y,
width, height);
picture = gtk_picture_new_for_paintable (piece);
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
gtk_grid_attach (GTK_GRID (grid),
picture,
x, y,
1, 1);
}
}
shuffle_puzzle (grid);
}
static void
reshuffle (void)
{
GtkWidget *grid;
grid = gtk_bin_get_child (GTK_BIN (frame));
if (solved)
start_puzzle (puzzle);
else
shuffle_puzzle (grid);
gtk_widget_grab_focus (grid);
}
static void
reconfigure (void)
{
GtkWidget *popover;
GtkWidget *grid;
GtkWidget *child;
GtkWidget *image;
GList *selected;
width = height = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (size_spin));
selected = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (choices));
if (selected == NULL)
child = gtk_widget_get_first_child (choices);
else
{
child = selected->data;
g_list_free (selected);
}
image = gtk_bin_get_child (GTK_BIN (child));
puzzle = gtk_image_get_paintable (GTK_IMAGE (image));
start_puzzle (puzzle);
popover = gtk_widget_get_ancestor (size_spin, GTK_TYPE_POPOVER);
gtk_popover_popdown (GTK_POPOVER (popover));
grid = gtk_bin_get_child (GTK_BIN (frame));
gtk_widget_grab_focus (grid);
}
static void
add_choice (GtkWidget *choices,
GdkPaintable *paintable)
{
GtkWidget *icon;
icon = gtk_image_new_from_paintable (paintable);
gtk_image_set_icon_size (GTK_IMAGE (icon), GTK_ICON_SIZE_LARGE);
gtk_container_add (GTK_CONTAINER (choices), icon);
}
GtkWidget *
do_sliding_puzzle (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *header;
GtkWidget *restart;
GtkWidget *tweak;
GtkWidget *popover;
GtkWidget *tweaks;
GtkWidget *apply;
GtkWidget *label;
GtkWidget *sw;
GtkMediaStream *media;
puzzle = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
tweaks = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (tweaks), 10);
gtk_grid_set_column_spacing (GTK_GRID (tweaks), 10);
g_object_set (tweaks, "margin", 10, NULL);
choices = gtk_flow_box_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (choices), GTK_STYLE_CLASS_VIEW);
add_choice (choices, puzzle);
add_choice (choices, gtk_nuclear_animation_new ());
media = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
gtk_media_stream_set_loop (media, TRUE);
gtk_media_stream_set_muted (media, TRUE);
gtk_media_stream_play (media);
add_choice (choices, GDK_PAINTABLE (media));
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (sw), choices);
gtk_grid_attach (GTK_GRID (tweaks), sw, 0, 0, 2, 1);
label = gtk_label_new ("Size");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_grid_attach (GTK_GRID (tweaks), label, 0, 1, 1, 1);
size_spin = gtk_spin_button_new_with_range (2, 10, 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (size_spin), width);
gtk_grid_attach (GTK_GRID (tweaks), size_spin, 1, 1, 1, 1);
apply = gtk_button_new_with_label ("Apply");
gtk_widget_set_halign (apply, GTK_ALIGN_END);
gtk_grid_attach (GTK_GRID (tweaks), apply, 1, 2, 1, 1);
g_signal_connect (apply, "clicked", G_CALLBACK (reconfigure), NULL);
popover = gtk_popover_new (NULL);
gtk_popover_set_modal (GTK_POPOVER (popover), TRUE);
gtk_container_add (GTK_CONTAINER (popover), tweaks);
tweak = gtk_menu_button_new ();
gtk_menu_button_set_popover (GTK_MENU_BUTTON (tweak), popover);
gtk_button_set_icon_name (GTK_BUTTON (tweak), "emblem-system-symbolic");
restart = gtk_button_new_from_icon_name ("view-refresh-symbolic");
g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Sliding Puzzle");
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
gtk_container_add (GTK_CONTAINER (window), frame);
start_puzzle (puzzle);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -33,14 +33,14 @@ hex_spin_output (GtkSpinButton *spin_button)
{ {
GtkAdjustment *adjustment; GtkAdjustment *adjustment;
gchar *buf; gchar *buf;
gdouble val; gint val;
adjustment = gtk_spin_button_get_adjustment (spin_button); adjustment = gtk_spin_button_get_adjustment (spin_button);
val = gtk_adjustment_get_value (adjustment); val = (gint) gtk_adjustment_get_value (adjustment);
if (fabs (val) < 1e-5) if (fabs (val) < 1e-5)
buf = g_strdup ("0x00"); buf = g_strdup ("0x00");
else else
buf = g_strdup_printf ("0x%.2X", (gint) val); buf = g_strdup_printf ("0x%.2X", val);
if (strcmp (buf, gtk_spin_button_get_text (spin_button))) if (strcmp (buf, gtk_spin_button_get_text (spin_button)))
gtk_spin_button_set_text (spin_button, buf); gtk_spin_button_set_text (spin_button, buf);
g_free (buf); g_free (buf);

412
demos/gtk-demo/widgetbowl.c Normal file
View File

@@ -0,0 +1,412 @@
/* Benchmark/Widgetbowl
*
* This is a version of the Fishbowl demo that instead shows different
* kinds of widgets, which is useful for comparing the rendering performance
* of theme specifics.
*/
#include <gtk/gtk.h>
#include "gtkfishbowl.h"
#include "gtkgears.h"
const char *const css =
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
"}"
"";
GtkWidget *fishbowl;
static GtkWidget *
create_button (void)
{
return gtk_button_new_with_label ("Button");
}
static GtkWidget *
create_blurred_button (void)
{
GtkWidget *w = gtk_button_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (w), "blurred-button");
return w;
}
static GtkWidget *
create_font_button (void)
{
return gtk_font_button_new ();
}
static GtkWidget *
create_level_bar (void)
{
GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
/* Force them to be a bit larger */
gtk_widget_set_size_request (w, 200, -1);
return w;
}
static GtkWidget *
create_spinner (void)
{
GtkWidget *w = gtk_spinner_new ();
gtk_spinner_start (GTK_SPINNER (w));
return w;
}
static GtkWidget *
create_spinbutton (void)
{
GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
return w;
}
static GtkWidget *
create_label (void)
{
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
return w;
}
static GtkWidget *
create_video (void)
{
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
GtkWidget *w = gtk_image_new_from_paintable (GDK_PAINTABLE (stream));
gtk_media_stream_set_loop (stream, TRUE);
gtk_media_stream_play (stream);
g_object_unref (stream);
return w;
}
static GtkWidget *
create_gears (void)
{
GtkWidget *w = gtk_gears_new ();
gtk_widget_set_size_request (w, 100, 100);
return w;
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
} widget_types[] = {
{ "Button", create_button },
{ "Blurbutton", create_blurred_button },
{ "Fontbutton", create_font_button },
{ "Levelbar" , create_level_bar },
{ "Label" , create_label },
{ "Spinner" , create_spinner },
{ "Spinbutton", create_spinbutton },
{ "Video", create_video },
{ "Gears", create_gears },
};
static int selected_widget_type = -1;
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
#define N_STATS 5
#define STATS_UPDATE_TIME G_USEC_PER_SEC
static void
set_widget_type (GtkWidget *headerbar,
int widget_type_index)
{
GList *children, *l;
if (widget_type_index == selected_widget_type)
return;
/* Remove everything */
children = gtk_container_get_children (GTK_CONTAINER (fishbowl));
for (l = children; l; l = l->next)
{
gtk_container_remove (GTK_CONTAINER (fishbowl), (GtkWidget*)l->data);
}
g_list_free (children);
selected_widget_type = widget_type_index;
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
widget_types[selected_widget_type].name);
}
typedef struct _Stats Stats;
struct _Stats {
gint64 last_stats;
gint64 last_frame;
gint last_suggestion;
guint frame_counter_max;
guint stats_index;
guint frame_counter[N_STATS];
guint item_counter[N_STATS];
};
static Stats *
get_stats (GtkWidget *widget)
{
static GQuark stats_quark = 0;
Stats *stats;
if (G_UNLIKELY (stats_quark == 0))
stats_quark = g_quark_from_static_string ("stats");
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
if (stats == NULL)
{
stats = g_new0 (Stats, 1);
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
stats->last_stats = stats->last_frame;
}
return stats;
}
static void
do_stats (GtkWidget *widget,
GtkWidget *info_label,
gint *suggested_change)
{
Stats *stats;
gint64 frame_time;
stats = get_stats (widget);
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
{
char *new_label;
guint i, n_frames;
n_frames = 0;
for (i = 0; i < N_STATS; i++)
{
n_frames += stats->frame_counter[i];
}
new_label = g_strdup_printf ("widgets - %.1f fps",
(double) G_USEC_PER_SEC * n_frames
/ (N_STATS * STATS_UPDATE_TIME));
gtk_label_set_label (GTK_LABEL (info_label), new_label);
g_free (new_label);
if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
{
if (stats->last_suggestion > 0)
stats->last_suggestion *= 2;
else
stats->last_suggestion = 1;
}
else
{
if (stats->last_suggestion < 0)
stats->last_suggestion--;
else
stats->last_suggestion = -1;
stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) stats->item_counter[stats->stats_index]);
}
stats->stats_index = (stats->stats_index + 1) % N_STATS;
stats->frame_counter[stats->stats_index] = 0;
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
stats->last_stats = frame_time;
if (suggested_change)
*suggested_change = stats->last_suggestion;
else
stats->last_suggestion = 0;
}
else
{
if (suggested_change)
*suggested_change = 0;
}
stats->last_frame = frame_time;
stats->frame_counter[stats->stats_index]++;
stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
}
static void
stats_update (GtkWidget *widget)
{
Stats *stats;
stats = get_stats (widget);
stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
}
static gboolean
move_fish (GtkWidget *bowl,
GdkFrameClock *frame_clock,
gpointer info_label)
{
gint suggested_change = 0;
do_stats (bowl, info_label, &suggested_change);
if (suggested_change > 0)
{
int i;
for (i = 0; i < suggested_change; i ++)
{
GtkWidget *new_widget = widget_types[selected_widget_type].create_func ();
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
}
}
else if (suggested_change < 0)
{
GList *children, *l;
int n_removed = 0;
children = gtk_container_get_children (GTK_CONTAINER (fishbowl));
for (l = children; l; l = l->next)
{
gtk_container_remove (GTK_CONTAINER (fishbowl), (GtkWidget *)l->data);
n_removed ++;
if (n_removed >= (-suggested_change))
break;
}
g_list_free (children);
}
stats_update (bowl);
return G_SOURCE_CONTINUE;
}
static void
next_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkWidget *headerbar = user_data;
int new_index;
if (selected_widget_type + 1 >= N_WIDGET_TYPES)
new_index = 0;
else
new_index = selected_widget_type + 1;
set_widget_type (headerbar, new_index);
}
static void
prev_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkWidget *headerbar = user_data;
int new_index;
if (selected_widget_type - 1 < 0)
new_index = N_WIDGET_TYPES - 1;
else
new_index = selected_widget_type - 1;
set_widget_type (headerbar, new_index);
}
GtkWidget *
do_widgetbowl (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
static GtkCssProvider *provider = NULL;
gtk_init ();
if (provider == NULL)
{
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
if (!window)
{
GtkWidget *info_label;
GtkWidget *count_label;
GtkWidget *titlebar;
GtkWidget *title_box;
GtkWidget *left_box;
GtkWidget *next_button;
GtkWidget *prev_button;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
titlebar = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (titlebar), TRUE);
info_label = gtk_label_new ("widget - 00.0 fps");
count_label = gtk_label_new ("0");
fishbowl = gtk_fishbowl_new ();
title_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
prev_button = gtk_button_new_from_icon_name ("pan-start-symbolic");
next_button = gtk_button_new_from_icon_name ("pan-end-symbolic");
left_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_bind_property (fishbowl, "count", count_label, "label", 0);
g_signal_connect (next_button, "clicked", G_CALLBACK (next_button_clicked_cb), titlebar);
g_signal_connect (prev_button, "clicked", G_CALLBACK (prev_button_clicked_cb), titlebar);
gtk_fishbowl_set_animating (GTK_FISHBOWL (fishbowl), TRUE);
gtk_widget_set_hexpand (title_box, TRUE);
gtk_widget_set_halign (title_box, GTK_ALIGN_END);
gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
gtk_container_add (GTK_CONTAINER (title_box), count_label);
gtk_container_add (GTK_CONTAINER (title_box), info_label);
gtk_header_bar_pack_end (GTK_HEADER_BAR (titlebar), title_box);
gtk_container_add (GTK_CONTAINER (window), fishbowl);
gtk_style_context_add_class (gtk_widget_get_style_context (left_box), "linked");
gtk_container_add (GTK_CONTAINER (left_box), prev_button);
gtk_container_add (GTK_CONTAINER (left_box), next_button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), left_box);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window);
gtk_widget_add_tick_callback (fishbowl, move_fish, info_label, NULL);
set_widget_type (titlebar, 0);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@@ -32,7 +32,7 @@ media-view-subtitles=The icon used to show subtitles in a media player
[network] [network]
Name=Network Name=Network
Description=Icons related to network status Description=Icons related to network status");
network-transmit-receive=The icon used data is being both transmitted and received simultaneously, while the computing device is connected to a network network-transmit-receive=The icon used data is being both transmitted and received simultaneously, while the computing device is connected to a network
network-transmit=The icon used when data is being transmitted, while the computing device is connected to a network network-transmit=The icon used when data is being transmitted, while the computing device is connected to a network

View File

@@ -286,16 +286,13 @@ populate (IconBrowserWindow *win)
} }
static gboolean static gboolean
key_event_cb (GtkEventController *controller, key_press_event_cb (GtkWidget *widget,
guint keyval, GdkEvent *event,
guint keycode,
GdkModifierType state,
gpointer data) gpointer data)
{ {
IconBrowserWindow *win = data; IconBrowserWindow *win = data;
return gtk_search_bar_handle_event (GTK_SEARCH_BAR (win->searchbar), return gtk_search_bar_handle_event (GTK_SEARCH_BAR (win->searchbar), event);
gtk_get_current_event ());
} }
static void static void
@@ -376,9 +373,10 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
static void static void
get_image_data (GtkWidget *widget, get_image_data (GtkWidget *widget,
GdkDrag *drag, GdkDragContext *context,
GtkSelectionData *selection, GtkSelectionData *selection,
guint target_info, guint target_info,
guint time,
gpointer data) gpointer data)
{ {
GtkWidget *image; GtkWidget *image;
@@ -398,9 +396,10 @@ get_image_data (GtkWidget *widget,
static void static void
get_scalable_image_data (GtkWidget *widget, get_scalable_image_data (GtkWidget *widget,
GdkDrag *drag, GdkDragContext *context,
GtkSelectionData *selection, GtkSelectionData *selection,
guint target_info, guint target_info,
guint time,
gpointer data) gpointer data)
{ {
gchar *uris[2]; gchar *uris[2];
@@ -452,7 +451,6 @@ static void
icon_browser_window_init (IconBrowserWindow *win) icon_browser_window_init (IconBrowserWindow *win)
{ {
GdkContentFormats *list; GdkContentFormats *list;
GtkEventController *controller;
gtk_widget_init_template (GTK_WIDGET (win)); gtk_widget_init_template (GTK_WIDGET (win));
@@ -482,30 +480,12 @@ icon_browser_window_init (IconBrowserWindow *win)
symbolic_toggled (GTK_TOGGLE_BUTTON (win->symbolic_radio), win); symbolic_toggled (GTK_TOGGLE_BUTTON (win->symbolic_radio), win);
controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_event_cb), win);
gtk_widget_add_controller (GTK_WIDGET (win), controller);
populate (win); populate (win);
} }
static void
icon_browser_window_finalize (GObject *object)
{
IconBrowserWindow *win = ICON_BROWSER_WINDOW (object);
g_hash_table_unref (win->contexts);
G_OBJECT_CLASS (icon_browser_window_parent_class)->finalize (object);
}
static void static void
icon_browser_window_class_init (IconBrowserWindowClass *class) icon_browser_window_class_init (IconBrowserWindowClass *class)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = icon_browser_window_finalize;
g_type_ensure (ICON_STORE_TYPE); g_type_ensure (ICON_STORE_TYPE);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
@@ -536,6 +516,7 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), selected_context_changed); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), selected_context_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), key_press_event_cb);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
} }

View File

@@ -14,7 +14,6 @@ executable('gtk4-icon-browser',
dependencies: libgtk_dep, dependencies: libgtk_dep,
include_directories: confinc, include_directories: confinc,
gui_app: true, gui_app: true,
link_args: extra_demo_ldflags,
install: true) install: true)
install_data('org.gtk.IconBrowser.desktop', install_dir: gtk_applicationsdir) install_data('gtk4-icon-browser.desktop', install_dir: gtk_applicationsdir)

View File

@@ -9,6 +9,7 @@
<property name="title" translatable="yes">Icon Browser</property> <property name="title" translatable="yes">Icon Browser</property>
<property name="default-width">1024</property> <property name="default-width">1024</property>
<property name="default-height">768</property> <property name="default-height">768</property>
<signal name="key-press-event" handler="key_press_event_cb"/>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="title" translatable="yes">Icon Browser</property> <property name="title" translatable="yes">Icon Browser</property>

View File

@@ -9,11 +9,10 @@ executable('gtk4-widget-factory',
dependencies: libgtk_dep, dependencies: libgtk_dep,
include_directories: confinc, include_directories: confinc,
gui_app: true, gui_app: true,
link_args: extra_demo_ldflags,
install: true) install: true)
# desktop file # desktop file
install_data('org.gtk.WidgetFactory.desktop', install_dir: gtk_applicationsdir) install_data('gtk4-widget-factory.desktop', install_dir: gtk_applicationsdir)
# icons # icons
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor') icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')

View File

@@ -353,6 +353,7 @@ update_pulse_time (GtkAdjustment *adjustment, GtkWidget *widget)
static void static void
on_entry_icon_release (GtkEntry *entry, on_entry_icon_release (GtkEntry *entry,
GtkEntryIconPosition icon_pos, GtkEntryIconPosition icon_pos,
GdkEvent *event,
gpointer user_data) gpointer user_data)
{ {
if (icon_pos != GTK_ENTRY_ICON_SECONDARY) if (icon_pos != GTK_ENTRY_ICON_SECONDARY)
@@ -966,8 +967,8 @@ background_loaded_cb (GObject *source,
return; return;
} }
child = gtk_picture_new_for_pixbuf (pixbuf); child = gtk_image_new_from_pixbuf (pixbuf);
gtk_widget_set_size_request (child, 110, 70); gtk_widget_show (child);
gtk_flow_box_insert (GTK_FLOW_BOX (bd->flowbox), child, -1); gtk_flow_box_insert (GTK_FLOW_BOX (bd->flowbox), child, -1);
child = gtk_widget_get_parent (child); child = gtk_widget_get_parent (child);
g_object_set_data_full (G_OBJECT (child), "filename", bd->filename, g_free); g_object_set_data_full (G_OBJECT (child), "filename", bd->filename, g_free);
@@ -995,7 +996,8 @@ populate_flowbox (GtkWidget *flowbox)
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
gdk_pixbuf_fill (pixbuf, 0xffffffff); gdk_pixbuf_fill (pixbuf, 0xffffffff);
child = gtk_picture_new_for_pixbuf (pixbuf); child = gtk_image_new_from_pixbuf (pixbuf);
gtk_widget_show (child);
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1); gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
location = "/usr/share/backgrounds/gnome"; location = "/usr/share/backgrounds/gnome";
@@ -1080,7 +1082,7 @@ set_accel (GtkApplication *app, GtkWidget *widget)
typedef struct typedef struct
{ {
GtkTextView tv; GtkTextView tv;
GdkTexture *texture; cairo_surface_t *surface;
} MyTextView; } MyTextView;
typedef GtkTextViewClass MyTextViewClass; typedef GtkTextViewClass MyTextViewClass;
@@ -1093,23 +1095,18 @@ my_text_view_init (MyTextView *tv)
} }
static void static void
my_tv_snapshot_layer (GtkTextView *widget, my_tv_draw_layer (GtkTextView *widget,
GtkTextViewLayer layer, GtkTextViewLayer layer,
GtkSnapshot *snapshot) cairo_t *cr)
{ {
MyTextView *tv = (MyTextView *)widget; MyTextView *tv = (MyTextView *)widget;
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->texture) if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->surface)
{ {
gtk_snapshot_push_opacity (snapshot, 0.333); cairo_save (cr);
gtk_snapshot_append_texture (snapshot, cairo_set_source_surface (cr, tv->surface, 0.0, 0.0);
tv->texture, cairo_paint_with_alpha (cr, 0.333);
&GRAPHENE_RECT_INIT( cairo_restore (cr);
0, 0,
gdk_texture_get_width (tv->texture),
gdk_texture_get_height (tv->texture)
));
gtk_snapshot_pop (snapshot);
} }
} }
@@ -1118,7 +1115,8 @@ my_tv_finalize (GObject *object)
{ {
MyTextView *tv = (MyTextView *)object; MyTextView *tv = (MyTextView *)object;
g_clear_object (&tv->texture); if (tv->surface)
cairo_surface_destroy (tv->surface);
G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object); G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object);
} }
@@ -1130,24 +1128,24 @@ my_text_view_class_init (MyTextViewClass *class)
GObjectClass *o_class = G_OBJECT_CLASS (class); GObjectClass *o_class = G_OBJECT_CLASS (class);
o_class->finalize = my_tv_finalize; o_class->finalize = my_tv_finalize;
tv_class->snapshot_layer = my_tv_snapshot_layer; tv_class->draw_layer = my_tv_draw_layer;
} }
static void static void
my_text_view_set_background (MyTextView *tv, const gchar *filename) my_text_view_set_background (MyTextView *tv, const gchar *filename)
{ {
GdkPixbuf *pixbuf;
GError *error = NULL; GError *error = NULL;
GFile *file;
g_clear_object (&tv->texture); if (tv->surface)
cairo_surface_destroy (tv->surface);
tv->surface = NULL;
if (filename == NULL) if (filename == NULL)
return; return;
file = g_file_new_for_path (filename); pixbuf = gdk_pixbuf_new_from_file (filename, &error);
tv->texture = gdk_texture_new_from_file (file, &error);
g_object_unref (file);
if (error) if (error)
{ {
g_warning ("%s", error->message); g_warning ("%s", error->message);
@@ -1155,6 +1153,10 @@ my_text_view_set_background (MyTextView *tv, const gchar *filename)
return; return;
} }
tv->surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
g_object_unref (pixbuf);
gtk_widget_queue_draw (GTK_WIDGET (tv)); gtk_widget_queue_draw (GTK_WIDGET (tv));
} }
@@ -1653,6 +1655,7 @@ activate (GApplication *app)
gint i; gint i;
GPermission *permission; GPermission *permission;
GAction *action; GAction *action;
GtkGesture *gesture;
g_type_ensure (my_text_view_get_type ()); g_type_ensure (my_text_view_get_type ());
@@ -1677,7 +1680,6 @@ activate (GApplication *app)
gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size); gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size);
gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value); gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value);
gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank); gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank);
gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed);
gtk_builder_connect_signals (builder, NULL); gtk_builder_connect_signals (builder, NULL);
@@ -1895,6 +1897,10 @@ activate (GApplication *app)
g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget); g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget);
g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget2); g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget2);
widget = (GtkWidget *)gtk_builder_get_object (builder, "osd_frame");
gesture = gtk_gesture_multi_press_new (widget);
g_signal_connect (gesture, "pressed", G_CALLBACK (osd_frame_pressed), widget);
gtk_widget_show (GTK_WIDGET (window)); gtk_widget_show (GTK_WIDGET (window));
g_object_unref (builder); g_object_unref (builder);

View File

@@ -468,8 +468,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<child> <child>
<object class="GtkEntry" id="entry1"> <object class="GtkEntry" id="entry1">
<property name="can-focus">1</property> <property name="can-focus">1</property>
<property name="enable-emoji-completion">1</property> <property name="invisible-char"></property>
<property name="invisible_char">•</property>
<property name="placeholder-text" translatable="yes">Click icon to change mode</property> <property name="placeholder-text" translatable="yes">Click icon to change mode</property>
<property name="secondary-icon-name">view-refresh-symbolic</property> <property name="secondary-icon-name">view-refresh-symbolic</property>
<property name="secondary-icon-tooltip-text">Change mode</property> <property name="secondary-icon-tooltip-text">Change mode</property>
@@ -879,7 +878,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<object class="GtkFontButton" id="fontbutton1"> <object class="GtkFontButton" id="fontbutton1">
<property name="can-focus">1</property> <property name="can-focus">1</property>
<property name="receives-default">1</property> <property name="receives-default">1</property>
<property name="level">family|style|size|features|variations</property>
</object> </object>
<packing> <packing>
<property name="position">6</property> <property name="position">6</property>
@@ -2226,9 +2224,6 @@ microphone-sensitivity-medium-symbolic</property>
<property name="tooltip-text" translatable="yes">Save the current document</property> <property name="tooltip-text" translatable="yes">Save the current document</property>
</object> </object>
</child> </child>
<child>
<object class="GtkSeparatorToolItem"/>
</child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="label" translatable="yes">Search</property> <property name="label" translatable="yes">Search</property>
@@ -3104,11 +3099,6 @@ microphone-sensitivity-medium-symbolic</property>
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkGestureMultiPress">
<signal name="pressed" handler="osd_frame_pressed" object="osd_frame" swapped="no"/>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -1,68 +0,0 @@
# These are the people responsible for subsystems in GTK; if you're opening
# a merge request for files listed here, please add the following people to
# the list of reviewers
# The syntax of this file is similar to the GitHub CODEOWNERS file:
# https://help.github.com/articles/about-codeowners/
# Which, in turn, is similar to the .gitignore and .gitattributes files:
#
# - comments start with `#`
# - the first column contains paths and globs
# - the second column contains GitLab user names or email addresses,
# separated by spaces
#
# If you want to be responsible for code reviews in specific sections of
# the GTK code base, add yourself here.
# Maintainer
* @matthiasc
# Build system
meson.build @ebassi @nirbheek
*.py @ebassi
# CSS
gtk/gtkcss*.[ch] @otte @baedert
gtk/gtkstyle*.[ch] @otte @baedert
# Gestures
gtk/gtkeventcontroller* @carlosg
gtk/gtkgesture*.[ch] @carlosg
# GtkFileChooser
gtk/gtkfilechooser* @federico
gtk/gtkfilesystem* @federico
gtk/gtkfilefilter* @federico
# GtkFontChooser
gtk/gtkfontchooser* @matthiasc
# Input methods
gtk/gtkimcontext* @carlosg
# Media
gtk/gtkmedia* @otte
# GSK
gsk @otte @baedert @ebassi
# GL rendering
gsk/gl @baedert @ebassi
# Vulkan rendering
gsk/vulkan
# Documentation
docs/ @ebassi @dboles
# Wayland
gdk/wayland @jadahl
# X11
gdk/x11 @ofourdan @matthiasc
# Themes
gtk/themes @lapoc @jimmac
# Inspector
gtk/inspector @otte @matthiasc

View File

@@ -71,7 +71,10 @@ straightforward manner.
void gdk_drag_status (GdkDragContext *context, void gdk_drag_status (GdkDragContext *context,
GdkDragAction action, GdkDragAction action,
guint32 time); guint32 time);
void gdk_drag_finish (GdkDragContext *context, void gdk_drop_reply (GdkDragContext *context,
gboolean ok,
guint32 time);
void gdk_drop_finish (GdkDragContext *context,
gboolean success, gboolean success,
guint32 time); guint32 time);
GdkAtom gdk_drag_get_selection (GdkDragContext *context); GdkAtom gdk_drag_get_selection (GdkDragContext *context);

View File

@@ -27,12 +27,12 @@
<xi:include href="xml/gdkmonitor.xml" /> <xi:include href="xml/gdkmonitor.xml" />
<xi:include href="xml/regions.xml" /> <xi:include href="xml/regions.xml" />
<xi:include href="xml/textures.xml" /> <xi:include href="xml/textures.xml" />
<xi:include href="xml/gdkpaintable.xml" />
<xi:include href="xml/rgba_colors.xml" /> <xi:include href="xml/rgba_colors.xml" />
<xi:include href="xml/cursors.xml" /> <xi:include href="xml/cursors.xml" />
<xi:include href="xml/gdksurface.xml" /> <xi:include href="xml/windows.xml" />
<xi:include href="xml/gdkframeclock.xml" /> <xi:include href="xml/gdkframeclock.xml" />
<xi:include href="xml/gdkframetimings.xml" /> <xi:include href="xml/gdkframetimings.xml" />
<xi:include href="xml/gdkdrawingcontext.xml" />
<xi:include href="xml/gdkdrawcontext.xml" /> <xi:include href="xml/gdkdrawcontext.xml" />
<xi:include href="xml/gdkglcontext.xml" /> <xi:include href="xml/gdkglcontext.xml" />
<xi:include href="xml/gdkvulkancontext.xml" /> <xi:include href="xml/gdkvulkancontext.xml" />

View File

@@ -167,10 +167,11 @@ gdk_rgba_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>
<TITLE>GdkSurface</TITLE> <TITLE>Windows</TITLE>
<FILE>gdksurface</FILE> <FILE>windows</FILE>
GdkSurface GdkSurface
GdkSurfaceType GdkSurfaceType
GdkSurfaceClass
GdkSurfaceHints GdkSurfaceHints
GdkGeometry GdkGeometry
GdkGravity GdkGravity
@@ -193,6 +194,7 @@ gdk_surface_is_visible
gdk_surface_is_viewable gdk_surface_is_viewable
gdk_surface_is_input_only gdk_surface_is_input_only
gdk_surface_get_state gdk_surface_get_state
gdk_surface_withdraw
gdk_surface_iconify gdk_surface_iconify
gdk_surface_deiconify gdk_surface_deiconify
gdk_surface_stick gdk_surface_stick
@@ -231,10 +233,13 @@ gdk_surface_set_opaque_region
gdk_surface_create_gl_context gdk_surface_create_gl_context
gdk_surface_create_vulkan_context gdk_surface_create_vulkan_context
<SUBSECTION>
gdk_surface_begin_draw_frame
gdk_surface_end_draw_frame
<SUBSECTION> <SUBSECTION>
gdk_surface_invalidate_rect gdk_surface_invalidate_rect
gdk_surface_invalidate_region gdk_surface_invalidate_region
gdk_surface_queue_expose
gdk_surface_freeze_updates gdk_surface_freeze_updates
gdk_surface_thaw_updates gdk_surface_thaw_updates
gdk_surface_get_frame_clock gdk_surface_get_frame_clock
@@ -280,6 +285,8 @@ gdk_surface_get_toplevel
gdk_surface_get_children gdk_surface_get_children
gdk_surface_get_children_with_user_data gdk_surface_get_children_with_user_data
gdk_surface_peek_children gdk_surface_peek_children
gdk_surface_get_events
gdk_surface_set_events
gdk_surface_set_icon_name gdk_surface_set_icon_name
gdk_surface_set_transient_for gdk_surface_set_transient_for
gdk_surface_set_role gdk_surface_set_role
@@ -297,6 +304,8 @@ gdk_surface_get_support_multidevice
gdk_surface_set_support_multidevice gdk_surface_set_support_multidevice
gdk_surface_get_device_cursor gdk_surface_get_device_cursor
gdk_surface_set_device_cursor gdk_surface_set_device_cursor
gdk_surface_get_device_events
gdk_surface_set_device_events
<SUBSECTION> <SUBSECTION>
gdk_surface_coords_from_parent gdk_surface_coords_from_parent
@@ -398,12 +407,15 @@ gdk_pango_layout_line_get_clip_region
<TITLE>Cairo Interaction</TITLE> <TITLE>Cairo Interaction</TITLE>
<FILE>cairo_interaction</FILE> <FILE>cairo_interaction</FILE>
gdk_surface_create_similar_surface gdk_surface_create_similar_surface
gdk_surface_create_similar_image_surface
gdk_cairo_get_clip_rectangle gdk_cairo_get_clip_rectangle
gdk_cairo_get_drawing_context
gdk_cairo_set_source_rgba gdk_cairo_set_source_rgba
gdk_cairo_set_source_pixbuf gdk_cairo_set_source_pixbuf
gdk_cairo_rectangle gdk_cairo_rectangle
gdk_cairo_region gdk_cairo_region
gdk_cairo_region_create_from_surface gdk_cairo_region_create_from_surface
gdk_cairo_surface_create_from_pixbuf
gdk_cairo_draw_from_gl gdk_cairo_draw_from_gl
gdk_cairo_surface_upload_to_gl gdk_cairo_surface_upload_to_gl
</SECTION> </SECTION>
@@ -621,6 +633,7 @@ GDK_BUTTON_SECONDARY
<SUBSECTION> <SUBSECTION>
gdk_event_new gdk_event_new
gdk_event_copy gdk_event_copy
gdk_event_free
gdk_event_get_axes gdk_event_get_axes
gdk_event_get_button gdk_event_get_button
gdk_event_get_click_count gdk_event_get_click_count
@@ -646,15 +659,16 @@ gdk_event_get_scancode
gdk_event_get_pointer_emulated gdk_event_get_pointer_emulated
gdk_event_get_crossing_detail gdk_event_get_crossing_detail
gdk_event_get_crossing_mode gdk_event_get_crossing_mode
gdk_event_get_drop gdk_event_get_drag_context
gdk_event_get_focus_in gdk_event_get_focus_in
gdk_event_get_grab_surface gdk_event_get_grab_window
gdk_event_get_motion_history gdk_event_get_motion_history
gdk_event_get_key_group gdk_event_get_key_group
gdk_event_get_key_is_modifier gdk_event_get_key_is_modifier
gdk_event_get_pad_axis_value gdk_event_get_pad_axis_value
gdk_event_get_pad_button gdk_event_get_pad_button
gdk_event_get_pad_group_mode gdk_event_get_pad_group_mode
gdk_event_get_string
gdk_event_get_touch_emulating_pointer gdk_event_get_touch_emulating_pointer
gdk_event_get_touchpad_angle_delta gdk_event_get_touchpad_angle_delta
gdk_event_get_touchpad_deltas gdk_event_get_touchpad_deltas
@@ -690,27 +704,19 @@ gdk_event_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>gdkpaintable</FILE> <TITLE>Paintable</TITLE>
<TITLE>GdkPaintable</TITLE> <FILE>paintable</FILE>
GdkPaintable GdkPaintable
GdkPaintableFlags
gdk_paintable_get_current_image
gdk_paintable_snapshot gdk_paintable_snapshot
gdk_paintable_get_current_image
gdk_paintable_get_flags gdk_paintable_get_flags
gdk_paintable_get_intrinsic_width gdk_paintable_get_intrinsic_width
gdk_paintable_get_intrinsic_height gdk_paintable_get_intrinsic_height
gdk_paintable_get_intrinsic_aspect_ratio gdk_paintable_get_intrinsic_aspect_ratio
gdk_paintable_compute_concrete_size gdk_paintable_compute_concrete_size
<SUBSECTION>
gdk_paintable_invalidate_contents gdk_paintable_invalidate_contents
gdk_paintable_invalidate_size gdk_paintable_invalidate_size
gdk_paintable_new_empty <SECTION>
<SUBSECTION Private>
GDK_TYPE_PAINTABLE
gdk_paintable_get_type
</SECTION>
<SECTION> <SECTION>
<TITLE>Textures</TITLE> <TITLE>Textures</TITLE>
@@ -722,9 +728,8 @@ gdk_texture_new_from_file
gdk_texture_get_width gdk_texture_get_width
gdk_texture_get_height gdk_texture_get_height
gdk_texture_download gdk_texture_download
gdk_texture_save_to_png
GdkMemoryFormat GdkMemoryFormat
GDK_MEMORY_DEFAULT GDK_MEMORY_FORMAT_DEFAULT
gdk_memory_texture_new gdk_memory_texture_new
gdk_gl_texture_new gdk_gl_texture_new
gdk_gl_texture_release gdk_gl_texture_release
@@ -772,60 +777,40 @@ gdk_cursor_get_type
<SECTION> <SECTION>
<TITLE>Drag and Drop</TITLE> <TITLE>Drag and Drop</TITLE>
<FILE>dnd</FILE> <FILE>dnd</FILE>
GdkDrag GdkDragContext
GdkDrop
GdkDragCancelReason GdkDragCancelReason
gdk_drop_reply
gdk_drag_drop_done gdk_drag_drop_done
gdk_drag_begin gdk_drag_begin
GdkDragAction
GDK_ACTION_ALL
gdk_drag_get_display
gdk_drag_get_actions
gdk_drag_get_suggested_action
gdk_drag_get_selected_action
gdk_drag_get_formats
gdk_drag_get_device
gdk_drag_get_drag_surface
gdk_drag_set_hotspot
<SUBSECTION>
gdk_drag_action_is_unique
<SUBSECTION>
gdk_drop_get_display
gdk_drop_get_device
gdk_drop_get_surface
gdk_drop_get_formats
gdk_drop_get_actions
gdk_drop_get_drag
gdk_drop_status
gdk_drop_finish gdk_drop_finish
gdk_drop_read_async GdkDragAction
gdk_drop_read_finish gdk_drag_status
gdk_drop_read_value_async gdk_drag_drop_succeeded
gdk_drop_read_value_finish
gdk_drop_read_text_async gdk_drag_context_get_display
gdk_drop_read_text_finish gdk_drag_context_get_actions
gdk_drag_context_get_suggested_action
gdk_drag_context_get_selected_action
gdk_drag_context_get_formats
gdk_drag_context_get_device
gdk_drag_context_get_source_surface
gdk_drag_context_get_dest_surface
gdk_drag_context_get_drag_surface
gdk_drag_context_set_hotspot
<SUBSECTION Standard> <SUBSECTION Standard>
GDK_DRAG GDK_DRAG_CONTEXT
GDK_TYPE_DRAG GDK_TYPE_DRAG_CONTEXT
GDK_IS_DRAG GDK_IS_DRAG_CONTEXT
GDK_DRAG_CLASS GDK_DRAG_CONTEXT_CLASS
GDK_DRAG_GET_CLASS GDK_DRAG_CONTEXT_GET_CLASS
GDK_IS_DRAG_CLASS GDK_IS_DRAG_CONTEXT_CLASS
GDK_TYPE_DRAG_ACTION GDK_TYPE_DRAG_ACTION
GDK_TYPE_DRAG_PROTOCOL GDK_TYPE_DRAG_PROTOCOL
GDK_TYPE_DROP
GDK_DROP
GDK_IS_DROP
<SUBSECTION Private> <SUBSECTION Private>
GdkDragClass GdkDragContextClass
gdk_drag_get_type gdk_drag_context_get_type
GdkDropClass
gdk_drop_get_type
</SECTION> </SECTION>
<SECTION> <SECTION>
@@ -868,6 +853,7 @@ gdk_x11_screen_lookup_visual
gdk_x11_screen_supports_net_wm_hint gdk_x11_screen_supports_net_wm_hint
gdk_x11_screen_get_number_of_desktops gdk_x11_screen_get_number_of_desktops
gdk_x11_screen_get_current_desktop gdk_x11_screen_get_current_desktop
gdk_x11_surface_foreign_new_for_display
gdk_x11_surface_lookup_for_display gdk_x11_surface_lookup_for_display
gdk_x11_surface_get_xid gdk_x11_surface_get_xid
gdk_x11_surface_set_theme_variant gdk_x11_surface_set_theme_variant
@@ -1120,10 +1106,6 @@ gdk_frame_timings_get_type
GdkDrawContext GdkDrawContext
gdk_draw_context_get_display gdk_draw_context_get_display
gdk_draw_context_get_surface gdk_draw_context_get_surface
gdk_draw_context_begin_frame
gdk_draw_context_end_frame
gdk_draw_context_is_in_frame
gdk_draw_context_get_frame_region
<SUBSECTION Standard> <SUBSECTION Standard>
GDK_DRAW_CONTEXT GDK_DRAW_CONTEXT
@@ -1157,6 +1139,7 @@ gdk_gl_context_is_legacy
<SUBSECTION> <SUBSECTION>
GdkGLError GdkGLError
gdk_gl_context_realize gdk_gl_context_realize
gdk_gl_context_get_damage
gdk_gl_context_make_current gdk_gl_context_make_current
gdk_gl_context_get_current gdk_gl_context_get_current
gdk_gl_context_clear_current gdk_gl_context_clear_current
@@ -1201,12 +1184,23 @@ GDK_IS_MONITOR
</SECTION> </SECTION>
<SECTION> <SECTION>
<FILE>gdkcairocontext</FILE> <FILE>gdkdrawingcontext</FILE>
GdkCairoContext GdkDrawingContext
gdk_cairo_context_cairo_create gdk_drawing_context_get_surface
gdk_drawing_context_get_clip
gdk_drawing_context_get_cairo_context
gdk_drawing_context_is_valid
gdk_drawing_context_get_paint_context
<SUBSECTION Standard> <SUBSECTION Standard>
gdk_cairo_context_get_type gdk_drawing_context_get_type
GdkDrawingContextClass
GDK_TYPE_DRAWING_CONTEXT
GDK_DRAWING_CONTEXT_CLASS
GDK_DRAWING_CONTEXT_GET_CLASS
GDK_IS_DRAWING_CONTEXT_CLASS
GDK_DRAWING_CONTEXT
GDK_IS_DRAWING_CONTEXT
</SECTION> </SECTION>
<SECTION> <SECTION>
@@ -1264,7 +1258,6 @@ gdk_clipboard_get_type
<SECTION> <SECTION>
<FILE>gdkcontentprovider</FILE> <FILE>gdkcontentprovider</FILE>
GdkContentProvider GdkContentProvider
GdkContentProviderClass
gdk_content_provider_new_for_value gdk_content_provider_new_for_value
gdk_content_provider_new_for_bytes gdk_content_provider_new_for_bytes
gdk_content_provider_ref_formats gdk_content_provider_ref_formats
@@ -1280,6 +1273,7 @@ GDK_CONTENT_PROVIDER_CLASS
GDK_CONTENT_PROVIDER_GET_CLASS GDK_CONTENT_PROVIDER_GET_CLASS
GDK_IS_CONTENT_PROVIDER GDK_IS_CONTENT_PROVIDER
GDK_IS_CONTENT_PROVIDER_CLASS GDK_IS_CONTENT_PROVIDER_CLASS
GdkContentProviderClass
gdk_content_provider_get_type gdk_content_provider_get_type
</SECTION> </SECTION>
@@ -1338,4 +1332,3 @@ GDK_CONTENT_DESERIALIZER
GDK_IS_CONTENT_DESERIALIZER GDK_IS_CONTENT_DESERIALIZER
gdk_content_deserializer_get_type gdk_content_deserializer_get_type
</SECTION> </SECTION>

View File

@@ -1,28 +1,18 @@
gdk_app_launch_context_get_type gdk_app_launch_context_get_type
gdk_clipboard_get_type
gdk_content_deserializer_get_type
gdk_content_formats_get_type
gdk_content_provider_get_type
gdk_content_serializer_get_type
gdk_cursor_get_type gdk_cursor_get_type
gdk_device_get_type gdk_device_get_type
gdk_device_pad_get_type gdk_device_pad_get_type
gdk_device_tool_get_type
gdk_display_get_type gdk_display_get_type
gdk_display_manager_get_type gdk_display_manager_get_type
gdk_drag_get_type gdk_drag_context_get_type
gdk_drop_get_type gdk_drawing_context_get_type
gdk_event_get_type
gdk_frame_clock_get_type gdk_frame_clock_get_type
gdk_gl_context_get_type gdk_gl_context_get_type
gdk_gl_texture_get_type
gdk_keymap_get_type gdk_keymap_get_type
gdk_memory_texture_get_type
gdk_monitor_get_type gdk_monitor_get_type
gdk_paintable_get_type
gdk_rgba_get_type
gdk_seat_get_type gdk_seat_get_type
gdk_snapshot_get_type
gdk_surface_get_type gdk_surface_get_type
gdk_texture_get_type gdk_content_serializer_get_type
gdk_vulkan_context_get_type gdk_content_deserializer_get_type
gdk_clipboard_get_type
gdk_content_formats_get_type

View File

@@ -3,6 +3,7 @@ private_headers = [
'gdkmarshalers.h', 'gdkmarshalers.h',
'gdkkeysyms.h', 'gdkkeysyms.h',
'gdkinternals.h', 'gdkinternals.h',
'gdkprivate.h',
'gdk-private.h', 'gdk-private.h',
'gdkapplaunchcontextprivate.h', 'gdkapplaunchcontextprivate.h',
'gdkclipboardprivate.h', 'gdkclipboardprivate.h',
@@ -10,39 +11,31 @@ private_headers = [
'gdkcontentproviderprivate.h', 'gdkcontentproviderprivate.h',
'gdkcursorprivate.h', 'gdkcursorprivate.h',
'gdkdeviceprivate.h', 'gdkdeviceprivate.h',
'gdkdevicepadprivate.h',
'gdkdevicetoolprivate.h',
'gdkdisplaymanagerprivate.h', 'gdkdisplaymanagerprivate.h',
'gdkdisplayprivate.h', 'gdkdisplayprivate.h',
'gdkdndprivate.h', 'gdkdndprivate.h',
'gdkdrawcontextprivate.h', 'gdkdrawcontextprivate.h',
'gdkeventsprivate.h', 'gdkeventsprivate.h',
'gdkframeclockidleprivate.h',
'gdkframeclockprivate.h', 'gdkframeclockprivate.h',
'gdkglcontextprivate.h', 'gdkglcontextprivate.h',
'gdkgltextureprivate.h',
'gdkkeysprivate.h', 'gdkkeysprivate.h',
'gdkmonitorprivate.h', 'gdkmonitorprivate.h',
'gdkmemorytextureprivate.h',
'gdkpipeiostreamprivate.h', 'gdkpipeiostreamprivate.h',
'gdkscreenprivate.h', 'gdkscreenprivate.h',
'gdkseatdefaultprivate.h', 'gdkseatdefaultprivate.h',
'gdkseatprivate.h', 'gdkseatprivate.h',
'gdksnapshotprivate.h',
'gdksurfaceimpl.h',
'gdktextureprivate.h', 'gdktextureprivate.h',
'gdkvisualprivate.h',
'gdkvulkancontextprivate.h', 'gdkvulkancontextprivate.h',
'keyname-table.h', 'keyname-table.h',
'gdkprivate-x11.h', 'x11/gdkprivate-x11.h',
'x11/gdkeventsource.h', 'x11/gdkeventsource.h',
'gtk-primary-selection-client-protocol.h', 'wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h',
'gtk-shell-client-protocol.h', 'wayland/pointer-gestures-unstable-v1-client-protocol.h',
'keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h', 'wayland/server-decoration-client-protocol.h',
'pointer-gestures-unstable-v1-client-protocol.h', 'wayland/tablet-unstable-v2-client-protocol.h',
'server-decoration-client-protocol.h', 'wayland/xdg-foreign-unstable-v1-client-protocol.h',
'tablet-unstable-v2-client-protocol.h', 'wayland/xdg-shell-unstable-v6-client-protocol.h',
'xdg-foreign-unstable-v1-client-protocol.h',
'xdg-shell-unstable-v6-client-protocol.h',
'win32', 'win32',
'quartz', 'quartz',
'broadway', 'broadway',
@@ -87,24 +80,19 @@ images = [
'images/zoom_out_cursor.png', 'images/zoom_out_cursor.png',
] ]
src_dir = [ gdkinc ]
if x11_enabled
src_dir += [ gdkx11_inc ]
endif
if wayland_enabled
src_dir += [ gdkwayland_inc ]
endif
configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf) configure_file(input: 'version.xml.in', output: 'version.xml', configuration: version_conf)
gnome.gtkdoc('gdk4', gnome.gtkdoc('gdk4',
mode: 'none', mode: 'none',
main_xml: 'gdk4-docs.xml', main_xml: 'gdk4-docs.xml',
src_dir: src_dir, src_dir: [
join_paths(meson.source_root(), 'gdk'),
join_paths(meson.source_root(), 'gdk', 'x11'),
join_paths(meson.source_root(), 'gdk', 'wayland'),
join_paths(meson.build_root(), 'gdk'),
],
dependencies: libgtk_dep, dependencies: libgtk_dep,
gobject_typesfile: join_paths(meson.current_source_dir(), 'gdk4.types'), gobject_typesfile: join_paths(meson.source_root(), 'docs/reference/gdk/gdk4.types'),
scan_args: [ scan_args: [
'--ignore-decorators=_GDK_EXTERN|G_GNUC_WARN_UNUSED_RESULT', '--ignore-decorators=_GDK_EXTERN|G_GNUC_WARN_UNUSED_RESULT',
'--ignore-headers=' + ' '.join(private_headers), '--ignore-headers=' + ' '.join(private_headers),

View File

@@ -5,6 +5,8 @@ gsk_renderer_get_surface
gsk_renderer_get_display gsk_renderer_get_display
gsk_renderer_realize gsk_renderer_realize
gsk_renderer_unrealize gsk_renderer_unrealize
gsk_renderer_begin_draw_frame
gsk_renderer_end_draw_frame
gsk_renderer_render gsk_renderer_render
gsk_renderer_render_texture gsk_renderer_render_texture
<SUBSECTION Standard> <SUBSECTION Standard>
@@ -29,6 +31,8 @@ gsk_render_node_serialize
gsk_render_node_deserialize gsk_render_node_deserialize
gsk_render_node_write_to_file gsk_render_node_write_to_file
GskScalingFilter GskScalingFilter
gsk_render_node_set_name
gsk_render_node_get_name
gsk_render_node_get_bounds gsk_render_node_get_bounds
<SUBSECTION Nodes> <SUBSECTION Nodes>
@@ -68,10 +72,6 @@ gsk_container_node_get_child
gsk_transform_node_new gsk_transform_node_new
gsk_transform_node_get_child gsk_transform_node_get_child
gsk_transform_node_peek_transform gsk_transform_node_peek_transform
gsk_offset_node_new
gsk_offset_node_get_child
gsk_offset_node_get_x_offset
gsk_offset_node_get_y_offset
gsk_opacity_node_new gsk_opacity_node_new
gsk_opacity_node_get_child gsk_opacity_node_get_child
gsk_opacity_node_get_opacity gsk_opacity_node_get_opacity
@@ -110,9 +110,6 @@ gsk_text_node_get_y
gsk_blur_node_new gsk_blur_node_new
gsk_blur_node_get_child gsk_blur_node_get_child
gsk_blur_node_get_radius gsk_blur_node_get_radius
gsk_debug_node_new
gsk_debug_node_get_child
gsk_debug_node_get_message
<SUBSECTION Standard> <SUBSECTION Standard>
GSK_IS_RENDER_NODE GSK_IS_RENDER_NODE
GSK_RENDER_NODE GSK_RENDER_NODE

View File

@@ -40,10 +40,11 @@ gnome.gtkdoc('gsk4',
mode: 'none', mode: 'none',
main_xml: 'gsk4-docs.xml', main_xml: 'gsk4-docs.xml',
src_dir: [ src_dir: [
gskinc, join_paths(meson.source_root(), 'gsk'),
join_paths(meson.build_root(), 'gsk'),
], ],
dependencies: libgtk_dep, dependencies: libgtk_dep,
gobject_typesfile: join_paths(meson.current_source_dir(), 'gsk4.types'), gobject_typesfile: join_paths(meson.source_root(), 'docs/reference/gsk/gsk4.types'),
scan_args: [ scan_args: [
'--ignore-decorators=_GDK_EXTERN', '--ignore-decorators=_GDK_EXTERN',
'--ignore-headers=' + ' '.join(private_headers), '--ignore-headers=' + ' '.join(private_headers),

View File

@@ -46,7 +46,7 @@ broadwayd :5
Then point your web browser at <literal>http://127.0.0.1:8085</literal>. Then point your web browser at <literal>http://127.0.0.1:8085</literal>.
Start your applications like this: Start your applications like this:
<programlisting> <programlisting>
GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk3-demo
</programlisting> </programlisting>
</para> </para>

View File

@@ -294,52 +294,13 @@ How to compile GTK+ itself
<command>meson</command> <command>meson</command>
<sbr/> <sbr/>
<group> <group>
<arg choice="plain">-Dx11-backend=true</arg> <arg choice="plain">-Ddocumentation=true</arg>
<arg choice="plain">-Dx11-backend=false</arg> <arg choice="plain">-Ddocumentation=false</arg>
</group> </group>
<sbr/> <sbr/>
<group> <group>
<arg choice="plain">-Dwayland-backend=true</arg> <arg choice="plain">-Dman-pages=true</arg>
<arg choice="plain">-Dwayland-backend=false</arg> <arg choice="plain">-Dman-pages=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dbroadway-backend=true</arg>
<arg choice="plain">-Dbroadway-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwin32-backend=true</arg>
<arg choice="plain">-Dwin32-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dquartz-backend=true</arg>
<arg choice="plain">-Dquartz-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dmedia=gstreamer</arg>
<arg choice="plain">-Dmedia=ffmpeg</arg>
<arg choice="plain">-Dmedia=all</arg>
<arg choice="plain">-Dmedia=none</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dvulkan=yes</arg>
<arg choice="plain">-Dvulkan=no</arg>
<arg choice="plain">-Dvulkan=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dxinerama=yes</arg>
<arg choice="plain">-Dxinerama=no</arg>
<arg choice="plain">-Dxinerama=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dcloudproviders=true</arg>
<arg choice="plain">-Dcloudproviders=false</arg>
</group> </group>
<sbr/> <sbr/>
<group> <group>
@@ -355,13 +316,45 @@ How to compile GTK+ itself
</group> </group>
<sbr/> <sbr/>
<group> <group>
<arg choice="plain">-Ddocumentation=true</arg> <arg choice="plain">-Dvulkan=yes</arg>
<arg choice="plain">-Ddocumentation=false</arg> <arg choice="plain">-Dvulkan=no</arg>
<arg choice="plain">-Dvulkan=auto</arg>
</group> </group>
<sbr/> <sbr/>
<group> <group>
<arg choice="plain">-Dman-pages=true</arg> <arg choice="plain">-Dx11-backend=true</arg>
<arg choice="plain">-Dman-pages=false</arg> <arg choice="plain">-Dx11-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dcloudproviders=true</arg>
<arg choice="plain">-Dcloudproviders=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dxinerama=yes</arg>
<arg choice="plain">-Dxinerama=no</arg>
<arg choice="plain">-Dxinerama=auto</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwin32-backend=true</arg>
<arg choice="plain">-Dwin32-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dquartz-backend=true</arg>
<arg choice="plain">-Dquartz-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dbroadway-backend=true</arg>
<arg choice="plain">-Dbroadway-backend=false</arg>
</group>
<sbr/>
<group>
<arg choice="plain">-Dwayland-backend=true</arg>
<arg choice="plain">-Dwayland-backend=false</arg>
</group> </group>
<sbr/> <sbr/>
<group> <group>

View File

@@ -50,7 +50,7 @@
<para> <para>
You can compile the program above with GCC using: You can compile the program above with GCC using:
<literallayout> <literallayout>
<literal>gcc `pkg-config --cflags gtk+-4.0` -o example-0 example-0.c `pkg-config --libs gtk+-4.0`</literal> <literal>gcc `pkg-config --cflags gtk+-3.0` -o example-0 example-0.c `pkg-config --libs gtk+-3.0`</literal>
</literallayout> </literallayout>
</para> </para>
@@ -120,7 +120,7 @@
here</ulink>.</para> here</ulink>.</para>
<para>Finally the window size is set using gtk_window_set_default_size and <para>Finally the window size is set using gtk_window_set_default_size and
the window is then shown by GTK via gtk_widget_show().</para> the window is then shown by GTK via gtk_widget_show_all().</para>
<para>When you exit the window, by for example pressing the X, <para>When you exit the window, by for example pressing the X,
the g_application_run() in the main loop returns with a number the g_application_run() in the main loop returns with a number
@@ -160,7 +160,7 @@
<para> <para>
You can compile the program above with GCC using: You can compile the program above with GCC using:
<literallayout> <literallayout>
<literal>gcc `pkg-config --cflags gtk+-4.0` -o example-1 example-1.c `pkg-config --libs gtk+-4.0`</literal> <literal>gcc `pkg-config --cflags gtk+-3.0` -o example-1 example-1.c `pkg-config --libs gtk+-3.0`</literal>
</literallayout> </literallayout>
</para> </para>
</section> </section>
@@ -238,7 +238,7 @@
<para> <para>
You can compile the program above with GCC using: You can compile the program above with GCC using:
<literallayout> <literallayout>
<literal>gcc `pkg-config --cflags gtk+-4.0` -o example-2 example-2.c `pkg-config --libs gtk+-4.0`</literal> <literal>gcc `pkg-config --cflags gtk+-3.0` -o example-2 example-2.c `pkg-config --libs gtk+-3.0`</literal>
</literallayout> </literallayout>
</para> </para>
</section> </section>
@@ -264,7 +264,7 @@
<para> <para>
You can compile the program above with GCC using: You can compile the program above with GCC using:
<literallayout> <literallayout>
<literal>gcc `pkg-config --cflags gtk+-4.0` -o example-3 example-3.c `pkg-config --libs gtk+-4.0`</literal> <literal>gcc `pkg-config --cflags gtk+-3.0` -o example-3 example-3.c `pkg-config --libs gtk+-3.0`</literal>
</literallayout> </literallayout>
</para> </para>
@@ -333,7 +333,7 @@
<para>The full, buildable sources for these examples can be found <para>The full, buildable sources for these examples can be found
in the examples/ directory of the GTK+ source distribution, or in the examples/ directory of the GTK+ source distribution, or
<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples">online</ulink> in the GTK+ git repository. <ulink url="https://git.gnome.org/browse/gtk+/tree/examples">online</ulink> in the GTK+ git repository.
You can build each example separately by using make with the <filename>Makefile.example</filename> You can build each example separately by using make with the <filename>Makefile.example</filename>
file. For more information, see the <filename>README</filename> included in the file. For more information, see the <filename>README</filename> included in the
examples directory.</para> examples directory.</para>
@@ -388,7 +388,7 @@
</informalfigure> </informalfigure>
<informalexample> <informalexample>
<programlisting><xi:include href="../../../../examples/application1/org.gtk.exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting> <programlisting><xi:include href="../../../../examples/application1/exampleapp.desktop" parse="text"><xi:fallback>MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
</informalexample> </informalexample>
<para>Note that <replaceable>@<!-- -->bindir@</replaceable> needs to be replaced <para>Note that <replaceable>@<!-- -->bindir@</replaceable> needs to be replaced
@@ -450,13 +450,13 @@ example_app_window_class_init (ExampleAppWindowClass *class)
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application2/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application2/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>You may have noticed that we used the <literal>_from_resource(<!-- -->)</literal> variant <para>You may have noticed that we used the <literal>_from_resource(<!-- -->)</literal> variant
of the function that sets a template. Now we need to use <ulink url="https://developer.gnome.org/gio/stable/GResource.html">GLib's resource functionality</ulink> of the function that sets a template. Now we need to use GLib's resource
to include the ui file in the binary. This is commonly done by listing functionality to include the ui file in the binary. This is commonly
all resources in a .gresource.xml file, such as this: done by listing all resources in a .gresource.xml file, such as this:
</para> </para>
<informalexample> <informalexample>
@@ -488,28 +488,23 @@ example_app_window_class_init (ExampleAppWindowClass *class)
<para>In this step, we make our application show the content of <para>In this step, we make our application show the content of
all the files that it is given on the commandline.</para> all the files that it is given on the commandline.</para>
<para>To this end, we add a member to the struct in application <para>To this end, we add a private struct to our application
window subclass and keep a reference to the #GtkStack there. window subclass and keep a reference to the #GtkStack there.
The first member of the struct should be the parent type from The gtk_widget_class_bind_template_child_private() function
which the class is derived. Here, ExampleAppWindow is derived
from GtkApplicationWindow.
The gtk_widget_class_bind_template_child() function
arranges things so that after instantiating the template, the arranges things so that after instantiating the template, the
@stack member of the struct will point to the widget of @stack member of the private struct will point to the widget of
the same name from the template.</para> the same name from the template.</para>
<informalexample> <informalexample>
<programlisting><![CDATA[ <programlisting><![CDATA[
... ...
struct _ExampleAppWindow struct _ExampleAppWindowPrivate
{ {
GtkApplicationWindow parent;
GtkWidget *stack; GtkWidget *stack;
}; };
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
... ...
@@ -518,12 +513,12 @@ example_app_window_class_init (ExampleAppWindowClass *class)
{ {
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui"); "/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
} }
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application3/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>Now we revisit the example_app_window_open() function that <para>Now we revisit the example_app_window_open() function that
@@ -538,21 +533,25 @@ void
example_app_window_open (ExampleAppWindow *win, example_app_window_open (ExampleAppWindow *win,
GFile *file) GFile *file)
{ {
ExampleAppWindowPrivate *priv;
gchar *basename; gchar *basename;
GtkWidget *scrolled, *view; GtkWidget *scrolled, *view;
gchar *contents; gchar *contents;
gsize length; gsize length;
priv = example_app_window_get_instance_private (win);
basename = g_file_get_basename (file); basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled);
gtk_widget_set_hexpand (scrolled, TRUE); gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (scrolled), view); gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename); gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
{ {
@@ -568,7 +567,7 @@ example_app_window_open (ExampleAppWindow *win,
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application3/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application3/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>Note that we did not have to touch the stack switcher <para>Note that we did not have to touch the stack switcher
@@ -666,7 +665,7 @@ example_app_class_init (ExampleAppClass *class)
... ...
</programlisting> </programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application4/exampleapp.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application4/exampleapp.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>Our preferences menu item does not do anything yet, <para>Our preferences menu item does not do anything yet,
@@ -719,17 +718,20 @@ example_app_class_init (ExampleAppClass *class)
static void static void
example_app_window_init (ExampleAppWindow *win) example_app_window_init (ExampleAppWindow *win)
{ {
gtk_widget_init_template (GTK_WIDGET (win)); ExampleAppWindowPrivate *priv;
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition", priv = example_app_window_get_instance_private (win);
win->stack, "transition-type", gtk_widget_init_template (GTK_WIDGET (win));
priv->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (priv->settings, "transition",
priv->stack, "transition-type",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
} }
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application5/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application5/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>The code to connect the font setting is a little more involved, <para>The code to connect the font setting is a little more involved,
@@ -778,7 +780,7 @@ preferences_activated (GSimpleAction *action,
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application6/exampleapp.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application6/exampleapp.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>After all this work, our application can now show <para>After all this work, our application can now show
@@ -821,6 +823,7 @@ static void
search_text_changed (GtkEntry *entry, search_text_changed (GtkEntry *entry,
ExampleAppWindow *win) ExampleAppWindow *win)
{ {
ExampleAppWindowPrivate *priv;
const gchar *text; const gchar *text;
GtkWidget *tab; GtkWidget *tab;
GtkWidget *view; GtkWidget *view;
@@ -832,7 +835,9 @@ search_text_changed (GtkEntry *entry,
if (text[0] == '\0') if (text[0] == '\0')
return; return;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack)); priv = example_app_window_get_instance_private (win);
tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
view = gtk_bin_get_child (GTK_BIN (tab)); view = gtk_bin_get_child (GTK_BIN (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -861,7 +866,7 @@ example_app_window_init (ExampleAppWindow *win)
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application7/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application7/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>With the search bar, our application now looks like this:</para> <para>With the search bar, our application now looks like this:</para>
@@ -921,7 +926,7 @@ example_app_window_init (ExampleAppWindow *win)
... ...
]]></programlisting> ]]></programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application8/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application8/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>What our application looks like now:</para> <para>What our application looks like now:</para>
@@ -973,23 +978,23 @@ example_app_window_init (ExampleAppWindow *win)
{ {
... ...
action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible"); action = (GAction*) g_property_action_new ("show-lines", priv->lines, "visible");
g_action_map_add_action (G_ACTION_MAP (win), action); g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action); g_object_unref (action);
g_object_bind_property (win->lines, "visible", g_object_bind_property (priv->lines, "visible",
win->lines_label, "visible", priv->lines_label, "visible",
G_BINDING_DEFAULT); G_BINDING_DEFAULT);
} }
... ...
</programlisting> </programlisting>
<para>(<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink>)</para> <para>(<ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application9/exampleappwin.c">full source</ulink>)</para>
</informalexample> </informalexample>
<para>We also need a function that counts the lines of the currently <para>We also need a function that counts the lines of the currently
active tab, and updates the @lines label. See the active tab, and updates the @lines label. See the
<ulink url="https://gitlab.gnome.org/GNOME/gtk/blob/master/examples/application9/exampleappwin.c">full source</ulink> <ulink url="https://git.gnome.org/browse/gtk+/tree/examples/application9/exampleappwin.c">full source</ulink>
if you are interested in the details.</para> if you are interested in the details.</para>
<para>This brings our example application to this appearance:</para> <para>This brings our example application to this appearance:</para>
@@ -1073,7 +1078,7 @@ example_app_window_init (ExampleAppWindow *win)
<para> <para>
You can compile the program above with GCC using: You can compile the program above with GCC using:
<literallayout> <literallayout>
<literal>gcc `pkg-config --cflags gtk+-4.0` -o example-4 example-4.c `pkg-config --libs gtk+-4.0`</literal> <literal>gcc `pkg-config --cflags gtk+-3.0` -o example-4 example-4.c `pkg-config --libs gtk+-3.0`</literal>
</literallayout> </literallayout>
</para> </para>
</section> </section>

View File

@@ -52,7 +52,7 @@ gtk4-broadwayd :5
Then point your web browser at <literal>http://127.0.0.1:8085</literal>. Then point your web browser at <literal>http://127.0.0.1:8085</literal>.
Start your applications like this: Start your applications like this:
<programlisting> <programlisting>
GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk3-demo
</programlisting> </programlisting>
You can add password protection for your session by creating a file in You can add password protection for your session by creating a file in

View File

@@ -93,22 +93,12 @@
<title>Display Widgets</title> <title>Display Widgets</title>
<xi:include href="xml/gtklabel.xml" /> <xi:include href="xml/gtklabel.xml" />
<xi:include href="xml/gtkimage.xml" /> <xi:include href="xml/gtkimage.xml" />
<xi:include href="xml/gtkpicture.xml" />
<xi:include href="xml/gtkspinner.xml" /> <xi:include href="xml/gtkspinner.xml" />
<xi:include href="xml/gtkinfobar.xml" /> <xi:include href="xml/gtkinfobar.xml" />
<xi:include href="xml/gtkprogressbar.xml" /> <xi:include href="xml/gtkprogressbar.xml" />
<xi:include href="xml/gtklevelbar.xml" /> <xi:include href="xml/gtklevelbar.xml" />
<xi:include href="xml/gtkstatusbar.xml" /> <xi:include href="xml/gtkstatusbar.xml" />
<xi:include href="xml/gtkaccellabel.xml" /> <xi:include href="xml/gtkaccellabel.xml" />
<xi:include href="xml/gtkcalendar.xml" />
</chapter>
<chapter id="MediaSupport">
<title>Media Support</title>
<xi:include href="xml/gtkvideo.xml" />
<xi:include href="xml/gtkmediacontrols.xml" />
<xi:include href="xml/gtkmediastream.xml" />
<xi:include href="xml/gtkmediafile.xml" />
</chapter> </chapter>
<chapter id="ButtonWidgets"> <chapter id="ButtonWidgets">
@@ -220,12 +210,6 @@
<xi:include href="xml/gtkfontchooserdialog.xml" /> <xi:include href="xml/gtkfontchooserdialog.xml" />
</chapter> </chapter>
<chapter id="DrawingWidgets">
<title>Widgets for custom drawing</title>
<xi:include href="xml/gtkdrawingarea.xml" />
<xi:include href="xml/gtkglarea.xml" />
</chapter>
<chapter id="Ornaments"> <chapter id="Ornaments">
<title>Ornaments</title> <title>Ornaments</title>
<xi:include href="xml/gtkframe.xml" /> <xi:include href="xml/gtkframe.xml" />
@@ -237,7 +221,6 @@
<xi:include href="xml/gtkscrollbar.xml" /> <xi:include href="xml/gtkscrollbar.xml" />
<xi:include href="xml/gtkscrolledwindow.xml" /> <xi:include href="xml/gtkscrolledwindow.xml" />
<xi:include href="xml/gtkscrollable.xml" /> <xi:include href="xml/gtkscrollable.xml" />
<xi:include href="xml/gtkviewport.xml" />
</chapter> </chapter>
<chapter id="Printing"> <chapter id="Printing">
@@ -264,12 +247,16 @@
<chapter id="MiscObjects"> <chapter id="MiscObjects">
<title>Miscellaneous</title> <title>Miscellaneous</title>
<xi:include href="xml/gtkadjustment.xml" /> <xi:include href="xml/gtkadjustment.xml" />
<xi:include href="xml/gtkcalendar.xml" />
<xi:include href="xml/gtkdrawingarea.xml" />
<xi:include href="xml/gtkglarea.xml" />
<xi:include href="xml/gtkimcontextsimple.xml" /> <xi:include href="xml/gtkimcontextsimple.xml" />
<xi:include href="xml/gtkimmulticontext.xml" /> <xi:include href="xml/gtkimmulticontext.xml" />
<xi:include href="xml/gtksizegroup.xml" /> <xi:include href="xml/gtksizegroup.xml" />
<xi:include href="xml/gtktooltip.xml" /> <xi:include href="xml/gtktooltip.xml" />
<xi:include href="xml/gtkviewport.xml" />
<xi:include href="xml/gtkaccessible.xml" />
<xi:include href="xml/gtksnapshot.xml" /> <xi:include href="xml/gtksnapshot.xml" />
<xi:include href="xml/gtkwidgetpaintable.xml" />
</chapter> </chapter>
<chapter id="AbstractObjects"> <chapter id="AbstractObjects">
@@ -281,7 +268,6 @@
<xi:include href="xml/gtkrange.xml" /> <xi:include href="xml/gtkrange.xml" />
<xi:include href="xml/gtkimcontext.xml" /> <xi:include href="xml/gtkimcontext.xml" />
<xi:include href="xml/gtknativedialog.xml" /> <xi:include href="xml/gtknativedialog.xml" />
<xi:include href="xml/gtkaccessible.xml" />
</chapter> </chapter>
<chapter id="RecentDocuments"> <chapter id="RecentDocuments">
@@ -300,7 +286,6 @@
<chapter id="Gestures"> <chapter id="Gestures">
<title>Gestures and event handling</title> <title>Gestures and event handling</title>
<xi:include href="xml/gtkeventcontroller.xml" /> <xi:include href="xml/gtkeventcontroller.xml" />
<xi:include href="xml/gtkeventcontrollerkey.xml" />
<xi:include href="xml/gtkeventcontrollerscroll.xml" /> <xi:include href="xml/gtkeventcontrollerscroll.xml" />
<xi:include href="xml/gtkeventcontrollermotion.xml" /> <xi:include href="xml/gtkeventcontrollermotion.xml" />
<xi:include href="xml/gtkgesture.xml" /> <xi:include href="xml/gtkgesture.xml" />
@@ -312,7 +297,6 @@
<xi:include href="xml/gtkgestureswipe.xml" /> <xi:include href="xml/gtkgestureswipe.xml" />
<xi:include href="xml/gtkgesturerotate.xml" /> <xi:include href="xml/gtkgesturerotate.xml" />
<xi:include href="xml/gtkgesturezoom.xml" /> <xi:include href="xml/gtkgesturezoom.xml" />
<xi:include href="xml/gtkgesturestylus.xml" />
<xi:include href="xml/gtkpadcontroller.xml" /> <xi:include href="xml/gtkpadcontroller.xml" />
</chapter> </chapter>
@@ -385,6 +369,7 @@
<xi:include href="osx.sgml" /> <xi:include href="osx.sgml" />
<xi:include href="broadway.xml" /> <xi:include href="broadway.xml" />
<xi:include href="wayland.xml" /> <xi:include href="wayland.xml" />
<xi:include href="mir.xml" />
</part> </part>
<xi:include href="glossary.xml" /> <xi:include href="glossary.xml" />

View File

@@ -679,6 +679,8 @@ gtk_combo_box_get_active_id
gtk_combo_box_set_active_id gtk_combo_box_set_active_id
gtk_combo_box_get_model gtk_combo_box_get_model
gtk_combo_box_set_model gtk_combo_box_set_model
gtk_combo_box_popup_for_device
gtk_combo_box_popup
gtk_combo_box_popdown gtk_combo_box_popdown
gtk_combo_box_get_popup_accessible gtk_combo_box_get_popup_accessible
gtk_combo_box_get_row_separator_func gtk_combo_box_get_row_separator_func
@@ -758,6 +760,9 @@ gtk_container_child_set_valist
gtk_container_child_notify gtk_container_child_notify
gtk_container_child_notify_by_pspec gtk_container_child_notify_by_pspec
gtk_container_forall gtk_container_forall
gtk_container_get_focus_chain
gtk_container_set_focus_chain
gtk_container_unset_focus_chain
gtk_container_class_find_child_property gtk_container_class_find_child_property
gtk_container_class_install_child_property gtk_container_class_install_child_property
gtk_container_class_install_child_properties gtk_container_class_install_child_properties
@@ -1265,6 +1270,8 @@ gtk_fixed_get_type
GtkFontButton GtkFontButton
gtk_font_button_new gtk_font_button_new
gtk_font_button_new_with_font gtk_font_button_new_with_font
gtk_font_button_set_font_name
gtk_font_button_get_font_name
gtk_font_button_set_use_font gtk_font_button_set_use_font
gtk_font_button_get_use_font gtk_font_button_get_use_font
gtk_font_button_set_use_size gtk_font_button_set_use_size
@@ -1295,7 +1302,7 @@ gtk_font_chooser_set_font
gtk_font_chooser_get_font_desc gtk_font_chooser_get_font_desc
gtk_font_chooser_set_font_desc gtk_font_chooser_set_font_desc
gtk_font_chooser_get_font_features gtk_font_chooser_get_font_features
gtk_font_chooser_set_language gtk_font_chooser_get_font_language
gtk_font_chooser_get_preview_text gtk_font_chooser_get_preview_text
gtk_font_chooser_set_preview_text gtk_font_chooser_set_preview_text
gtk_font_chooser_get_show_preview_entry gtk_font_chooser_get_show_preview_entry
@@ -1476,28 +1483,32 @@ GtkIconViewPrivate
<TITLE>GtkImage</TITLE> <TITLE>GtkImage</TITLE>
GtkImage GtkImage
GtkImageType GtkImageType
gtk_image_new gtk_image_get_texture
gtk_image_new_from_file
gtk_image_new_from_resource
gtk_image_new_from_pixbuf
gtk_image_new_from_paintable
gtk_image_new_from_icon_name
gtk_image_new_from_gicon
gtk_image_clear
gtk_image_set_from_file
gtk_image_set_from_resource
gtk_image_set_from_pixbuf
gtk_image_set_from_paintable
gtk_image_set_from_icon_name
gtk_image_set_from_gicon
gtk_image_get_storage_type
gtk_image_get_paintable
gtk_image_get_icon_name gtk_image_get_icon_name
gtk_image_get_gicon gtk_image_get_gicon
gtk_image_get_storage_type
gtk_image_new_from_file
gtk_image_new_from_pixbuf
gtk_image_new_from_icon_name
gtk_image_new_from_gicon
gtk_image_new_from_resource
gtk_image_new_from_texture
gtk_image_set_from_file
gtk_image_set_from_pixbuf
gtk_image_set_from_icon_name
gtk_image_set_from_gicon
gtk_image_set_from_resource
gtk_image_set_from_texture
gtk_image_clear
gtk_image_new
gtk_image_set_pixel_size gtk_image_set_pixel_size
gtk_image_get_pixel_size gtk_image_get_pixel_size
gtk_image_set_icon_size gtk_image_set_icon_size
gtk_image_get_icon_size gtk_image_get_icon_size
gtk_image_set_keep_aspect_ratio
gtk_image_get_keep_aspect_ratio
gtk_image_set_can_shrink
gtk_image_get_can_shrink
<SUBSECTION Standard> <SUBSECTION Standard>
GTK_IMAGE GTK_IMAGE
GTK_IS_IMAGE GTK_IS_IMAGE
@@ -1719,6 +1730,8 @@ gtk_menu_attach
gtk_menu_popup_at_rect gtk_menu_popup_at_rect
gtk_menu_popup_at_widget gtk_menu_popup_at_widget
gtk_menu_popup_at_pointer gtk_menu_popup_at_pointer
gtk_menu_popup_for_device
gtk_menu_popup
gtk_menu_set_accel_group gtk_menu_set_accel_group
gtk_menu_get_accel_group gtk_menu_get_accel_group
gtk_menu_set_accel_path gtk_menu_set_accel_path
@@ -1910,8 +1923,8 @@ gtk_info_bar_set_message_type
gtk_info_bar_get_message_type gtk_info_bar_get_message_type
gtk_info_bar_get_action_area gtk_info_bar_get_action_area
gtk_info_bar_get_content_area gtk_info_bar_get_content_area
gtk_info_bar_get_show_close_button gtk_info_bar_get_show_title_buttons
gtk_info_bar_set_show_close_button gtk_info_bar_set_show_title_buttons
gtk_info_bar_get_revealed gtk_info_bar_get_revealed
gtk_info_bar_set_revealed gtk_info_bar_set_revealed
@@ -2038,40 +2051,6 @@ GtkPanedPrivate
gtk_paned_get_type gtk_paned_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>gtkpicture</FILE>
<TITLE>GtkPicture</TITLE>
GtkPicture
gtk_picture_new
gtk_picture_new_for_paintable
gtk_picture_new_for_pixbuf
gtk_picture_new_for_file
gtk_picture_new_for_filename
gtk_picture_new_for_resource
gtk_picture_set_paintable
gtk_picture_get_paintable
gtk_picture_set_pixbuf
gtk_picture_set_file
gtk_picture_get_file
gtk_picture_set_filename
gtk_picture_set_resource
gtk_picture_set_keep_aspect_ratio
gtk_picture_get_keep_aspect_ratio
gtk_picture_set_can_shrink
gtk_picture_get_can_shrink
gtk_picture_set_alternative_text
gtk_picture_get_alternative_text
<SUBSECTION Standard>
GTK_PICTURE
GTK_IS_PICTURE
GTK_TYPE_PICTURE
GTK_PICTURE_CLASS
GTK_IS_PICTURE_CLASS
GTK_PICTURE_GET_CLASS
<SUBSECTION Private>
gtk_picture_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>gtkprogressbar</FILE> <FILE>gtkprogressbar</FILE>
<TITLE>GtkProgressBar</TITLE> <TITLE>GtkProgressBar</TITLE>
@@ -2418,8 +2397,6 @@ gtk_search_bar_set_search_mode
gtk_search_bar_get_show_close_button gtk_search_bar_get_show_close_button
gtk_search_bar_set_show_close_button gtk_search_bar_set_show_close_button
gtk_search_bar_handle_event gtk_search_bar_handle_event
gtk_search_bar_set_key_capture_widget
gtk_search_bar_get_key_capture_widget
<SUBSECTION Standard> <SUBSECTION Standard>
GTK_TYPE_SEARCH_BAR GTK_TYPE_SEARCH_BAR
GTK_SEARCH_BAR GTK_SEARCH_BAR
@@ -2437,8 +2414,6 @@ gtk_search_bar_get_type
GtkSearchEntry GtkSearchEntry
gtk_search_entry_new gtk_search_entry_new
gtk_search_entry_handle_event gtk_search_entry_handle_event
gtk_search_entry_set_key_capture_widget
gtk_search_entry_get_key_capture_widget
<SUBSECTION Standard> <SUBSECTION Standard>
GTK_TYPE_SEARCH_ENTRY GTK_TYPE_SEARCH_ENTRY
GTK_SEARCH_ENTRY GTK_SEARCH_ENTRY
@@ -4193,10 +4168,15 @@ gtk_volume_button_get_type
<TITLE>GtkSnapshot</TITLE> <TITLE>GtkSnapshot</TITLE>
GtkSnapshot GtkSnapshot
gtk_snapshot_new gtk_snapshot_new
gtk_snapshot_ref
gtk_snapshot_unref
gtk_snapshot_to_node gtk_snapshot_to_node
gtk_snapshot_to_paintable gtk_snapshot_to_paintable
gtk_snapshot_free_to_node gtk_snapshot_free_to_node
gtk_snapshot_free_to_paintable gtk_snapshot_free_to_paintable
gtk_snapshot_get_renderer
gtk_snapshot_get_record_names
gtk_snapshot_push
gtk_snapshot_push_transform gtk_snapshot_push_transform
gtk_snapshot_push_opacity gtk_snapshot_push_opacity
gtk_snapshot_push_color_matrix gtk_snapshot_push_color_matrix
@@ -4213,6 +4193,7 @@ gtk_snapshot_append_cairo
gtk_snapshot_append_texture gtk_snapshot_append_texture
gtk_snapshot_append_color gtk_snapshot_append_color
gtk_snapshot_append_layout gtk_snapshot_append_layout
gtk_snapshot_clips_rect
gtk_snapshot_render_background gtk_snapshot_render_background
gtk_snapshot_render_frame gtk_snapshot_render_frame
gtk_snapshot_render_focus gtk_snapshot_render_focus
@@ -4220,24 +4201,6 @@ gtk_snapshot_render_layout
gtk_snapshot_render_insertion_cursor gtk_snapshot_render_insertion_cursor
</SECTION> </SECTION>
<SECTION>
<FILE>gtkwidgetpaintable</FILE>
<TITLE>GtkWidgetPaintable</TITLE>
gtk_widget_paintable_new
gtk_widget_paintable_get_widget
gtk_widget_paintable_set_widget
<SUBSECTION Standard>
GTK_WIDGET_PAINTABLE
GTK_IS_WIDGET_PAINTABLE
GTK_TYPE_WIDGET_PAINTABLE
GTK_WIDGET_PAINTABLE_CLASS
GTK_IS_WIDGET_PAINTABLE_CLASS
GTK_WIDGET_PAINTABLE_GET_CLASS
<SUBSECTION Private>
gtk_widget_paintable_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>gtkwidget</FILE> <FILE>gtkwidget</FILE>
<TITLE>GtkWidget</TITLE> <TITLE>GtkWidget</TITLE>
@@ -4257,6 +4220,7 @@ gtk_widget_map
gtk_widget_unmap gtk_widget_unmap
gtk_widget_realize gtk_widget_realize
gtk_widget_unrealize gtk_widget_unrealize
gtk_widget_draw
gtk_widget_queue_draw gtk_widget_queue_draw
gtk_widget_queue_resize gtk_widget_queue_resize
gtk_widget_queue_resize_no_redraw gtk_widget_queue_resize_no_redraw
@@ -4288,8 +4252,6 @@ gtk_widget_get_toplevel
gtk_widget_get_ancestor gtk_widget_get_ancestor
gtk_widget_is_ancestor gtk_widget_is_ancestor
gtk_widget_translate_coordinates gtk_widget_translate_coordinates
gtk_widget_add_controller
gtk_widget_remove_controller
gtk_widget_set_direction gtk_widget_set_direction
GtkTextDirection GtkTextDirection
gtk_widget_get_direction gtk_widget_get_direction
@@ -4303,6 +4265,8 @@ gtk_widget_get_font_options
gtk_widget_set_font_map gtk_widget_set_font_map
gtk_widget_get_font_map gtk_widget_get_font_map
gtk_widget_create_pango_layout gtk_widget_create_pango_layout
gtk_widget_queue_draw_area
gtk_widget_queue_draw_region
gtk_widget_get_cursor gtk_widget_get_cursor
gtk_widget_set_cursor gtk_widget_set_cursor
gtk_widget_set_cursor_from_name gtk_widget_set_cursor_from_name
@@ -4348,7 +4312,7 @@ gtk_widget_get_allocated_baseline
gtk_widget_get_allocated_size gtk_widget_get_allocated_size
gtk_widget_get_width gtk_widget_get_width
gtk_widget_get_height gtk_widget_get_height
gtk_widget_compute_bounds gtk_widget_get_clip
gtk_widget_contains gtk_widget_contains
gtk_widget_pick gtk_widget_pick
gtk_widget_get_can_default gtk_widget_get_can_default
@@ -4357,7 +4321,6 @@ gtk_widget_get_can_focus
gtk_widget_set_can_focus gtk_widget_set_can_focus
gtk_widget_get_focus_on_click gtk_widget_get_focus_on_click
gtk_widget_set_focus_on_click gtk_widget_set_focus_on_click
gtk_widget_set_focus_child
gtk_widget_get_has_surface gtk_widget_get_has_surface
gtk_widget_set_has_surface gtk_widget_set_has_surface
gtk_widget_get_sensitive gtk_widget_get_sensitive
@@ -4379,6 +4342,7 @@ gtk_widget_set_receives_default
gtk_widget_get_receives_default gtk_widget_get_receives_default
gtk_widget_set_support_multidevice gtk_widget_set_support_multidevice
gtk_widget_get_support_multidevice gtk_widget_get_support_multidevice
gtk_widget_set_realized
gtk_widget_get_realized gtk_widget_get_realized
gtk_widget_get_mapped gtk_widget_get_mapped
gtk_widget_device_is_shadowed gtk_widget_device_is_shadowed
@@ -4858,6 +4822,7 @@ gtk_style_context_get_parent
gtk_style_context_get_path gtk_style_context_get_path
gtk_style_context_get_property gtk_style_context_get_property
gtk_style_context_get_display gtk_style_context_get_display
gtk_style_context_get_frame_clock
gtk_style_context_get_state gtk_style_context_get_state
gtk_style_context_get_valist gtk_style_context_get_valist
gtk_style_context_get_section gtk_style_context_get_section
@@ -4880,6 +4845,7 @@ gtk_style_context_remove_class
gtk_style_context_has_class gtk_style_context_has_class
gtk_style_context_list_classes gtk_style_context_list_classes
gtk_style_context_set_display gtk_style_context_set_display
gtk_style_context_set_frame_clock
gtk_style_context_set_state gtk_style_context_set_state
gtk_style_context_set_scale gtk_style_context_set_scale
gtk_style_context_get_scale gtk_style_context_get_scale
@@ -4900,11 +4866,14 @@ gtk_render_check
gtk_render_expander gtk_render_expander
gtk_render_focus gtk_render_focus
gtk_render_frame gtk_render_frame
gtk_render_frame_gap
gtk_render_handle gtk_render_handle
gtk_render_layout gtk_render_layout
gtk_render_line gtk_render_line
gtk_render_option gtk_render_option
gtk_render_slider
gtk_render_activity gtk_render_activity
gtk_render_icon_surface
gtk_render_icon gtk_render_icon
gtk_render_insertion_cursor gtk_render_insertion_cursor
@@ -4927,6 +4896,7 @@ gtk_border_get_type
<FILE>gtkcssprovider</FILE> <FILE>gtkcssprovider</FILE>
<TITLE>GtkCssProvider</TITLE> <TITLE>GtkCssProvider</TITLE>
GtkCssProvider GtkCssProvider
gtk_css_provider_get_default
gtk_css_provider_get_named gtk_css_provider_get_named
gtk_css_provider_load_from_data gtk_css_provider_load_from_data
gtk_css_provider_load_from_file gtk_css_provider_load_from_file
@@ -5003,7 +4973,6 @@ gtk_selection_data_get_type
<TITLE>Drag and Drop</TITLE> <TITLE>Drag and Drop</TITLE>
GtkDestDefaults GtkDestDefaults
GtkDragResult GtkDragResult
<SUBSECTION Destination Side> <SUBSECTION Destination Side>
gtk_drag_dest_set gtk_drag_dest_set
gtk_drag_dest_unset gtk_drag_dest_unset
@@ -5015,13 +4984,13 @@ gtk_drag_dest_add_image_targets
gtk_drag_dest_add_uri_targets gtk_drag_dest_add_uri_targets
gtk_drag_dest_set_track_motion gtk_drag_dest_set_track_motion
gtk_drag_dest_get_track_motion gtk_drag_dest_get_track_motion
gtk_drag_finish
gtk_drag_get_data gtk_drag_get_data
gtk_drag_get_source_widget gtk_drag_get_source_widget
gtk_drag_highlight gtk_drag_highlight
gtk_drag_unhighlight gtk_drag_unhighlight
<SUBSECTION Source Side> <SUBSECTION Source Side>
gtk_drag_begin gtk_drag_begin_with_coordinates
gtk_drag_cancel gtk_drag_cancel
gtk_drag_set_icon_widget gtk_drag_set_icon_widget
gtk_drag_set_icon_paintable gtk_drag_set_icon_paintable
@@ -5291,7 +5260,6 @@ gtk_printer_request_details
gtk_printer_get_capabilities gtk_printer_get_capabilities
gtk_printer_get_default_page_size gtk_printer_get_default_page_size
gtk_printer_get_hard_margins gtk_printer_get_hard_margins
gtk_printer_get_hard_margins_for_paper_size
GtkPrinterFunc GtkPrinterFunc
gtk_enumerate_printers gtk_enumerate_printers
@@ -6006,8 +5974,6 @@ gtk_overlay_get_overlay_pass_through
gtk_overlay_set_overlay_pass_through gtk_overlay_set_overlay_pass_through
gtk_overlay_get_measure_overlay gtk_overlay_get_measure_overlay
gtk_overlay_set_measure_overlay gtk_overlay_set_measure_overlay
gtk_overlay_get_clip_overlay
gtk_overlay_set_clip_overlay
<SUBSECTION Standard> <SUBSECTION Standard>
GTK_TYPE_OVERLAY GTK_TYPE_OVERLAY
@@ -6455,7 +6421,7 @@ gtk_gesture_single_get_type
<SECTION> <SECTION>
<FILE>gtkeventcontrollerscroll</FILE> <FILE>gtkeventcontrollerscroll</FILE>
<TITLE>GtkEventControllerScroll</TITLE> <TITLE>GtkEventControlerScroll</TITLE>
GtkEventControllerScroll GtkEventControllerScroll
GtkEventControllerScrollFlags GtkEventControllerScrollFlags
gtk_event_controller_scroll_new gtk_event_controller_scroll_new
@@ -6476,7 +6442,7 @@ gtk_event_controller_scroll_get_type
<SECTION> <SECTION>
<FILE>gtkeventcontrollermotion</FILE> <FILE>gtkeventcontrollermotion</FILE>
<TITLE>GtkEventControllerMotion</TITLE> <TITLE>GtkEventControlerMotion</TITLE>
GtkEventControllerMotion GtkEventControllerMotion
gtk_event_controller_motion_new gtk_event_controller_motion_new
@@ -6492,24 +6458,6 @@ GTK_EVENT_CONTROLLER_MOTION_GET_CLASS
gtk_event_controller_motion_get_type gtk_event_controller_motion_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>gtkeventcontrollerkey</FILE>
<TITLE>GtkEventControllerKey</TITLE>
GtkEventControllerKey
gtk_event_controller_key_new
<SUBSECTION Standard>
GTK_TYPE_EVENT_CONTROLLER_KEY
GTK_EVENT_CONTROLLER_KEY
GTK_EVENT_CONTROLLER_KEY_CLASS
GTK_IS_EVENT_CONTROLLER_KEY
GTK_IS_EVENT_CONTROLLER_KEY_CLASS
GTK_EVENT_CONTROLLER_KEY_GET_CLASS
<SUBSECTION Private>
gtk_event_controller_key_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>gtkgesturedrag</FILE> <FILE>gtkgesturedrag</FILE>
<TITLE>GtkGestureDrag</TITLE> <TITLE>GtkGestureDrag</TITLE>
@@ -6668,39 +6616,15 @@ GTK_PAD_CONTROLLER_GET_CLASS
gtk_pad_controller_get_type gtk_pad_controller_get_type
</SECTION> </SECTION>
<SECTION>
<FILE>gtkgesturestylus</FILE>
<TITLE>GtkGestureStylus</TITLE>
GtkGestureStylus
gtk_gesture_stylus_new
gtk_gesture_stylus_get_axis
gtk_gesture_stylus_get_axes
gtk_gesture_stylus_get_backlog
gtk_gesture_stylus_get_device_tool
<SUBSECTION Standard>
GTK_TYPE_GESTURE_STYLUS
GTK_GESTURE_STYLUS
GTK_GESTURE_STYLUS_CLASS
GTK_IS_GESTURE_STYLUS
GTK_IS_GESTURE_STYLUS_CLASS
GTK_GESTURE_STYLUS_GET_CLASS
GtkGestureStylusClass
<SUBSECTION Private>
gtk_gesture_stylus_get_type
</SECTION>
<SECTION> <SECTION>
<FILE>gtkstacksidebar</FILE> <FILE>gtkstacksidebar</FILE>
GtkStackSidebar GtkStackSidebar
GtkStackSidebarClass
gtk_stack_sidebar_new gtk_stack_sidebar_new
gtk_stack_sidebar_set_stack gtk_stack_sidebar_set_stack
gtk_stack_sidebar_get_stack gtk_stack_sidebar_get_stack
<SUBSECTION Standard> <SUBSECTION Standard>
GtkStackSidebarClass
GTK_TYPE_STACK_SIDEBAR GTK_TYPE_STACK_SIDEBAR
GTK_STACK_SIDEBAR GTK_STACK_SIDEBAR
GTK_STACK_SIDEBAR_CLASS GTK_STACK_SIDEBAR_CLASS
@@ -6725,6 +6649,8 @@ gtk_gl_area_attach_buffers
gtk_gl_area_set_error gtk_gl_area_set_error
gtk_gl_area_get_error gtk_gl_area_get_error
<SUBSECTION> <SUBSECTION>
gtk_gl_area_set_has_alpha
gtk_gl_area_get_has_alpha
gtk_gl_area_set_has_depth_buffer gtk_gl_area_set_has_depth_buffer
gtk_gl_area_get_has_depth_buffer gtk_gl_area_get_has_depth_buffer
gtk_gl_area_set_has_stencil_buffer gtk_gl_area_set_has_stencil_buffer
@@ -6831,102 +6757,3 @@ GTK_SHORTCUT_LABEL_GET_CLASS
GTK_IS_SHORTCUT_LABEL GTK_IS_SHORTCUT_LABEL
GTK_IS_SHORTCUT_LABEL_CLASS GTK_IS_SHORTCUT_LABEL_CLASS
</SECTION> </SECTION>
<SECTION>
<FILE>gtkvideo</FILE>
GtkVideo
gtk_video_new
gtk_video_new_for_media_stream
gtk_video_new_for_file
gtk_video_new_for_filename
gtk_video_new_for_resource
gtk_video_get_media_stream
gtk_video_set_media_stream
gtk_video_get_file
gtk_video_set_file
gtk_video_set_filename
gtk_video_set_resource
gtk_video_get_autoplay
gtk_video_set_autoplay
gtk_video_get_loop
gtk_video_set_loop
<SUBSECTION Private>
gtk_video_get_type
</SECTION>
<SECTION>
<FILE>gtkmediacontrols</FILE>
GtkMediaControls
gtk_media_controls_new
gtk_media_controls_get_media_stream
gtk_media_controls_set_media_stream
<SUBSECTION Private>
gtk_media_controls_get_type
</SECTION>
<SECTION>
<FILE>gtkmediafile</FILE>
GtkMediaFile
gtk_media_file_new
gtk_media_file_new_for_filename
gtk_media_file_new_for_resource
gtk_media_file_new_for_file
gtk_media_file_new_for_input_stream
gtk_media_file_clear
gtk_media_file_set_filename
gtk_media_file_set_resource
gtk_media_file_set_file
gtk_media_file_get_file
gtk_media_file_set_input_stream
gtk_media_file_get_input_stream
<SUBSECTION Private>
GTK_TYPE_MEDIA_FILE
gtk_media_file_get_type
</SECTION>
<SECTION>
<FILE>gtkmediastream</FILE>
GtkMediaStream
GtkMediaStreamClass
gtk_media_stream_is_prepared
gtk_media_stream_get_error
gtk_media_stream_has_audio
gtk_media_stream_has_video
gtk_media_stream_play
gtk_media_stream_pause
gtk_media_stream_get_playing
gtk_media_stream_set_playing
gtk_media_stream_get_ended
gtk_media_stream_get_timestamp
gtk_media_stream_get_duration
gtk_media_stream_is_seekable
gtk_media_stream_is_seeking
gtk_media_stream_seek
gtk_media_stream_get_loop
gtk_media_stream_set_loop
gtk_media_stream_get_muted
gtk_media_stream_set_muted
gtk_media_stream_get_volume
gtk_media_stream_set_volume
gtk_media_stream_realize
gtk_media_stream_unrealize
<SUBSECTION>
gtk_media_stream_prepared
gtk_media_stream_unprepared
gtk_media_stream_update
gtk_media_stream_ended
gtk_media_stream_seek_success
gtk_media_stream_seek_failed
gtk_media_stream_gerror
gtk_media_stream_error
gtk_media_stream_error_valist
<SUBSECTION Private>
GTK_TYPE_MEDIA_STREAM
gtk_media_stream_get_type
</SECTION>

View File

@@ -53,9 +53,8 @@ gtk_entry_buffer_get_type
gtk_entry_completion_get_type gtk_entry_completion_get_type
gtk_entry_get_type gtk_entry_get_type
gtk_event_controller_get_type gtk_event_controller_get_type
gtk_event_controller_key_get_type
gtk_event_controller_motion_get_type
gtk_event_controller_scroll_get_type gtk_event_controller_scroll_get_type
gtk_event_controller_motion_get_type
gtk_expander_get_type gtk_expander_get_type
gtk_file_chooser_button_get_type gtk_file_chooser_button_get_type
gtk_file_chooser_dialog_get_type gtk_file_chooser_dialog_get_type
@@ -77,7 +76,6 @@ gtk_gesture_multi_press_get_type
gtk_gesture_pan_get_type gtk_gesture_pan_get_type
gtk_gesture_rotate_get_type gtk_gesture_rotate_get_type
gtk_gesture_single_get_type gtk_gesture_single_get_type
gtk_gesture_stylus_get_type
gtk_gesture_swipe_get_type gtk_gesture_swipe_get_type
gtk_gesture_zoom_get_type gtk_gesture_zoom_get_type
gtk_gl_area_get_type gtk_gl_area_get_type
@@ -98,9 +96,6 @@ gtk_list_store_get_type
gtk_list_box_get_type gtk_list_box_get_type
gtk_list_box_row_get_type gtk_list_box_row_get_type
gtk_lock_button_get_type gtk_lock_button_get_type
gtk_media_controls_get_type
gtk_media_file_get_type
gtk_media_stream_get_type
gtk_menu_bar_get_type gtk_menu_bar_get_type
gtk_menu_button_get_type gtk_menu_button_get_type
gtk_menu_get_type gtk_menu_get_type
@@ -118,7 +113,6 @@ gtk_page_setup_get_type
@DISABLE_ON_W32@gtk_page_setup_unix_dialog_get_type @DISABLE_ON_W32@gtk_page_setup_unix_dialog_get_type
gtk_paned_get_type gtk_paned_get_type
gtk_paper_size_get_type gtk_paper_size_get_type
gtk_picture_get_type
gtk_popover_get_type gtk_popover_get_type
gtk_popover_menu_get_type gtk_popover_menu_get_type
@DISABLE_ON_W32@gtk_printer_get_type @DISABLE_ON_W32@gtk_printer_get_type
@@ -185,7 +179,6 @@ gtk_tree_sortable_get_type
gtk_tree_store_get_type gtk_tree_store_get_type
gtk_tree_view_column_get_type gtk_tree_view_column_get_type
gtk_tree_view_get_type gtk_tree_view_get_type
gtk_video_get_type
gtk_viewport_get_type gtk_viewport_get_type
gtk_volume_button_get_type gtk_volume_button_get_type
gtk_widget_get_type gtk_widget_get_type

View File

@@ -179,6 +179,41 @@
</para> </para>
</refsect2> </refsect2>
<refsect2 id="event-masks">
<title>Event masks</title>
<para>
Each widget instance has a basic event mask and another per input device,
which determine the types of input event it receives. Each event mask set
on a widget is added to the corresponding (basic or per-device) event mask
for the widgets #GdkSurface, and all child #GdkSurfaces.
</para>
<para>
Filtering events against event masks happens inside #GdkSurface, which
exposes event masks to the windowing system to reduce the number of events
GDK receives from it. On receiving an event, it is filtered against the
#GdkSurfaces mask for the input device, if set. Otherwise, it is filtered
against the #GdkSurfaces basic event mask.
</para>
<para>
This means that widgets must add to the event mask for each event type
they expect to receive, using gtk_widget_set_events() or
gtk_widget_add_events() to preserve the existing mask. Widgets which are
aware of floating devices should use gtk_widget_set_device_events() or
gtk_widget_add_device_events(), and must explicitly enable the device
using gtk_widget_set_device_enabled(). See the #GdkDeviceManager
documentation for more information.
</para>
<para>
All standard widgets set the event mask for all events they expect to
receive, and it is not necessary to modify this. Masks should be set when
implementing a new widget.
</para>
</refsect2>
<refsect2> <refsect2>
<title>Touch events</title> <title>Touch events</title>

View File

@@ -1,195 +1,4 @@
private_headers = [ private_headers = [
'gdkpixbufutilsprivate.h',
'gtkaccelgroupprivate.h',
'gtkaccelmapprivate.h',
'gtkactionhelperprivate.h',
'gtkactionmuxerprivate.h',
'gtkadjustmentprivate.h',
'gtkallocatedbitmaskprivate.h',
'gtkappchooserprivate.h',
'gtkapplicationaccelsprivate.h',
'gtkapplicationprivate.h',
'gtkbindingsprivate.h',
'gtkbitmaskprivate.h',
'gtkboxprivate.h',
'gtkbuilderprivate.h',
'gtkbuttonprivate.h',
'gtkcellareaboxcontextprivate.h',
'gtkcheckbuttonprivate.h',
'gtkcheckmenuitemprivate.h',
'gtkcolorchooserprivate.h',
'gtkcoloreditorprivate.h',
'gtkcolorplaneprivate.h',
'gtkcolorscaleprivate.h',
'gtkcolorswatchprivate.h',
'gtkcomboboxprivate.h',
'gtkcontainerprivate.h',
'gtkcssanimatedstyleprivate.h',
'gtkcssanimationprivate.h',
'gtkcssarrayvalueprivate.h',
'gtkcssbgsizevalueprivate.h',
'gtkcssbordervalueprivate.h',
'gtkcsscalcvalueprivate.h',
'gtkcsscolorvalueprivate.h',
'gtkcsscornervalueprivate.h',
'gtkcssdimensionvalueprivate.h',
'gtkcssdynamicprivate.h',
'gtkcsseasevalueprivate.h',
'gtkcssenumvalueprivate.h',
'gtkcssfiltervalueprivate.h',
'gtkcssfontfeaturesvalueprivate.h',
'gtkcssfontvariationsvalueprivate.h',
'gtkcssiconthemevalueprivate.h',
'gtkcssimagebuiltinprivate.h',
'gtkcssimagecrossfadeprivate.h',
'gtkcssimagefallbackprivate.h',
'gtkcssimageiconthemeprivate.h',
'gtkcssimageinvalidprivate.h',
'gtkcssimagelinearprivate.h',
'gtkcssimagepaintableprivate.h',
'gtkcssimageprivate.h',
'gtkcssimageradialprivate.h',
'gtkcssimagerecolorprivate.h',
'gtkcssimagescaledprivate.h',
'gtkcssimageurlprivate.h',
'gtkcssimagevalueprivate.h',
'gtkcssimagewin32private.h',
'gtkcssinheritvalueprivate.h',
'gtkcssinitialvalueprivate.h',
'gtkcsskeyframesprivate.h',
'gtkcsslookupprivate.h',
'gtkcssmatcherprivate.h',
'gtkcssnodedeclarationprivate.h',
'gtkcssnodeprivate.h',
'gtkcssnodestylecacheprivate.h',
'gtkcssnumbervalueprivate.h',
'gtkcsspalettevalueprivate.h',
'gtkcssparserprivate.h',
'gtkcsspathnodeprivate.h',
'gtkcsspositionvalueprivate.h',
'gtkcssproviderprivate.h',
'gtkcssrepeatvalueprivate.h',
'gtkcssrgbavalueprivate.h',
'gtkcsssectionprivate.h',
'gtkcssselectorprivate.h',
'gtkcssshadowsvalueprivate.h',
'gtkcssshadowvalueprivate.h',
'gtkcssshorthandpropertyprivate.h',
'gtkcssstaticstyleprivate.h',
'gtkcssstringvalueprivate.h',
'gtkcssstylechangeprivate.h',
'gtkcssstyleprivate.h',
'gtkcssstylepropertyprivate.h',
'gtkcsstransformvalueprivate.h',
'gtkcsstransientnodeprivate.h',
'gtkcsstransitionprivate.h',
'gtkcsstypesprivate.h',
'gtkcssunsetvalueprivate.h',
'gtkcssvalueprivate.h',
'gtkcsswidgetnodeprivate.h',
'gtkcsswin32sizevalueprivate.h',
'gtkdialogprivate.h',
'gtkdndprivate.h',
'gtkentryprivate.h',
'gtkeventcontrollerlegacyprivate.h',
'gtkeventcontrollerprivate.h',
'gtkfilechoosererrorstackprivate.h',
'gtkfilechoosernativeprivate.h',
'gtkfilechooserprivate.h',
'gtkfilechooserwidgetprivate.h',
'gtkfilefilterprivate.h',
'gtkfontchooserprivate.h',
'gtkfontchooserwidgetprivate.h',
'gtkgesturedragprivate.h',
'gtkgesturelongpressprivate.h',
'gtkgesturemultipressprivate.h',
'gtkgesturepanprivate.h',
'gtkgestureprivate.h',
'gtkgesturerotateprivate.h',
'gtkgesturesingleprivate.h',
'gtkgesturestylusprivate.h',
'gtkgestureswipeprivate.h',
'gtkgesturezoomprivate.h',
'gtkgizmoprivate.h',
'gtkheaderbarprivate.h',
'gtkhslaprivate.h',
'gtkiconcacheprivate.h',
'gtkiconcachevalidatorprivate.h',
'gtkiconhelperprivate.h',
'gtkiconprivate.h',
'gtkiconthemeprivate.h',
'gtkiconviewprivate.h',
'gtkimagedefinitionprivate.h',
'gtkimageprivate.h',
'gtkimcontextsimpleprivate.h',
'gtkimmoduleprivate.h',
'gtkkineticscrollingprivate.h',
'gtklabelprivate.h',
'gtklockbuttonprivate.h',
'gtkmagnifierprivate.h',
'gtkmediafileprivate.h',
'gtkmenubuttonprivate.h',
'gtkmenuitemprivate.h',
'gtkmenuprivate.h',
'gtkmenushellprivate.h',
'gtkmodulesprivate.h',
'gtkmountoperationprivate.h',
'gtknativedialogprivate.h',
'gtknomediafileprivate.h',
'gtkorientableprivate.h',
'gtkplacessidebarprivate.h',
'gtkplacesviewprivate.h',
'gtkplacesviewrowprivate.h',
'gtkpointerfocusprivate.h',
'gtkpopoverprivate.h',
'gtkprinter-private.h',
'gtkprintoperation-private.h',
'gtkprivate.h',
'gtkprogresstrackerprivate.h',
'gtkrangeprivate.h',
'gtkrbtreeprivate.h',
'gtkrenderbackgroundprivate.h',
'gtkrenderborderprivate.h',
'gtkrendericonprivate.h',
'gtkrendernodepaintableprivate.h',
'gtkroundedboxprivate.h',
'gtkscalerprivate.h',
'gtksearchentryprivate.h',
'gtkselectionprivate.h',
'gtksettingsprivate.h',
'gtkshortcutsshortcutprivate.h',
'gtkshortcutswindowprivate.h',
'gtksidebarrowprivate.h',
'gtksizegroup-private.h',
'gtksizerequestcacheprivate.h',
'gtksnapshotprivate.h',
'gtkstyleanimationprivate.h',
'gtkstylecascadeprivate.h',
'gtkstylecontextprivate.h',
'gtkstylepropertyprivate.h',
'gtkstyleproviderprivate.h',
'gtktextbufferprivate.h',
'gtktextchildprivate.h',
'gtktextdisplayprivate.h',
'gtktexthandleprivate.h',
'gtktextiterprivate.h',
'gtktextlayoutprivate.h',
'gtktextmarkprivate.h',
'gtktexttagprivate.h',
'gtktextviewprivate.h',
'gtktogglebuttonprivate.h',
'gtktoolbarprivate.h',
'gtktooltipprivate.h',
'gtktooltipwindowprivate.h',
'gtktreeprivate.h',
'gtkutilsprivate.h',
'gtkwidgetpaintableprivate.h',
'gtkwidgetpathprivate.h',
'gtkwidgetprivate.h',
'gtkwin32drawprivate.h',
'gtkwin32themeprivate.h',
'gtkwindowprivate.h',
'gtk-text-input-client-protocol.h',
] ]
images = [ images = [
@@ -355,6 +164,7 @@ content_files = [
'input-handling.xml', 'input-handling.xml',
'migrating-2to4.xml', 'migrating-2to4.xml',
'migrating-3to4.xml', 'migrating-3to4.xml',
'mir.xml',
'osx.sgml', 'osx.sgml',
'other_software.sgml', 'other_software.sgml',
'overview.xml', 'overview.xml',
@@ -397,18 +207,17 @@ else
types_conf.set('DISABLE_ON_QUARTZ', '') types_conf.set('DISABLE_ON_QUARTZ', '')
endif endif
configure_file(input: 'gtk4.types.in', output: 'gtk4.types', configuration: types_conf)
gnome.gtkdoc('gtk4', gnome.gtkdoc('gtk4',
mode: 'none', mode: 'none',
main_xml: 'gtk4-docs.xml', main_xml: 'gtk4-docs.xml',
src_dir: [ src_dir: [
gtkinc, join_paths(meson.source_root(), 'gtk'),
join_paths(meson.build_root(), 'gtk'),
], ],
dependencies: libgtk_dep, dependencies: libgtk_dep,
gobject_typesfile: configure_file( gobject_typesfile: 'gtk4.types',
input: 'gtk4.types.in',
output: 'gtk4.types',
configuration: types_conf,
),
scan_args: [ scan_args: [
'--ignore-decorators=_GDK_EXTERN|G_GNUC_WARN_UNUSED_RESULT', '--ignore-decorators=_GDK_EXTERN|G_GNUC_WARN_UNUSED_RESULT',
'--ignore-headers=' + ' '.join(private_headers), '--ignore-headers=' + ' '.join(private_headers),

View File

@@ -20,11 +20,11 @@
<para> <para>
The steps outlined in the following sections assume that your The steps outlined in the following sections assume that your
application is working with GTK+ 3.24, which is the final stable application is working with GTK+ 3.22, which is the final stable
release of GTK+ 3.x. It includes all the necessary APIs and tools release of GTK+ 3.x. It includes all the necessary APIs and tools
to help you port your application to GTK+ 4. If you are still using to help you port your application to GTK+ 4. If you are still using
an older version of GTK+ 3.x, you should first get your application an older version of GTK+ 3.x, you should first get your application
to build and work with the latest minor release in the 3.24 series. to build and work with the latest minor release in the 3.22 series.
</para> </para>
<section> <section>
@@ -34,7 +34,7 @@
widgets have been deprecated. These deprecations are clearly spelled widgets have been deprecated. These deprecations are clearly spelled
out in the API reference, with hints about the recommended replacements. out in the API reference, with hints about the recommended replacements.
The API reference for GTK+ 3 also includes an The API reference for GTK+ 3 also includes an
<ulink url="https://developer.gnome.org/gtk3/3.24/api-index-deprecated.html">index</ulink> of all deprecated symbols. <ulink url="https://developer.gnome.org/gtk3/3.22/api-index-deprecated.html">index</ulink> of all deprecated symbols.
</para> </para>
<para> <para>
To verify that your program does not use any deprecated symbols, To verify that your program does not use any deprecated symbols,
@@ -79,13 +79,13 @@
<title>Review your window creation flags</title> <title>Review your window creation flags</title>
<para> <para>
GTK+ 4 removes the GDK_WA_CURSOR flag. Instead, just use GTK+ 4 removes the GDK_WA_CURSOR flag. Instead, just use
gdk_window_set_cursor() to set a cursor on the window after gdk_surface_set_cursor() to set a cursor on the window after
creating it. creating it.
</para> </para>
<para> <para>
GTK+ 4 also removes the GDK_WA_VISUAL flag, and always uses GTK+ 4 also removes the GDK_WA_VISUAL flag, and always uses
an RGBA visual for windows. To prepare your code for this, an RGBA visual for windows. To prepare your code for this,
use gdk_window_set_visual (gdk_screen_get_rgba_visual ()) after use gdk_surface_set_visual (gdk_screen_get_rgba_visual ()) after
creating your window. creating your window.
</para> </para>
<para> <para>
@@ -169,30 +169,6 @@
</para> </para>
</section> </section>
<section>
<title>Stop using GtkWidget event signals</title>
<para>
Event controllers and #GtkGestures replace event signals in GTK+ 4. They
have been backported to GTK+ 3.x so you can prepare for this change.
</para>
</section>
<section>
<title>Set a proper app_id</title>
<para>
In GTK+4 we want the application's #GApplication
'application-id' (and therefore the D-Bus name), the desktop
file basename and Wayland's xdg-shell app_id to match. In
order to achieve this with GTK+3 call g_set_prgname() with the same
application id you passed to #GtkApplication. Rename your
desktop files to match the application id if needed.
</para>
<para>
The call to g_set_prgname() can be removed once you fully migrated
to GTK+4.
</para>
</section>
</section> </section>
<section> <section>
@@ -241,12 +217,9 @@
</section> </section>
<section> <section>
<title>Adapt to GdkWindow API changes</title> <title>Adapt to GdkSurface API changes</title>
<para> <para>
GdkWindow has been renamed to GdkSurface. The gdk_surface_new() function has been replaced by a number of more
</para>
<para>
The gdk_window_new() function has been replaced by a number of more
specialized constructors: gdk_surface_new_toplevel(), gdk_surface_new_popup(), specialized constructors: gdk_surface_new_toplevel(), gdk_surface_new_popup(),
gdk_surface_new_temp(), gdk_surface_new_child(), gdk_surface_new_input(), gdk_surface_new_temp(), gdk_surface_new_child(), gdk_surface_new_input(),
gdk_wayland_surface_new_subsurface(). Use the appropriate ones to create gdk_wayland_surface_new_subsurface(). Use the appropriate ones to create
@@ -257,7 +230,7 @@
complicating the code and could not be supported across backends. complicating the code and could not be supported across backends.
</para> </para>
<para> <para>
gdk_window_reparent() is no longer available. gdk_surface_reparent() is no longer available.
</para> </para>
</section> </section>
@@ -335,15 +308,6 @@
</para> </para>
</section> </section>
<section>
<title>Adapt to GtkWidget's size allocation changes</title>
<para>
The #GtkWidget::size-allocate signal now takes the baseline as an
argument, so you no longer need to call gtk_widget_get_allocated_baseline()
to get it.
</para>
</section>
<section> <section>
<title>Switch to GtkWidget's children APIs</title> <title>Switch to GtkWidget's children APIs</title>
<para> <para>
@@ -424,10 +388,6 @@
from ui files it run the command <command>gtk4-builder-tool simplify --replace</command> from ui files it run the command <command>gtk4-builder-tool simplify --replace</command>
on them. on them.
</para> </para>
<para>
The function gtk_widget_show_all(), the #GtkWidget::no-show-all property
and its getter and setter have been removed in GTK+ 4, so you should stop using them.
</para>
</section> </section>
<section> <section>
@@ -456,8 +416,8 @@
<title>GdkPixbuf is deemphasized</title> <title>GdkPixbuf is deemphasized</title>
<para> <para>
A number of #GdkPixbuf-based APIs have been removed. The available replacements A number of #GdkPixbuf-based APIs have been removed. The available replacements
are either using #GIcon, or the newly introduced #GdkTexture or #GdkPaintable are either using #GIcon, cairo_surface_t or the newly introduced #GdkTexture class
classes instead. instead.
</para> </para>
<para> <para>
If you are dealing with pixbufs, you can use gdk_texture_new_for_pixbuf() If you are dealing with pixbufs, you can use gdk_texture_new_for_pixbuf()
@@ -466,36 +426,12 @@
</section> </section>
<section> <section>
<title>GtkWidget event signals are removed</title> <title>GtkWidget event signals are deemphasized</title>
<para> <para>
Event controllers and #GtkGestures have already been introduced in GTK+ 3 to handle Event controllers and #GtkGestures have already been introduced in GTK+ 3 to handle
input for many cases. In GTK+ 4, the traditional widget signals for handling input, input for many cases. In GTK+ 4, even more are available, such as #GtkEventControllerScroll
such as #GtkWidget::motion-event or #GtkWidget::event have been removed. and GtkEventControllerMotion, and the traditional widget signals for handling input,
</para> such as #GtkWidget::motion-event or #GtkWidget::event have been deprecated.
</section>
<section>
<title>Invalidation handling has changed</title>
<para>
Only gtk_widget_queue_draw() is left to mark a widget as needing redraw.
Variations like gtk_widget_queue_draw_rectangle() or gtk_widget_queue_draw_region()
are no longer available.
</para>
</section>
<section>
<title>Stop using GtkWidget::draw</title>
<para>
The #GtkWidget::draw signal has been removed. Widgets need to implement the
#GtkWidget::snapshot function now. Connecting draw signal handlers is no longer possible.
</para>
</section>
<section>
<title>Window content observation has changed</title>
<para>
Observing widget contents and widget size is now done by using the
#GtkWidgetPaintable object instead of connecting to widget signals.
</para> </para>
</section> </section>
@@ -539,7 +475,6 @@
#GtkCellRendererPixbuf:icon-size. #GtkCellRendererPixbuf:icon-size.
</para> </para>
</section> </section>
</section> </section>
</chapter> </chapter>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<refentry id="gtk-mir">
<refmeta>
<refentrytitle>Using GTK+ with Mir</refentrytitle>
<manvolnum>3</manvolnum>
<refmiscinfo>GTK Library</refmiscinfo>
</refmeta>
<refnamediv>
<refname>Using GTK+ with Mir</refname>
<refpurpose>
Mir-specific aspects of using GTK+
</refpurpose>
</refnamediv>
<refsect1>
<title>Using GTK+ with Mir</title>
<para>
The GDK Mir backend provides support for running GTK+ applications
under Mir based display servers. To run your application in this way,
select the Mir backend by setting <literal>GDK_BACKEND=mir</literal>.
</para>
<para>
Currently, the Mir backend does not use any additional commandline
options or environment variables.
</para>
</refsect1>
</refentry>

View File

@@ -162,10 +162,10 @@ additional environment variables.
Linux and Unix, and the ';' character on Windows. Linux and Unix, and the ';' character on Windows.
</para> </para>
<warning> <warning>
Note that this environment variable is read by GTK+ 2.x and GTK+ 3.x too, Note that this environment variable is read by GTK+ 2.x too, which
which makes it unsuitable for setting it system-wide (or session-wide), makes it unsuitable for setting it system-wide (or session-wide),
since doing so will cause applications using different GTK+ versions since doing so will cause either GTK+ 2.x applications or GTK+ 3
to see incompatible modules. applications to see incompatible modules.
</warning> </warning>
</formalpara> </formalpara>
@@ -309,7 +309,7 @@ nevertheless.
<listitem><para>Use a legacy OpenGL context</para></listitem> <listitem><para>Use a legacy OpenGL context</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term>gl-gles</term> <term>gl-legacy</term>
<listitem><para>Use a GLES OpenGL context</para></listitem> <listitem><para>Use a GLES OpenGL context</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@@ -320,6 +320,11 @@ nevertheless.
<term>vulkan-validate</term> <term>vulkan-validate</term>
<listitem><para>Load the Vulkan validation layer, if available</para></listitem> <listitem><para>Load the Vulkan validation layer, if available</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>cairo-image</term>
<listitem><para>Use image surfaces for cairo rendering. This essentially
turns off all hardware acceleration with the cairo renderer</para></listitem>
</varlistentry>
</variablelist> </variablelist>
The special value <literal>all</literal> can be used to turn on all The special value <literal>all</literal> can be used to turn on all
debug options. The special value <literal>help</literal> can be used debug options. The special value <literal>help</literal> can be used
@@ -347,14 +352,6 @@ nevertheless.
<term>opengl</term> <term>opengl</term>
<listitem><para>OpenGL renderer information</para></listitem> <listitem><para>OpenGL renderer information</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>shaders</term>
<listitem><para>Shaders</para></listitem>
</varlistentry>
<varlistentry>
<term>ssurface</term>
<listitem><para>Surfaces</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>vulkan</term> <term>vulkan</term>
<listitem><para>Vulkan renderer information</para></listitem> <listitem><para>Vulkan renderer information</para></listitem>
@@ -370,10 +367,6 @@ nevertheless.
</variablelist> </variablelist>
A number of options affect behavior instead of logging: A number of options affect behavior instead of logging:
<variablelist> <variablelist>
<varlistentry>
<term>diff</term>
<listitem><para>Show differences</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>geometry</term> <term>geometry</term>
<listitem><para>Show borders</para></listitem> <listitem><para>Show borders</para></listitem>
@@ -435,6 +428,11 @@ nevertheless.
<listitem><para>Selects the Wayland backend for connecting to Wayland display servers</para></listitem> <listitem><para>Selects the Wayland backend for connecting to Wayland display servers</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>mir</term>
<listitem><para>Selects the Mir backend for connecting to Mir display servers</para></listitem>
</varlistentry>
</variablelist> </variablelist>
Since 3.10, this environment variable can contain a comma-separated list Since 3.10, this environment variable can contain a comma-separated list
of backend names, which are tried in order. The list may also contain of backend names, which are tried in order. The list may also contain
@@ -455,44 +453,6 @@ nevertheless.
</para> </para>
</formalpara> </formalpara>
<formalpara>
<title><envar>GSK_RENDERER</envar></title>
<para>
If set, selects the GSK renderer to use. The following renderers can
be selected, provided they are included in the GTK library you are using
and the GDK backend supports them:
<variablelist>
<varlistentry>
<term>help</term>
<listitem><para>Prints information about available options</para></listitem>
</varlistentry>
<varlistentry>
<term>broadway</term>
<listitem><para>Selects the Broadway-backend specific renderer</para></listitem>
</varlistentry>
<varlistentry>
<term>cairo</term>
<listitem><para>Selects the fallback Cairo renderer</para></listitem>
</varlistentry>
<varlistentry>
<term>gl</term>
<listitem><para>Selects the default OpenGL renderer</para></listitem>
</varlistentry>
<varlistentry>
<term>vulkan</term>
<listitem><para>Selects the Vulkan renderer</para></listitem>
</varlistentry>
</variablelist>
</para>
</formalpara>
<formalpara> <formalpara>
<title><envar>GTK_CSD</envar></title> <title><envar>GTK_CSD</envar></title>

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
SRC = main.c exampleapp.c exampleappwin.c SRC = main.c exampleapp.c exampleappwin.c

View File

@@ -2,8 +2,8 @@ To make gnome-shell use the desktop file and icon for this example
while running it uninstalled, do the following: while running it uninstalled, do the following:
mkdir -p ~/.local/share/applications mkdir -p ~/.local/share/applications
sed -e "s#@bindir@#$PWD#" org.gtk.exampleapp.desktop \ sed -e "s#@bindir@#$PWD#" exampleapp.desktop \
> ~/.local/share/applications/org.gtk.exampleapp.desktop > ~/.local/share/applications/lt-exampleapp.desktop
mkdir -p ~/.local/share/icons/hicolor/48x48/apps mkdir -p ~/.local/share/icons/hicolor/48x48/apps
cp exampleapp.png ~/.local/share/icons/hicolor/48x48/apps cp exampleapp.png ~/.local/share/icons/hicolor/48x48/apps

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0) GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0)

View File

@@ -7,36 +7,43 @@
struct _ExampleAppPrefs struct _ExampleAppPrefs
{ {
GtkDialog parent; GtkDialog parent;
};
typedef struct _ExampleAppPrefsPrivate ExampleAppPrefsPrivate;
struct _ExampleAppPrefsPrivate
{
GSettings *settings; GSettings *settings;
GtkWidget *font; GtkWidget *font;
GtkWidget *transition; GtkWidget *transition;
}; };
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
static void static void
example_app_prefs_init (ExampleAppPrefs *prefs) example_app_prefs_init (ExampleAppPrefs *prefs)
{ {
gtk_widget_init_template (GTK_WIDGET (prefs)); ExampleAppPrefsPrivate *priv;
prefs->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (prefs->settings, "font", priv = example_app_prefs_get_instance_private (prefs);
prefs->font, "font", gtk_widget_init_template (GTK_WIDGET (prefs));
priv->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (priv->settings, "font",
priv->font, "font",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
g_settings_bind (prefs->settings, "transition", g_settings_bind (priv->settings, "transition",
prefs->transition, "active-id", priv->transition, "active-id",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
} }
static void static void
example_app_prefs_dispose (GObject *object) example_app_prefs_dispose (GObject *object)
{ {
ExampleAppPrefs *prefs; ExampleAppPrefsPrivate *priv;
prefs = EXAMPLE_APP_PREFS (object); priv = example_app_prefs_get_instance_private (EXAMPLE_APP_PREFS (object));
g_clear_object (&priv->settings);
g_clear_object (&prefs->settings);
G_OBJECT_CLASS (example_app_prefs_parent_class)->dispose (object); G_OBJECT_CLASS (example_app_prefs_parent_class)->dispose (object);
} }
@@ -48,8 +55,8 @@ example_app_prefs_class_init (ExampleAppPrefsClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/prefs.ui"); "/org/gtk/exampleapp/prefs.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppPrefs, font); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppPrefs, font);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppPrefs, transition); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppPrefs, transition);
} }
ExampleAppPrefs * ExampleAppPrefs *

View File

@@ -6,7 +6,12 @@
struct _ExampleAppWindow struct _ExampleAppWindow
{ {
GtkApplicationWindow parent; GtkApplicationWindow parent;
};
typedef struct _ExampleAppWindowPrivate ExampleAppWindowPrivate;
struct _ExampleAppWindowPrivate
{
GSettings *settings; GSettings *settings;
GtkWidget *stack; GtkWidget *stack;
GtkWidget *search; GtkWidget *search;
@@ -19,12 +24,13 @@ struct _ExampleAppWindow
GtkWidget *lines_label; GtkWidget *lines_label;
}; };
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
static void static void
search_text_changed (GtkEntry *entry, search_text_changed (GtkEntry *entry)
ExampleAppWindow *win)
{ {
ExampleAppWindow *win;
ExampleAppWindowPrivate *priv;
const gchar *text; const gchar *text;
GtkWidget *tab; GtkWidget *tab;
GtkWidget *view; GtkWidget *view;
@@ -36,7 +42,10 @@ search_text_changed (GtkEntry *entry,
if (text[0] == '\0') if (text[0] == '\0')
return; return;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack)); win = EXAMPLE_APP_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry)));
priv = example_app_window_get_instance_private (win);
tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
view = gtk_bin_get_child (GTK_BIN (tab)); view = gtk_bin_get_child (GTK_BIN (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -55,15 +64,19 @@ static void
find_word (GtkButton *button, find_word (GtkButton *button,
ExampleAppWindow *win) ExampleAppWindow *win)
{ {
ExampleAppWindowPrivate *priv;
const gchar *word; const gchar *word;
priv = example_app_window_get_instance_private (win);
word = gtk_button_get_label (button); word = gtk_button_get_label (button);
gtk_entry_set_text (GTK_ENTRY (win->searchentry), word); gtk_entry_set_text (GTK_ENTRY (priv->searchentry), word);
} }
static void static void
update_words (ExampleAppWindow *win) update_words (ExampleAppWindow *win)
{ {
ExampleAppWindowPrivate *priv;
GHashTable *strings; GHashTable *strings;
GHashTableIter iter; GHashTableIter iter;
GtkWidget *tab, *view, *row; GtkWidget *tab, *view, *row;
@@ -72,7 +85,9 @@ update_words (ExampleAppWindow *win)
GList *children, *l; GList *children, *l;
gchar *word, *key; gchar *word, *key;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack)); priv = example_app_window_get_instance_private (win);
tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
if (tab == NULL) if (tab == NULL)
return; return;
@@ -100,9 +115,9 @@ update_words (ExampleAppWindow *win)
} }
done: done:
children = gtk_container_get_children (GTK_CONTAINER (win->words)); children = gtk_container_get_children (GTK_CONTAINER (priv->words));
for (l = children; l; l = l->next) for (l = children; l; l = l->next)
gtk_container_remove (GTK_CONTAINER (win->words), GTK_WIDGET (l->data)); gtk_container_remove (GTK_CONTAINER (priv->words), GTK_WIDGET (l->data));
g_list_free (children); g_list_free (children);
g_hash_table_iter_init (&iter, strings); g_hash_table_iter_init (&iter, strings);
@@ -111,7 +126,8 @@ done:
row = gtk_button_new_with_label (key); row = gtk_button_new_with_label (key);
g_signal_connect (row, "clicked", g_signal_connect (row, "clicked",
G_CALLBACK (find_word), win); G_CALLBACK (find_word), win);
gtk_container_add (GTK_CONTAINER (win->words), row); gtk_widget_show (row);
gtk_container_add (GTK_CONTAINER (priv->words), row);
} }
g_hash_table_unref (strings); g_hash_table_unref (strings);
@@ -120,12 +136,16 @@ done:
static void static void
update_lines (ExampleAppWindow *win) update_lines (ExampleAppWindow *win)
{ {
ExampleAppWindowPrivate *priv;
GtkWidget *tab, *view; GtkWidget *tab, *view;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
GtkTextIter iter;
int count; int count;
gchar *lines; gchar *lines;
tab = gtk_stack_get_visible_child (GTK_STACK (win->stack)); priv = example_app_window_get_instance_private (win);
tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
if (tab == NULL) if (tab == NULL)
return; return;
@@ -133,21 +153,34 @@ update_lines (ExampleAppWindow *win)
view = gtk_bin_get_child (GTK_BIN (tab)); view = gtk_bin_get_child (GTK_BIN (tab));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
count = gtk_text_buffer_get_line_count (buffer); count = 0;
gtk_text_buffer_get_start_iter (buffer, &iter);
while (!gtk_text_iter_is_end (&iter))
{
count++;
if (!gtk_text_iter_forward_line (&iter))
break;
}
lines = g_strdup_printf ("%d", count); lines = g_strdup_printf ("%d", count);
gtk_label_set_text (GTK_LABEL (win->lines), lines); gtk_label_set_text (GTK_LABEL (priv->lines), lines);
g_free (lines); g_free (lines);
} }
static void static void
visible_child_changed (GObject *stack, visible_child_changed (GObject *stack,
GParamSpec *pspec, GParamSpec *pspec)
ExampleAppWindow *win)
{ {
ExampleAppWindow *win;
ExampleAppWindowPrivate *priv;
if (gtk_widget_in_destruction (GTK_WIDGET (stack))) if (gtk_widget_in_destruction (GTK_WIDGET (stack)))
return; return;
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (win->searchbar), FALSE); win = EXAMPLE_APP_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (stack)));
priv = example_app_window_get_instance_private (win);
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->searchbar), FALSE);
update_words (win); update_words (win);
update_lines (win); update_lines (win);
} }
@@ -163,43 +196,45 @@ words_changed (GObject *sidebar,
static void static void
example_app_window_init (ExampleAppWindow *win) example_app_window_init (ExampleAppWindow *win)
{ {
ExampleAppWindowPrivate *priv;
GtkBuilder *builder; GtkBuilder *builder;
GMenuModel *menu; GMenuModel *menu;
GAction *action; GAction *action;
priv = example_app_window_get_instance_private (win);
gtk_widget_init_template (GTK_WIDGET (win)); gtk_widget_init_template (GTK_WIDGET (win));
win->settings = g_settings_new ("org.gtk.exampleapp"); priv->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition", g_settings_bind (priv->settings, "transition",
win->stack, "transition-type", priv->stack, "transition-type",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
g_settings_bind (win->settings, "show-words", g_settings_bind (priv->settings, "show-words",
win->sidebar, "reveal-child", priv->sidebar, "reveal-child",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
g_object_bind_property (win->search, "active", g_object_bind_property (priv->search, "active",
win->searchbar, "search-mode-enabled", priv->searchbar, "search-mode-enabled",
G_BINDING_BIDIRECTIONAL); G_BINDING_BIDIRECTIONAL);
g_signal_connect (win->sidebar, "notify::reveal-child", g_signal_connect (priv->sidebar, "notify::reveal-child",
G_CALLBACK (words_changed), win); G_CALLBACK (words_changed), win);
builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui"); builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu")); menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (win->gears), menu); gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->gears), menu);
g_object_unref (builder); g_object_unref (builder);
action = g_settings_create_action (win->settings, "show-words"); action = g_settings_create_action (priv->settings, "show-words");
g_action_map_add_action (G_ACTION_MAP (win), action); g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action); g_object_unref (action);
action = (GAction*) g_property_action_new ("show-lines", win->lines, "visible"); action = (GAction*) g_property_action_new ("show-lines", priv->lines, "visible");
g_action_map_add_action (G_ACTION_MAP (win), action); g_action_map_add_action (G_ACTION_MAP (win), action);
g_object_unref (action); g_object_unref (action);
g_object_bind_property (win->lines, "visible", g_object_bind_property (priv->lines, "visible",
win->lines_label, "visible", priv->lines_label, "visible",
G_BINDING_DEFAULT); G_BINDING_DEFAULT);
g_object_set (gtk_settings_get_default (), "gtk-shell-shows-app-menu", FALSE, NULL); g_object_set (gtk_settings_get_default (), "gtk-shell-shows-app-menu", FALSE, NULL);
@@ -210,10 +245,12 @@ static void
example_app_window_dispose (GObject *object) example_app_window_dispose (GObject *object)
{ {
ExampleAppWindow *win; ExampleAppWindow *win;
ExampleAppWindowPrivate *priv;
win = EXAMPLE_APP_WINDOW (object); win = EXAMPLE_APP_WINDOW (object);
priv = example_app_window_get_instance_private (win);
g_clear_object (&win->settings); g_clear_object (&priv->settings);
G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object); G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
} }
@@ -226,15 +263,15 @@ example_app_window_class_init (ExampleAppWindowClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui"); "/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, search); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, search);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchbar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchentry); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, searchentry);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, words); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, words);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, sidebar); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, sidebar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines_label); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, lines_label);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), visible_child_changed); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), visible_child_changed);
@@ -250,6 +287,7 @@ void
example_app_window_open (ExampleAppWindow *win, example_app_window_open (ExampleAppWindow *win,
GFile *file) GFile *file)
{ {
ExampleAppWindowPrivate *priv;
gchar *basename; gchar *basename;
GtkWidget *scrolled, *view; GtkWidget *scrolled, *view;
gchar *contents; gchar *contents;
@@ -258,16 +296,19 @@ example_app_window_open (ExampleAppWindow *win,
GtkTextTag *tag; GtkTextTag *tag;
GtkTextIter start_iter, end_iter; GtkTextIter start_iter, end_iter;
priv = example_app_window_get_instance_private (win);
basename = g_file_get_basename (file); basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled);
gtk_widget_set_hexpand (scrolled, TRUE); gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (scrolled), view); gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename); gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -278,7 +319,7 @@ example_app_window_open (ExampleAppWindow *win,
} }
tag = gtk_text_buffer_create_tag (buffer, NULL, NULL); tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
g_settings_bind (win->settings, "font", g_settings_bind (priv->settings, "font",
tag, "font", tag, "font",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
@@ -288,7 +329,7 @@ example_app_window_open (ExampleAppWindow *win,
g_free (basename); g_free (basename);
gtk_widget_set_sensitive (win->search, TRUE); gtk_widget_set_sensitive (priv->search, TRUE);
update_words (win); update_words (win);
update_lines (win); update_lines (win);

View File

@@ -9,13 +9,15 @@
<object class="GtkBox" id="vbox"> <object class="GtkBox" id="vbox">
<child> <child>
<object class="GtkGrid" id="grid"> <object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="margin">6</property> <property name="margin">6</property>
<property name="row-spacing">12</property> <property name="row-spacing">12</property>
<property name="column-spacing">6</property> <property name="column-spacing">6</property>
<child> <child>
<object class="GtkLabel" id="fontlabel"> <object class="GtkLabel" id="fontlabel">
<property name="visible">True</property>
<property name="label">_Font:</property> <property name="label">_Font:</property>
<property name="use-underline">1</property> <property name="use-underline">True</property>
<property name="mnemonic-widget">font</property> <property name="mnemonic-widget">font</property>
<property name="xalign">1</property> <property name="xalign">1</property>
</object> </object>
@@ -26,6 +28,7 @@
</child> </child>
<child> <child>
<object class="GtkFontButton" id="font"> <object class="GtkFontButton" id="font">
<property name="visible">True</property>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left-attach">1</property>
@@ -34,8 +37,9 @@
</child> </child>
<child> <child>
<object class="GtkLabel" id="transitionlabel"> <object class="GtkLabel" id="transitionlabel">
<property name="visible">True</property>
<property name="label">_Transition:</property> <property name="label">_Transition:</property>
<property name="use-underline">1</property> <property name="use-underline">True</property>
<property name="mnemonic-widget">transition</property> <property name="mnemonic-widget">transition</property>
<property name="xalign">1</property> <property name="xalign">1</property>
</object> </object>
@@ -46,6 +50,7 @@
</child> </child>
<child> <child>
<object class="GtkComboBoxText" id="transition"> <object class="GtkComboBoxText" id="transition">
<property name="visible">True</property>
<items> <items>
<item translatable="yes" id="none">None</item> <item translatable="yes" id="none">None</item>
<item translatable="yes" id="crossfade">Fade</item> <item translatable="yes" id="crossfade">Fade</item>

View File

@@ -7,35 +7,54 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property> <property name="visible">True</property>
<property name="show-title-buttons">True</property>
<child> <child>
<object class="GtkLabel" id="lines_label"> <object class="GtkLabel" id="lines_label">
<property name="visible">0</property> <property name="visible">False</property>
<property name="label" translatable="yes">Lines:</property> <property name="label" translatable="yes">Lines:</property>
</object> </object>
<packing>
<property name="pack-type">start</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="lines"> <object class="GtkLabel" id="lines">
<property name="visible">0</property> <property name="visible">False</property>
</object> </object>
<packing>
<property name="pack-type">start</property>
</packing>
</child> </child>
<child type="title"> <child type="title">
<object class="GtkStackSwitcher" id="tabs"> <object class="GtkStackSwitcher" id="tabs">
<property name="visible">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkToggleButton" id="search"> <object class="GtkToggleButton" id="search">
<property name="sensitive">0</property> <property name="visible">True</property>
<property name="sensitive">False</property>
<style>
<class name="image-button"/>
</style>
<child>
<object class="GtkImage" id="search-icon">
<property name="visible">True</property>
<property name="icon-name">edit-find-symbolic</property> <property name="icon-name">edit-find-symbolic</property>
</object> </object>
</child>
</object>
<packing> <packing>
<property name="pack-type">end</property> <property name="pack-type">end</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkMenuButton" id="gears"> <object class="GtkMenuButton" id="gears">
<property name="visible">True</property>
<property name="direction">none</property> <property name="direction">none</property>
<property name="use-popover">True</property>
<style> <style>
<class name="image-button"/> <class name="image-button"/>
</style> </style>
@@ -48,26 +67,34 @@
</child> </child>
<child> <child>
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkSearchBar" id="searchbar"> <object class="GtkSearchBar" id="searchbar">
<property name="visible">True</property>
<child> <child>
<object class="GtkSearchEntry" id="searchentry"> <object class="GtkSearchEntry" id="searchentry">
<signal name="search-changed" handler="search_text_changed"/> <signal name="search-changed" handler="search_text_changed"/>
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkBox" id="hbox"> <object class="GtkBox" id="hbox">
<property name="visible">True</property>
<child> <child>
<object class="GtkRevealer" id="sidebar"> <object class="GtkRevealer" id="sidebar">
<property name="visible">True</property>
<property name="transition-type">slide-right</property> <property name="transition-type">slide-right</property>
<child> <child>
<object class="GtkScrolledWindow" id="sidebar-sw"> <object class="GtkScrolledWindow" id="sidebar-sw">
<property name="visible">True</property>
<property name="hscrollbar-policy">never</property> <property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<child> <child>
<object class="GtkListBox" id="words"> <object class="GtkListBox" id="words">
<property name="visible">True</property>
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
</object> </object>
</child> </child>
@@ -78,6 +105,7 @@
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<signal name="notify::visible-child" handler="visible_child_changed"/> <signal name="notify::visible-child" handler="visible_child_changed"/>
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
SRC = exampleapp.c exampleappwin.c main.c SRC = exampleapp.c exampleappwin.c main.c

View File

@@ -7,11 +7,14 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child> <child>
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<child type="title"> <child type="title">
<object class="GtkStackSwitcher" id="tabs"> <object class="GtkStackSwitcher" id="tabs">
<property name="visible">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
</child> </child>
@@ -19,6 +22,7 @@
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
SRC = exampleapp.c exampleappwin.c main.c SRC = exampleapp.c exampleappwin.c main.c

View File

@@ -6,11 +6,16 @@
struct _ExampleAppWindow struct _ExampleAppWindow
{ {
GtkApplicationWindow parent; GtkApplicationWindow parent;
};
typedef struct _ExampleAppWindowPrivate ExampleAppWindowPrivate;
struct _ExampleAppWindowPrivate
{
GtkWidget *stack; GtkWidget *stack;
}; };
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
static void static void
example_app_window_init (ExampleAppWindow *win) example_app_window_init (ExampleAppWindow *win)
@@ -23,7 +28,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
{ {
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui"); "/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
} }
ExampleAppWindow * ExampleAppWindow *
@@ -36,21 +41,25 @@ void
example_app_window_open (ExampleAppWindow *win, example_app_window_open (ExampleAppWindow *win,
GFile *file) GFile *file)
{ {
ExampleAppWindowPrivate *priv;
gchar *basename; gchar *basename;
GtkWidget *scrolled, *view; GtkWidget *scrolled, *view;
gchar *contents; gchar *contents;
gsize length; gsize length;
priv = example_app_window_get_instance_private (win);
basename = g_file_get_basename (file); basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled);
gtk_widget_set_hexpand (scrolled, TRUE); gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (scrolled), view); gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename); gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
{ {

View File

@@ -7,11 +7,14 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child> <child>
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<child type="title"> <child type="title">
<object class="GtkStackSwitcher" id="tabs"> <object class="GtkStackSwitcher" id="tabs">
<property name="visible">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
</child> </child>
@@ -19,6 +22,7 @@
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
SRC = exampleapp.c exampleappwin.c main.c SRC = exampleapp.c exampleappwin.c main.c

View File

@@ -6,11 +6,16 @@
struct _ExampleAppWindow struct _ExampleAppWindow
{ {
GtkApplicationWindow parent; GtkApplicationWindow parent;
};
typedef struct _ExampleAppWindowPrivate ExampleAppWindowPrivate;
struct _ExampleAppWindowPrivate
{
GtkWidget *stack; GtkWidget *stack;
}; };
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
static void static void
example_app_window_init (ExampleAppWindow *win) example_app_window_init (ExampleAppWindow *win)
@@ -23,7 +28,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
{ {
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui"); "/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
} }
ExampleAppWindow * ExampleAppWindow *
@@ -36,21 +41,25 @@ void
example_app_window_open (ExampleAppWindow *win, example_app_window_open (ExampleAppWindow *win,
GFile *file) GFile *file)
{ {
ExampleAppWindowPrivate *priv;
gchar *basename; gchar *basename;
GtkWidget *scrolled, *view; GtkWidget *scrolled, *view;
gchar *contents; gchar *contents;
gsize length; gsize length;
priv = example_app_window_get_instance_private (win);
basename = g_file_get_basename (file); basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled);
gtk_widget_set_hexpand (scrolled, TRUE); gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (scrolled), view); gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename); gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL)) if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
{ {

View File

@@ -7,11 +7,14 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child> <child>
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<child type="title"> <child type="title">
<object class="GtkStackSwitcher" id="tabs"> <object class="GtkStackSwitcher" id="tabs">
<property name="visible">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
</child> </child>
@@ -19,6 +22,7 @@
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0) GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0)

View File

@@ -6,21 +6,29 @@
struct _ExampleAppWindow struct _ExampleAppWindow
{ {
GtkApplicationWindow parent; GtkApplicationWindow parent;
};
typedef struct _ExampleAppWindowPrivate ExampleAppWindowPrivate;
struct _ExampleAppWindowPrivate
{
GSettings *settings; GSettings *settings;
GtkWidget *stack; GtkWidget *stack;
}; };
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
static void static void
example_app_window_init (ExampleAppWindow *win) example_app_window_init (ExampleAppWindow *win)
{ {
gtk_widget_init_template (GTK_WIDGET (win)); ExampleAppWindowPrivate *priv;
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition", priv = example_app_window_get_instance_private (win);
win->stack, "transition-type", gtk_widget_init_template (GTK_WIDGET (win));
priv->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (priv->settings, "transition",
priv->stack, "transition-type",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
} }
@@ -28,10 +36,12 @@ static void
example_app_window_dispose (GObject *object) example_app_window_dispose (GObject *object)
{ {
ExampleAppWindow *win; ExampleAppWindow *win;
ExampleAppWindowPrivate *priv;
win = EXAMPLE_APP_WINDOW (object); win = EXAMPLE_APP_WINDOW (object);
priv = example_app_window_get_instance_private (win);
g_clear_object (&win->settings); g_clear_object (&priv->settings);
G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object); G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
} }
@@ -43,7 +53,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui"); "/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
} }
ExampleAppWindow * ExampleAppWindow *
@@ -56,6 +66,7 @@ void
example_app_window_open (ExampleAppWindow *win, example_app_window_open (ExampleAppWindow *win,
GFile *file) GFile *file)
{ {
ExampleAppWindowPrivate *priv;
gchar *basename; gchar *basename;
GtkWidget *scrolled, *view; GtkWidget *scrolled, *view;
gchar *contents; gchar *contents;
@@ -64,16 +75,19 @@ example_app_window_open (ExampleAppWindow *win,
GtkTextTag *tag; GtkTextTag *tag;
GtkTextIter start_iter, end_iter; GtkTextIter start_iter, end_iter;
priv = example_app_window_get_instance_private (win);
basename = g_file_get_basename (file); basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled);
gtk_widget_set_hexpand (scrolled, TRUE); gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (scrolled), view); gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename); gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -84,7 +98,7 @@ example_app_window_open (ExampleAppWindow *win,
} }
tag = gtk_text_buffer_create_tag (buffer, NULL, NULL); tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
g_settings_bind (win->settings, "font", tag, "font", G_SETTINGS_BIND_DEFAULT); g_settings_bind (priv->settings, "font", tag, "font", G_SETTINGS_BIND_DEFAULT);
gtk_text_buffer_get_start_iter (buffer, &start_iter); gtk_text_buffer_get_start_iter (buffer, &start_iter);
gtk_text_buffer_get_end_iter (buffer, &end_iter); gtk_text_buffer_get_end_iter (buffer, &end_iter);

View File

@@ -7,11 +7,14 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child> <child>
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<child type="title"> <child type="title">
<object class="GtkStackSwitcher" id="tabs"> <object class="GtkStackSwitcher" id="tabs">
<property name="visible">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
</child> </child>
@@ -19,6 +22,7 @@
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>

View File

@@ -1,7 +1,7 @@
CC ?= gcc CC ?= gcc
PKGCONFIG = $(shell which pkg-config) PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-4.0) CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-4.0) LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)
GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0) GLIB_COMPILE_RESOURCES = $(shell $(PKGCONFIG) --variable=glib_compile_resources gio-2.0)
GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0) GLIB_COMPILE_SCHEMAS = $(shell $(PKGCONFIG) --variable=glib_compile_schemas gio-2.0)

View File

@@ -7,36 +7,43 @@
struct _ExampleAppPrefs struct _ExampleAppPrefs
{ {
GtkDialog parent; GtkDialog parent;
};
typedef struct _ExampleAppPrefsPrivate ExampleAppPrefsPrivate;
struct _ExampleAppPrefsPrivate
{
GSettings *settings; GSettings *settings;
GtkWidget *font; GtkWidget *font;
GtkWidget *transition; GtkWidget *transition;
}; };
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
static void static void
example_app_prefs_init (ExampleAppPrefs *prefs) example_app_prefs_init (ExampleAppPrefs *prefs)
{ {
gtk_widget_init_template (GTK_WIDGET (prefs)); ExampleAppPrefsPrivate *priv;
prefs->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (prefs->settings, "font", priv = example_app_prefs_get_instance_private (prefs);
prefs->font, "font", gtk_widget_init_template (GTK_WIDGET (prefs));
priv->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (priv->settings, "font",
priv->font, "font",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
g_settings_bind (prefs->settings, "transition", g_settings_bind (priv->settings, "transition",
prefs->transition, "active-id", priv->transition, "active-id",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
} }
static void static void
example_app_prefs_dispose (GObject *object) example_app_prefs_dispose (GObject *object)
{ {
ExampleAppPrefs *prefs; ExampleAppPrefsPrivate *priv;
prefs = EXAMPLE_APP_PREFS (object); priv = example_app_prefs_get_instance_private (EXAMPLE_APP_PREFS (object));
g_clear_object (&priv->settings);
g_clear_object (&prefs->settings);
G_OBJECT_CLASS (example_app_prefs_parent_class)->dispose (object); G_OBJECT_CLASS (example_app_prefs_parent_class)->dispose (object);
} }
@@ -48,8 +55,8 @@ example_app_prefs_class_init (ExampleAppPrefsClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/prefs.ui"); "/org/gtk/exampleapp/prefs.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppPrefs, font); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppPrefs, font);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppPrefs, transition); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppPrefs, transition);
} }
ExampleAppPrefs * ExampleAppPrefs *

View File

@@ -6,21 +6,29 @@
struct _ExampleAppWindow struct _ExampleAppWindow
{ {
GtkApplicationWindow parent; GtkApplicationWindow parent;
};
typedef struct ExampleAppWindowPrivate ExampleAppWindowPrivate;
struct ExampleAppWindowPrivate
{
GSettings *settings; GSettings *settings;
GtkWidget *stack; GtkWidget *stack;
}; };
G_DEFINE_TYPE (ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW) G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
static void static void
example_app_window_init (ExampleAppWindow *win) example_app_window_init (ExampleAppWindow *win)
{ {
gtk_widget_init_template (GTK_WIDGET (win)); ExampleAppWindowPrivate *priv;
win->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (win->settings, "transition", priv = example_app_window_get_instance_private (win);
win->stack, "transition-type", gtk_widget_init_template (GTK_WIDGET (win));
priv->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind (priv->settings, "transition",
priv->stack, "transition-type",
G_SETTINGS_BIND_DEFAULT); G_SETTINGS_BIND_DEFAULT);
} }
@@ -28,10 +36,12 @@ static void
example_app_window_dispose (GObject *object) example_app_window_dispose (GObject *object)
{ {
ExampleAppWindow *win; ExampleAppWindow *win;
ExampleAppWindowPrivate *priv;
win = EXAMPLE_APP_WINDOW (object); win = EXAMPLE_APP_WINDOW (object);
priv = example_app_window_get_instance_private (win);
g_clear_object (&win->settings); g_clear_object (&priv->settings);
G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object); G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
} }
@@ -43,7 +53,7 @@ example_app_window_class_init (ExampleAppWindowClass *class)
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class), gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/exampleapp/window.ui"); "/org/gtk/exampleapp/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), ExampleAppWindow, stack);
} }
ExampleAppWindow * ExampleAppWindow *
@@ -56,6 +66,7 @@ void
example_app_window_open (ExampleAppWindow *win, example_app_window_open (ExampleAppWindow *win,
GFile *file) GFile *file)
{ {
ExampleAppWindowPrivate *priv;
gchar *basename; gchar *basename;
GtkWidget *scrolled, *view; GtkWidget *scrolled, *view;
gchar *contents; gchar *contents;
@@ -64,16 +75,19 @@ example_app_window_open (ExampleAppWindow *win,
GtkTextTag *tag; GtkTextTag *tag;
GtkTextIter start_iter, end_iter; GtkTextIter start_iter, end_iter;
priv = example_app_window_get_instance_private (win);
basename = g_file_get_basename (file); basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new (NULL, NULL); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolled);
gtk_widget_set_hexpand (scrolled, TRUE); gtk_widget_set_hexpand (scrolled, TRUE);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (scrolled), view); gtk_container_add (GTK_CONTAINER (scrolled), view);
gtk_stack_add_titled (GTK_STACK (win->stack), scrolled, basename, basename); gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -84,7 +98,7 @@ example_app_window_open (ExampleAppWindow *win,
} }
tag = gtk_text_buffer_create_tag (buffer, NULL, NULL); tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
g_settings_bind (win->settings, "font", tag, "font", G_SETTINGS_BIND_DEFAULT); g_settings_bind (priv->settings, "font", tag, "font", G_SETTINGS_BIND_DEFAULT);
gtk_text_buffer_get_start_iter (buffer, &start_iter); gtk_text_buffer_get_start_iter (buffer, &start_iter);
gtk_text_buffer_get_end_iter (buffer, &end_iter); gtk_text_buffer_get_end_iter (buffer, &end_iter);

View File

@@ -9,13 +9,15 @@
<object class="GtkBox" id="vbox"> <object class="GtkBox" id="vbox">
<child> <child>
<object class="GtkGrid" id="grid"> <object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="margin">6</property> <property name="margin">6</property>
<property name="row-spacing">12</property> <property name="row-spacing">12</property>
<property name="column-spacing">6</property> <property name="column-spacing">6</property>
<child> <child>
<object class="GtkLabel" id="fontlabel"> <object class="GtkLabel" id="fontlabel">
<property name="visible">True</property>
<property name="label">_Font:</property> <property name="label">_Font:</property>
<property name="use-underline">1</property> <property name="use-underline">True</property>
<property name="mnemonic-widget">font</property> <property name="mnemonic-widget">font</property>
<property name="xalign">1</property> <property name="xalign">1</property>
</object> </object>
@@ -26,6 +28,7 @@
</child> </child>
<child> <child>
<object class="GtkFontButton" id="font"> <object class="GtkFontButton" id="font">
<property name="visible">True</property>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left-attach">1</property>
@@ -34,8 +37,9 @@
</child> </child>
<child> <child>
<object class="GtkLabel" id="transitionlabel"> <object class="GtkLabel" id="transitionlabel">
<property name="visible">True</property>
<property name="label">_Transition:</property> <property name="label">_Transition:</property>
<property name="use-underline">1</property> <property name="use-underline">True</property>
<property name="mnemonic-widget">transition</property> <property name="mnemonic-widget">transition</property>
<property name="xalign">1</property> <property name="xalign">1</property>
</object> </object>
@@ -46,6 +50,7 @@
</child> </child>
<child> <child>
<object class="GtkComboBoxText" id="transition"> <object class="GtkComboBoxText" id="transition">
<property name="visible">True</property>
<items> <items>
<item translatable="yes" id="none">None</item> <item translatable="yes" id="none">None</item>
<item translatable="yes" id="crossfade">Fade</item> <item translatable="yes" id="crossfade">Fade</item>

View File

@@ -7,11 +7,14 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child> <child>
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="visible">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="visible">True</property>
<child type="title"> <child type="title">
<object class="GtkStackSwitcher" id="tabs"> <object class="GtkStackSwitcher" id="tabs">
<property name="visible">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
</child> </child>
@@ -19,6 +22,7 @@
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="visible">True</property>
</object> </object>
</child> </child>
</object> </object>

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