Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias Clasen
16c3d4b236 Add gsk vulkan tests
Add a testsuite called gsk-compare-vulkan to run
the gsk renderer tests with the Vulkan renderer.

The current stats:

Ok:                 184
Expected Fail:      0
Fail:               204
Unexpected Pass:    0
Skipped:            2
Timeout:            0

For now, we mark all the tests as failing to
avoid ci breakage. To run the tests locally,
you can do:

meson test -C_build --suite gsk-compare-vulkan
2023-05-07 07:42:20 -04:00
908 changed files with 13153 additions and 48643 deletions

1
.gitignore vendored
View File

@@ -1,2 +1 @@
/subprojects/*/
.flatpak-builder/

View File

@@ -24,7 +24,7 @@ stages:
variables:
COMMON_MESON_FLAGS: "-Dwerror=true -Dcairo:werror=false -Dgi-docgen:werror=false -Dgraphene:werror=false -Dlibepoxy:werror=false -Dlibsass:werror=false -Dpango:werror=false -Dsassc:werror=false -Dgdk-pixbuf:werror=false -Dglib:werror=false -Dlibcloudproviders:werror=false -Dlibpng:werror=false -Dlibtiff:werror=false -Dsysprof:werror=false -Dwayland-protocols:werror=false -Dharfbuzz:werror=false -Dfreetype2:werror=false -Dfontconfig:werror=false -Dfribidi:werror=false -Dlibffi:werror=false -Dlibjpeg-turbo:werror=false -Dmutest:werror=false -Dpixman:werror=false -Dproxy-libintl:werror=false"
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46"
@@ -83,27 +83,6 @@ fedora-x86_64:
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- meson subprojects download
- meson subprojects update --reset
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
_build
- meson compile -C _build
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
release-build:
extends: .build-fedora-default
stage: build
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
@@ -122,8 +101,11 @@ release-build:
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build broadway
fedora-clang:
release-build:
extends: .build-fedora-default
stage: build
needs: []
@@ -132,7 +114,6 @@ fedora-clang:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- export CC=clang
- meson subprojects download
- meson subprojects update --reset
- meson setup
@@ -142,6 +123,7 @@ fedora-clang:
${FEATURE_FLAGS}
_build
- meson compile -C _build
- .gitlab-ci/run-tests.sh _build x11
fedora-mingw64:
extends: .build-fedora-default
@@ -222,7 +204,7 @@ macos:
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
-Dbuild-demos=false
-Ddemos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dbuild-testsuite=false
@@ -369,8 +351,6 @@ static-scan:
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
_scan_build
- ninja -C _scan_build scan-build
artifacts:
@@ -385,27 +365,17 @@ asan-build:
tags: [ asan ]
stage: analysis
needs: []
when: manual
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
- CC=clang meson setup
--buildtype=debugoptimized
-Db_sanitize=address
-Db_lundef=false
-Dbuild-demos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dintrospection=disabled
-Df16c=disabled
_build
- CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build x11
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
- _build/meson-logs
allow_failure: true
reference:
image: $FEDORA_IMAGE

View File

@@ -23,8 +23,8 @@ flatpak build ${builddir} meson \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Dbuild-demos=true \
-Ddemo-profile=devel \
-Ddemos=true \
-Dprofile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install

View File

@@ -9,7 +9,7 @@ backend=$2
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1
export G_SLICE=always-malloc
case "${backend}" in
@@ -69,6 +69,9 @@ case "${backend}" in
--no-suite=flaky \
--no-suite=gsk-compare-opengl
# don't let Broadway failures fail the run, for now
exit_code=0
kill ${server}
;;

200
NEWS
View File

@@ -1,167 +1,4 @@
Overview of Changes in 4.11.4, xx-xx-xxxx
=========================================
* GtkFileChooser:
- Default to sorting folders first
- Fix a crash when visiting recent files
* GtkTextView:
- Fix corner cases in word navigation
* GtkMenuButton:
- Normalize label layout
* GtkDropDown:
- Add support for sections
* GtkVideo:
- Make the overlay icon clickable
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* GtkFileDialog:
- Always set initial-folder
* GtkDropDown:
- Update on expression changes
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkStackSwitcher, GtkMediaControls, GtkColorDialogButton, GtkDropDown,
GtkInfoBar, GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Adapt name computation for the common 'nested button' scenario
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
- Add properties for accessible names of not directly exposed
widgets in GtkListView, GtkGridView and GtkColumnView
* DND:
- Fix criticals when drops are rejected
* X11:
- Fix regressions in GLX setup
* Windows:
- Center newly created transient windows
* Vulkan:
- Add antialising for gradients
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
- Add a pipeline cache
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
* Tools:
- gtk4-builder-tool: Make render an alias screenshot
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay with warnings and recommendations
- Limit the width of the a11y tab
* Build:
- Require GLib 2.76
- Make asan builds work again
* Translation updates:
Brazilian Portuguese
Catalan
Czech
Georgian
Overview of Changes in 4.11.3, 05-06-2023
=========================================
* GtkGridView:
- Respect css border-spacing
- Don't leak the factories
* GtkListView:
- Don't leak the factories
* GtkColumnView:
- Support displaying sections
* GtkNotebook:
- Make the pages model implement GtkSelectionModel
* GtkScrolledWindow:
- Propagate child measure size whenever possible
* GtkPopoverMenu:
- Avoid unnecessary left padding
* GtkSearchEntry:
- Improve size allocation for the clear icon
* GtkBoxLayout:
- Fix a regression from recent baseline work
* CSS:
- Add new binding-friendly css provider apis
* Theme:
- Show focus in the shortcuts window
* GDK:
- Support grayscale and alpha texture formats for loading
and saving to png and tiff, and in GL
- Fix some regressions in GL context initialization
* GSK:
- Support grayscale and alpha texture formats in the GL renderer
- Support straight alpha textures in the GL renderer
- Many improvements to the experimental Vulkan renderer
* Wayland:
- Make exporting surface handles more flexible
* X11:
- Trap XRandr errors
- Stop using passive grabs during DND
* Windows:
- Many cleanups and simplifications
* Tests:
- Improve test coverage
* Build:
- Some build options have been renamed:
demos -> build-demos
profile -> demo-profile
The old names still work
* Deprecations:
- gtk_css_provider_load_from_data
- gdk_wayland_toplevel_unexport_handle
- gdk_pixbuf_get_from_surface
- gdk_pixbuf_get_from_texture
- gtk_image_new_from_pixbuf
- gtk_image_set_from_pixbuf
- gtk_picture_new_for_pixbuf
- gtk_picture_set_pixbuf
* Translation updates:
Basque
Catalan
Georgian
Russian
Turkish
Overview of Changes in 4.11.2, 09-05-2023
Overview of Changes in 4.11.2, xx-xx-xxxx
=========================================
* GtkGLArea:
@@ -170,12 +7,6 @@ Overview of Changes in 4.11.2, 09-05-2023
* GtkListBox:
- Fix a problem with gtk_list_box_remove_all
* Add the GtkSectionModel interface, and implement it in most
of our list models
* GtkListView:
- Support displaying sections
* GtkCenterBox:
- Add a shrink-center-last property
@@ -192,9 +23,6 @@ Overview of Changes in 4.11.2, 09-05-2023
- A few memory leak fixes
- Handle webdav in the pathbar
* GtkBox:
- Support baselines in vertical orientation with GtkBox:baseline-child
* Dialogs:
- Destroy windows promptly when the async callback finishes
- Detect absence of the OpenURI portal and fall back
@@ -205,22 +33,12 @@ Overview of Changes in 4.11.2, 09-05-2023
* Accessibility:
- Fix alert dialogs in the a11y tree
- Improve accessibility of GtkShortcutsWindow
* Layout:
- Some fixes to baseline alignment
- Separate GTK_ALIGN_BASELINE_CENTER and _FILL
* CSS:
- Fix a crash with color transitions
* GSK:
- Fix problems with negative scales
- Improve scaling of offscreens for (cross-fades, masks, blends)
* GL:
- Add GdkGLTextureBuilder, a more flexible api for creating textures
- Support setting update regions for GL textures
- Ensure that we work with GLES 2
* Vulkan:
@@ -231,37 +49,23 @@ Overview of Changes in 4.11.2, 09-05-2023
- Don't destroy wl_surfaces on hide
- Plug leaks of compositor-side resources
* X11:
- Fix artifacts in gnome-shell frame decorations
* Windows:
- Fix GL context initialization
* Inspector:
- Improve the action list
- Improve the accessibility pane
- Fix a crash
* Tools:
- gtk4-node-editor: Improve scaling
- gtk4-node-editor: Preserve aspect ratio of textures
- gtk4-node-editor: Add some smarter editing
- gtk4-demo: Make the stylus demo work with mice
* Deprecations:
- gtk_widget_get_allocated_width/height/baseline
- GTK_ALIGN_BASELINE
* Translation updates
Bulgarian
Chinese (China)
Friulian
Galician
Hebrew
Persian
Polish
Portuguese
`Russian
Russian
Turkish

View File

@@ -187,7 +187,7 @@
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Ddemo-profile=devel"
"-Dprofile=devel"
],
"sources" : [
{

View File

@@ -116,7 +116,7 @@
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Ddemo-profile=devel"
"-Dprofile=devel"
],
"sources" : [
{

View File

@@ -116,7 +116,7 @@
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Ddemo-profile=devel"
"-Dprofile=devel"
],
"sources" : [
{

View File

@@ -116,7 +116,7 @@
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Ddemo-profile=devel"
"-Dprofile=devel"
],
"sources" : [
{

View File

@@ -1,201 +0,0 @@
#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: 2022 Collabora Inc.
# 2023 Emmanuele Bassi
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Original author: Xavier Claessens <xclaesse@gmail.com>
import argparse
import textwrap
from pathlib import Path
# Disable line length warnings as wrapping the C code templates would be hard
# flake8: noqa: E501
def gen_versions_macros(args, current_major_version, current_minor_version, current_micro_version):
with args.out_path.open("w", encoding="utf-8") as ofile, args.in_path.open(
"r", encoding="utf-8"
) as ifile:
for line in ifile.readlines():
if "@GDK_VERSIONS@" in line:
ofile.write(
textwrap.dedent(
f"""\
/**
* GDK_MAJOR_VERSION:
*
* The major version component of the library's version, e.g. "1" for "1.2.3".
*/
#define GDK_MAJOR_VERSION ({current_major_version})
/**
* GDK_MINOR_VERSION:
*
* The minor version component of the library's version, e.g. "2" for "1.2.3".
*/
#define GDK_MINOR_VERSION ({current_minor_version})
/**
* GDK_MICRO_VERSION:
*
* The micro version component of the library's version, e.g. "3" for "1.2.3".
*/
#define GDK_MICRO_VERSION ({current_micro_version})
"""
)
)
for minor in range(0, current_minor_version + 2, 2):
ofile.write(
textwrap.dedent(
f"""\
/**
* GDK_VERSION_{current_major_version}_{minor}:
*
* A macro that evaluates to the {current_major_version}.{minor} version of GTK, in a format
* that can be used by the C pre-processor.
*
* Since: {current_major_version}.{minor}
*/
#define GDK_VERSION_{current_major_version}_{minor} (G_ENCODE_VERSION ({current_major_version}, {minor}))
"""
)
)
else:
ofile.write(line)
def gen_visibility_macros(args, current_major_version, current_minor_version, current_micro_version):
"""
Generates a set of macros for each minor stable version of GTK
- GDK_DEPRECATED
- GDK_DEPRECATED_IN_…
- GDK_DEPRECATED_MACRO_IN_…
- GDK_DEPRECATED_ENUMERATOR_IN_…
- GDK_DEPRECATED_TYPE_IN_…
- GDK_AVAILABLE_IN_ALL
- GDK_AVAILABLE_IN_…
- GDK_AVAILABLE_STATIC_INLINE_IN_…
- GDK_AVAILABLE_MACRO_IN_…
- GDK_AVAILABLE_ENUMERATOR_IN_…
- GDK_AVAILABLE_TYPE_IN_…
- GDK_UNAVAILABLE(maj,min)
- GDK_UNAVAILABLE_STATIC_INLINE(maj,min)
"""
ns = args.namespace
with args.out_path.open("w", encoding="utf-8") as f:
f.write(
textwrap.dedent(
f"""\
#pragma once
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined({ns}_STATIC_COMPILATION)
# define _{ns}_EXPORT __declspec(dllexport)
# define _{ns}_IMPORT __declspec(dllimport)
#elif __GNUC__ >= 4
# define _{ns}_EXPORT __attribute__((visibility("default")))
# define _{ns}_IMPORT
#else
# define _{ns}_EXPORT
# define _{ns}_IMPORT
#endif
#ifdef GTK_COMPILATION
# define _{ns}_API _{ns}_EXPORT
#else
# define _{ns}_API _{ns}_IMPORT
#endif
#define _{ns}_EXTERN _{ns}_API extern
#define {ns}_VAR _{ns}_EXTERN
#define {ns}_AVAILABLE_IN_ALL _{ns}_EXTERN
#ifdef GDK_DISABLE_DEPRECATION_WARNINGS
#define {ns}_DEPRECATED _{ns}_EXTERN
#define {ns}_DEPRECATED_FOR(f) _{ns}_EXTERN
#define {ns}_UNAVAILABLE(maj,min) _{ns}_EXTERN
#define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min)
#else
#define {ns}_DEPRECATED G_DEPRECATED _{ns}_EXTERN
#define {ns}_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _{ns}_EXTERN
#define {ns}_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _{ns}_EXTERN
#define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min) G_UNAVAILABLE(maj,min)
#endif
"""
)
)
for minor in range(0, current_minor_version + 2, 2):
f.write(
textwrap.dedent(
f"""
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_{minor}
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor} {ns}_DEPRECATED
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor}_FOR(f) {ns}_DEPRECATED_FOR (f)
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor} GDK_DEPRECATED_MACRO
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_MACRO_FOR (f)
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor} GDK_DEPRECATED_ENUMERATOR
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_ENUMERATOR_FOR (f)
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor} GDK_DEPRECATED_TYPE
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_TYPE_FOR (f)
#else
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor} _{ns}_EXTERN
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor}_FOR(f) _{ns}_EXTERN
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}_FOR(f)
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}_FOR(f)
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}_FOR(f)
#endif
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_{current_major_version}_{minor}
#define {ns}_AVAILABLE_IN_{current_major_version}_{minor} {ns}_UNAVAILABLE ({current_major_version}, {minor})
#define {ns}_AVAILABLE_STATIC_INLINE_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_STATIC_INLINE ({current_major_version}, {minor})
#define {ns}_AVAILABLE_MACRO_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_MACRO ({current_major_version}, {minor})
#define {ns}_AVAILABLE_ENUMERATOR_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_ENUMERATOR ({current_major_version}, {minor})
#define {ns}_AVAILABLE_TYPE_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_TYPE ({current_major_version}, {minor})
#else
#define {ns}_AVAILABLE_IN_{current_major_version}_{minor} _{ns}_EXTERN
#define {ns}_AVAILABLE_STATIC_INLINE_IN_{current_major_version}_{minor}
#define {ns}_AVAILABLE_MACRO_IN_{current_major_version}_{minor}
#define {ns}_AVAILABLE_ENUMERATOR_IN_{current_major_version}_{minor}
#define {ns}_AVAILABLE_TYPE_IN_{current_major_version}_{minor}
#endif
"""
)
)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("gtk_version", help="Current GLib version")
subparsers = parser.add_subparsers()
versions_parser = subparsers.add_parser(
"versions-macros", help="Generate versions macros"
)
versions_parser.add_argument("in_path", help="input file", type=Path)
versions_parser.add_argument("out_path", help="output file", type=Path)
versions_parser.set_defaults(func=gen_versions_macros)
visibility_parser = subparsers.add_parser(
"visibility-macros", help="Generate visibility macros"
)
visibility_parser.add_argument("namespace", help="Macro namespace")
visibility_parser.add_argument("out_path", help="output file", type=Path)
visibility_parser.set_defaults(func=gen_visibility_macros)
args = parser.parse_args()
version = [int(i) for i in args.gtk_version.split(".")]
args.func(args, version[0], version[1], version[2])
if __name__ == "__main__":
main()

View File

@@ -162,10 +162,6 @@ create_page4 (GtkWidget *assistant)
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), progress_bar, GTK_ASSISTANT_PAGE_PROGRESS);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), progress_bar, "Applying changes");
gtk_accessible_update_property (GTK_ACCESSIBLE (progress_bar),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Applying changes",
-1);
/* This prevents the assistant window from being
* closed while we're "busy" applying changes.
*/

View File

@@ -116,8 +116,7 @@ effective_align (GtkAlign align,
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
case GTK_ALIGN_FILL:
case GTK_ALIGN_CENTER:
case GTK_ALIGN_BASELINE_FILL:
case GTK_ALIGN_BASELINE_CENTER:
case GTK_ALIGN_BASELINE:
default:
return align;
}
@@ -259,8 +258,7 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
case GTK_ALIGN_END:
alloc->x += width - alloc->width;
break;
case GTK_ALIGN_BASELINE_FILL:
case GTK_ALIGN_BASELINE_CENTER:
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
@@ -283,8 +281,7 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
case GTK_ALIGN_END:
alloc->y += height - alloc->height;
break;
case GTK_ALIGN_BASELINE_FILL:
case GTK_ALIGN_BASELINE_CENTER:
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;

View File

@@ -51,11 +51,15 @@ struct _BlurOverlayClass
GtkAllocation *allocation);
};
GDK_AVAILABLE_IN_ALL
GType blur_overlay_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget *blur_overlay_new (void);
GDK_AVAILABLE_IN_ALL
void blur_overlay_add_overlay (BlurOverlay *overlay,
GtkWidget *widget,
double blur);
GDK_AVAILABLE_IN_ALL
void blur_overlay_set_child (BlurOverlay *overlay,
GtkWidget *widget);

View File

@@ -4,9 +4,6 @@
<object class="GtkWindow" id="window">
<property name="resizable">1</property>
<property name="title">Clipboard</property>
<accessibility>
<relation name="described-by">label</relation>
</accessibility>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
@@ -16,7 +13,7 @@
<property name="margin-bottom">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="label">
<object class="GtkLabel">
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
<property name="wrap">1</property>
<property name="max-width-chars">40</property>
@@ -27,9 +24,6 @@
<property name="spacing">12</property>
<child>
<object class="GtkDropDown" id="source_chooser">
<accessibility>
<property name="label">Source Type</property>
</accessibility>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
@@ -60,9 +54,6 @@
<property name="name">Text</property>
<property name="child">
<object class="GtkEntry" id="source_text">
<accessibility>
<property name="label">Text Drag Source</property>
</accessibility>
<property name="valign">center</property>
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
<property name="text">Copy this!</property>
@@ -75,9 +66,6 @@
<property name="name">Color</property>
<property name="child">
<object class="GtkColorDialogButton" id="source_color">
<accessibility>
<property name="label">Color Drag Source</property>
</accessibility>
<property name="dialog">
<object class="GtkColorDialog">
</object>
@@ -99,17 +87,14 @@
</style>
<child>
<object class="GtkToggleButton" id="image_rose">
<accessibility>
<property name="label">Photo Drag Source</property>
</accessibility>
<property name="active">1</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">Portland Rose Photo</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
@@ -120,9 +105,6 @@
</child>
<child>
<object class="GtkToggleButton" id="image_floppy">
<accessibility>
<property name="label">Icon Drag Source</property>
</accessibility>
<property name="group">image_rose</property>
<child>
<object class="GtkDragSource">
@@ -131,9 +113,6 @@
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">Floppy Buddy Icon</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
@@ -144,9 +123,6 @@
</child>
<child>
<object class="GtkToggleButton" id="image_logo">
<accessibility>
<property name="label">SVG Drag Source</property>
</accessibility>
<property name="group">image_floppy</property>
<child>
<object class="GtkDragSource">
@@ -155,9 +131,6 @@
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">gtk-demo logo</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
@@ -175,9 +148,6 @@
<property name="name">File</property>
<property name="child">
<object class="GtkButton" id="source_file">
<accessibility>
<property name="label">File Drag Source</property>
</accessibility>
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
@@ -202,9 +172,6 @@
<property name="name">Folder</property>
<property name="child">
<object class="GtkButton" id="source_folder">
<accessibility>
<property name="label">Folder Drag Source</property>
</accessibility>
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
@@ -258,7 +225,7 @@
</object>
</child>
<child>
<object class="GtkLabel" id="paste_label">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="visible-child-name" type="GtkStack">
@@ -285,9 +252,6 @@
<property name="name">Text</property>
<property name="child">
<object class="GtkLabel">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
@@ -301,9 +265,6 @@
<property name="name">Image</property>
<property name="child">
<object class="GtkImage">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<style>
@@ -322,9 +283,6 @@
<property name="valign">center</property>
<child>
<object class="GtkColorSwatch">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="accessible-role">img</property>
<property name="can-focus">0</property>
<property name="selectable">0</property>
@@ -340,9 +298,6 @@
<property name="name">File</property>
<property name="child">
<object class="GtkLabel">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>

View File

@@ -50,7 +50,7 @@ update_css_for_blend_mode (GtkCssProvider *provider,
blend_mode,
blend_mode);
gtk_css_provider_load_from_string (provider, css);
gtk_css_provider_load_from_data (provider, css, -1);
g_bytes_unref (bytes);
g_free (css);

View File

@@ -195,9 +195,6 @@
<gresource prefix="/listview_settings">
<file>listview_settings.ui</file>
</gresource>
<gresource prefix="/listview_settings2">
<file>listview_settings2.ui</file>
</gresource>
<gresource prefix="/listview_ucd_data/">
<file>ucdnames.data</file>
</gresource>
@@ -315,7 +312,6 @@
<file>listview_minesweeper.c</file>
<file>listview_selections.c</file>
<file>listview_settings.c</file>
<file>listview_settings2.c</file>
<file>listview_ucd.c</file>
<file>listview_weather.c</file>
<file>listview_words.c</file>
@@ -335,9 +331,6 @@
<file>paintable_symbolic.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -423,9 +416,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>

View File

@@ -387,8 +387,6 @@ demo3_widget_class_init (Demo3WidgetClass *class)
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
gtk_widget_class_bind_template_callback (widget_class, pressed_cb);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_IMG);
}
GtkWidget *

View File

@@ -19,14 +19,8 @@
</item>
</menu>
<template class="Demo3Widget">
<accessibility>
<property name="label">Demo image</property>
</accessibility>
<child>
<object class="GtkPopoverMenu" id="menu">
<accessibility>
<property name="label">Context menu</property>
</accessibility>
<property name="has-arrow">0</property>
<property name="menu-model">model</property>
</object>

View File

@@ -70,7 +70,7 @@ set_color (CanvasItem *item,
css = g_strdup_printf ("#%s { background: %s; }", name, str);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, css);
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider_for_display (gtk_widget_get_display (item->label), GTK_STYLE_PROVIDER (provider), 700);
item->provider = GTK_STYLE_PROVIDER (provider);
@@ -162,39 +162,27 @@ click_done (GtkGesture *gesture)
gtk_widget_insert_after (item, canvas, last_child);
}
/* GtkSettings treats `GTK_THEME=foo:dark` as theme name `foo`, variant `dark`,
* and our embedded CSS files let `foo-dark` work as an alias for `foo:dark`. */
static gboolean
has_dark_suffix (const char *theme)
{
return g_str_has_suffix (theme, ":dark") ||
g_str_has_suffix (theme, "-dark");
}
/* So we can make a good guess whether the current theme is dark by checking for
* either: it is suffixed `[:-]dark`, or Settings:…prefer-dark-theme is TRUE. */
static gboolean
theme_is_dark (void)
{
const char *env_theme;
GtkSettings *settings;
char *theme;
gboolean prefer_dark;
gboolean dark;
/* Like GtkSettings, 1st see if theme is overridden by environment variable */
env_theme = g_getenv ("GTK_THEME");
if (env_theme != NULL)
return has_dark_suffix (env_theme);
/* If not, test Settings:…theme-name in the same way OR :…prefer-dark-theme */
settings = gtk_settings_get_default ();
g_object_get (settings,
"gtk-theme-name", &theme,
"gtk-application-prefer-dark-theme", &prefer_dark,
NULL);
dark = prefer_dark || has_dark_suffix (theme);
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
dark = TRUE;
else
dark = FALSE;
g_free (theme);
return dark;
}
@@ -777,7 +765,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
g_string_append_printf (css, ".canvasitem.%s { background: %s; }\n", colors[i], colors[i]);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, css->str);
gtk_css_provider_load_from_data (provider, css->str, css->len);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);

View File

@@ -334,17 +334,11 @@ do_drawingarea (GtkWidget *do_widget)
gtk_widget_set_vexpand (frame, TRUE);
gtk_box_append (GTK_BOX (vbox), frame);
da = g_object_new (GTK_TYPE_DRAWING_AREA,
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
gtk_accessible_update_relation (GTK_ACCESSIBLE (da),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
/*
* Create the scribble area
@@ -358,17 +352,11 @@ do_drawingarea (GtkWidget *do_widget)
gtk_widget_set_vexpand (frame, TRUE);
gtk_box_append (GTK_BOX (vbox), frame);
da = g_object_new (GTK_TYPE_DRAWING_AREA,
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
gtk_accessible_update_relation (GTK_ACCESSIBLE (da),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), scribble_draw, NULL, NULL);
gtk_frame_set_child (GTK_FRAME (frame), da);
g_signal_connect (da, "resize",
G_CALLBACK (scribble_resize), NULL);
@@ -384,7 +372,7 @@ do_drawingarea (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -95,13 +95,6 @@ do_entry_completion (GtkWidget *do_widget)
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (vbox), entry);
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE, GTK_ACCESSIBLE_AUTOCOMPLETE_LIST,
-1);
/* Create the completion object */
completion = gtk_entry_completion_new ();

View File

@@ -43,10 +43,6 @@ do_entry_undo (GtkWidget *do_widget)
entry = gtk_entry_new ();
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
gtk_box_append (GTK_BOX (vbox), entry);
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
}
if (!gtk_widget_get_visible (window))

View File

@@ -22,15 +22,11 @@ validate_more_details (GtkEntry *entry,
{
gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "Must have details first");
gtk_widget_add_css_class (GTK_WIDGET (entry), "error");
gtk_accessible_update_state (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_INVALID_TRUE,
-1);
}
else
{
gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "");
gtk_widget_remove_css_class (GTK_WIDGET (entry), "error");
gtk_accessible_reset_state (GTK_ACCESSIBLE (entry), GTK_ACCESSIBLE_STATE_INVALID);
}
}
@@ -48,18 +44,10 @@ mode_switch_state_set (GtkSwitch *sw,
{
gtk_widget_set_visible (label, FALSE);
gtk_switch_set_state (sw, state);
gtk_accessible_reset_relation (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE);
gtk_accessible_reset_state (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_STATE_INVALID);
}
else
{
gtk_widget_set_visible (label, TRUE);
gtk_accessible_update_relation (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, label,
-1);
gtk_accessible_update_state (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_INVALID_TRUE,
-1);
}
return TRUE;
@@ -85,9 +73,6 @@ level_scale_value_changed (GtkRange *range,
{
gtk_switch_set_state (GTK_SWITCH (sw), FALSE);
}
gtk_accessible_reset_relation (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE);
gtk_accessible_reset_state (GTK_ACCESSIBLE (sw), GTK_ACCESSIBLE_STATE_INVALID);
}
GtkWidget *

View File

@@ -301,7 +301,7 @@ do_fishbowl (GtkWidget *do_widget)
if (provider == NULL)
{
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, css);
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);

View File

@@ -1294,18 +1294,18 @@ add_axis (hb_face_t *hb_face,
axis_label = gtk_label_new (name);
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
gtk_grid_attach (GTK_GRID (demo->variations_grid), axis_label, 0, i, 1, 1);
adjustment = gtk_adjustment_new (value, ax->min_value, ax->max_value,
1.0, 10.0, 0.0);
axis_scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
gtk_scale_add_mark (GTK_SCALE (axis_scale), ax->default_value, GTK_POS_TOP, NULL);
gtk_widget_set_valign (axis_scale, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (axis_scale, GTK_ALIGN_BASELINE);
gtk_widget_set_hexpand (axis_scale, TRUE);
gtk_widget_set_size_request (axis_scale, 100, -1);
gtk_grid_attach (GTK_GRID (demo->variations_grid), axis_scale, 1, i, 1, 1);
axis_entry = gtk_entry_new ();
gtk_widget_set_valign (axis_entry, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (axis_entry, GTK_ALIGN_BASELINE);
gtk_editable_set_width_chars (GTK_EDITABLE (axis_entry), 4);
gtk_editable_set_max_width_chars (GTK_EDITABLE (axis_entry), 4);
gtk_widget_set_hexpand (axis_entry, FALSE);
@@ -1562,14 +1562,14 @@ update_font_variations (void)
label = gtk_label_new ("Instance");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_grid_attach (GTK_GRID (demo->variations_grid), label, 0, -1, 1, 1);
strings = gtk_string_list_new (NULL);
combo = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
gtk_widget_set_halign (combo, GTK_ALIGN_START);
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
gtk_string_list_append (strings, "");

View File

@@ -59,9 +59,6 @@
<property name="spacing">6</property>
<child>
<object class="GtkFontDialogButton" id="font">
<accessibility>
<property name="label">Font</property>
</accessibility>
<property name="dialog">
<object class="GtkFontDialog">
</object>
@@ -76,7 +73,7 @@
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
<child>
<object class="GtkLabel" id="size_label">
<object class="GtkLabel">
<property name="label">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -92,9 +89,6 @@
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">size_adjustment</property>
<accessibility>
<relation name="labelled-by">size_label</relation>
</accessibility>
<layout>
<property name="column">1</property>
<property name="row">0</property>
@@ -107,9 +101,6 @@
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<accessibility>
<relation name="labelled-by">size_label</relation>
</accessibility>
<signal name="activate" handler="basic_entry_activated"
object="size_adjustment" swapped="false"/>
<layout>
@@ -119,7 +110,7 @@
</object>
</child>
<child>
<object class="GtkLabel" id="letterspacing_label">
<object class="GtkLabel">
<property name="label">Letterspacing</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -135,9 +126,6 @@
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">letterspacing_adjustment</property>
<accessibility>
<relation name="labelled-by">letterspacing_label</relation>
</accessibility>
<layout>
<property name="column">1</property>
<property name="row">1</property>
@@ -150,9 +138,6 @@
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<accessibility>
<relation name="labelled-by">letterspacing_label</relation>
</accessibility>
<signal name="activate" handler="basic_entry_activated"
object="letterspacing_adjustment" swapped="false"/>
<layout>
@@ -162,7 +147,7 @@
</object>
</child>
<child>
<object class="GtkLabel" id="line_height_label">
<object class="GtkLabel">
<property name="label">Line Height</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -178,9 +163,6 @@
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">line_height_adjustment</property>
<accessibility>
<relation name="labelled-by">line_height_label</relation>
</accessibility>
<layout>
<property name="column">1</property>
<property name="row">2</property>
@@ -193,9 +175,6 @@
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<accessibility>
<relation name="labelled-by">line_height_label</relation>
</accessibility>
<signal name="activate" handler="basic_entry_activated"
object="line_height_adjustment" swapped="false"/>
<layout>
@@ -205,7 +184,7 @@
</object>
</child>
<child>
<object class="GtkLabel" id="foreground_label">
<object class="GtkLabel">
<property name="label">Foreground</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -223,9 +202,6 @@
</property>
<property name="valign">baseline</property>
<property name="rgba">black</property>
<accessibility>
<relation name="labelled-by">foreground_label</relation>
</accessibility>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
@@ -234,7 +210,7 @@
</object>
</child>
<child>
<object class="GtkLabel" id="background_label">
<object class="GtkLabel">
<property name="label">Background</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
@@ -252,9 +228,6 @@
</property>
<property name="valign">baseline</property>
<property name="rgba">white</property>
<accessibility>
<relation name="labelled-by">background_label</relation>
</accessibility>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
@@ -267,9 +240,6 @@
<property name="icon-name">object-flip-vertical-symbolic</property>
<property name="halign">start</property>
<property name="valign">center</property>
<accessibility>
<property name="label">Swap colors</property>
</accessibility>
<style>
<class name="circular"/>
</style>
@@ -371,9 +341,6 @@
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
<accessibility>
<property name="label">Font example</property>
</accessibility>
</object>
</property>
</object>
@@ -383,9 +350,6 @@
<property name="name">entry</property>
<property name="child">
<object class="GtkTextView" id="entry">
<accessibility>
<property name="label">Example text</property>
</accessibility>
<property name="buffer">
<object class="GtkTextBuffer">
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
@@ -482,9 +446,6 @@
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<accessibility>
<property name="label">Edit text</property>
</accessibility>
<signal name="clicked" handler="font_features_toggle_edit"/>
</object>
</child>

View File

@@ -43,7 +43,6 @@ update_image (void)
cairo_t *cr;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf2;
GdkTexture *texture;
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
@@ -121,17 +120,8 @@ update_image (void)
cairo_destroy (cr);
g_object_unref (layout);
pixbuf = gdk_pixbuf_new_from_data (cairo_image_surface_get_data (surface),
GDK_COLORSPACE_RGB, TRUE, 8,
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
cairo_image_surface_get_stride (surface),
NULL, NULL);
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf,
gdk_pixbuf_get_width (pixbuf) * scale,
gdk_pixbuf_get_height (pixbuf) * scale,
GDK_INTERP_NEAREST);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
@@ -288,25 +278,15 @@ retry:
pango_layout_iter_free (iter);
g_object_unref (layout);
pixbuf = gdk_pixbuf_new_from_data (cairo_image_surface_get_data (surface),
GDK_COLORSPACE_RGB, TRUE, 8,
cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
cairo_image_surface_get_stride (surface),
NULL, NULL);
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf,
gdk_pixbuf_get_width (pixbuf) * scale,
gdk_pixbuf_get_height (pixbuf) * scale,
GDK_INTERP_NEAREST);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
g_object_unref (pixbuf);
cairo_surface_destroy (surface);
}
texture = gdk_texture_new_for_pixbuf (pixbuf2);
gtk_picture_set_paintable (GTK_PICTURE (image), GDK_PAINTABLE (texture));
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
g_object_unref (pixbuf2);
g_object_unref (texture);
}
static gboolean fading = FALSE;

View File

@@ -39,7 +39,7 @@
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<child>
<object class="GtkLabel" id="text_label">
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Text</property>
<property name="xalign">1</property>
@@ -57,13 +57,10 @@
<layout>
<property name="column">2</property>
</layout>
<accessibility>
<relation name="labelled-by">text_label</relation>
</accessibility>
</object>
</child>
<child>
<object class="GtkLabel" id="font_label">
<object class="GtkLabel">
<property name="margin-start">10</property>
<property name="label">Font</property>
<property name="xalign">1</property>
@@ -78,9 +75,6 @@
</child>
<child>
<object class="GtkFontDialogButton" id="font_button">
<accessibility>
<relation name="labelled-by">font_label</relation>
</accessibility>
<property name="dialog">
<object class="GtkFontDialog">
</object>
@@ -192,9 +186,6 @@
<property name="icon-name">list-add-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<accessibility>
<property name="label">Zoom in</property>
</accessibility>
<style>
<class name="circular"/>
</style>
@@ -220,9 +211,6 @@
<property name="icon-name">list-remove-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<accessibility>
<property name="label">Zoom out</property>
</accessibility>
<style>
<class name="circular"/>
</style>
@@ -263,9 +251,6 @@
<property name="vexpand">1</property>
<child>
<object class="GtkPicture" id="image">
<accessibility>
<property name="label">Font rendering example</property>
</accessibility>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="can-shrink">0</property>

View File

@@ -337,7 +337,7 @@ create_gltransition_window (GtkWidget *do_widget)
1, 1, 1, 1);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, "button.small { padding: 0; }");
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

View File

@@ -27,17 +27,24 @@ G_BEGIN_DECLS
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
GDK_AVAILABLE_IN_ALL
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data);
GDK_AVAILABLE_IN_ALL
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader);
GDK_AVAILABLE_IN_ALL
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time);

View File

@@ -18,7 +18,6 @@ do_headerbar (GtkWidget *do_widget)
GtkWidget *header;
GtkWidget *button;
GtkWidget *box;
GtkWidget *content;
if (!window)
{
@@ -38,26 +37,16 @@ do_headerbar (GtkWidget *do_widget)
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class (box, "linked");
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
gtk_widget_set_tooltip_text (button, "Back");
gtk_box_append (GTK_BOX (box), button);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
gtk_widget_set_tooltip_text (button, "Forward");
gtk_box_append (GTK_BOX (box), button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box);
button = gtk_switch_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Change something",
-1);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), gtk_switch_new ());
gtk_window_set_titlebar (GTK_WINDOW (window), header);
content = gtk_text_view_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (content),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Content",
-1);
gtk_window_set_child (GTK_WINDOW (window), content);
gtk_window_set_child (GTK_WINDOW (window), gtk_text_view_new ());
}
if (!gtk_widget_get_visible (window))

View File

@@ -370,7 +370,7 @@ do_iconscroll (GtkWidget *do_widget)
set_widget_type (0);
label = GTK_WIDGET (gtk_builder_get_object (builder, "fps_label"));
id = g_timeout_add_full (G_PRIORITY_HIGH, 500, update_fps, label, NULL);
id = g_timeout_add (500, update_fps, label);
g_object_set_data_full (G_OBJECT (label), "timeout",
GUINT_TO_POINTER (id), remove_timeout);

View File

@@ -164,18 +164,12 @@ do_image_scaling (GtkWidget *do_widget)
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
gtk_widget_set_tooltip_text (scale, "Zoom");
gtk_accessible_update_property (GTK_ACCESSIBLE (scale),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Zoom",
-1);
gtk_range_set_value (GTK_RANGE (scale), 0.);
gtk_widget_set_hexpand (scale, TRUE);
gtk_box_append (GTK_BOX (box2), scale);
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
gtk_widget_set_tooltip_text (dropdown, "Filter");
gtk_accessible_update_property (GTK_ACCESSIBLE (dropdown),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Filter",
-1);
gtk_box_append (GTK_BOX (box2), dropdown);
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);

View File

@@ -30,7 +30,6 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
{
GdkPixbuf *pixbuf;
GtkWidget *picture;
GdkTexture *texture;
picture = GTK_WIDGET (data);
@@ -41,9 +40,7 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
*/
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
texture = gdk_texture_new_for_pixbuf (pixbuf);
gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (texture));
g_object_unref (texture);
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf);
}
static void
@@ -54,18 +51,22 @@ progressive_updated_callback (GdkPixbufLoader *loader,
int height,
gpointer data)
{
GtkWidget *picture = GTK_WIDGET (data);
GdkTexture *texture;
GtkWidget *picture;
GdkPixbuf *pixbuf;
texture = gdk_texture_new_for_pixbuf (gdk_pixbuf_loader_get_pixbuf (loader));
gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (texture));
g_object_unref (texture);
picture = GTK_WIDGET (data);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
gtk_picture_set_pixbuf (GTK_PICTURE (picture), NULL);
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf);
}
static int
progressive_timeout (gpointer data)
{
GtkWidget *picture = GTK_WIDGET (data);
GtkWidget *picture;
picture = GTK_WIDGET (data);
/* This shows off fully-paranoid error handling, so looks scary.
* You could factor out the error handling code into a nice separate

View File

@@ -49,7 +49,6 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">switch</property>
</object>
</child>
<child>
@@ -74,7 +73,6 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">check</property>
</object>
</child>
<child>
@@ -112,7 +110,6 @@
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="opacity">0</property>
<property name="accessible-role">status</property>
</object>
</child>
</object>
@@ -153,11 +150,10 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">scale</property>
</object>
</child>
<child>
<object class="GtkScale" id="scale">
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">0</property>
@@ -189,11 +185,10 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">spin</property>
</object>
</child>
<child>
<object class="GtkSpinButton" id="spin">
<object class="GtkSpinButton">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="adjustment">
@@ -222,11 +217,10 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">dropdown</property>
</object>
</child>
<child>
<object class="GtkDropDown" id="dropdown">
<object class="GtkDropDown">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="model">
@@ -258,11 +252,10 @@
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="mnemonic-widget">entry</property>
</object>
</child>
<child>
<object class="GtkEntry" id="entry">
<object class="GtkEntry">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="placeholder-text">Type here…</property>

View File

@@ -52,10 +52,6 @@ setup_listitem_cb (GtkListItemFactory *factory,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
image = gtk_image_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_PROPERTY_LABEL,
"App icon",
-1);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), image);
label = gtk_label_new ("");
@@ -83,7 +79,6 @@ bind_listitem_cb (GtkListItemFactory *factory,
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
gtk_list_item_set_accessible_label (list_item, g_app_info_get_display_name (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown

View File

@@ -431,9 +431,6 @@ setup_listitem_cb (GtkListItemFactory *factory,
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_box_append (GTK_BOX (box), picture);
gtk_accessible_update_relation (GTK_ACCESSIBLE (picture),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, location_label, NULL,
-1);
/* And finally, everything comes together.
@@ -490,9 +487,6 @@ do_listview_clocks (GtkWidget *do_widget)
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_clocks_model ()));
gridview = gtk_grid_view_new (model, factory);
gtk_accessible_update_property (GTK_ACCESSIBLE (gridview),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Clocks",
-1);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);

View File

@@ -368,38 +368,6 @@ match_func (MatchObject *obj,
g_free (tmp2);
}
static void
setup_header (GtkSignalListItemFactory *factory,
GObject *list_item,
gpointer data)
{
GtkListHeader *self = GTK_LIST_HEADER (list_item);
GtkWidget *child;
child = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (child), 0);
gtk_label_set_use_markup (GTK_LABEL (child), TRUE);
gtk_widget_set_margin_top (child, 10);
gtk_widget_set_margin_bottom (child, 10);
gtk_list_header_set_child (self, child);
}
static void
bind_header (GtkSignalListItemFactory *factory,
GObject *list_item,
gpointer data)
{
GtkListHeader *self = GTK_LIST_HEADER (list_item);
GtkWidget *child = gtk_list_header_get_child (self);
GObject *item = gtk_list_header_get_item (self);
if (strstr (gtk_string_object_get_string (GTK_STRING_OBJECT (item)), "hour"))
gtk_label_set_label (GTK_LABEL (child), "<big><b>Hours</b></big>");
else
gtk_label_set_label (GTK_LABEL (child), "<big><b>Minutes</b></big>");
}
GtkWidget *
do_listview_selections (GtkWidget *do_widget)
{
@@ -409,12 +377,10 @@ do_listview_selections (GtkWidget *do_widget)
GtkExpression *expression;
GtkListItemFactory *factory;
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
const char * const minutes[] = {
const char * const many_times[] = {
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
"25 minutes", "30 minutes", "35 minutes", "40 minutes", "45 minutes", "50 minutes",
"55 minutes", NULL
};
const char * const hours[] = { "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
"55 minutes", "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
"8 hours", "9 hours", "10 hours", "11 hours", "12 hours", NULL
};
const char * const device_titles[] = { "Digital Output", "Headphones", "Digital Output", "Analog Output", NULL };
@@ -429,10 +395,6 @@ do_listview_selections (GtkWidget *do_widget)
if (!window)
{
GtkStringList *minutes_model, *hours_model;
GListStore *store;
GtkFlattenListModel *flat;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
@@ -460,25 +422,14 @@ do_listview_selections (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (box), button);
/* A dropdown using an expression to obtain strings */
minutes_model = gtk_string_list_new (minutes);
hours_model = gtk_string_list_new (hours);
store = g_list_store_new (G_TYPE_LIST_MODEL);
g_list_store_append (store, minutes_model);
g_list_store_append (store, hours_model);
g_object_unref (minutes_model);
g_object_unref (hours_model);
flat = gtk_flatten_list_model_new (G_LIST_MODEL (store));
button = drop_down_new_from_strings (many_times, NULL, NULL);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
0, NULL,
(GCallback)get_title,
NULL, NULL);
button = gtk_drop_down_new (G_LIST_MODEL (flat), expression);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_header), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_header), NULL);
gtk_drop_down_set_header_factory (GTK_DROP_DOWN (button), factory);
g_object_unref (factory);
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
gtk_expression_unref (expression);
gtk_box_append (GTK_BOX (box), button);
button = gtk_drop_down_new (NULL, NULL);

View File

@@ -14,7 +14,138 @@
#include <gtk/gtk.h>
#include "settings-key.h"
#include <stdlib.h>
/* Create an object that wraps GSettingsSchemaKey because that's a boxed type */
typedef struct _SettingsKey SettingsKey;
struct _SettingsKey
{
GObject parent_instance;
GSettings *settings;
GSettingsSchemaKey *key;
};
enum {
PROP_0,
PROP_NAME,
PROP_SUMMARY,
PROP_DESCRIPTION,
PROP_VALUE,
PROP_TYPE,
PROP_DEFAULT_VALUE,
N_PROPS
};
#define SETTINGS_TYPE_KEY (settings_key_get_type ())
G_DECLARE_FINAL_TYPE (SettingsKey, settings_key, SETTINGS, KEY, GObject);
G_DEFINE_TYPE (SettingsKey, settings_key, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
settings_key_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SettingsKey *self = SETTINGS_KEY (object);
switch (property_id)
{
case PROP_DESCRIPTION:
g_value_set_string (value, g_settings_schema_key_get_description (self->key));
break;
case PROP_NAME:
g_value_set_string (value, g_settings_schema_key_get_name (self->key));
break;
case PROP_SUMMARY:
g_value_set_string (value, g_settings_schema_key_get_summary (self->key));
break;
case PROP_VALUE:
{
GVariant *variant = g_settings_get_value (self->settings, g_settings_schema_key_get_name (self->key));
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
case PROP_TYPE:
{
const GVariantType *type = g_settings_schema_key_get_value_type (self->key);
g_value_set_string (value, g_variant_type_peek_string (type));
}
break;
case PROP_DEFAULT_VALUE:
{
GVariant *variant = g_settings_schema_key_get_default_value (self->key);
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
settings_key_finalize (GObject *object)
{
SettingsKey *self = SETTINGS_KEY (object);
g_object_unref (self->settings);
g_settings_schema_key_unref (self->key);
G_OBJECT_CLASS (settings_key_parent_class)->finalize (object);
}
static void
settings_key_class_init (SettingsKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = settings_key_finalize;
gobject_class->get_property = settings_key_get_property;
properties[PROP_DESCRIPTION] =
g_param_spec_string ("description", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_SUMMARY] =
g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_VALUE] =
g_param_spec_string ("value", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_TYPE] =
g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_DEFAULT_VALUE] =
g_param_spec_string ("default-value", NULL, NULL, NULL, G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
settings_key_init (SettingsKey *self)
{
}
static SettingsKey *
settings_key_new (GSettings *settings,
GSettingsSchemaKey *key)
{
SettingsKey *result = g_object_new (SETTINGS_TYPE_KEY, NULL);
result->settings = g_object_ref (settings);
result->key = g_settings_schema_key_ref (key);
return result;
}
static void
item_value_changed (GtkEditableLabel *label,
@@ -22,7 +153,6 @@ item_value_changed (GtkEditableLabel *label,
GtkColumnViewCell *cell)
{
SettingsKey *self;
GSettingsSchemaKey *key;
const char *text;
const GVariantType *type;
GVariant *variant;
@@ -33,10 +163,9 @@ item_value_changed (GtkEditableLabel *label,
text = gtk_editable_get_text (GTK_EDITABLE (label));
self = gtk_column_view_cell_get_item (cell);
key = settings_key_get_key (self);
type = g_settings_schema_key_get_value_type (key);
name = g_settings_schema_key_get_name (key);
type = g_settings_schema_key_get_value_type (self->key);
name = g_settings_schema_key_get_name (self->key);
variant = g_variant_parse (type, text, NULL, NULL, &error);
if (!variant)
@@ -46,13 +175,13 @@ item_value_changed (GtkEditableLabel *label,
goto revert;
}
if (!g_settings_schema_key_range_check (key, variant))
if (!g_settings_schema_key_range_check (self->key, variant))
{
g_warning ("Not a valid value for %s", name);
goto revert;
}
g_settings_set_value (settings_key_get_settings (self), name, variant);
g_settings_set_value (self->settings, name, variant);
g_variant_unref (variant);
return;

View File

@@ -1,230 +0,0 @@
/* Lists/Alternative Settings
* #Keywords: GtkListHeaderFactory, GtkSectionModel
*
* This demo shows an alternative settings viewer for GSettings.
*
* It demonstrates how to implement support for sections with GtkListView.
*
* It also shows how to quickly flatten a large tree of items into a list
* that can be filtered to find the items one is looking for.
*/
#include <gtk/gtk.h>
#include "settings-key.h"
static void
item_value_changed (GtkEditableLabel *label,
GParamSpec *pspec,
GtkColumnViewCell *cell)
{
SettingsKey *self;
GSettingsSchemaKey *key;
const char *text;
const GVariantType *type;
GVariant *variant;
GError *error = NULL;
const char *name;
char *value;
text = gtk_editable_get_text (GTK_EDITABLE (label));
self = gtk_column_view_cell_get_item (cell);
key = settings_key_get_key (self);
type = g_settings_schema_key_get_value_type (key);
name = g_settings_schema_key_get_name (key);
variant = g_variant_parse (type, text, NULL, NULL, &error);
if (!variant)
{
g_warning ("%s", error->message);
g_clear_error (&error);
goto revert;
}
if (!g_settings_schema_key_range_check (key, variant))
{
g_warning ("Not a valid value for %s", name);
goto revert;
}
g_settings_set_value (settings_key_get_settings (self), name, variant);
g_variant_unref (variant);
return;
revert:
gtk_widget_error_bell (GTK_WIDGET (label));
g_object_get (self, "value", &value, NULL);
gtk_editable_set_text (GTK_EDITABLE (label), value);
g_free (value);
}
static int
strvcmp (gconstpointer p1,
gconstpointer p2)
{
const char * const *s1 = p1;
const char * const *s2 = p2;
return strcmp (*s1, *s2);
}
static gpointer
map_settings_to_keys (gpointer item,
gpointer unused)
{
GSettings *settings = item;
GSettingsSchema *schema;
GListStore *store;
char **keys;
guint i;
g_object_get (settings, "settings-schema", &schema, NULL);
store = g_list_store_new (SETTINGS_TYPE_KEY);
keys = g_settings_schema_list_keys (schema);
for (i = 0; keys[i] != NULL; i++)
{
GSettingsSchemaKey *almost_there = g_settings_schema_get_key (schema, keys[i]);
SettingsKey *finally = settings_key_new (settings, almost_there);
g_list_store_append (store, finally);
g_object_unref (finally);
g_settings_schema_key_unref (almost_there);
}
g_strfreev (keys);
g_settings_schema_unref (schema);
g_object_unref (settings);
return store;
}
static GListModel *
create_settings_model (gpointer item,
gpointer unused)
{
GSettings *settings = item;
char **schemas;
GListStore *result;
guint i;
if (settings == NULL)
{
g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (),
TRUE,
&schemas,
NULL);
}
else
{
schemas = g_settings_list_children (settings);
}
if (schemas == NULL || schemas[0] == NULL)
{
g_free (schemas);
return NULL;
}
qsort (schemas, g_strv_length (schemas), sizeof (char *), strvcmp);
result = g_list_store_new (G_TYPE_SETTINGS);
for (i = 0; schemas[i] != NULL; i++)
{
GSettings *child;
if (settings == NULL)
child = g_settings_new (schemas[i]);
else
child = g_settings_get_child (settings, schemas[i]);
g_list_store_append (result, child);
g_object_unref (child);
}
g_strfreev (schemas);
return G_LIST_MODEL (result);
}
static void
search_enabled (GtkSearchEntry *entry)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
}
static void
stop_search (GtkSearchEntry *entry,
gpointer data)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_settings2 (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkListView *listview;
GListModel *model;
GtkTreeListModel *treemodel;
GtkNoSelection *selection;
GtkBuilderScope *scope;
GtkBuilder *builder;
GError *error = NULL;
GtkFilter *filter;
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, search_enabled);
gtk_builder_cscope_add_callback (scope, stop_search);
gtk_builder_cscope_add_callback (scope, settings_key_get_search_string);
gtk_builder_cscope_add_callback (scope, item_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
gtk_builder_add_from_resource (builder, "/listview_settings2/listview_settings2.ui", &error);
g_assert_no_error (error);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
listview = GTK_LIST_VIEW (gtk_builder_get_object (builder, "listview"));
filter = GTK_FILTER (gtk_builder_get_object (builder, "filter"));
model = create_settings_model (NULL, NULL);
treemodel = gtk_tree_list_model_new (model,
TRUE,
TRUE,
create_settings_model,
NULL,
NULL);
model = G_LIST_MODEL (gtk_map_list_model_new (G_LIST_MODEL (treemodel), map_settings_to_keys, NULL, NULL));
model = G_LIST_MODEL (gtk_flatten_list_model_new (model));
model = G_LIST_MODEL (gtk_filter_list_model_new (model, g_object_ref (filter)));
selection = gtk_no_selection_new (model);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), GTK_SELECTION_MODEL (selection));
g_object_unref (selection);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,130 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkStringFilter" id="filter">
<property name="expression">
<closure type="gchararray" function="settings_key_get_search_string" />
</property>
<property name="search" bind-source="entry" bind-property="text" />
</object>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Settings</property>
<property name="default-width">640</property>
<property name="default-height">480</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="search_button">
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional"/>
<signal name="notify::search-mode-enabled" handler="search_enabled" object="entry"/>
<child>
<object class="GtkSearchEntry" id="entry">
<signal name="stop-search" handler="stop_search"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView" id="listview">
<property name="vexpand">1</property>
<style>
<class name="rich-list"/>
</style>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<style>
<class name="dim-label"/>
</style>
<property name="xalign">0</property>
<property name="ellipsize">end</property>
<binding name="label">
<lookup name="summary" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="hexpand">1</property>
<property name="halign">end</property>
<binding name="text">
<lookup name="value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<signal name="notify::label" handler="item_value_changed"/>
</object>
</child>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
<property name="header-factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListHeader">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="schema" type="GSettings">
<lookup name="settings" type="SettingsKey">
<lookup name="item">GtkListHeader</lookup>
</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -367,7 +367,7 @@ do_listview_ucd (GtkWidget *do_widget)
gtk_label_set_width_chars (GTK_LABEL (label), 2);
gtk_widget_add_css_class (label, "enormous");
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, "label.enormous { font-size: 80px; }");
gtk_css_provider_load_from_data (provider, "label.enormous { font-size: 80px; }", -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (), GTK_STYLE_PROVIDER (provider), 800);
gtk_widget_set_hexpand (label, TRUE);
gtk_box_append (GTK_BOX (box), label);

View File

@@ -10,8 +10,6 @@
<property name="child">
<object class="GtkInscription">
<property name="hexpand">1</property>
<property name="nat-chars">25</property>
<property name="text-overflow">ellipsize-end</property>
<binding name="text">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>

View File

@@ -18,6 +18,7 @@
#include <string.h>
#include "config.h"
#include <gtk/gtk.h>
#include <glib/gstdio.h>
@@ -267,9 +268,9 @@ activate_run (GSimpleAction *action,
}
static GtkWidget *
display_image (const char *format,
const char *resource,
GtkWidget *label)
display_image (const char *format,
const char *resource,
char **label)
{
GtkWidget *sw, *image;
@@ -279,17 +280,13 @@ display_image (const char *format,
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), image);
gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
return sw;
}
static GtkWidget *
display_images (const char *format,
const char *resource_dir,
GtkWidget *label)
display_images (const char *format,
const char *resource_dir,
char **label)
{
char **resources;
GtkWidget *grid;
@@ -314,15 +311,13 @@ display_images (const char *format,
{
char *resource_name;
GtkWidget *box;
GtkWidget *image_label;
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
image_label = gtk_label_new (resources[i]);
widget = display_image (NULL, resource_name, image_label);
widget = display_image (NULL, resource_name, NULL);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_append (GTK_BOX (box), widget);
gtk_box_append (GTK_BOX (box), image_label);
gtk_box_append (GTK_BOX (box), gtk_label_new (resources[i]));
gtk_flow_box_insert (GTK_FLOW_BOX (grid), box, -1);
g_free (resource_name);
@@ -330,19 +325,15 @@ display_images (const char *format,
g_strfreev (resources);
gtk_label_set_label (GTK_LABEL (label), "Images");
gtk_accessible_update_relation (GTK_ACCESSIBLE (grid),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
*label = g_strdup ("Images");
return sw;
}
static GtkWidget *
display_text (const char *format,
const char *resource,
GtkWidget *label)
display_text (const char *format,
const char *resource,
char **label)
{
GtkTextBuffer *buffer;
GtkWidget *textview, *sw;
@@ -377,10 +368,6 @@ display_text (const char *format,
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
gtk_accessible_update_relation (GTK_ACCESSIBLE (textview),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
sw = gtk_scrolled_window_new ();
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
@@ -391,19 +378,15 @@ display_text (const char *format,
}
static GtkWidget *
display_video (const char *format,
const char *resource,
GtkWidget *label)
display_video (const char *format,
const char *resource,
char **label)
{
GtkWidget *video;
video = gtk_video_new_for_resource (resource);
gtk_video_set_loop (GTK_VIDEO (video), TRUE);
gtk_accessible_update_relation (GTK_ACCESSIBLE (video),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
return video;
}
@@ -425,9 +408,9 @@ display_nothing (const char *resource)
static struct {
const char *extension;
const char *format;
GtkWidget * (* display_func) (const char *format,
const char *resource,
GtkWidget *label);
GtkWidget * (* display_func) (const char *format,
const char *resource,
char **label);
} display_funcs[] = {
{ ".gif", NULL, display_image },
{ ".jpg", NULL, display_image },
@@ -450,6 +433,7 @@ add_data_tab (const char *demoname)
char **resources;
GtkWidget *widget, *label;
guint i, j;
char *label_string;
resource_dir = g_strconcat ("/", demoname, NULL);
resources = g_resources_enumerate_children (resource_dir, 0, NULL);
@@ -469,21 +453,23 @@ add_data_tab (const char *demoname)
break;
}
label = gtk_label_new (resources[i]);
label_string = NULL;
if (j < G_N_ELEMENTS (display_funcs))
widget = display_funcs[j].display_func (display_funcs[j].format,
resource_name,
label);
&label_string);
else
widget = display_nothing (resource_name);
label = gtk_label_new (label_string ? label_string : resources[i]);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK (notebook), widget),
"tab-expand", FALSE,
NULL);
g_free (resource_name);
g_free (label_string);
}
g_strfreev (resources);

View File

@@ -57,17 +57,14 @@
<object class="GtkBox">
<child>
<object class="GtkBox">
<property name="width-request">220</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar" id="searchbar">
<accessibility>
<relation name="labelled-by">search-entry</relation>
</accessibility>
<property name="key-capture-widget">window</property>
<child>
<object class="GtkSearchEntry" id="search-entry">
<accessibility>
<property name="label" translatable="yes">Search</property>
<relation name="controls">listview</relation>
</accessibility>
</object>
@@ -79,15 +76,15 @@
<style>
<class name="sidebar"/>
</style>
<property name="width-request">120</property>
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-width">1</property>
<property name="min-content-width">150</property>
<property name="vexpand">1</property>
<child>
<object class="GtkListView" id="listview">
<style>
<class name="navigation-sidebar"/>
</style>
<property name="tab-behavior">item</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>

View File

@@ -57,7 +57,6 @@ demos = files([
'listview_minesweeper.c',
'listview_selections.c',
'listview_settings.c',
'listview_settings2.c',
'listview_ucd.c',
'listview_weather.c',
'listview_words.c',
@@ -72,9 +71,6 @@ demos = files([
'paintable_symbolic.c',
'panes.c',
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',
@@ -135,7 +131,6 @@ extra_demo_sources = files([
'demo4widget.c',
'pixbufpaintable.c',
'script-names.c',
'settings-key.c',
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
@@ -161,7 +156,17 @@ demos_h = custom_target('gtk4 demo header',
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
if can_use_objcopy_for_resources
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',
@@ -228,7 +233,8 @@ endif
demo_cflags = []
foreach flag: common_cflags
if flag not in ['-Werror=missing-prototypes', '-Wmissing-prototypes',
'-Werror=missing-declarations', '-Wmissing-declarations']
'-Werror=missing-declarations', '-Wmissing-declarations',
'-fvisibility=hidden']
demo_cflags += flag
endif
endforeach

View File

@@ -68,9 +68,6 @@ do_password_entry (GtkWidget *do_widget)
"placeholder-text", "Password",
"activates-default", TRUE,
NULL);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Password",
-1);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_button), NULL);
gtk_box_append (GTK_BOX (box), entry);
@@ -80,9 +77,6 @@ do_password_entry (GtkWidget *do_widget)
"placeholder-text", "Confirm",
"activates-default", TRUE,
NULL);
gtk_accessible_update_property (GTK_ACCESSIBLE (entry2),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Confirm",
-1);
g_signal_connect (entry2, "notify::text", G_CALLBACK (update_button), NULL);
gtk_box_append (GTK_BOX (box), entry2);

View File

@@ -1,321 +0,0 @@
/* Path/Fill
*
* This demo shows how to use PangoCairo to draw text with more than
* just a single color.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define GTK_TYPE_PATH_PAINTABLE (gtk_path_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathPaintable, gtk_path_paintable, GTK, PATH_PAINTABLE, GObject)
struct _GtkPathPaintable
{
GObject parent_instance;
int width;
int height;
GskPath *path;
GdkPaintable *background;
};
struct _GtkPathPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_path_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_width (self->background), self->width);
else
return self->width;
}
static int
gtk_path_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_height (self->background), self->height);
else
return self->height;
}
static void
gtk_path_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
#if 0
gtk_snapshot_push_fill (snapshot, self->path, GSK_FILL_RULE_WINDING);
#else
GskStroke *stroke = gsk_stroke_new (4.0);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
#endif
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static GdkPaintableFlags
gtk_path_paintable_get_flags (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return gdk_paintable_get_flags (self->background);
else
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_path_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_path_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_path_paintable_get_intrinsic_height;
iface->snapshot = gtk_path_paintable_snapshot;
iface->get_flags = gtk_path_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkPathPaintable, gtk_path_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_path_paintable_paintable_init))
/* Here's the boilerplate for the GObject declaration.
* We need to disconnect the signals here that we set up elsewhere
*/
static void
gtk_path_paintable_dispose (GObject *object)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (object);
if (self->background)
{
g_signal_handlers_disconnect_by_func (self->background, gdk_paintable_invalidate_contents, self);
g_signal_handlers_disconnect_by_func (self->background, gdk_paintable_invalidate_size, self);
g_clear_object (&self->background);
}
G_OBJECT_CLASS (gtk_path_paintable_parent_class)->dispose (object);
}
static void
gtk_path_paintable_class_init (GtkPathPaintableClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_paintable_dispose;
}
static void
gtk_path_paintable_init (GtkPathPaintable *self)
{
}
/* And finally, we add a simple constructor.
* It is declared in the header so that the other examples
* can use it.
*/
GdkPaintable *
gtk_path_paintable_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkPathPaintable *self;
self = g_object_new (GTK_TYPE_PATH_PAINTABLE, NULL);
self->path = path;
self->background = background;
if (self->background)
{
g_object_ref (self->background);
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
}
self->width = width;
self->height = height;
return GDK_PAINTABLE (self);
}
void
gtk_path_paintable_set_path (GtkPathPaintable *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
self->path = gsk_path_ref (path);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static GskPath *
create_hexagon (GtkWidget *widget)
{
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, 120, 0);
gsk_path_builder_line_to (builder, 360, 0);
gsk_path_builder_line_to (builder, 480, 208);
gsk_path_builder_line_to (builder, 360, 416);
gsk_path_builder_line_to (builder, 120, 416);
gsk_path_builder_line_to (builder, 0, 208);
gsk_path_builder_close (builder);
return gsk_path_builder_free_to_path (builder);
}
static GskPath *
create_path_from_text (GtkWidget *widget)
{
cairo_surface_t *surface;
cairo_t *cr;
cairo_path_t *path;
PangoLayout *layout;
PangoFontDescription *desc;
GskPath *result;
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
cr = cairo_create (surface);
layout = gtk_widget_create_pango_layout (widget, "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path_flat (cr);
result = gsk_path_new_from_cairo (path);
cairo_path_destroy (path);
g_object_unref (layout);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return result;
}
static gboolean
update_path (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer measure)
{
float progress = gdk_frame_clock_get_frame_time (frame_clock) % (60 * G_USEC_PER_SEC) / (float) (30 * G_USEC_PER_SEC);
GskPathBuilder *builder;
GskPath *path;
graphene_point_t pos;
graphene_vec2_t tangent;
builder = gsk_path_builder_new ();
gsk_path_measure_add_segment (measure,
builder,
progress > 1 ? (progress - 1) * gsk_path_measure_get_length (measure) : 0.0,
(progress < 1 ? progress : 1.0) * gsk_path_measure_get_length (measure));
gsk_path_measure_get_point (measure,
(progress > 1 ? (progress - 1) : progress) * gsk_path_measure_get_length (measure),
&pos,
&tangent);
gsk_path_builder_move_to (builder, pos.x + 5 * graphene_vec2_get_x (&tangent), pos.y + 5 * graphene_vec2_get_y (&tangent));
gsk_path_builder_line_to (builder, pos.x + 3 * graphene_vec2_get_y (&tangent), pos.y + 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_line_to (builder, pos.x - 3 * graphene_vec2_get_y (&tangent), pos.y - 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_close (builder);
path = gsk_path_builder_free_to_path (builder);
gtk_path_paintable_set_path (GTK_PATH_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget))),
path);
gsk_path_unref (path);
return G_SOURCE_CONTINUE;
}
GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
GtkMediaStream *stream;
GskPath *path;
graphene_rect_t bounds;
GskPathMeasure *measure;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_hexagon (window);
path = create_path_from_text (window);
gsk_path_get_bounds (path, &bounds);
paintable = gtk_path_paintable_new (path,
GDK_PAINTABLE (stream),
bounds.origin.x + bounds.size.width,
bounds.origin.y + bounds.size.height);
picture = gtk_picture_new_for_paintable (paintable);
measure = gsk_path_measure_new (path);
gtk_widget_add_tick_callback (picture, update_path, measure, (GDestroyNotify) gsk_path_measure_unref);
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,338 +0,0 @@
/* Path/Maze
*
* This demo shows how to use a GskPath to create a maze and use
* gsk_path_measure_get_closest_point() to check the mouse stays
* on the path.
*
* It also shows off the performance of GskPath (or not) as this
* is a rather complex path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define MAZE_GRID_SIZE 20
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
#define MAZE_WIDTH 31
#define MAZE_HEIGHT 21
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
struct _GtkMaze
{
GtkWidget parent_instance;
int width;
int height;
GskPath *path;
GskPathMeasure *measure;
GdkPaintable *background;
gboolean active;
};
struct _GtkMazeClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
static void
gtk_maze_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkMaze *self = GTK_MAZE (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = self->width;
else
*minimum = *natural = self->height;
}
static void
gtk_maze_snapshot (GtkWidget *widget,
GdkSnapshot *snapshot)
{
GtkMaze *self = GTK_MAZE (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskStroke *stroke;
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
if (self->active)
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_pop (snapshot);
}
static void
gtk_maze_dispose (GObject *object)
{
GtkMaze *self = GTK_MAZE (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
if (self->background)
{
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
g_clear_object (&self->background);
}
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
}
static void
gtk_maze_class_init (GtkMazeClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_maze_dispose;
widget_class->measure = gtk_maze_measure;
widget_class->snapshot = gtk_maze_snapshot;
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkMaze *self)
{
if (!self->active)
return;
if (gsk_path_measure_get_closest_point (self->measure, &GRAPHENE_POINT_INIT (x, y), NULL) <= MAZE_STROKE_SIZE_ACTIVE / 2.0f)
return;
self->active = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkMaze *self)
{
if (!self->active)
{
self->active = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
gtk_maze_init (GtkMaze *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->active = TRUE;
}
static void
gtk_maze_set_path (GtkMaze *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
self->path = gsk_path_ref (path);
self->measure = gsk_path_measure_new (path);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
GtkWidget *
gtk_maze_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkMaze *self;
self = g_object_new (GTK_TYPE_MAZE, NULL);
gtk_maze_set_path (self, path);
gsk_path_unref (path);
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
}
self->width = width;
self->height = height;
return GTK_WIDGET (self);
}
static void
add_point_to_maze (GtkBitset *maze,
GskPathBuilder *builder,
guint x,
guint y)
{
gboolean set[4] = { FALSE, FALSE, FALSE, FALSE };
guint dir;
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
while (TRUE)
{
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
if (set[0] && set[1] && set[2] && set[3])
return;
do
{
dir = g_random_int_range (0, 4);
}
while (set[dir]);
switch (dir)
{
case 0:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x - 1, y);
break;
case 1:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y - 1);
break;
case 2:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x + 1, y);
break;
case 3:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y + 1);
break;
default:
g_assert_not_reached ();
break;
}
}
}
static GskPath *
create_path_for_maze (GtkWidget *widget)
{
GskPathBuilder *builder;
GtkBitset *maze;
builder = gsk_path_builder_new ();
maze = gtk_bitset_new_empty ();
/* make sure the outer lines are unreachable:
* Set the full range, then remove the center again. */
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
/* Fill the maze */
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
/* Add start and stop lines */
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
gtk_bitset_unref (maze);
return gsk_path_builder_free_to_path (builder);
}
GtkWidget *
do_path_maze (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *maze;
GtkMediaStream *stream;
GskPath *path;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_path_for_maze (window);
maze = gtk_maze_new (path,
GDK_PAINTABLE (stream),
MAZE_WIDTH * MAZE_GRID_SIZE,
MAZE_HEIGHT * MAZE_GRID_SIZE);
gtk_window_set_child (GTK_WINDOW (window), maze);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,580 +0,0 @@
/* Path/Text
*
* This demo shows how to use GskPath to animate a path along another path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_TEXT,
PROP_EDITABLE,
N_PROPS
};
struct _GtkPathWidget
{
GtkWidget parent_instance;
char *text;
gboolean editable;
graphene_point_t points[4];
guint active_point;
float line_closest;
GskPath *line_path;
GskPathMeasure *line_measure;
GskPath *text_path;
GdkPaintable *background;
};
struct _GtkPathWidgetClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
static GskPath *
create_path_from_text (GtkWidget *widget,
const char *text)
{
cairo_surface_t *surface;
cairo_t *cr;
cairo_path_t *path;
PangoLayout *layout;
PangoFontDescription *desc;
GskPath *result;
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
cr = cairo_create (surface);
layout = gtk_widget_create_pango_layout (widget, text);
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path_flat (cr);
result = gsk_path_new_from_cairo (path);
cairo_path_destroy (path);
g_object_unref (layout);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
gsk_path_measure_get_point (measure, pt->x * scale, res, &tangent);
res->x -= pt->y * scale * graphene_vec2_get_y (&tangent);
res->y += pt->y * scale * graphene_vec2_get_x (&tangent);
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_CURVE:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], transform->scale, &res[2]);
gsk_path_builder_curve_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
}
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (transform->builder);
break;
default:
g_assert_not_reached();
return FALSE;
}
return TRUE;
}
static GskPath *
gtk_path_transform (GskPathMeasure *measure,
GskPath *path)
{
GtkPathTransform transform = { measure, gsk_path_builder_new () };
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
if (bounds.origin.x + bounds.size.width > 0)
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
else
transform.scale = 1.0f;
gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVES, gtk_path_transform_op, &transform);
return gsk_path_builder_free_to_path (transform.builder);
}
static void
gtk_path_widget_clear_text_path (GtkPathWidget *self)
{
g_clear_pointer (&self->text_path, gsk_path_unref);
}
static void
gtk_path_widget_clear_paths (GtkPathWidget *self)
{
gtk_path_widget_clear_text_path (self);
g_clear_pointer (&self->line_path, gsk_path_unref);
g_clear_pointer (&self->line_measure, gsk_path_measure_unref);
}
static void
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
gtk_path_widget_clear_text_path (self);
if (self->line_measure == NULL)
return;
path = create_path_from_text (GTK_WIDGET (self), self->text);
self->text_path = gtk_path_transform (self->line_measure, path);
gsk_path_unref (path);
}
static void
gtk_path_widget_create_paths (GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
GskPathBuilder *builder;
gtk_path_widget_clear_paths (self);
if (width <= 0 || height <= 0)
return;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder,
self->points[0].x * width, self->points[0].y * height);
gsk_path_builder_curve_to (builder,
self->points[1].x * width, self->points[1].y * height,
self->points[2].x * width, self->points[2].y * height,
self->points[3].x * width, self->points[3].y * height);
self->line_path = gsk_path_builder_free_to_path (builder);
self->line_measure = gsk_path_measure_new (self->line_path);
gtk_path_widget_create_text_path (self);
}
static void
gtk_path_widget_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
gtk_path_widget_create_paths (self);
}
static void
gtk_path_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskPath *path;
GskStroke *stroke;
gsize i;
/* frosted glass the background */
gtk_snapshot_push_blur (snapshot, 100);
gdk_paintable_snapshot (self->background, snapshot, width, height);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.6 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the text */
if (self->text_path)
{
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
gdk_paintable_snapshot (self->background, snapshot, width, height);
/* ... with an emboss effect */
stroke = gsk_stroke_new (2.0);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_stroke_free (stroke);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
}
if (self->editable && self->line_path)
{
GskPathBuilder *builder;
/* draw the control line */
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the points */
builder = gsk_path_builder_new ();
for (i = 0; i < 4; i++)
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
}
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
if (self->line_closest >= 0)
{
GskPathBuilder *builder;
graphene_point_t closest;
builder = gsk_path_builder_new ();
gsk_path_measure_get_point (self->line_measure, self->line_closest, &closest, NULL);
gsk_path_builder_add_circle (builder, &closest, POINT_SIZE);
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
}
static void
gtk_path_widget_set_text (GtkPathWidget *self,
const char *text)
{
if (g_strcmp0 (self->text, text) == 0)
return;
g_free (self->text);
self->text = g_strdup (text);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
}
static void
gtk_path_widget_set_editable (GtkPathWidget *self,
gboolean editable)
{
if (self->editable == editable)
return;
self->editable = editable;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
}
static void
gtk_path_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
gtk_path_widget_set_text (self, g_value_get_string (value));
break;
case PROP_EDITABLE:
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, self->text);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, self->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_dispose (GObject *object)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
gtk_path_widget_clear_paths (self);
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
}
static void
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_widget_dispose;
object_class->set_property = gtk_path_widget_set_property;
object_class->get_property = gtk_path_widget_get_property;
widget_class->size_allocate = gtk_path_widget_allocate;
widget_class->snapshot = gtk_path_widget_snapshot;
properties[PROP_TEXT] =
g_param_spec_string ("text",
"text",
"Text transformed along a path",
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_EDITABLE] =
g_param_spec_boolean ("editable",
"editable",
"If the path can be edited by the user",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkPathWidget *self)
{
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
gsize i;
for (i = 0; i < 4; i++)
{
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
{
self->active_point = i;
break;
}
}
if (i == 4)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
double start_x, start_y;
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
(start_y + offset_y) / height);
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkPathWidget *self)
{
gsk_path_measure_get_closest_point_full (self->line_measure,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&self->line_closest,
NULL, NULL, NULL);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
self->line_closest = -1;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_widget_init (GtkPathWidget *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->line_closest = -1;
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
gtk_path_widget_set_text (self, "It's almost working");
}
GtkWidget *
gtk_path_widget_new (void)
{
GtkPathWidget *self;
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_text (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WIDGET);
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Text along a Path</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="edit-toggle">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer">
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<child>
<object class="GtkEntry" id="text">
<property name="text">Through the looking glass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPathWidget" id="view">
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -384,7 +384,7 @@ create_board (GtkWidget *window)
"}";
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, css);
gtk_css_provider_load_from_data (provider, css, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);

View File

@@ -189,7 +189,6 @@ do_pickers (GtkWidget *do_widget)
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
picker = gtk_color_dialog_button_new (gtk_color_dialog_new ());
gtk_label_set_mnemonic_widget (GTK_LABEL (label), picker);
gtk_grid_attach (GTK_GRID (table), picker, 1, 0, 1, 1);
label = gtk_label_new ("Font:");
@@ -199,7 +198,6 @@ do_pickers (GtkWidget *do_widget)
gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
picker = gtk_font_dialog_button_new (gtk_font_dialog_new ());
gtk_label_set_mnemonic_widget (GTK_LABEL (label), picker);
gtk_grid_attach (GTK_GRID (table), picker, 1, 1, 1, 1);
label = gtk_label_new ("File:");
@@ -210,9 +208,6 @@ do_pickers (GtkWidget *do_widget)
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Select File",
-1);
label = gtk_label_new ("None");
@@ -228,9 +223,6 @@ do_pickers (GtkWidget *do_widget)
gtk_box_append (GTK_BOX (picker), button);
app_picker = gtk_button_new_from_icon_name ("emblem-system-symbolic");
gtk_widget_set_halign (app_picker, GTK_ALIGN_END);
gtk_accessible_update_property (GTK_ACCESSIBLE (app_picker),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Open File",
-1);
gtk_widget_set_sensitive (app_picker, FALSE);
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
gtk_box_append (GTK_BOX (picker), app_picker);
@@ -249,7 +241,7 @@ do_pickers (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -1,165 +0,0 @@
#include "settings-key.h"
/* Create an object that wraps GSettingsSchemaKey because that's a boxed type */
struct _SettingsKey
{
GObject parent_instance;
GSettings *settings;
GSettingsSchemaKey *key;
};
enum {
PROP_0,
PROP_NAME,
PROP_SETTINGS,
PROP_SUMMARY,
PROP_DESCRIPTION,
PROP_VALUE,
PROP_TYPE,
PROP_DEFAULT_VALUE,
N_PROPS
};
G_DEFINE_TYPE (SettingsKey, settings_key, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
settings_key_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SettingsKey *self = SETTINGS_KEY (object);
switch (property_id)
{
case PROP_DESCRIPTION:
g_value_set_string (value, g_settings_schema_key_get_description (self->key));
break;
case PROP_NAME:
g_value_set_string (value, g_settings_schema_key_get_name (self->key));
break;
case PROP_SUMMARY:
g_value_set_string (value, g_settings_schema_key_get_summary (self->key));
break;
case PROP_VALUE:
{
GVariant *variant = g_settings_get_value (self->settings, g_settings_schema_key_get_name (self->key));
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
case PROP_TYPE:
{
const GVariantType *type = g_settings_schema_key_get_value_type (self->key);
g_value_set_string (value, g_variant_type_peek_string (type));
}
break;
case PROP_DEFAULT_VALUE:
{
GVariant *variant = g_settings_schema_key_get_default_value (self->key);
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
case PROP_SETTINGS:
g_value_set_object (value, self->settings);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
settings_key_finalize (GObject *object)
{
SettingsKey *self = SETTINGS_KEY (object);
g_object_unref (self->settings);
g_settings_schema_key_unref (self->key);
G_OBJECT_CLASS (settings_key_parent_class)->finalize (object);
}
static void
settings_key_class_init (SettingsKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = settings_key_finalize;
gobject_class->get_property = settings_key_get_property;
properties[PROP_DESCRIPTION] =
g_param_spec_string ("description", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_SETTINGS] =
g_param_spec_object ("settings", NULL, NULL, G_TYPE_SETTINGS, G_PARAM_READABLE);
properties[PROP_SUMMARY] =
g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_VALUE] =
g_param_spec_string ("value", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_TYPE] =
g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_DEFAULT_VALUE] =
g_param_spec_string ("default-value", NULL, NULL, NULL, G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
settings_key_init (SettingsKey *self)
{
}
SettingsKey *
settings_key_new (GSettings *settings,
GSettingsSchemaKey *key)
{
SettingsKey *result = g_object_new (SETTINGS_TYPE_KEY, NULL);
result->settings = g_object_ref (settings);
result->key = g_settings_schema_key_ref (key);
return result;
}
GSettingsSchemaKey *
settings_key_get_key (SettingsKey *self)
{
return self->key;
}
GSettings *
settings_key_get_settings (SettingsKey *self)
{
return self->settings;
}
char *
settings_key_get_search_string (SettingsKey *self)
{
char *schema, *result;
g_object_get (self->settings, "schema-id", &schema, NULL);
result = g_strconcat (g_settings_schema_key_get_name (self->key), " ",
g_settings_schema_key_get_summary (self->key), " ",
schema,
NULL);
g_free (schema);
return result;
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#include <stdlib.h>
/* Create an object that wraps GSettingsSchemaKey because that's a boxed type */
typedef struct _SettingsKey SettingsKey;
#define SETTINGS_TYPE_KEY (settings_key_get_type ())
G_DECLARE_FINAL_TYPE (SettingsKey, settings_key, SETTINGS, KEY, GObject);
SettingsKey * settings_key_new (GSettings *settings,
GSettingsSchemaKey *key);
GSettingsSchemaKey * settings_key_get_key (SettingsKey *self);
GSettings * settings_key_get_settings (SettingsKey *self);
char * settings_key_get_search_string (SettingsKey *self);

View File

@@ -28,14 +28,14 @@ add_row (GtkGrid *table,
label = gtk_label_new_with_mnemonic (label_text);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_widget_set_hexpand (label, TRUE);
gtk_grid_attach (table, label, 0, row, 1, 1);
dropdown = gtk_drop_down_new_from_strings (options);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), dropdown);
gtk_widget_set_halign (dropdown, GTK_ALIGN_END);
gtk_widget_set_valign (dropdown, GTK_ALIGN_BASELINE_FILL);
gtk_widget_set_valign (dropdown, GTK_ALIGN_BASELINE);
gtk_size_group_add_widget (size_group, dropdown);
gtk_grid_attach (table, dropdown, 1, row, 1, 1);
}

View File

@@ -150,36 +150,20 @@ do_video_player (GtkWidget *do_widget)
button = gtk_button_new ();
image = gtk_image_new_from_resource ("/cursors/images/gtk_logo_cursor.png");
gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, button, NULL,
-1);
gtk_image_set_pixel_size (GTK_IMAGE (image), 24);
gtk_button_set_child (GTK_BUTTON (button), image);
g_signal_connect (button, "clicked", G_CALLBACK (logo_clicked_cb), video);
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "GTK Logo",
-1);
gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);
button = gtk_button_new ();
image = gtk_image_new_from_resource ("/video-player/bbb.png");
gtk_accessible_update_relation (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, button, NULL,
-1);
gtk_image_set_pixel_size (GTK_IMAGE (image), 24);
gtk_button_set_child (GTK_BUTTON (button), image);
g_signal_connect (button, "clicked", G_CALLBACK (bbb_clicked_cb), video);
gtk_accessible_update_property (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Big Buck Bunny",
-1);
gtk_header_bar_pack_start (GTK_HEADER_BAR (title), button);
fullscreen_button = gtk_button_new_from_icon_name ("view-fullscreen-symbolic");
g_signal_connect (fullscreen_button, "clicked", G_CALLBACK (fullscreen_clicked_cb), NULL);
gtk_accessible_update_property (GTK_ACCESSIBLE (fullscreen_button),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Fullscreen",
-1);
gtk_header_bar_pack_end (GTK_HEADER_BAR (title), fullscreen_button);
controller = gtk_shortcut_controller_new ();

View File

@@ -1,5 +1,5 @@
gen_demo_header = find_program('../build-aux/meson/gen-demo-header.py')
demo_profile = get_option('demo-profile')
demo_profile = get_option('profile')
demo_conf_h = declare_dependency(
sources: custom_target('demo-header',

View File

@@ -201,7 +201,7 @@ node_editor_application_startup (GApplication *app)
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, css);
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);

View File

@@ -1190,362 +1190,11 @@ node_editor_window_unrealize (GtkWidget *widget)
GTK_WIDGET_CLASS (node_editor_window_parent_class)->unrealize (widget);
}
typedef struct
{
NodeEditorWindow *self;
GtkTextIter start, end;
} Selection;
static void
color_cb (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkColorDialog *dialog = GTK_COLOR_DIALOG (source);
Selection *selection = data;
NodeEditorWindow *self = selection->self;
GdkRGBA *color;
char *text;
GError *error = NULL;
GtkTextBuffer *buffer;
color = gtk_color_dialog_choose_rgba_finish (dialog, result, &error);
if (!color)
{
g_print ("%s\n", error->message);
g_error_free (error);
g_free (selection);
return;
}
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->text_view));
text = gdk_rgba_to_string (color);
gtk_text_buffer_delete (buffer, &selection->start, &selection->end);
gtk_text_buffer_insert (buffer, &selection->start, text, -1);
g_free (text);
gdk_rgba_free (color);
g_free (selection);
}
static void
font_cb (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkFontDialog *dialog = GTK_FONT_DIALOG (source);
Selection *selection = data;
NodeEditorWindow *self = selection->self;
GError *error = NULL;
PangoFontDescription *desc;
GtkTextBuffer *buffer;
char *text;
desc = gtk_font_dialog_choose_font_finish (dialog, result, &error);
if (!desc)
{
g_print ("%s\n", error->message);
g_error_free (error);
g_free (selection);
return;
}
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->text_view));
text = pango_font_description_to_string (desc);
gtk_text_buffer_delete (buffer, &selection->start, &selection->end);
gtk_text_buffer_insert (buffer, &selection->start, text, -1);
g_free (text);
pango_font_description_free (desc);
g_free (selection);
}
static void
file_cb (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
Selection *selection = data;
NodeEditorWindow *self = selection->self;
GError *error = NULL;
GFile *file;
GtkTextBuffer *buffer;
char *text;
file = gtk_file_dialog_open_finish (dialog, result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
g_free (selection);
return;
}
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->text_view));
text = g_file_get_uri (file);
gtk_text_buffer_delete (buffer, &selection->start, &selection->end);
gtk_text_buffer_insert (buffer, &selection->start, text, -1);
g_free (text);
g_object_unref (file);
g_free (selection);
}
static void
key_pressed (GtkEventControllerKey *controller,
unsigned int keyval,
unsigned int keycode,
GdkModifierType state,
gpointer data)
{
GtkWidget *dd = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (controller));
Selection *selection = data;
NodeEditorWindow *self = selection->self;
unsigned int selected;
GtkStringList *strings;
GtkTextBuffer *buffer;
const char *text;
if (keyval != GDK_KEY_Escape)
return;
strings = GTK_STRING_LIST (gtk_drop_down_get_model (GTK_DROP_DOWN (dd)));
selected = gtk_drop_down_get_selected (GTK_DROP_DOWN (dd));
text = gtk_string_list_get_string (strings, selected);
gtk_text_view_remove (GTK_TEXT_VIEW (self->text_view), dd);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->text_view));
gtk_text_iter_backward_search (&selection->start, "mode:", 0, NULL, &selection->start, NULL);
gtk_text_iter_forward_search (&selection->start, ";", 0, &selection->end, NULL, NULL);
gtk_text_buffer_delete (buffer, &selection->start, &selection->end);
gtk_text_buffer_insert (buffer, &selection->start, " ", -1);
gtk_text_buffer_insert (buffer, &selection->start, text, -1);
}
static void
node_editor_window_edit (NodeEditorWindow *self,
GtkTextIter *iter)
{
GtkTextIter start, end;
GtkTextBuffer *buffer;
Selection *selection;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->text_view));
gtk_text_iter_set_line_offset (iter, 0);
if (gtk_text_iter_forward_search (iter, ";", 0, &end, NULL, NULL) &&
gtk_text_iter_forward_search (iter, "color:", 0, NULL, &start, &end))
{
GtkColorDialog *dialog;
GdkRGBA color;
char *text;
while (g_unichar_isspace (gtk_text_iter_get_char (&start)))
gtk_text_iter_forward_char (&start);
gtk_text_buffer_select_range (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
gdk_rgba_parse (&color, text);
g_free (text);
selection = g_new0 (Selection, 1);
selection->self = self;
selection->start = start;
selection->end = end;
dialog = gtk_color_dialog_new ();
gtk_color_dialog_choose_rgba (dialog, GTK_WINDOW (self), &color, NULL, color_cb, selection);
}
else if (gtk_text_iter_forward_search (iter, ";", 0, &end, NULL, NULL) &&
gtk_text_iter_forward_search (iter, "font:", 0, NULL, &start, &end))
{
GtkFontDialog *dialog;
PangoFontDescription *desc;
char *text;
while (g_unichar_isspace (gtk_text_iter_get_char (&start)))
gtk_text_iter_forward_char (&start);
/* Skip the quotes */
gtk_text_iter_forward_char (&start);
gtk_text_iter_backward_char (&end);
gtk_text_buffer_select_range (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
desc = pango_font_description_from_string (text);
g_free (text);
selection = g_new0 (Selection, 1);
selection->self = self;
selection->start = start;
selection->end = end;
dialog = gtk_font_dialog_new ();
gtk_font_dialog_choose_font (dialog, GTK_WINDOW (self), desc, NULL, font_cb, selection);
pango_font_description_free (desc);
}
else if (gtk_text_iter_forward_search (iter, ";", 0, &end, NULL, NULL) &&
gtk_text_iter_forward_search (iter, "mode:", 0, NULL, &start, &end))
{
/* Assume we have a blend node, for now */
GEnumClass *class;
GtkStringList *strings;
GtkWidget *dd;
GtkTextChildAnchor *anchor;
unsigned int selected = 0;
GtkEventController *key_controller;
gboolean is_blend_mode = FALSE;
char *text;
while (g_unichar_isspace (gtk_text_iter_get_char (&start)))
gtk_text_iter_forward_char (&start);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
strings = gtk_string_list_new (NULL);
class = g_type_class_ref (GSK_TYPE_BLEND_MODE);
for (unsigned int i = 0; i < class->n_values; i++)
{
if (strcmp (class->values[i].value_nick, text) == 0)
is_blend_mode = TRUE;
}
g_type_class_unref (class);
if (is_blend_mode)
class = g_type_class_ref (GSK_TYPE_BLEND_MODE);
else
class = g_type_class_ref (GSK_TYPE_MASK_MODE);
for (unsigned int i = 0; i < class->n_values; i++)
{
if (i == 0 && is_blend_mode)
gtk_string_list_append (strings, "normal");
else
gtk_string_list_append (strings, class->values[i].value_nick);
if (strcmp (class->values[i].value_nick, text) == 0)
selected = i;
}
g_type_class_unref (class);
gtk_text_buffer_delete (buffer, &start, &end);
anchor = gtk_text_buffer_create_child_anchor (buffer, &start);
dd = gtk_drop_down_new (G_LIST_MODEL (strings), NULL);
gtk_drop_down_set_selected (GTK_DROP_DOWN (dd), selected);
gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (self->text_view), dd, anchor);
selection = g_new0 (Selection, 1);
selection->self = self;
selection->start = start;
selection->end = end;
key_controller = gtk_event_controller_key_new ();
g_signal_connect (key_controller, "key-pressed", G_CALLBACK (key_pressed), selection);
gtk_widget_add_controller (dd, key_controller);
}
else if (gtk_text_iter_forward_search (iter, ";", 0, &end, NULL, NULL) &&
gtk_text_iter_forward_search (iter, "texture:", 0, NULL, &start, &end))
{
GtkFileDialog *dialog;
GtkTextIter skip;
char *text;
GFile *file;
while (g_unichar_isspace (gtk_text_iter_get_char (&start)))
gtk_text_iter_forward_char (&start);
skip = start;
gtk_text_iter_forward_chars (&skip, strlen ("url(\""));
text = gtk_text_iter_get_text (&start, &skip);
if (strcmp (text, "url(\"") != 0)
{
g_free (text);
return;
}
g_free (text);
start = skip;
skip = end;
gtk_text_iter_backward_chars (&skip, strlen ("\")"));
text = gtk_text_iter_get_text (&skip, &end);
if (strcmp (text, "\")") != 0)
{
g_free (text);
return;
}
g_free (text);
end = skip;
gtk_text_buffer_select_range (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
file = g_file_new_for_uri (text);
g_free (text);
selection = g_new0 (Selection, 1);
selection->self = self;
selection->start = start;
selection->end = end;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_initial_file (dialog, file);
gtk_file_dialog_open (dialog, GTK_WINDOW (self), NULL, file_cb, selection);
g_object_unref (file);
}
}
static void
click_gesture_pressed (GtkGestureClick *gesture,
int n_press,
double x,
double y,
NodeEditorWindow *self)
{
GtkTextIter iter;
int bx, by, trailing;
GdkModifierType state;
state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (gesture));
if ((state & GDK_CONTROL_MASK) == 0)
return;
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (self->text_view), GTK_TEXT_WINDOW_TEXT, x, y, &bx, &by);
gtk_text_view_get_iter_at_position (GTK_TEXT_VIEW (self->text_view), &iter, &trailing, bx, by);
node_editor_window_edit (self, &iter);
}
static void
edit_action_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
NodeEditorWindow *self = NODE_EDITOR_WINDOW (widget);
GtkTextBuffer *buffer;
GtkTextIter start, end;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->text_view));
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
node_editor_window_edit (self, &start);
}
static void
node_editor_window_class_init (NodeEditorWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GtkShortcutTrigger *trigger;
GtkShortcutAction *action;
GtkShortcut *shortcut;
object_class->dispose = node_editor_window_dispose;
object_class->finalize = node_editor_window_finalize;
@@ -1576,14 +1225,6 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
gtk_widget_class_bind_template_callback (widget_class, dark_mode_cb);
gtk_widget_class_bind_template_callback (widget_class, on_picture_drag_prepare_cb);
gtk_widget_class_bind_template_callback (widget_class, on_picture_drop_cb);
gtk_widget_class_bind_template_callback (widget_class, click_gesture_pressed);
gtk_widget_class_install_action (widget_class, "smart-edit", NULL, edit_action_cb);
trigger = gtk_keyval_trigger_new (GDK_KEY_e, GDK_CONTROL_MASK);
action = gtk_named_action_new ("smart-edit");
shortcut = gtk_shortcut_new (trigger, action);
gtk_widget_class_add_shortcut (widget_class, shortcut);
}
static GtkWidget *
@@ -1701,13 +1342,6 @@ node_editor_window_init (NodeEditorWindow *self)
" }\n"
" transform: translate(0, 140);\n"
"}", -1);
if (g_getenv ("GSK_RENDERER"))
{
char *new_title = g_strdup_printf ("GTK Node Editor - %s", g_getenv ("GSK_RENDERER"));
gtk_window_set_title (GTK_WINDOW (self), new_title);
g_free (new_title);
}
}
NodeEditorWindow *

View File

@@ -16,14 +16,6 @@
</item>
</section>
</menu>
<menu id="extra_menu">
<section>
<item>
<attribute name="label" translatable="yes">Assisted _Edit</attribute>
<attribute name="action">smart-edit</attribute>
</item>
</section>
</menu>
<object class="GtkPopover" id="testcase_popover">
<child>
@@ -203,17 +195,10 @@
<property name="right-margin">6</property>
<property name="bottom-margin">6</property>
<property name="has-tooltip">1</property>
<property name="extra-menu">extra_menu</property>
<signal name="query-tooltip" handler="text_view_query_tooltip_cb"/>
<style>
<class name="editor" />
</style>
<child>
<object class="GtkGestureClick">
<property name="button">1</property>
<signal name="pressed" handler="click_gesture_pressed"/>
</object>
</child>
</object>
</child>
</object>

View File

@@ -193,7 +193,7 @@ Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| source | `<node>` | color { } | always |
| mode | `<mask-mode>` | alpha | non-default |
| mode | `<blend-mode>` | alpha | non-default |
| mask | `<node>` | color { } | always |
Creates a node like `gsk_mask_node_new()` with the given properties.

View File

@@ -1,6 +1,16 @@
# demos/widget-factory
if can_use_objcopy_for_resources
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',

View File

@@ -1210,12 +1210,12 @@ typedef struct {
static void
add_background (GtkWidget *flowbox,
const char *filename,
GdkTexture *texture,
GdkPixbuf *pixbuf,
gboolean is_resource)
{
GtkWidget *child;
child = gtk_picture_new_for_paintable (GDK_PAINTABLE (texture));
child = gtk_picture_new_for_pixbuf (pixbuf);
gtk_widget_set_size_request (child, 110, 70);
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
child = gtk_widget_get_parent (child);
@@ -1231,7 +1231,6 @@ background_loaded_cb (GObject *source,
{
BackgroundData *bd = data;
GdkPixbuf *pixbuf;
GdkTexture *texture;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
@@ -1242,11 +1241,8 @@ background_loaded_cb (GObject *source,
return;
}
texture = gdk_texture_new_for_pixbuf (pixbuf);
add_background (bd->flowbox, bd->filename, texture, FALSE);
add_background (bd->flowbox, bd->filename, pixbuf, FALSE);
g_object_unref (texture);
g_object_unref (pixbuf);
g_free (bd->filename);
g_free (bd);
}
@@ -1263,10 +1259,7 @@ populate_flowbox (GtkWidget *flowbox)
GInputStream *stream;
BackgroundData *bd;
GdkPixbuf *pixbuf;
GdkTexture *texture;
GtkWidget *child;
guchar *data;
GBytes *bytes;
int i;
const char *resources[] = {
"sunset.jpg", "portland-rose.jpg", "beach.jpg", "nyc.jpg"
@@ -1277,14 +1270,9 @@ populate_flowbox (GtkWidget *flowbox)
g_object_set_data (G_OBJECT (flowbox), "populated", GUINT_TO_POINTER (1));
data = g_malloc (4 * 110 * 70);
memset (data, 0xff, 4 * 110 * 70);
bytes = g_bytes_new_take (data, 4 * 110 * 70);
texture = gdk_memory_texture_new (110, 70, GDK_MEMORY_DEFAULT, bytes, 4 * 110);
child = gtk_picture_new_for_paintable (GDK_PAINTABLE (texture));
g_object_unref (texture);
g_bytes_unref (bytes);
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
gdk_pixbuf_fill (pixbuf, 0xffffffff);
child = gtk_picture_new_for_pixbuf (pixbuf);
gtk_widget_add_css_class (child, "frame");
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
@@ -1292,10 +1280,7 @@ populate_flowbox (GtkWidget *flowbox)
{
filename = g_strconcat ("/org/gtk/WidgetFactory4/", resources[i], NULL);
pixbuf = gdk_pixbuf_new_from_resource_at_scale (filename, 110, 110, TRUE, NULL);
texture = gdk_texture_new_for_pixbuf (pixbuf);
add_background (flowbox, filename, texture, TRUE);
g_object_unref (texture);
g_object_unref (pixbuf);
add_background (flowbox, filename, pixbuf, TRUE);
}
location = "/usr/share/backgrounds/gnome";

View File

@@ -1572,9 +1572,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="valign">3</property>
<child>
<object class="GtkVolumeButton">
<accessibility>
<property name="label" translatable="1">Volume</property>
</accessibility>
<property name="orientation">1</property>
<property name="valign">3</property>
<property name="value">.5</property>
@@ -1587,9 +1584,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</child>
<child>
<object class="GtkScaleButton" id="mic-button">
<accessibility>
<property name="label" translatable="1">Microphone gain</property>
</accessibility>
<property name="has-tooltip">1</property>
<property name="icons">microphone-sensitivity-muted-symbolic
microphone-sensitivity-high-symbolic
@@ -2250,24 +2244,20 @@ microphone-sensitivity-medium-symbolic</property>
<child>
<object class="GtkBox">
<property name="spacing">6</property>
<property name="valign">center</property>
<child>
<object class="GtkBox" id="lockbox">
<property name="hexpand">1</property>
<property name="spacing">6</property>
<property name="valign">center</property>
<child>
<object class="GtkMenuButton" id="open_menubutton">
<property name="halign">3</property>
<property name="popover">open_popover</property>
<property name="label">Open</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkToggleButton" id="record_button">
<property name="halign">3</property>
<property name="valign">center</property>
<signal name="toggled" handler="on_record_button_toggled"/>
<style>
<class name="text-button"/>
@@ -2277,19 +2267,16 @@ microphone-sensitivity-medium-symbolic</property>
<child>
<object class="GtkBox">
<property name="spacing">6</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="valign">4</property>
<property name="icon-name">media-record-symbolic</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="valign">4</property>
<property name="label">Record</property>
<property name="valign">center</property>
</object>
</child>
</object>
@@ -2298,7 +2285,6 @@ microphone-sensitivity-medium-symbolic</property>
</child>
<child>
<object class="GtkBox">
<property name="valign">center</property>
<style>
<class name="linked"/>
</style>
@@ -2306,14 +2292,12 @@ microphone-sensitivity-medium-symbolic</property>
<object class="GtkToggleButton" id="grid_button">
<property name="active">1</property>
<property name="icon-name">view-grid-symbolic</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkToggleButton" id="list_button">
<property name="group">grid_button</property>
<property name="icon-name">view-list-symbolic</property>
<property name="valign">center</property>
</object>
</child>
</object>
@@ -2321,7 +2305,6 @@ microphone-sensitivity-medium-symbolic</property>
<child>
<object class="GtkButton" id="circular_button">
<property name="icon-name">emblem-system-symbolic</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
@@ -2330,15 +2313,12 @@ microphone-sensitivity-medium-symbolic</property>
</object>
</child>
<child>
<object class="GtkLockButton" id="lockbutton">
<property name="valign">center</property>
</object>
<object class="GtkLockButton" id="lockbutton"/>
</child>
<child>
<object class="GtkMenuButton">
<property name="icon-name">view-more-symbolic</property>
<property name="menu-model">new_style_menu_model</property>
<property name="valign">center</property>
</object>
</child>
</object>

View File

@@ -220,6 +220,6 @@ clipboard.cut, clipboard.copy, clipboard.paste
selection.delete, selection.select-all
: Selection operations on entries, text view and labels
color.select, color.customize
color.select, color.customize:
: Operate on colors in a `GtkColorChooserWidget`. These actions are
unusual in that they have the non-trivial parameter type (dddd).
unusual in that they have the non-trivial parameter type (dddd):

View File

@@ -288,7 +288,7 @@ support.
If you want to run the testsuite to ensure that your GTK build
works, you should enable it with this option.
### `build-tests`, `build-examples`, `build-demos`
### `build-tests`, `build-examples`, `demos`
By default, GTK will build quite a few tests, examples and demos.
While these are useful on a developer system, they are not

View File

@@ -23,7 +23,7 @@ When it comes to rendering, GTK follows the CSS box model as far as practical.
The CSS stylesheet that is in use determines the sizes (and appearance) of the
margin, border and padding areas for each widget. The size of the content area
is determined by GTKs layout algorithm using each widgets [vfunc@Gtk.Widget.measure]
is determined by GTKs layout algorithm using each widgets [vfunc@Gtk.Widget.measure]
and [vfunc@Gtk.Widget.size_allocate] vfuncs.
You can learn more about the CSS box model by reading the
@@ -37,11 +37,11 @@ To learn more about where GTK CSS differs from CSS on the web, see the
The content area in the CSS box model is the region that the widget considers its own.
The origin of the widgets coordinate system is the top left corner of the content area,
and its size is the widgets size. The size can be queried with [method@Gtk.Widget.get_width]
The origin of the widgets coordinate system is the top left corner of the content area,
and its size is the widgets size. The size can be queried with [method@Gtk.Widget.get_width]
and [method@Gtk.Widget.get_height]. GTK allows general 3D transformations to position
widgets (although most of the time, the transformation will be a simple 2D translation).
The transform to go from one widgets coordinate system to another one can be obtained
The transform to go from one widgets coordinate system to another one can be obtained
with [method@Gtk.Widget.compute_transform].
In addition to a size, widgets can optionally have a **_baseline_** to position text on.
@@ -55,8 +55,8 @@ or [method@Gtk.Widget.compute_bounds]. These methods can fail (either because th
don't share a common ancestor, or because of a singular transformation), and callers need
to handle this eventuality.
Another area that is occasionally relevant are the widgets **_bounds_**, which is the area
that a widgets rendering is typically confined to (technically, widgets can draw outside
Another area that is occasionally relevant are the widgets **_bounds_**, which is the area
that a widgets rendering is typically confined to (technically, widgets can draw outside
of this area, unless clipping is enforced via the [property@Gtk.Widget:overflow] property).
In CSS terms, the bounds of a widget correspond to the border area.

View File

@@ -68,7 +68,7 @@ in a selector, widget names must be prefixed with a &num; character.
| E:focus-within | [CSS Selector Level 4](https://drafts.csswg.org/selectors/#focus-within-pseudo) | Set on all ancestors of the focus widget, unlike CSS |
| E:focus-visible | [CSS Selector Level 4](https://drafts.csswg.org/selectors/#focus-within-pseudo) | Set on focus widget and all ancestors, unlike CSS |
| E:disabled | [CSS Selector Level 3](https://www.w3.org/TR/css3-selectors/#UIstates) | Corresponds to GTK_STATE_FLAG_INSENSITIVE |
| E:checked | [CSS Selector Level 3](https://www.w3.org/TR/css3-selectors/#UIstates) | Corresponds to GTK_STATE_FLAG_CHECKED |
| E:disabled | [CSS Selector Level 3](https://www.w3.org/TR/css3-selectors/#UIstates) | Corresponds to GTK_STATE_FLAG_CHECKED |
| E:indeterminate | [CSS Selector Level 3](https://www.w3.org/TR/css3-selectors/#indeterminate) | Corresponds to GTK_STATE_FLAG_INCONSISTENT |
| E:backdrop, E:selected | | Corresponds to GTK_STATE_FLAG_BACKDROP, GTK_STATE_FLAG_SELECTED |
| E:not(selector) | [CSS Selector Level 3](https://www.w3.org/TR/css3-selectors/#negation) | |

View File

@@ -16,7 +16,6 @@ SYNOPSIS
| **gtk4-builder-tool** enumerate [OPTIONS...] <FILE>
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
| **gtk4-builder-tool** render [OPTIONS...] <FILE>
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
DESCRIPTION
@@ -70,11 +69,12 @@ file to use.
Load style information from the given CSS file.
Render
^^^^^^
Screenshot
^^^^^^^^^^
The ``render`` command saves a rendering of the UI definition file as a png image
or node file. The name of the file to write can be specified as a second FILE argument.
The ``screenshot`` command saves a rendering of the UI definition file
as a png image or node file. The name of the file to write can be specified as
a second FILE argument.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
@@ -96,11 +96,6 @@ file to use.
Overwrite an existing file.
Screenshot
^^^^^^^^^^
The ``screenshot`` command is an alias for ``render``.
Simplification
^^^^^^^^^^^^^^

View File

@@ -103,15 +103,14 @@ fields, but e.g. buttons can take the focus too.
Input widgets can be given the focus by clicking on them, but focus
can also be moved around with certain key events (this is known as
“keyboard navigation”).
GTK reserves the <kbd>Tab</kbd> key to move the focus to the next location,
and <kbd>Shift</kbd>+<kbd>Tab</kbd> to move it back to the previous one.
In addition many containers allow “directional navigation” with the arrow keys.
“keyboard navigation”). GTK reserves the <kbd>Tab</kbd> key to move the focus
to the next location, and <kbd>Shift</kbd>+<kbd>Tab</kbd> to move it back to the previous
one. In addition many containers allow “directional navigation” with
the arrow keys.
Many widgets can be “activated” to trigger and action.
E.g., you can activate a button or switch by clicking on them,
but you can also activate them with the keyboard,
by using the <kbd>Enter</kbd> or <kbd>Space</kbd> keys.
Many widgets can be “activated” to trigger and action. E.g., you can
activate a button or switch by clicking on them, but you can also
activate them with the keyboard, by using the <kbd>Enter</kbd> or <kbd>␣</kbd> keys.
Apart from keyboard navigation, activation and directly typing into
entries or text views, GTK widgets can use key events for activating
@@ -122,17 +121,15 @@ GTK has traditionally supported different kinds of shortcuts:
- Accelerators are any other shortcuts that can be activated regardless
of where the focus is, and typically trigger global actions, such as
<kbd>Ctrl</kbd>+<kbd>Q</kbd> to quit an application.
- Mnemonics are usually triggered using <kbd>Alt</kbd>
as a modifier for a letter.
Ctrl-Q to quit an application.
- Mnemonics are usually triggered using Alt as a modifier for a letter.
They are used in places where a label is associated with a control,
and are indicated by underlining the letter in the label. As a special
case, inside menus (i.e. inside `GtkPopoverMenu`), mnemonics can be
triggered without the modifier.
- Key bindings are specific to individual widgets,
such as <kbd>Ctrl</kbd>+<kbd>C</kbd> or <kbd>Ctrl</kbd>+<kbd>V</kbd>
in an entry copy to or paste from the clipboard.
They are only triggered when the widget has focus.
- Key bindings are specific to individual widgets, such as Ctrl-C or
Ctrl-V in an entry copy to or paste from the clipboard. They are only
triggered when the widget has focus.
GTK handles accelerators and mnemonics in a global scope, during the
capture phase, and key bindings locally, during the target phase.
@@ -211,4 +208,4 @@ sequence, so setting the state on one does transfer the state to
the others. They also are mutually exclusive, within a widget
where may be only one gesture group claiming a given sequence.
If another gesture group claims later that same sequence, the
first group will deny the sequence.
first group will deny the sequence:

View File

@@ -133,9 +133,3 @@ The function gtk_widget_get_allocation() is also going away. It does not have a
replacement, but the previously mentioned alternatives can be used for it too.
The function gtk_widget_get_allocated_baseline() has been renamed to [method@Gtk.Widget.get_baseline].
## Stop using GdkPixbuf
GTK is moving away from GdkPixbuf as the primary API for transporting image data, in favor
of GdkTexture. APIs that are accepting or returning GdkPixbufs are being replaced by equivalent
APIs using GdkTexture or GdkPaintable objects.

View File

@@ -208,12 +208,6 @@ A number of options affect behavior instead of logging:
`nograbs`
: Turn off all pointer and keyboard grabs
`portals`
: Force the use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`no-portals`
: Disable use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`gl-disable`
: Disable OpenGL support

View File

@@ -31,7 +31,7 @@ described by a set of *attributes*.
Roles define the taxonomy and semantics of a UI control to any assistive
technology application; for instance, a button will have a role of
`GTK_ACCESSIBLE_ROLE_BUTTON`; an entry will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a check button will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a toggle button will have a role of
`GTK_ACCESSIBLE_ROLE_CHECKBOX`; etc.
Each role is part of the widget's instance, and **cannot** be changed over
@@ -46,7 +46,6 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| Role name | Description | Related GTK widget |
|-----------|-------------|--------------------|
| `APPLICATION` | An application window | [class@Gtk.Window] |
| `BUTTON` | A control that performs an action when pressed | [class@Gtk.Button], [class@Gtk.LinkButton], [class@Gtk.Expander] |
| `CHECKBOX` | A control that has three possible value: `true`, `false`, or `undefined` | [class@Gtk.CheckButton] |
| `COMBOBOX` | A control that can be expanded to show a list of possible values to select | [class@Gtk.ComboBox] |
@@ -79,6 +78,7 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| `TAB_PANEL` | A page in a notebook or stack | [class@Gtk.Stack] |
| `TEXT_BOX` | A type of input that allows free-form text as its value. | [class@Gtk.Entry], [class@Gtk.PasswordEntry], [class@Gtk.TextView] |
| `TREE_GRID` | A treeview-like columned list | [class@Gtk.ColumnView] |
| `WINDOW` | An application window | [class@Gtk.Window] |
| `...` | … |
See the [WAI-ARIA](https://www.w3.org/WAI/PF/aria/appendices#quickref) list
@@ -204,27 +204,19 @@ you should ensure that:
readable and localised action performed when pressed; for instance "Copy",
"Paste", "Add layer", or "Remove"
GTK will try to fill in some information by using ancillary UI control properties,
for instance the accessible name will be taken from the label used by the UI control,
or from its tooltip, if the `GTK_ACCESSIBLE_PROPERTY_LABEL` property or the
`GTK_ACCESSIBLE_RELATION_LABELLED_BY` relation are unset. Similary for the accessible
description. Nevertheless, it is good practice and project hygiene to explicitly specify
the accessible properties, just like it's good practice to specify tooltips and style classes.
GTK will try to fill in some information by using ancillary UI control
properties, for instance the accessible label will be taken from the label or
placeholder text used by the UI control, or from its tooltip, if the
`GTK_ACCESSIBLE_PROPERTY_LABEL` property or the `GTK_ACCESSIBLE_RELATION_LABELLED_BY`
relation are unset. Nevertheless, it is good practice and project hygiene
to explicitly specify the accessible properties, just like it's good practice
to specify tooltips and style classes.
Application developers using GTK **should** ensure that their UI controls
are accessible as part of the development process. The GTK Inspector shows
the accessible attributes of each widget, and also provides an overlay that
can highlight accessibility issues.
It is possible to set accessible attributes in UI files as well:
```xml
<object class="GtkButton" id="button1">
<accessibility>
<property name="label">Download</property>
<relation name="labelled-by">label1</relation>
/accessibility>
</object>
```
are accessible as part of the development process. When using `GtkBuilder`
templates and UI definition files, GTK provides a validation tool that
verifies that each UI element has a valid role and properties; this tool can
be used as part of the application's test suite to avoid regressions.
## Implementations
@@ -267,13 +259,6 @@ turn automatically any widget into a `GtkButton`; but if your widget behaves
like a button, using the %GTK_ACCESSIBLE_ROLE_BUTTON will allow any
assistive technology to handle it like they would a `GtkButton`.
For widgets that act as containers of other widgets, you should use
%GTK_ACCESSIBLE_ROLE_GROUP if the grouping of the children is semantic
in nature; for instance, the children of a [class@Gtk.HeaderBar] are
grouped together on the header of a window. For generic containers that
only impose a layout on their children, you should use
%GTK_ACCESSIBLE_ROLE_GENERIC instead.
### Attributes can both hide and enhance
Accessible attributes can be used to override the content of a UI element,
@@ -382,6 +367,3 @@ To allow changing the value via accessible technologies, you can export
actions. Since the accessibility interfaces only support actions
without parameters, you should provide actions such as `increase-value`
and `decrease-value`.
Since GTK 4.10, the best way to suppose changing the value is by implementing
the [iface@Gtk.AccessibleRange] interface.

View File

@@ -196,15 +196,6 @@ The _data table_ style of list is a high density table, similar in style to a
traditional treeview. Individual cells can be selectable and editable. Use
the `.data-table` style class.
## Sections
List models can optionally group their items into **_sections_**, by implementing
the `GtkSectionModel` interface. Both `GtkListView` and `GtkGridView` can
display headers for sections, by installing a separate **_header factory_**.
Many GTK list models support section inherently, or they pass through the
section of a model they are wrapping.
## Comparison to GtkTreeView
Developers familiar with `GtkTreeView` may wonder how this way of doing lists

View File

@@ -1,7 +0,0 @@
A trivial example
=================
This is a very minimal example of an app that can be built against GTK.
We use this in CI to test that building against the installed GTK works.
That is why there is a standalone meson.build in this subdirectory.

View File

@@ -57,7 +57,7 @@ window_paste (GSimpleAction *action,
{
GtkWindow *window = GTK_WINDOW (user_data);
GtkTextView *text = g_object_get_data ((GObject*)window, "plugman-text");
gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text),
gtk_widget_get_clipboard (GTK_WIDGET (text)),
NULL,
@@ -221,7 +221,7 @@ plugin_action (GAction *action,
g_message ("Color: %s", g_action_get_name (action));
css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (css_provider, css_to_load);
gtk_css_provider_load_from_data (css_provider, css_to_load, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);

View File

@@ -34,7 +34,7 @@ gdk_broadway_cairo_context_dispose (GObject *object)
static void
gdk_broadway_cairo_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
gboolean prefers_high_depth,
cairo_region_t *region)
{
GdkBroadwayCairoContext *self = GDK_BROADWAY_CAIRO_CONTEXT (draw_context);

View File

@@ -34,7 +34,7 @@ gdk_broadway_draw_context_dispose (GObject *object)
static void
gdk_broadway_draw_context_begin_frame (GdkDrawContext *draw_context,
GdkMemoryDepth depth,
gboolean prefers_high_depth,
cairo_region_t *region)
{
GdkBroadwayDrawContext *self = GDK_BROADWAY_DRAW_CONTEXT (draw_context);

View File

@@ -1,7 +0,0 @@
gdk_deprecated_sources = files([
'gdkpixbuf.c',
])
gdk_deprecated_headers = files([
'gdkpixbuf.h',
])

View File

@@ -24,7 +24,7 @@
#include "config.h"
#include "version/gdkversionmacros.h"
#include "gdkversionmacros.h"
#include "gdkresources.h"
@@ -132,7 +132,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer", TRUE },
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
};

View File

@@ -61,7 +61,7 @@
#include <gdk/gdkmonitor.h>
#include <gdk/gdkpaintable.h>
#include <gdk/gdkpango.h>
#include <gdk/deprecated/gdkpixbuf.h>
#include <gdk/gdkpixbuf.h>
#include <gdk/gdkpopup.h>
#include <gdk/gdkpopuplayout.h>
#include <gdk/gdkrectangle.h>
@@ -75,7 +75,7 @@
#include <gdk/gdktoplevellayout.h>
#include <gdk/gdktoplevelsize.h>
#include <gdk/gdktypes.h>
#include <gdk/version/gdkversionmacros.h>
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkvulkancontext.h>
#undef __GDK_H_INSIDE__

View File

@@ -24,6 +24,7 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -1,5 +1,5 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2005 Red Hat, Inc.
* Copyright (C) 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,10 +17,7 @@
#include "config.h"
#include "gdkcairo.h"
#include "gdkrgba.h"
#include "gdktexture.h"
#include "gdkcairoprivate.h"
#include <math.h>
@@ -90,7 +87,7 @@ gdk_cairo_region (cairo_t *cr,
}
}
static void
void
gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
const GdkPixbuf *pixbuf)
{
@@ -171,7 +168,7 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr,
*
* Returns: %TRUE if the extents fit in a `GdkRectangle`, %FALSE if not
*/
static gboolean
gboolean
_gdk_cairo_surface_extents (cairo_surface_t *surface,
GdkRectangle *extents)
{
@@ -303,3 +300,38 @@ gdk_cairo_region_create_from_surface (cairo_surface_t *surface)
return region;
}
cairo_region_t *
gdk_cairo_region_from_clip (cairo_t *cr)
{
cairo_rectangle_list_t *rectangles;
cairo_region_t *region;
int i;
rectangles = cairo_copy_clip_rectangle_list (cr);
if (rectangles->status != CAIRO_STATUS_SUCCESS)
return NULL;
region = cairo_region_create ();
for (i = 0; i < rectangles->num_rectangles; i++)
{
cairo_rectangle_int_t clip_rect;
cairo_rectangle_t *rect;
rect = &rectangles->rectangles[i];
/* Here we assume clip rects are ints for direct targets, which
is true for cairo */
clip_rect.x = (int)rect->x;
clip_rect.y = (int)rect->y;
clip_rect.width = (int)rect->width;
clip_rect.height = (int)rect->height;
cairo_region_union_rectangle (region, &clip_rect);
}
cairo_rectangle_list_destroy (rectangles);
return region;
}

View File

@@ -1,5 +1,5 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2005 Red Hat, Inc.
* Copyright (C) 2005 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,8 +21,9 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
#include <gdk/deprecated/gdkpixbuf.h>
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkrgba.h>
#include <gdk/gdkpixbuf.h>
#include <pango/pangocairo.h>
G_BEGIN_DECLS

View File

@@ -24,8 +24,11 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <cairo.h>
G_BEGIN_DECLS
#define GDK_TYPE_CAIRO_CONTEXT (gdk_cairo_context_get_type ())

View File

@@ -1,10 +1,10 @@
/*
* Copyright © 2023 Red Hat, Inc.
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,20 +13,25 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#pragma once
#include "inspectoroverlay.h"
#include "gdkcairo.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cairo.h>
G_BEGIN_DECLS
#define GTK_TYPE_A11Y_OVERLAY (gtk_a11y_overlay_get_type ())
G_DECLARE_FINAL_TYPE (GtkA11yOverlay, gtk_a11y_overlay, GTK, A11Y_OVERLAY, GtkInspectorOverlay)
gboolean _gdk_cairo_surface_extents (cairo_surface_t *surface,
GdkRectangle *extents);
void gdk_cairo_surface_paint_pixbuf (cairo_surface_t *surface,
const GdkPixbuf *pixbuf);
cairo_region_t *gdk_cairo_region_from_clip (cairo_t *cr);
GtkInspectorOverlay * gtk_a11y_overlay_new (void);
G_END_DECLS

View File

@@ -22,7 +22,10 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <gio/gio.h>
G_BEGIN_DECLS

View File

@@ -21,6 +21,8 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -645,9 +645,6 @@ gdk_content_formats_builder_clear (GdkContentFormatsBuilder *builder)
{
g_clear_pointer (&builder->gtypes, g_slist_free);
g_clear_pointer (&builder->mime_types, g_slist_free);
builder->n_gtypes = 0;
builder->n_mime_types = 0;
}
/**

View File

@@ -21,6 +21,8 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -22,8 +22,10 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_CONTENT_PROVIDER (gdk_content_provider_get_type ())

View File

@@ -22,6 +22,7 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -22,7 +22,7 @@
#include "gdkcontentserializer.h"
#include "gdkcontentformats.h"
#include "deprecated/gdkpixbuf.h"
#include "gdkpixbuf.h"
#include "filetransferportalprivate.h"
#include "gdktextureprivate.h"
#include "gdkrgba.h"
@@ -642,9 +642,7 @@ pixbuf_serializer (GdkContentSerializer *serializer)
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE))
{
GdkTexture *texture = g_value_get_object (value);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
pixbuf = gdk_pixbuf_get_from_texture (texture);
G_GNUC_END_IGNORE_DEPRECATIONS
}
else
{

View File

@@ -21,6 +21,8 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -28,6 +28,7 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -52,7 +52,6 @@ typedef enum {
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
GDK_DEBUG_NO_VSYNC = 1 << 26,
} GdkDebugFlags;
extern guint _gdk_debug_flags;

View File

@@ -21,10 +21,12 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkdevicetool.h>
#include <gdk/gdkenums.h>
G_BEGIN_DECLS
#define GDK_TYPE_DEVICE (gdk_device_get_type ())

View File

@@ -23,6 +23,7 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS

View File

@@ -21,7 +21,10 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkversionmacros.h>
G_BEGIN_DECLS

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