Compare commits
264 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa4af4c946 | |||
| 7b76be5360 | |||
| 2e2336ffce | |||
| 76d80ef516 | |||
| 287d80bd36 | |||
| 77072b3eaa | |||
| c7833bb090 | |||
| 899024cef7 | |||
| 7c02ae00c2 | |||
| 80e29a3627 | |||
| 26163a4f30 | |||
| dbd88fc210 | |||
| 2de31e4cac | |||
| 1bff328895 | |||
| facf78a5b6 | |||
| 6b19fcd859 | |||
| ca784e3e1a | |||
| 314c8558d7 | |||
| af30a7fe06 | |||
| 9ffd7d1970 | |||
| cb906c80eb | |||
| 96ce0eb600 | |||
| 0e476c1f28 | |||
| f2924988db | |||
| 671435e07f | |||
| b17cfb9b65 | |||
| 0385f1aaf4 | |||
| 8611faf338 | |||
| 7e19911d3f | |||
| c1f5153f6d | |||
| 2bd87ce771 | |||
| de0547ede7 | |||
| 14589c2a59 | |||
| f678b3804d | |||
| 720c298786 | |||
| f721d2de15 | |||
| 11f07cb5ad | |||
| 37d7ab88dc | |||
| 6cde64072d | |||
| 6a60b0f591 | |||
| 339d9f05e4 | |||
| 4e4207457f | |||
| 46bb3e3046 | |||
| 34008e6aab | |||
| d6b3ac850d | |||
| 9742200ff6 | |||
| ec10857b84 | |||
| 353d4d161c | |||
| bcd650f169 | |||
| 72d66dfcdd | |||
| 5e97df5058 | |||
| 059d131e2b | |||
| 8f7c207c7c | |||
| b9e8935037 | |||
| 5f33f4ae8e | |||
| adf0e8b1e6 | |||
| 7500f9b255 | |||
| a8d433dd26 | |||
| ecaf6fced0 | |||
| 31a7cac4a6 | |||
| 5eec736b07 | |||
| cf4a8e2152 | |||
| 31bb969cce | |||
| f4a7c7f6bf | |||
| 495069c868 | |||
| dfe470475b | |||
| de56e892aa | |||
| e518c1f2f3 | |||
| c5ea59d7d1 | |||
| 22eccbdbb6 | |||
| 58e85c85e4 | |||
| 6b89148487 | |||
| ddb9e428ec | |||
| b7fa353db2 | |||
| 87b5eadb7c | |||
| 60a09e59e8 | |||
| 6f8e9bf3a9 | |||
| 90b7b84337 | |||
| 088b5fc57f | |||
| a4cd974912 | |||
| 65359dcc59 | |||
| ac8b398c50 | |||
| aac2417893 | |||
| ad8892df10 | |||
| edc7977c4e | |||
| 8bf8ac5076 | |||
| c36cbd5140 | |||
| ee96bc7185 | |||
| f94f325636 | |||
| 6c1217dd93 | |||
| edb792503b | |||
| 3a43859286 | |||
| c55dd104d4 | |||
| 497d137fb8 | |||
| df01c5c7a4 | |||
| 2d1135fba6 | |||
| f54ed6f7dc | |||
| b7efd896b6 | |||
| 46eb51bc30 | |||
| 500dbaabc3 | |||
| 594ec3d822 | |||
| f280508209 | |||
| 480b88c776 | |||
| a4e63905b1 | |||
| 5666127dbc | |||
| c1c110ba65 | |||
| eb2a839892 | |||
| 1c537a6d2e | |||
| c12261a6ec | |||
| 5af7d6bff3 | |||
| de0f4b0f5b | |||
| 966ab1152d | |||
| 74a4432688 | |||
| 115d0cdc07 | |||
| d0ec616fba | |||
| 38cce2bb18 | |||
| 9cb7002b98 | |||
| eb9c91c0a9 | |||
| be07153efa | |||
| 627ec82e60 | |||
| ccc34ca06c | |||
| 2b5dd0082d | |||
| 7b36b339aa | |||
| b7eb663b82 | |||
| 1b28353be5 | |||
| a07c030d02 | |||
| 339cccdf53 | |||
| 577126e99c | |||
| 125ea5ee4a | |||
| 3c5afc06d1 | |||
| f87c15f4f9 | |||
| fe5c0e2fe3 | |||
| c8421cfd82 | |||
| fbf99b8d65 | |||
| 57312c9b79 | |||
| 35d2539ef8 | |||
| 08a4f4552c | |||
| 6502d3669f | |||
| 53831e67a7 | |||
| e742fc1206 | |||
| 4ef5ee23e6 | |||
| 4a8330fda0 | |||
| b4096cee64 | |||
| 032302c358 | |||
| a888e1cb65 | |||
| c80b33b2ad | |||
| f32239df1f | |||
| 22c1b541df | |||
| 78a59c95fe | |||
| 7583d48266 | |||
| f1188aaeac | |||
| 4dac5c222f | |||
| 0145809a94 | |||
| 2e6b8810c0 | |||
| d8abcdb5a1 | |||
| 65ecfa20dd | |||
| aa5ab02166 | |||
| 7ddbbb50ff | |||
| f2eb036119 | |||
| 8a8b96bf4b | |||
| bdcda2d8f0 | |||
| ef3f997d55 | |||
| b41d380230 | |||
| 0210850e86 | |||
| 053223bf65 | |||
| 746b84cc0f | |||
| f1ad883e00 | |||
| 191e0e8d5e | |||
| 55217e2181 | |||
| 7c8cd23c5f | |||
| 6aafb81702 | |||
| 0578422612 | |||
| ad04da84c9 | |||
| 333b013f7f | |||
| b3dc517565 | |||
| 70e4dabe89 | |||
| d3443d6f2a | |||
| a508f68044 | |||
| f191b64bbc | |||
| e9efe77839 | |||
| d98c0d32f2 | |||
| dfa2dcceb8 | |||
| d441e7106b | |||
| 4cd92f979c | |||
| d1a068e5b1 | |||
| 4d90846182 | |||
| 986f721938 | |||
| 7903246355 | |||
| 0252ae2be3 | |||
| fa90e42a38 | |||
| 2d36109565 | |||
| de8258171a | |||
| 2ed6224778 | |||
| e1a0171094 | |||
| 395521f3d3 | |||
| 8c95a84ea4 | |||
| 75db19c789 | |||
| f00d2b30bb | |||
| c0c5ce2f9b | |||
| ee9f9ae05e | |||
| 387649ded4 | |||
| be12131d74 | |||
| 896ebdc9d7 | |||
| bc58bd0b83 | |||
| 8d4c87876b | |||
| cebc99ddc7 | |||
| 1b62203f18 | |||
| 06dd8c2cfd | |||
| 5da21ca4dc | |||
| 3e16ef33b0 | |||
| 2746a2d929 | |||
| e31bacf7be | |||
| 911ae64931 | |||
| 99a0b35705 | |||
| 89bf8af878 | |||
| f3744c991a | |||
| dcee15c0f1 | |||
| 2321e9de05 | |||
| 73dcda460f | |||
| 0f8bc67a98 | |||
| 379d830123 | |||
| bc8bc68b80 | |||
| 8c4df51a14 | |||
| 06d67d2384 | |||
| cc8bb5fc54 | |||
| 8fb1e33d0f | |||
| 0dc946da63 | |||
| 26a23d3e56 | |||
| 766f4bc8fe | |||
| 3d008d5929 | |||
| 0546e26434 | |||
| e6d8eedc00 | |||
| 13b37b0ba4 | |||
| 779c71b66d | |||
| 8e73d007f5 | |||
| e376d638fb | |||
| 52982a88aa | |||
| 422c1d9c0d | |||
| ccc8ad8700 | |||
| 6b0eb970d8 | |||
| 775e35865c | |||
| 49ce680d53 | |||
| 463f3d3a52 | |||
| f6347f18b0 | |||
| 2e959fe300 | |||
| 56f771ba29 | |||
| 32e96215b4 | |||
| 86f800e11d | |||
| 4d371b2b16 | |||
| 7e97c2513f | |||
| 2bf5a150e6 | |||
| 18c87faaa5 | |||
| fdeda388bf | |||
| ea2c27c640 | |||
| dfc04a590d | |||
| fe5b364675 | |||
| 9b73c55559 | |||
| 0b38a0663d | |||
| e5c0716293 | |||
| 54a3293cad | |||
| 818287a7ce | |||
| 59119cd898 | |||
| 2fb755e0c9 | |||
| cd096819d8 |
+18
-2
@@ -19,8 +19,8 @@ variables:
|
||||
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
|
||||
FEATURE_FLAGS: "-Dcloudproviders=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 2
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v17"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v20"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
|
||||
|
||||
@@ -180,6 +180,22 @@ static-scan:
|
||||
- _scan_build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
# Run tests with the address sanitizer. We need to turn off introspection,
|
||||
# since it is incompatible with asan
|
||||
asan-build:
|
||||
image: $FEDORA_IMAGE
|
||||
tags: [ privileged ]
|
||||
stage: analysis
|
||||
variables:
|
||||
script:
|
||||
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
reference:
|
||||
image: $DOCS_IMAGE
|
||||
stage: docs
|
||||
|
||||
@@ -35,4 +35,13 @@ branch, as well as their available versions.
|
||||
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
|
||||
- [ ] Open a merge request with your changes and let it run
|
||||
|
||||
### Checklist for Adding a new dependency to a CI image
|
||||
|
||||
Our images are layered, and the base (called fedora-base) contains
|
||||
all the rpm payload. Therefore, adding a new dependency is a 2-step
|
||||
process:
|
||||
|
||||
1. [ ] Build and upload fedora-base:$version+1
|
||||
1. [ ] Build and upload fedora:$version+1 based on fedora-base:version+1
|
||||
|
||||
[registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry
|
||||
|
||||
@@ -41,12 +41,14 @@ RUN dnf -y install \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
lcov \
|
||||
libasan \
|
||||
libattr-devel \
|
||||
libepoxy-devel \
|
||||
libffi-devel \
|
||||
libmount-devel \
|
||||
librsvg2 \
|
||||
libselinux-devel \
|
||||
libubsan \
|
||||
libXcomposite-devel \
|
||||
libXcursor-devel \
|
||||
libXcursor-devel \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v20
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
|
||||
@@ -7,10 +7,14 @@ srcdir=$( pwd )
|
||||
builddir=$1
|
||||
backend=$2
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
|
||||
|
||||
case "${backend}" in
|
||||
x11)
|
||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
@@ -30,6 +34,7 @@ case "${backend}" in
|
||||
export WAYLAND_DISPLAY=wayland-5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
@@ -48,6 +53,7 @@ case "${backend}" in
|
||||
export BROADWAY_DISPLAY=:5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
|
||||
@@ -1,3 +1,80 @@
|
||||
Overview of Changes in GTK 3.99.0
|
||||
=================================
|
||||
|
||||
* Add GtkEditableLabel
|
||||
|
||||
* Add GtkBookmarkList, a list model for bookmarks
|
||||
|
||||
* Add GtkStringList, a list model for strings
|
||||
|
||||
* Add GtkBitset, and use it for representing selections
|
||||
|
||||
* GtkTreeView:
|
||||
- Make cell editing work again
|
||||
|
||||
* GtkSpinButton:
|
||||
- Make autosizing work again
|
||||
|
||||
* Printing:
|
||||
- Use GtkDropDown in the print dialog
|
||||
|
||||
* GtkApplication
|
||||
- Support opening files on OS X
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix libcloudproviders support
|
||||
- Turn GtkFileFilter into a GtkFilter
|
||||
- Simplify the api
|
||||
|
||||
* GtkGridView, GtkListView:
|
||||
- Improve scrolling behavior
|
||||
- Autoscroll and autoexpand during DND
|
||||
|
||||
* GtkScrolledWindow:
|
||||
- Make autoscrolling work again
|
||||
|
||||
* GtkFilterListModel:
|
||||
- Add incremental filtering
|
||||
|
||||
* GtkEntry:
|
||||
- Make entry completion work again
|
||||
- Drop action support from GtkEntryCompletion
|
||||
|
||||
* Inspector:
|
||||
- Improve list model support
|
||||
- Add direct navigation between objects
|
||||
|
||||
* GDK:
|
||||
- Compress scroll events
|
||||
- Keep a scroll history
|
||||
- Clean up GdkDevice api
|
||||
- Improve frame clock accuracy
|
||||
|
||||
* GSK:
|
||||
- Use GL_ARB_framebuffer_object
|
||||
|
||||
* gtk-demo:
|
||||
- Add incremental refill to the color grid
|
||||
- Improve performance of the color grid
|
||||
- Add an incrementally filtering word list
|
||||
- Improve the sidebar
|
||||
|
||||
* Install print-editor as another demo
|
||||
|
||||
* Translation updates
|
||||
Basque
|
||||
Catalan
|
||||
Chinese
|
||||
Japanese
|
||||
Kazakh
|
||||
Lithuanian
|
||||
Polish
|
||||
Romanian
|
||||
Spanish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK 3.98.5
|
||||
=================================
|
||||
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
{
|
||||
"app-id": "org.gtk.WidgetFactory4",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"app-id" : "org.gtk.WidgetFactory4",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gtk4-widget-factory",
|
||||
"tags" : [
|
||||
"devel",
|
||||
"development",
|
||||
"nightly"
|
||||
],
|
||||
"desktop-file-name-prefix" : "(Development) ",
|
||||
"finish-args" : [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs",
|
||||
"--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup": [
|
||||
"cleanup" : [
|
||||
"/include",
|
||||
"/lib/pkgconfig", "/share/pkgconfig",
|
||||
"/lib/pkgconfig",
|
||||
"/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man", "/share/man", "/share/gtk-doc",
|
||||
"*.la", ".a",
|
||||
"/man",
|
||||
"/share/man",
|
||||
"/share/gtk-doc",
|
||||
"*.la",
|
||||
".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
"modules" : [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
@@ -39,18 +48,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"name" : "graphene",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
],
|
||||
"sources": [
|
||||
"sources" : [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ebassi/graphene.git"
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -58,7 +67,7 @@
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts": [
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -73,7 +82,7 @@
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts": [
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -85,18 +94,23 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources": [
|
||||
"sources" : [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,13 @@ if 'DESTDIR' not in os.environ:
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
subprocess.call(['glib-compile-schemas',
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
'--variable=glib_compile_schemas',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(glib_compile_schemas):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
glib_compile_schemas = 'glib-compile-schemas'
|
||||
subprocess.call([glib_compile_schemas,
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
@@ -24,8 +30,14 @@ if 'DESTDIR' not in os.environ:
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||
subprocess.call(['gio-querymodules', gtk_printmodule_dir])
|
||||
gio_querymodules = subprocess.check_output(['pkg-config',
|
||||
'--variable=gio_querymodules',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(gio_querymodules):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call(['gio-querymodules', gtk_immodule_dir])
|
||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
||||
|
||||
+78
-12
@@ -597,6 +597,83 @@ css_button_new (const char *class)
|
||||
return button;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GdkRGBA color;
|
||||
} ColorSwatch;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
} ColorSwatchClass;
|
||||
|
||||
G_DEFINE_TYPE (ColorSwatch, color_swatch, GTK_TYPE_WIDGET)
|
||||
|
||||
static GdkContentProvider *
|
||||
color_swatch_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
ColorSwatch *swatch)
|
||||
{
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &swatch->color);
|
||||
}
|
||||
|
||||
static void
|
||||
color_swatch_init (ColorSwatch *swatch)
|
||||
{
|
||||
GtkDragSource *source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (color_swatch_drag_prepare), swatch);
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
||||
static void
|
||||
color_swatch_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
ColorSwatch *swatch = (ColorSwatch *)widget;
|
||||
float w = gtk_widget_get_width (widget);
|
||||
float h = gtk_widget_get_height (widget);
|
||||
|
||||
gtk_snapshot_append_color (snapshot, &swatch->color,
|
||||
&GRAPHENE_RECT_INIT(0, 0, w, h));
|
||||
}
|
||||
|
||||
void
|
||||
color_swatch_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum_size,
|
||||
int *natural_size,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*minimum_size = *natural_size = 48;
|
||||
else
|
||||
*minimum_size = *natural_size = 32;
|
||||
}
|
||||
|
||||
static void
|
||||
color_swatch_class_init (ColorSwatchClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
widget_class->snapshot = color_swatch_snapshot;
|
||||
widget_class->measure = color_swatch_measure;
|
||||
gtk_widget_class_set_css_name (widget_class, "colorswatch");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
color_swatch_new (const char *color)
|
||||
{
|
||||
ColorSwatch *swatch = g_object_new (color_swatch_get_type (), NULL);
|
||||
|
||||
gdk_rgba_parse (&swatch->color, color);
|
||||
|
||||
return GTK_WIDGET (swatch);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
@@ -670,18 +747,7 @@ do_dnd (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box3);
|
||||
|
||||
for (i = 0; colors[i]; i++)
|
||||
{
|
||||
GdkRGBA rgba;
|
||||
GtkWidget *swatch;
|
||||
|
||||
gdk_rgba_parse (&rgba, colors[i]);
|
||||
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &rgba,
|
||||
"selectable", FALSE,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (box3), swatch);
|
||||
}
|
||||
gtk_box_append (GTK_BOX (box3), color_swatch_new (colors[i]));
|
||||
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow1"));
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
|
||||
|
||||
@@ -676,7 +676,7 @@ create_color_grid (void)
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
|
||||
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
|
||||
|
||||
model = G_LIST_MODEL (gtk_sor5_list_model_new (gtk_color_list_new (0), NULL));
|
||||
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
|
||||
|
||||
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
|
||||
@@ -835,54 +835,6 @@ update_selection_average (GListModel *model,
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_red (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkColor *colora = (GtkColor *) a;
|
||||
GtkColor *colorb = (GtkColor *) b;
|
||||
|
||||
if (colora->color.red < colorb->color.red)
|
||||
return GTK_ORDERING_LARGER;
|
||||
else if (colora->color.red > colorb->color.red)
|
||||
return GTK_ORDERING_SMALLER;
|
||||
else
|
||||
return GTK_ORDERING_EQUAL;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_green (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkColor *colora = (GtkColor *) a;
|
||||
GtkColor *colorb = (GtkColor *) b;
|
||||
|
||||
if (colora->color.green < colorb->color.green)
|
||||
return GTK_ORDERING_LARGER;
|
||||
else if (colora->color.green > colorb->color.green)
|
||||
return GTK_ORDERING_SMALLER;
|
||||
else
|
||||
return GTK_ORDERING_EQUAL;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_blue (gconstpointer a,
|
||||
gconstpointer b,
|
||||
gpointer unused)
|
||||
{
|
||||
GtkColor *colora = (GtkColor *) a;
|
||||
GtkColor *colorb = (GtkColor *) b;
|
||||
|
||||
if (colora->color.blue < colorb->color.blue)
|
||||
return GTK_ORDERING_LARGER;
|
||||
else if (colora->color.blue > colorb->color.blue)
|
||||
return GTK_ORDERING_SMALLER;
|
||||
else
|
||||
return GTK_ORDERING_EQUAL;
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
@@ -998,7 +950,8 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
g_object_unref (selection_filter);
|
||||
g_object_unref (no_selection);
|
||||
|
||||
g_object_get (model, "model", &model, NULL);
|
||||
model = gtk_multi_selection_get_model (GTK_MULTI_SELECTION (model));
|
||||
g_object_ref (model);
|
||||
|
||||
selection_info_toggle = gtk_toggle_button_new ();
|
||||
gtk_button_set_icon_name (GTK_BUTTON (selection_info_toggle), "emblem-important-symbolic");
|
||||
@@ -1012,7 +965,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
button = gtk_button_new_with_mnemonic ("_Refill");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (refill),
|
||||
gtk_sor5_list_model_get_model (GTK_SOR5_LIST_MODEL (model)));
|
||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
||||
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||
|
||||
@@ -1035,7 +988,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_drop_down_set_from_strings (GTK_DROP_DOWN (dropdown), (const char *[]) { "8", "64", "512", "4096", "32768", "262144", "2097152", "16777216", NULL });
|
||||
g_signal_connect (dropdown, "notify::selected",
|
||||
G_CALLBACK (limit_changed_cb),
|
||||
gtk_sor5_list_model_get_model (GTK_SOR5_LIST_MODEL (model)));
|
||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
||||
g_signal_connect (dropdown, "notify::selected",
|
||||
G_CALLBACK (limit_changed_cb2),
|
||||
label);
|
||||
@@ -1070,30 +1023,18 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_custom_sorter_new (compare_red, NULL, NULL);
|
||||
set_title (sorter, "Red (fast)");
|
||||
g_list_store_append (sorters, sorter);
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "green"));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Green");
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_custom_sorter_new (compare_green, NULL, NULL);
|
||||
set_title (sorter, "Green (fast)");
|
||||
g_list_store_append (sorters, sorter);
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "blue"));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Blue");
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_custom_sorter_new (compare_blue, NULL, NULL);
|
||||
set_title (sorter, "Blue (fast)");
|
||||
g_list_store_append (sorters, sorter);
|
||||
|
||||
set_title (multi_sorter, "RGB");
|
||||
g_list_store_append (sorters, multi_sorter);
|
||||
g_object_unref (multi_sorter);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
list.viewswitcher {
|
||||
listview.viewswitcher {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
list.viewswitcher > row {
|
||||
listview.viewswitcher > row {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
list.viewswitcher row:selected {
|
||||
listview.viewswitcher row:selected {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
@@ -215,7 +215,6 @@ transform_settings_to_keys (GBinding *binding,
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkFilter *filter;
|
||||
GtkNoSelection *selection_model;
|
||||
GtkExpression *expression;
|
||||
char **keys;
|
||||
guint i;
|
||||
|
||||
@@ -246,11 +245,8 @@ transform_settings_to_keys (GBinding *binding,
|
||||
gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data)));
|
||||
g_object_unref (store);
|
||||
|
||||
expression = gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name");
|
||||
filter = gtk_string_filter_new ();
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||
filter = gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
|
||||
gtk_expression_unref (expression);
|
||||
g_object_unref (sort_model);
|
||||
|
||||
g_set_object (¤t_filter, filter);
|
||||
|
||||
@@ -160,7 +160,6 @@ do_listview_words (GtkWidget *do_widget)
|
||||
GtkNoSelection *selection;
|
||||
GtkStringList *stringlist;
|
||||
GtkFilter *filter;
|
||||
GtkExpression *expression;
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_path ("/usr/share/dict/words");
|
||||
@@ -177,10 +176,7 @@ do_listview_words (GtkWidget *do_widget)
|
||||
g_strfreev (words);
|
||||
}
|
||||
|
||||
filter = gtk_string_filter_new ();
|
||||
expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||
gtk_expression_unref (expression);
|
||||
filter = gtk_string_filter_new (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string"));
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
|
||||
gtk_filter_list_model_set_incremental (filter_model, TRUE);
|
||||
|
||||
@@ -215,6 +211,7 @@ do_listview_words (GtkWidget *do_widget)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
|
||||
+113
-4
@@ -18,6 +18,7 @@ static gchar *current_file = NULL;
|
||||
static GtkWidget *notebook;
|
||||
static GtkSingleSelection *selection;
|
||||
static GtkWidget *toplevel;
|
||||
static char **search_needle;
|
||||
|
||||
typedef struct _GtkDemo GtkDemo;
|
||||
struct _GtkDemo
|
||||
@@ -945,7 +946,18 @@ selection_cb (GtkSingleSelection *sel,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeListRow *row = gtk_single_selection_get_selected_item (sel);
|
||||
GtkDemo *demo = gtk_tree_list_row_get_item (row);
|
||||
GtkDemo *demo;
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (notebook), !!row);
|
||||
|
||||
if (!row)
|
||||
{
|
||||
gtk_window_set_title (GTK_WINDOW (toplevel), "No match");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
demo = gtk_tree_list_row_get_item (row);
|
||||
|
||||
if (demo->filename)
|
||||
load_file (demo->name, demo->filename);
|
||||
@@ -953,6 +965,84 @@ selection_cb (GtkSingleSelection *sel,
|
||||
gtk_window_set_title (GTK_WINDOW (toplevel), demo->title);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_demo (GtkDemo *demo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Show only if the name maches every needle */
|
||||
for (i = 0; search_needle[i]; i++)
|
||||
{
|
||||
if (!demo->title)
|
||||
return FALSE;
|
||||
|
||||
if (g_str_match_string (search_needle[i], demo->title, TRUE))
|
||||
continue;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
demo_filter_by_name (GtkTreeListRow *row,
|
||||
GtkFilterListModel *model)
|
||||
{
|
||||
GListModel *children;
|
||||
GtkDemo *demo;
|
||||
guint i, n;
|
||||
|
||||
/* Show all items if search is empty */
|
||||
if (!search_needle || !search_needle[0] || !*search_needle[0])
|
||||
return TRUE;
|
||||
|
||||
g_assert (GTK_IS_TREE_LIST_ROW (row));
|
||||
g_assert (GTK_IS_FILTER_LIST_MODEL (model));
|
||||
|
||||
children = gtk_tree_list_row_get_children (row);
|
||||
if (children)
|
||||
{
|
||||
n = g_list_model_get_n_items (children);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
demo = g_list_model_get_item (children, i);
|
||||
g_assert (GTK_IS_DEMO (demo));
|
||||
|
||||
if (filter_demo (demo))
|
||||
{
|
||||
g_object_unref (demo);
|
||||
return TRUE;
|
||||
}
|
||||
g_object_unref (demo);
|
||||
}
|
||||
}
|
||||
|
||||
demo = gtk_tree_list_row_get_item (row);
|
||||
g_assert (GTK_IS_DEMO (demo));
|
||||
|
||||
return filter_demo (demo);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_search_changed_cb (GtkSearchEntry *entry,
|
||||
GtkFilter *filter)
|
||||
{
|
||||
const char *text;
|
||||
|
||||
g_assert (GTK_IS_SEARCH_ENTRY (entry));
|
||||
g_assert (GTK_IS_FILTER (filter));
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
|
||||
g_clear_pointer (&search_needle, g_strfreev);
|
||||
|
||||
if (text && *text)
|
||||
search_needle = g_strsplit (text, " ", 0);
|
||||
|
||||
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
create_demo_model (void)
|
||||
{
|
||||
@@ -1007,13 +1097,25 @@ get_child_model (gpointer item,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_search (GtkSearchBar *bar)
|
||||
{
|
||||
if (!gtk_search_bar_get_search_mode (bar))
|
||||
{
|
||||
GtkWidget *entry = gtk_search_bar_get_child (GTK_SEARCH_BAR (bar));
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), "");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *app)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GListModel *listmodel;
|
||||
GtkTreeListModel *treemodel;
|
||||
GtkWidget *window, *listview;
|
||||
GtkWidget *window, *listview, *search_entry, *search_bar;
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkFilter *filter;
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "run", activate_run, NULL, NULL, NULL }
|
||||
@@ -1034,6 +1136,8 @@ activate (GApplication *app)
|
||||
toplevel = GTK_WIDGET (window);
|
||||
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
|
||||
g_signal_connect (listview, "activate", G_CALLBACK (activate_cb), window);
|
||||
search_bar = GTK_WIDGET (gtk_builder_get_object (builder, "searchbar"));
|
||||
g_signal_connect (search_bar, "notify::search-mode-enabled", G_CALLBACK (clear_search), NULL);
|
||||
|
||||
listmodel = create_demo_model ();
|
||||
treemodel = gtk_tree_list_model_new (FALSE,
|
||||
@@ -1042,7 +1146,13 @@ activate (GApplication *app)
|
||||
get_child_model,
|
||||
NULL,
|
||||
NULL);
|
||||
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (treemodel), NULL);
|
||||
filter = gtk_custom_filter_new ((GtkCustomFilterFunc)demo_filter_by_name, filter_model, NULL);
|
||||
gtk_filter_list_model_set_filter (filter_model, filter);
|
||||
search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
|
||||
g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
|
||||
|
||||
selection = gtk_single_selection_new (G_LIST_MODEL (filter_model));
|
||||
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||
|
||||
@@ -1139,7 +1249,6 @@ out:
|
||||
demo = (func) (window);
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
|
||||
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
|
||||
|
||||
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
|
||||
}
|
||||
|
||||
+22
-5
@@ -55,12 +55,29 @@
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-width">150</property>
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/ui/main-listitem.ui</property>
|
||||
<object class="GtkBox">
|
||||
<property name="width-request">220</property>
|
||||
<property name="orientation">vertical</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkSearchBar" id="searchbar">
|
||||
<property name="key-capture-widget">window</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="search-entry"/>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/ui/main-listitem.ui</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
|
||||
<stop offset="0" stop-color="#26a269"/>
|
||||
<stop offset="0.0934161" stop-color="#84e3b7"/>
|
||||
<stop offset="0.330831" stop-color="#26a269"/>
|
||||
<stop offset="0.686952" stop-color="#26a269"/>
|
||||
<stop offset="0.89736" stop-color="#175e3c"/>
|
||||
<stop offset="1" stop-color="#26a269"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.154754" stop-color="#ffffff"/>
|
||||
<stop offset="0.433722" stop-color="#bdbbb5"/>
|
||||
<stop offset="0.650505" stop-color="#c1c0ba"/>
|
||||
<stop offset="0.825253" stop-color="#ffffff"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#813d9c"/>
|
||||
<stop offset="0.109119" stop-color="#b378ca"/>
|
||||
<stop offset="0.241583" stop-color="#813d9c"/>
|
||||
<stop offset="0.731841" stop-color="#813d9c"/>
|
||||
<stop offset="0.872163" stop-color="#4d255d"/>
|
||||
<stop offset="1" stop-color="#813d9c"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#e66100"/>
|
||||
<stop offset="0.0678478" stop-color="#ff903e"/>
|
||||
<stop offset="0.168852" stop-color="#e66100"/>
|
||||
<stop offset="0.886626" stop-color="#e66100"/>
|
||||
<stop offset="1" stop-color="#9d4200"/>
|
||||
</linearGradient>
|
||||
<clipPath id="g">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="h">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<filter id="i" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="j">
|
||||
<g clip-path="url(#h)" filter="url(#i)">
|
||||
<g clip-path="url(#g)">
|
||||
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
|
||||
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
|
||||
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
|
||||
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
|
||||
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
|
||||
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<mask id="k">
|
||||
<g filter="url(#i)">
|
||||
<rect fill-opacity="0.8" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="l" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
|
||||
<stop offset="0" stop-color="#f9f06b"/>
|
||||
<stop offset="1" stop-color="#f5c211"/>
|
||||
</linearGradient>
|
||||
<clipPath id="m">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="n">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
|
||||
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
|
||||
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
|
||||
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
|
||||
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
|
||||
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
|
||||
<g clip-path="url(#n)" mask="url(#j)">
|
||||
<g clip-path="url(#m)" mask="url(#k)">
|
||||
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
|
||||
<stop offset="0" stop-color="#26a269"/>
|
||||
<stop offset="0.0934161" stop-color="#84e3b7"/>
|
||||
<stop offset="0.330831" stop-color="#26a269"/>
|
||||
<stop offset="0.686952" stop-color="#26a269"/>
|
||||
<stop offset="0.89736" stop-color="#175e3c"/>
|
||||
<stop offset="1" stop-color="#26a269"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.154754" stop-color="#ffffff"/>
|
||||
<stop offset="0.433722" stop-color="#bdbbb5"/>
|
||||
<stop offset="0.650505" stop-color="#c1c0ba"/>
|
||||
<stop offset="0.825253" stop-color="#ffffff"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
|
||||
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#813d9c"/>
|
||||
<stop offset="0.109119" stop-color="#b378ca"/>
|
||||
<stop offset="0.241583" stop-color="#813d9c"/>
|
||||
<stop offset="0.731841" stop-color="#813d9c"/>
|
||||
<stop offset="0.872163" stop-color="#4d255d"/>
|
||||
<stop offset="1" stop-color="#813d9c"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
|
||||
<stop offset="0" stop-color="#e66100"/>
|
||||
<stop offset="0.0678478" stop-color="#ff903e"/>
|
||||
<stop offset="0.168852" stop-color="#e66100"/>
|
||||
<stop offset="0.886626" stop-color="#e66100"/>
|
||||
<stop offset="1" stop-color="#9d4200"/>
|
||||
</linearGradient>
|
||||
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
|
||||
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
|
||||
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
|
||||
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
|
||||
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
|
||||
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 5.75 1 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 0.191406 l -1 2 h -3.191406 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 4.5 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 h -0.191406 l 1 -2 h 1.882812 l 1 2 h -0.191406 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 4.5 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 h -3.191406 l -1 -2 h 0.191406 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 z m 0 0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 801 B |
@@ -19,3 +19,12 @@ executable('gtk4-node-editor',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size,
|
||||
install_dir: icontheme_dir
|
||||
)
|
||||
endforeach
|
||||
|
||||
@@ -101,7 +101,7 @@ activate_about (GSimpleAction *action,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to test GTK rendering",
|
||||
"authors", (const char *[]){ "Benjamin Otte", "Timm Bäder", NULL},
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"logo-icon-name", "org.gtk.gtk4.NodeEditor.Devel",
|
||||
"title", "About GTK Node Editor",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="a" gradientTransform="matrix(0.232143 0 0 0.328947 -7.567033 263.82666)" gradientUnits="userSpaceOnUse" x1="88.595886" x2="536.595886" y1="-449.394012" y2="-449.394012">
|
||||
<stop offset="0" stop-color="#acabae"/>
|
||||
<stop offset="0.0384615" stop-color="#deddda"/>
|
||||
<stop offset="0.0768555" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.923077" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.961538" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="26.999876" x2="100.999876" y1="32.999688" y2="32.999688">
|
||||
<stop offset="0" stop-color="#7e7c77"/>
|
||||
<stop offset="0.3" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="67.467916" x2="67.467916" y1="83.999688" y2="36.782906">
|
||||
<stop offset="0" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<clipPath id="d">
|
||||
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
|
||||
</clipPath>
|
||||
<clipPath id="e">
|
||||
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
|
||||
</clipPath>
|
||||
<linearGradient id="f" gradientTransform="matrix(0 0.126951 0.126951 0 76.460862 36.359884)" gradientUnits="userSpaceOnUse" x1="344" x2="340" y1="76" y2="72">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#ffffff"/>
|
||||
</linearGradient>
|
||||
<filter id="g" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="h">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.396" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="i" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1c71d8"/>
|
||||
<stop offset="0.323117" stop-color="#62a0ea"/>
|
||||
<stop offset="0.59387" stop-color="#1b5aa6"/>
|
||||
<stop offset="1" stop-color="#1c71d8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="j" gradientTransform="matrix(1.597748 1.597748 -1.06066 1.06066 -56.853041 -543.720139)" x1="224.504562" x2="231.453873" xlink:href="#i" y1="282.5" y2="282.5"/>
|
||||
<radialGradient id="k" cx="227.599915" cy="201.029724" gradientTransform="matrix(4.072817 4.073078 -5.940048 5.939073 373.883117 -2098.049112)" gradientUnits="userSpaceOnUse" r="2.5">
|
||||
<stop offset="0" stop-color="#93bdf1"/>
|
||||
<stop offset="1" stop-color="#1a5fb4"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="l" gradientTransform="matrix(2.121328 2.121328 -2.174353 2.174353 181.766074 -1021.145947)" gradientUnits="userSpaceOnUse" x1="226.90625" x2="228.86203" y1="288.75" y2="288.767151">
|
||||
<stop offset="0" stop-color="#77767b"/>
|
||||
<stop offset="0.443872" stop-color="#f6f5f4"/>
|
||||
<stop offset="1" stop-color="#5e5c64"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="m" gradientTransform="matrix(1.258421 1.258421 -1.06066 1.06066 57.381892 -503.024312)" gradientUnits="userSpaceOnUse" x1="223.1875" x2="233.0625" y1="278" y2="278">
|
||||
<stop offset="0" stop-color="#ffa348"/>
|
||||
<stop offset="0.265823" stop-color="#ffd7af"/>
|
||||
<stop offset="0.734177" stop-color="#ff8d1c"/>
|
||||
<stop offset="1" stop-color="#ffa348"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="n" gradientTransform="matrix(1.573027 1.573027 -1.06066 1.06066 -14.348129 -574.754333)" x1="224.504562" x2="231.453873" xlink:href="#i" y1="282.5" y2="282.5"/>
|
||||
<clipPath id="o">
|
||||
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
|
||||
</clipPath>
|
||||
<clipPath id="p">
|
||||
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
|
||||
</clipPath>
|
||||
<mask id="q">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.396" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="r">
|
||||
<rect height="152" width="192"/>
|
||||
</clipPath>
|
||||
<g id="s" clip-path="url(#r)">
|
||||
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
|
||||
</g>
|
||||
<clipPath id="t">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="u">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<mask id="v">
|
||||
<g clip-path="url(#u)" filter="url(#g)">
|
||||
<g clip-path="url(#t)">
|
||||
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
|
||||
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
|
||||
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac" fill-opacity="0.984252"/>
|
||||
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda" fill-opacity="0.984252"/>
|
||||
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
|
||||
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
|
||||
<g clip-path="url(#o)">
|
||||
<g clip-path="url(#p)">
|
||||
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
|
||||
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
|
||||
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
|
||||
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
|
||||
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
|
||||
<use mask="url(#q)" transform="matrix(1 0 0 1 -8 -16)" xlink:href="#s"/>
|
||||
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
|
||||
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
|
||||
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
|
||||
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#j)"/>
|
||||
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#k)"/>
|
||||
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
|
||||
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
|
||||
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#m)"/>
|
||||
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#n)"/>
|
||||
</g>
|
||||
</g>
|
||||
</mask>
|
||||
<mask id="w">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.8" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<linearGradient id="x" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
|
||||
<stop offset="0" stop-color="#f9f06b"/>
|
||||
<stop offset="1" stop-color="#f5c211"/>
|
||||
</linearGradient>
|
||||
<clipPath id="y">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
<clipPath id="z">
|
||||
<rect height="128" width="128"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
|
||||
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
|
||||
<g fill-opacity="0.984252">
|
||||
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac"/>
|
||||
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1"/>
|
||||
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda"/>
|
||||
</g>
|
||||
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
|
||||
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
|
||||
<g clip-path="url(#d)">
|
||||
<g clip-path="url(#e)">
|
||||
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
|
||||
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
|
||||
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
|
||||
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
|
||||
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
|
||||
<use mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)" xlink:href="#s"/>
|
||||
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
|
||||
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
|
||||
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
|
||||
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#j)"/>
|
||||
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#k)"/>
|
||||
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
|
||||
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
|
||||
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#m)"/>
|
||||
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#n)"/>
|
||||
<g clip-path="url(#z)" mask="url(#v)">
|
||||
<g clip-path="url(#y)" mask="url(#w)">
|
||||
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#x)"/>
|
||||
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientTransform="matrix(0.232143 0 0 0.328947 -7.567033 263.82666)" gradientUnits="userSpaceOnUse" x1="88.595886" x2="536.595886" y1="-449.394012" y2="-449.394012">
|
||||
<stop offset="0" stop-color="#acabae"/>
|
||||
<stop offset="0.0384615" stop-color="#deddda"/>
|
||||
<stop offset="0.0768555" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.923077" stop-color="#c0bfbc"/>
|
||||
<stop offset="0.961538" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="26.999876" x2="100.999876" y1="32.999688" y2="32.999688">
|
||||
<stop offset="0" stop-color="#7e7c77"/>
|
||||
<stop offset="0.3" stop-color="#9a9996"/>
|
||||
<stop offset="1" stop-color="#9a9996"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="67.467916" x2="67.467916" y1="83.999688" y2="36.782906">
|
||||
<stop offset="0" stop-color="#deddda"/>
|
||||
<stop offset="1" stop-color="#c0bfbc"/>
|
||||
</linearGradient>
|
||||
<clipPath id="d">
|
||||
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
|
||||
</clipPath>
|
||||
<clipPath id="e">
|
||||
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
|
||||
</clipPath>
|
||||
<linearGradient id="f" gradientTransform="matrix(0 0.126951 0.126951 0 76.460862 36.359884)" gradientUnits="userSpaceOnUse" x1="344" x2="340" y1="76" y2="72">
|
||||
<stop offset="0" stop-color="#d5d3cf"/>
|
||||
<stop offset="1" stop-color="#ffffff"/>
|
||||
</linearGradient>
|
||||
<filter id="g" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="h">
|
||||
<g filter="url(#g)">
|
||||
<rect fill-opacity="0.396" height="128" width="128"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="i">
|
||||
<rect height="152" width="192"/>
|
||||
</clipPath>
|
||||
<linearGradient id="j" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#1c71d8"/>
|
||||
<stop offset="0.323117" stop-color="#62a0ea"/>
|
||||
<stop offset="0.59387" stop-color="#1b5aa6"/>
|
||||
<stop offset="1" stop-color="#1c71d8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="k" gradientTransform="matrix(1.597748 1.597748 -1.06066 1.06066 -56.853041 -543.720139)" x1="224.504562" x2="231.453873" xlink:href="#j" y1="282.5" y2="282.5"/>
|
||||
<radialGradient id="l" cx="227.599915" cy="201.029724" gradientTransform="matrix(4.072817 4.073078 -5.940048 5.939073 373.883117 -2098.049112)" gradientUnits="userSpaceOnUse" r="2.5">
|
||||
<stop offset="0" stop-color="#93bdf1"/>
|
||||
<stop offset="1" stop-color="#1a5fb4"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="m" gradientTransform="matrix(2.121328 2.121328 -2.174353 2.174353 181.766074 -1021.145947)" gradientUnits="userSpaceOnUse" x1="226.90625" x2="228.86203" y1="288.75" y2="288.767151">
|
||||
<stop offset="0" stop-color="#77767b"/>
|
||||
<stop offset="0.443872" stop-color="#f6f5f4"/>
|
||||
<stop offset="1" stop-color="#5e5c64"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="n" gradientTransform="matrix(1.258421 1.258421 -1.06066 1.06066 57.381892 -503.024312)" gradientUnits="userSpaceOnUse" x1="223.1875" x2="233.0625" y1="278" y2="278">
|
||||
<stop offset="0" stop-color="#ffa348"/>
|
||||
<stop offset="0.265823" stop-color="#ffd7af"/>
|
||||
<stop offset="0.734177" stop-color="#ff8d1c"/>
|
||||
<stop offset="1" stop-color="#ffa348"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="o" gradientTransform="matrix(1.573027 1.573027 -1.06066 1.06066 -14.348129 -574.754333)" x1="224.504562" x2="231.453873" xlink:href="#j" y1="282.5" y2="282.5"/>
|
||||
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
|
||||
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
|
||||
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
|
||||
<g fill-opacity="0.984252">
|
||||
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac"/>
|
||||
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1"/>
|
||||
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda"/>
|
||||
</g>
|
||||
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
|
||||
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
|
||||
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
|
||||
<g clip-path="url(#d)">
|
||||
<g clip-path="url(#e)">
|
||||
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
|
||||
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
|
||||
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
|
||||
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
|
||||
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
|
||||
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)">
|
||||
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
|
||||
</g>
|
||||
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
|
||||
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
|
||||
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
|
||||
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#k)"/>
|
||||
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#l)"/>
|
||||
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
|
||||
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
|
||||
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#m)"/>
|
||||
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#n)"/>
|
||||
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#o)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<filter id="a" height="100%" width="100%" x="0%" y="0%">
|
||||
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="b">
|
||||
<g filter="url(#a)">
|
||||
<rect fill-opacity="0.396" height="16" width="16"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="c">
|
||||
<rect height="152" width="192"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#c)" mask="url(#b)" transform="matrix(1 0 0 1 -168 -16)">
|
||||
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
|
||||
</g>
|
||||
<g fill="#2e3436">
|
||||
<path d="m 4 2 v 2 h 5.585938 l 2 -2 z m -2 3 c -0.5 0 -1 0.5 -1 1 v 4 c 0 0.5 0.5 1 1 1 h 1 v -2 h 2 c 0 -0.265625 0.105469 -0.519531 0.292969 -0.707031 l 3.292969 -3.292969 z m 11.414062 0 l -4 4 h 3.585938 v 2 h 1 c 0.5 0 1 -0.5 1 -1 v -4 c 0 -0.5 -0.5 -1 -1 -1 z m -9.414062 5 v 5 h 8 v -5 h -3.585938 l -0.707031 0.707031 c -0.1875 0.1875 -0.441406 0.292969 -0.707031 0.292969 h -1 c -0.550781 0 -1 -0.449219 -1 -1 z m 0 0"/>
|
||||
<path d="m 6 10 h 1 l 9 -9 l -1 -1 l -9 9 z m 0 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -12,3 +12,12 @@ install_data('org.gtk.PrintEditor4.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# appdata
|
||||
install_data('org.gtk.PrintEditor4.appdata.xml', install_dir: gtk_appdatadir)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size,
|
||||
install_dir: icontheme_dir
|
||||
)
|
||||
endforeach
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Name=Print Editor
|
||||
Comment=A simple editor demonstrating GTK printing
|
||||
Exec=gtk4-print-editor %f
|
||||
Icon=text-editor-symbolic
|
||||
Icon=org.gtk.PrintEditor4.Devel
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
|
||||
@@ -633,7 +633,7 @@ activate_about (GSimpleAction *action,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK printing",
|
||||
"authors", (const char *[]){ "Alexander Larsson", NULL },
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"logo-icon-name", "org.gtk.PrintEditor4.Devel",
|
||||
"title", "About GTK Print Editor",
|
||||
"system-information", sysinfo->str,
|
||||
NULL);
|
||||
@@ -781,6 +781,8 @@ activate (GApplication *app)
|
||||
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
|
||||
update_title (GTK_WINDOW (main_window));
|
||||
|
||||
gtk_widget_add_css_class (main_window, "devel");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (main_window), box);
|
||||
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
<section>
|
||||
<xi:include href="xml/gtksorter.xml" />
|
||||
<xi:include href="xml/gtkcustomsorter.xml" />
|
||||
<xi:include href="xml/gtkmultisorter.xml" />
|
||||
<xi:include href="xml/gtkstringsorter.xml" />
|
||||
<xi:include href="xml/gtknumericsorter.xml" />
|
||||
<xi:include href="xml/gtkmultisorter.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkselectionmodel.xml" />
|
||||
<section>
|
||||
@@ -93,7 +93,9 @@
|
||||
<xi:include href="xml/gtklistview.xml" />
|
||||
<xi:include href="xml/gtkgridview.xml" />
|
||||
<xi:include href="xml/gtkcolumnview.xml" />
|
||||
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
|
||||
<section>
|
||||
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkdropdown.xml" />
|
||||
</chapter>
|
||||
|
||||
|
||||
@@ -1300,10 +1300,6 @@ gtk_file_chooser_get_current_name
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_get_file
|
||||
gtk_file_chooser_set_file
|
||||
gtk_file_chooser_select_file
|
||||
gtk_file_chooser_unselect_file
|
||||
gtk_file_chooser_select_all
|
||||
gtk_file_chooser_unselect_all
|
||||
gtk_file_chooser_get_files
|
||||
gtk_file_chooser_set_current_folder
|
||||
gtk_file_chooser_get_current_folder
|
||||
@@ -1316,7 +1312,7 @@ gtk_file_chooser_get_filter
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_add_shortcut_folder
|
||||
gtk_file_chooser_remove_shortcut_folder
|
||||
gtk_file_chooser_list_shortcut_folders
|
||||
gtk_file_chooser_get_shortcut_folders
|
||||
<SUBSECTION>
|
||||
gtk_file_chooser_add_choice
|
||||
gtk_file_chooser_remove_choice
|
||||
@@ -1444,6 +1440,8 @@ gtk_directory_list_get_file
|
||||
gtk_directory_list_set_file
|
||||
gtk_directory_list_get_io_priority
|
||||
gtk_directory_list_set_io_priority
|
||||
gtk_directory_list_get_monitored
|
||||
gtk_directory_list_set_monitored
|
||||
gtk_directory_list_is_loading
|
||||
gtk_directory_list_get_error
|
||||
<SUBSECTION Standard>
|
||||
@@ -3422,6 +3420,7 @@ gtk_tree_list_row_get_type
|
||||
<SECTION>
|
||||
<FILE>gtktreeexpander</FILE>
|
||||
<TITLE>GtkTreeExpander</TITLE>
|
||||
GtkTreeExpander
|
||||
gtk_tree_expander_new
|
||||
gtk_tree_expander_get_child
|
||||
gtk_tree_expander_set_child
|
||||
@@ -7543,12 +7542,27 @@ gtk_expression_watch_unwatch
|
||||
<SUBSECTION>
|
||||
gtk_property_expression_new
|
||||
gtk_property_expression_new_for_pspec
|
||||
gtk_property_expression_get_expression
|
||||
gtk_property_expression_get_pspec
|
||||
gtk_constant_expression_new
|
||||
gtk_constant_expression_new_for_value
|
||||
gtk_constant_expression_get_value
|
||||
gtk_object_expression_new
|
||||
gtk_object_expression_get_object
|
||||
gtk_closure_expression_new
|
||||
gtk_cclosure_expression_new
|
||||
|
||||
<SUBSECTION>
|
||||
GTK_VALUE_HOLDS_EXPRESSION
|
||||
gtk_value_set_expression
|
||||
gtk_value_take_expression
|
||||
gtk_value_get_expression
|
||||
gtk_value_dup_expression
|
||||
|
||||
<SUBSECTION>
|
||||
GtkParamSpecExpression
|
||||
gtk_param_spec_expression
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_IS_EXPRESSION
|
||||
GTK_TYPE_EXPRESSION
|
||||
|
||||
@@ -19,6 +19,7 @@ gtk_assistant_get_type
|
||||
gtk_assistant_page_get_type
|
||||
gtk_bin_layout_get_type
|
||||
gtk_bitset_get_type
|
||||
gtk_expression_get_type
|
||||
gtk_bookmark_list_get_type
|
||||
gtk_box_get_type
|
||||
gtk_box_layout_get_type
|
||||
@@ -29,6 +30,7 @@ gtk_builder_list_item_factory_get_type
|
||||
gtk_builder_scope_get_type
|
||||
gtk_button_get_type
|
||||
gtk_calendar_get_type
|
||||
gtk_cclosure_expression_get_type
|
||||
gtk_cell_area_get_type
|
||||
gtk_cell_area_box_get_type
|
||||
gtk_cell_area_context_get_type
|
||||
@@ -46,6 +48,7 @@ gtk_cell_renderer_toggle_get_type
|
||||
gtk_cell_view_get_type
|
||||
gtk_center_layout_get_type
|
||||
gtk_check_button_get_type
|
||||
gtk_closure_expression_get_type
|
||||
gtk_color_button_get_type
|
||||
gtk_color_chooser_get_type
|
||||
gtk_color_chooser_dialog_get_type
|
||||
@@ -54,6 +57,7 @@ gtk_column_view_get_type
|
||||
gtk_column_view_column_get_type
|
||||
gtk_combo_box_get_type
|
||||
gtk_combo_box_text_get_type
|
||||
gtk_constant_expression_get_type
|
||||
gtk_constraint_get_type
|
||||
gtk_constraint_guide_get_type
|
||||
gtk_constraint_layout_get_type
|
||||
@@ -150,6 +154,7 @@ gtk_no_selection_get_type
|
||||
gtk_notebook_get_type
|
||||
gtk_notebook_page_get_type
|
||||
gtk_numeric_sorter_get_type
|
||||
gtk_object_expression_get_type
|
||||
gtk_orientable_get_type
|
||||
gtk_overlay_get_type
|
||||
gtk_overlay_layout_get_type
|
||||
@@ -172,6 +177,7 @@ gtk_print_operation_preview_get_type
|
||||
gtk_print_settings_get_type
|
||||
@DISABLE_ON_W32@gtk_print_unix_dialog_get_type
|
||||
gtk_progress_bar_get_type
|
||||
gtk_property_expression_get_type
|
||||
gtk_radio_button_get_type
|
||||
gtk_range_get_type
|
||||
gtk_recent_manager_get_type
|
||||
@@ -229,6 +235,7 @@ gtk_text_view_get_type
|
||||
gtk_toggle_button_get_type
|
||||
gtk_tree_drag_dest_get_type
|
||||
gtk_tree_drag_source_get_type
|
||||
gtk_tree_expander_get_type
|
||||
gtk_tree_list_model_get_type
|
||||
gtk_tree_list_row_get_type
|
||||
gtk_tree_list_row_sorter_get_type
|
||||
|
||||
@@ -170,7 +170,7 @@ in GTK 3, you can prepare for the switch by using gtk_widget_destroy()
|
||||
only on toplevel windows, and replace all other uses with
|
||||
gtk_container_remove() or g_object_unref().
|
||||
|
||||
### Reduce the use of generic container APIs</title>
|
||||
### Reduce the use of generic container APIs
|
||||
|
||||
GTK 4 removes gtk_container_add() and gtk_container_remove(). While there
|
||||
is not always a replacement for gtk_container_remove() in GTK 3, you can
|
||||
|
||||
@@ -183,7 +183,7 @@ transitioning code for easy lookup:
|
||||
| #GtkTreeModel | #GListModel |
|
||||
| #GtkTreePath | #guint position, #GtkTreeListRow |
|
||||
| #GtkTreeIter | #guint position |
|
||||
| GtkTreeRowReference | #GObject item |
|
||||
| #GtkTreeRowReference | #GObject item |
|
||||
| #GtkListStore | #GListStore |
|
||||
| #GtkTreeStore | #GtkTreeListModel, #GtkTreeExpander |
|
||||
| #GtkTreeSelection | #GtkSelectionModel |
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright © 2020 Benjamin Otte
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* 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: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifndef GDK_ARRAY_TYPE_NAME
|
||||
#define GDK_ARRAY_TYPE_NAME GdkArray
|
||||
#endif
|
||||
|
||||
#ifndef GDK_ARRAY_NAME
|
||||
#define GDK_ARRAY_NAME gdk_array
|
||||
#endif
|
||||
|
||||
#ifndef GDK_ARRAY_ELEMENT_TYPE
|
||||
#define GDK_ARRAY_ELEMENT_TYPE gpointer
|
||||
#endif
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
#if GDK_ARRAY_PREALLOC == 0
|
||||
#undef GDK_ARRAY_PREALLOC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
#define GDK_ARRAY_REAL_SIZE(_size) ((_size) + 1)
|
||||
#else
|
||||
#define GDK_ARRAY_REAL_SIZE(_size) (_size)
|
||||
#endif
|
||||
|
||||
/* make this readable */
|
||||
#define _T_ GDK_ARRAY_ELEMENT_TYPE
|
||||
#define GdkArray GDK_ARRAY_TYPE_NAME
|
||||
#define gdk_array_paste_more(GDK_ARRAY_NAME, func_name) GDK_ARRAY_NAME ## _ ## func_name
|
||||
#define gdk_array_paste(GDK_ARRAY_NAME, func_name) gdk_array_paste_more (GDK_ARRAY_NAME, func_name)
|
||||
#define gdk_array(func_name) gdk_array_paste (GDK_ARRAY_NAME, func_name)
|
||||
|
||||
typedef struct GdkArray GdkArray;
|
||||
|
||||
struct GdkArray
|
||||
{
|
||||
_T_ *start;
|
||||
_T_ *end;
|
||||
_T_ *end_allocation;
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
_T_ preallocated[GDK_ARRAY_REAL_SIZE(GDK_ARRAY_PREALLOC)];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* no G_GNUC_UNUSED here, if you don't use an array type, remove it. */
|
||||
static inline void
|
||||
gdk_array(init) (GdkArray *self)
|
||||
{
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
self->start = self->preallocated;
|
||||
self->end = self->start;
|
||||
self->end_allocation = self->start + GDK_ARRAY_PREALLOC;
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
*self->start = *(_T_[1]) {};
|
||||
#endif
|
||||
#else
|
||||
self->start = NULL;
|
||||
self->end = NULL;
|
||||
self->end_allocation = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_array(free_elements) (_T_ *start,
|
||||
_T_ *end)
|
||||
{
|
||||
#ifdef GDK_ARRAY_FREE_FUNC
|
||||
_T_ *e;
|
||||
for (e = start; e < end; e++)
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
GDK_ARRAY_FREE_FUNC (e);
|
||||
#else
|
||||
GDK_ARRAY_FREE_FUNC (*e);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* no G_GNUC_UNUSED here */
|
||||
static inline void
|
||||
gdk_array(clear) (GdkArray *self)
|
||||
{
|
||||
gdk_array(free_elements) (self->start, self->end);
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
if (self->start != self->preallocated)
|
||||
#endif
|
||||
g_free (self->start);
|
||||
gdk_array(init) (self);
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline _T_ *
|
||||
gdk_array(get_data) (const GdkArray *self)
|
||||
{
|
||||
return self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline _T_ *
|
||||
gdk_array(index) (const GdkArray *self,
|
||||
gsize pos)
|
||||
{
|
||||
return self->start + pos;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline gsize
|
||||
gdk_array(get_capacity) (const GdkArray *self)
|
||||
{
|
||||
return self->end_allocation - self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline gsize
|
||||
gdk_array(get_size) (const GdkArray *self)
|
||||
{
|
||||
return self->end - self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static inline gboolean
|
||||
gdk_array(is_empty) (const GdkArray *self)
|
||||
{
|
||||
return self->end == self->start;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(reserve) (GdkArray *self,
|
||||
gsize n)
|
||||
{
|
||||
gsize new_size, size;
|
||||
|
||||
if (n <= gdk_array(get_capacity) (self))
|
||||
return;
|
||||
|
||||
size = gdk_array(get_size) (self);
|
||||
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
if (self->start == self->preallocated)
|
||||
{
|
||||
self->start = g_new (_T_, new_size);
|
||||
memcpy (self->start, self->preallocated, sizeof (_T_) * GDK_ARRAY_REAL_SIZE (size));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
if (self->start == NULL)
|
||||
{
|
||||
self->start = g_new (_T_, new_size);
|
||||
*self->start = *(_T_[1]) {};
|
||||
}
|
||||
else
|
||||
#endif
|
||||
self->start = g_renew (_T_, self->start, new_size);
|
||||
|
||||
self->end = self->start + size;
|
||||
self->end_allocation = self->start + new_size;
|
||||
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||
self->end_allocation--;
|
||||
#endif
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(splice) (GdkArray *self,
|
||||
gsize pos,
|
||||
gsize removed,
|
||||
_T_ *additions,
|
||||
gsize added)
|
||||
{
|
||||
gsize size;
|
||||
gsize remaining;
|
||||
|
||||
size = gdk_array(get_size) (self);
|
||||
g_assert (pos + removed <= size);
|
||||
remaining = size - pos - removed;
|
||||
|
||||
gdk_array(free_elements) (gdk_array(index) (self, pos),
|
||||
gdk_array(index) (self, pos + removed));
|
||||
|
||||
gdk_array(reserve) (self, size - removed + added);
|
||||
|
||||
if (GDK_ARRAY_REAL_SIZE (remaining) && removed != added)
|
||||
memmove (gdk_array(index) (self, pos + added),
|
||||
gdk_array(index) (self, pos + removed),
|
||||
GDK_ARRAY_REAL_SIZE (remaining) * sizeof (_T_));
|
||||
|
||||
if (added)
|
||||
{
|
||||
if (additions)
|
||||
memcpy (gdk_array(index) (self, pos),
|
||||
additions,
|
||||
added * sizeof (_T_));
|
||||
else
|
||||
memset (gdk_array(index) (self, pos), 0, added * sizeof (_T_));
|
||||
}
|
||||
|
||||
|
||||
/* might overflow, but does the right thing */
|
||||
self->end += added - removed;
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(set_size) (GdkArray *self,
|
||||
gsize new_size)
|
||||
{
|
||||
gsize old_size = gdk_array(get_size) (self);
|
||||
if (new_size > old_size)
|
||||
gdk_array(splice) (self, old_size, 0, NULL, new_size - old_size);
|
||||
else
|
||||
gdk_array(splice) (self, new_size, old_size - new_size, NULL, 0);
|
||||
}
|
||||
|
||||
G_GNUC_UNUSED static void
|
||||
gdk_array(append) (GdkArray *self,
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
_T_ *value)
|
||||
#else
|
||||
_T_ value)
|
||||
#endif
|
||||
{
|
||||
gdk_array(splice) (self,
|
||||
gdk_array(get_size) (self),
|
||||
0,
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
value,
|
||||
#else
|
||||
&value,
|
||||
#endif
|
||||
1);
|
||||
}
|
||||
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
G_GNUC_UNUSED static _T_ *
|
||||
gdk_array(get) (const GdkArray *self,
|
||||
gsize pos)
|
||||
{
|
||||
return gdk_array(index) (self, pos);
|
||||
}
|
||||
#else
|
||||
G_GNUC_UNUSED static _T_
|
||||
gdk_array(get) (const GdkArray *self,
|
||||
gsize pos)
|
||||
{
|
||||
return *gdk_array(index) (self, pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GDK_ARRAY_NO_UNDEF
|
||||
|
||||
#undef _T_
|
||||
#undef GdkArray
|
||||
#undef gdk_array_paste_more
|
||||
#undef gdk_array_paste
|
||||
#undef gdk_array
|
||||
#undef GDK_ARRAY_REAL_SIZE
|
||||
|
||||
#undef GDK_ARRAY_BY_VALUE
|
||||
#undef GDK_ARRAY_ELEMENT_TYPE
|
||||
#undef GDK_ARRAY_FREE_FUNC
|
||||
#undef GDK_ARRAY_NAME
|
||||
#undef GDK_ARRAY_NULL_TERMINATED
|
||||
#undef GDK_ARRAY_PREALLOC
|
||||
#undef GDK_ARRAY_TYPE_NAME
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -354,7 +354,7 @@ gdk_rgba_equal (gconstpointer p1,
|
||||
*
|
||||
* Returns a textual specification of @rgba in the form
|
||||
* `rgb(r,g,b)` or
|
||||
* `rgba(r g,b,a)`,
|
||||
* `rgba(r,g,b,a)`,
|
||||
* where “r”, “g”, “b” and “a” represent the red, green,
|
||||
* blue and alpha values respectively. “r”, “g”, and “b” are
|
||||
* represented as integers in the range 0 to 255, and “a”
|
||||
|
||||
@@ -544,6 +544,12 @@ gdk_registry_handle_global (void *data,
|
||||
gdk_wayland_display_init_xdg_output (display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
|
||||
{
|
||||
display_wayland->idle_inhibit_manager =
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
&zwp_idle_inhibit_manager_v1_interface, 1);
|
||||
}
|
||||
|
||||
g_hash_table_insert (display_wayland->known_globals,
|
||||
GUINT_TO_POINTER (id), g_strdup (interface));
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/server-decoration-client-protocol.h>
|
||||
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
|
||||
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <gdk/gdkkeys.h>
|
||||
@@ -109,6 +110,7 @@ struct _GdkWaylandDisplay
|
||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
|
||||
struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
|
||||
GList *async_roundtrips;
|
||||
|
||||
|
||||
@@ -191,6 +191,9 @@ struct _GdkWaylandSurface
|
||||
|
||||
struct zxdg_imported_v1 *imported_transient_for;
|
||||
GHashTable *shortcuts_inhibitors;
|
||||
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
size_t idle_inhibitor_refcount;
|
||||
};
|
||||
|
||||
struct _GdkWaylandSurfaceClass
|
||||
@@ -1648,6 +1651,38 @@ create_zxdg_toplevel_v6_resources (GdkSurface *surface)
|
||||
surface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_set_application_id (GdkSurface *surface, const char* application_id)
|
||||
{
|
||||
GdkWaylandSurface *impl;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
|
||||
g_return_if_fail (application_id != NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (surface))
|
||||
return;
|
||||
|
||||
if (!is_realized_toplevel (surface))
|
||||
return;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
|
||||
xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel,
|
||||
application_id);
|
||||
break;
|
||||
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
|
||||
zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6,
|
||||
application_id);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
|
||||
{
|
||||
@@ -1702,19 +1737,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
|
||||
if (app_id == NULL)
|
||||
app_id = "GTK+ Application";
|
||||
|
||||
switch (display_wayland->shell_variant)
|
||||
{
|
||||
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
|
||||
xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel,
|
||||
app_id);
|
||||
break;
|
||||
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
|
||||
zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6,
|
||||
app_id);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
gdk_wayland_surface_set_application_id (surface, app_id);
|
||||
|
||||
maybe_set_gtk_surface_dbus_properties (surface);
|
||||
maybe_set_gtk_surface_modal (surface);
|
||||
@@ -1964,6 +1987,39 @@ gdk_wayland_surface_announce_csd (GdkSurface *surface)
|
||||
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_surface_inhibit_idle (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!display_wayland->idle_inhibit_manager)
|
||||
return false;
|
||||
if (!impl->idle_inhibitor)
|
||||
{
|
||||
g_assert (impl->idle_inhibitor_refcount == 0);
|
||||
impl->idle_inhibitor =
|
||||
zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager,
|
||||
impl->display_server.wl_surface);
|
||||
}
|
||||
++impl->idle_inhibitor_refcount;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_uninhibit_idle (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
g_assert (impl->idle_inhibitor && impl->idle_inhibitor_refcount > 0);
|
||||
|
||||
if (--impl->idle_inhibitor_refcount == 0)
|
||||
{
|
||||
zwp_idle_inhibitor_v1_destroy (impl->idle_inhibitor);
|
||||
impl->idle_inhibitor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_popup_rect (GdkSurface *surface,
|
||||
GdkPopupLayout *layout,
|
||||
|
||||
@@ -74,8 +74,15 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface,
|
||||
char *parent_handle_str);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_surface_set_application_id (GdkSurface *surface,
|
||||
const char *application_id);
|
||||
|
||||
void gdk_wayland_surface_announce_csd (GdkSurface *surface);
|
||||
|
||||
gboolean gdk_wayland_surface_inhibit_idle (GdkSurface *surface);
|
||||
void gdk_wayland_surface_uninhibit_idle (GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WAYLAND_SURFACE_H__ */
|
||||
|
||||
@@ -54,6 +54,7 @@ proto_sources = [
|
||||
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
|
||||
['server-decoration', 'private' ],
|
||||
['xdg-output', 'unstable', 'v1', ],
|
||||
['idle-inhibit', 'unstable', 'v1', ],
|
||||
]
|
||||
|
||||
gdk_wayland_gen_headers = []
|
||||
|
||||
@@ -653,6 +653,8 @@ gdk_x11_clipboard_store_async (GdkClipboard *clipboard,
|
||||
GDK_DISPLAY_NOTE (display, CLIPBOARD,
|
||||
g_printerr ("%s: X error during ConvertSelection() while storing selection: %d\n", cb->selection, error));
|
||||
}
|
||||
|
||||
g_free (atoms);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -1874,6 +1874,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
case XI_Leave:
|
||||
{
|
||||
XIEnterEvent *xev = (XIEnterEvent *) ev;
|
||||
GdkModifierType state;
|
||||
|
||||
GDK_DISPLAY_NOTE (display, EVENTS,
|
||||
g_message ("%s notify:\twindow %ld\n\tsubwindow:%ld\n"
|
||||
@@ -1890,6 +1891,18 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
source_device = g_hash_table_lookup (device_manager->id_table,
|
||||
GUINT_TO_POINTER (xev->sourceid));
|
||||
|
||||
state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
/* Ignore normal crossing events while there is an implicit grab.
|
||||
* We will receive a crossing event with one of the other details if
|
||||
* the implicit grab were finished (eg. releasing the button outside
|
||||
* the window triggers a XINotifyUngrab leave).
|
||||
*/
|
||||
if (xev->mode == XINotifyNormal &&
|
||||
(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
|
||||
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)))
|
||||
break;
|
||||
|
||||
if (ev->evtype == XI_Enter &&
|
||||
xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
|
||||
GDK_IS_TOPLEVEL (surface))
|
||||
@@ -1916,12 +1929,11 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
device,
|
||||
source_device,
|
||||
xev->time,
|
||||
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
|
||||
state,
|
||||
(double) xev->event_x / scale,
|
||||
(double) xev->event_y / scale,
|
||||
translate_crossing_mode (xev->mode),
|
||||
translate_notify_type (xev->detail));
|
||||
|
||||
}
|
||||
break;
|
||||
case XI_FocusIn:
|
||||
|
||||
@@ -184,7 +184,7 @@ gdk_x11_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_x11_surface_pre_damage (surface);
|
||||
|
||||
#ifdef HAVE_XDAMAGE
|
||||
if (context_x11->xdamage != 0)
|
||||
if (context_x11->xdamage != 0 && _gdk_x11_surface_syncs_frames (surface))
|
||||
{
|
||||
g_assert (context_x11->frame_fence == 0);
|
||||
|
||||
|
||||
@@ -360,8 +360,8 @@ gdk_x11_surface_begin_frame (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_sync_frame_drawing (GdkSurface *surface)
|
||||
gboolean
|
||||
_gdk_x11_surface_syncs_frames (GdkSurface *surface)
|
||||
{
|
||||
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
|
||||
|
||||
@@ -395,7 +395,7 @@ static void
|
||||
maybe_sync_counter_for_end_frame (GdkSurface *surface)
|
||||
{
|
||||
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
|
||||
gboolean frame_sync_negotiated = should_sync_frame_drawing (surface);
|
||||
gboolean frame_sync_negotiated = _gdk_x11_surface_syncs_frames (surface);
|
||||
gboolean frame_done_painting = !impl->toplevel->frame_pending;
|
||||
|
||||
#ifdef HAVE_XDAMAGE
|
||||
@@ -478,7 +478,7 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
|
||||
|
||||
maybe_sync_counter_for_end_frame (surface);
|
||||
|
||||
if (should_sync_frame_drawing (surface))
|
||||
if (_gdk_x11_surface_syncs_frames (surface))
|
||||
{
|
||||
impl->toplevel->frame_pending = TRUE;
|
||||
gdk_surface_freeze_updates (surface);
|
||||
|
||||
@@ -179,6 +179,7 @@ GdkCursor *_gdk_x11_surface_get_cursor (GdkSurface *window);
|
||||
void _gdk_x11_surface_update_size (GdkX11Surface *impl);
|
||||
void _gdk_x11_surface_set_surface_scale (GdkSurface *window,
|
||||
int scale);
|
||||
gboolean _gdk_x11_surface_syncs_frames (GdkSurface *surface);
|
||||
|
||||
void gdk_x11_surface_pre_damage (GdkSurface *surface);
|
||||
|
||||
@@ -188,6 +189,7 @@ void gdk_x11_surface_move (GdkSurface *surface,
|
||||
void gdk_x11_surface_check_monitor (GdkSurface *surface,
|
||||
GdkMonitor *monitor);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_X11_SURFACE__ */
|
||||
|
||||
+180
-120
@@ -70,7 +70,6 @@ typedef enum
|
||||
RESET_CLIP = 1 << 1,
|
||||
RESET_OPACITY = 1 << 2,
|
||||
DUMP_FRAMEBUFFER = 1 << 3,
|
||||
CENTER_CHILD = 1 << 4,
|
||||
NO_CACHE_PLZ = 1 << 5,
|
||||
} OffscreenFlags;
|
||||
|
||||
@@ -906,6 +905,7 @@ upload_texture (GskGLRenderer *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
out_region->texture_id =
|
||||
gsk_gl_driver_get_texture_for_texture (self->gl_driver,
|
||||
texture,
|
||||
@@ -1152,6 +1152,59 @@ rounded_inner_rect_contains_rect (const GskRoundedRect *rounded,
|
||||
return graphene_rect_contains_rect (&inner, rect);
|
||||
}
|
||||
|
||||
/* Current clip is NOT rounded but new one is definitely! */
|
||||
static inline bool
|
||||
intersect_rounded_rectilinear (const graphene_rect_t *non_rounded,
|
||||
const GskRoundedRect *rounded,
|
||||
GskRoundedRect *result)
|
||||
{
|
||||
int n_corners = 0;
|
||||
bool corners[4];
|
||||
|
||||
/* Intersects with top left corner? */
|
||||
n_corners += corners[0] = rounded_rect_has_corner (rounded, 0) &&
|
||||
graphene_rect_intersection (non_rounded,
|
||||
&rounded_rect_corner (rounded, 0), NULL);
|
||||
/* top right? */
|
||||
n_corners += corners[1] = rounded_rect_has_corner (rounded, 1) &&
|
||||
graphene_rect_intersection (non_rounded,
|
||||
&rounded_rect_corner (rounded, 1), NULL);
|
||||
/* bottom right? */
|
||||
n_corners += corners[2] = rounded_rect_has_corner (rounded, 2) &&
|
||||
graphene_rect_intersection (non_rounded,
|
||||
&rounded_rect_corner (rounded, 2), NULL);
|
||||
/* bottom left */
|
||||
n_corners += corners[3] = rounded_rect_has_corner (rounded, 3) &&
|
||||
graphene_rect_intersection (non_rounded,
|
||||
&rounded_rect_corner (rounded, 3), NULL);
|
||||
|
||||
if (corners[0] && !graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 0)))
|
||||
return false;
|
||||
if (corners[1] && !graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 1)))
|
||||
return false;
|
||||
if (corners[2] && !graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 2)))
|
||||
return false;
|
||||
if (corners[3] && !graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 3)))
|
||||
return false;
|
||||
|
||||
/* We do intersect with at least one of the corners, but in such a way that the
|
||||
* intersection between the two clips can still be represented by a single rounded
|
||||
* rect in a trivial way. do that. */
|
||||
graphene_rect_intersection (non_rounded, &rounded->bounds, &result->bounds);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (corners[i])
|
||||
result->corner[i] = rounded->corner[i];
|
||||
else
|
||||
result->corner[i].width = result->corner[i].height = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This code intersects the current (maybe rounded) clip with the new
|
||||
* non-rounded clip */
|
||||
static inline void
|
||||
render_clipped_child (GskGLRenderer *self,
|
||||
RenderOpBuilder *builder,
|
||||
@@ -1159,112 +1212,57 @@ render_clipped_child (GskGLRenderer *self,
|
||||
GskRenderNode *child)
|
||||
{
|
||||
graphene_rect_t transformed_clip;
|
||||
GskRoundedRect child_clip;
|
||||
GskRoundedRect intersection;
|
||||
|
||||
ops_transform_bounds_modelview (builder, clip, &transformed_clip);
|
||||
|
||||
if (builder->clip_is_rectilinear)
|
||||
goto trivial;
|
||||
|
||||
{
|
||||
const GskRoundedRect *cur_clip = builder->current_clip;
|
||||
int n_corners = 0;
|
||||
bool corners[4];
|
||||
|
||||
/* Intersects with top left corner? */
|
||||
n_corners += corners[0] = rounded_rect_has_corner (cur_clip, 0) &&
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&rounded_rect_corner (cur_clip, 0), NULL);
|
||||
/* top right? */
|
||||
n_corners += corners[1] = rounded_rect_has_corner (cur_clip, 1) &&
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&rounded_rect_corner (cur_clip, 1), NULL);
|
||||
/* bottom right? */
|
||||
n_corners += corners[2] = rounded_rect_has_corner (cur_clip, 2) &&
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&rounded_rect_corner (cur_clip, 2), NULL);
|
||||
/* bottom left */
|
||||
n_corners += corners[3] = rounded_rect_has_corner (cur_clip, 3) &&
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&rounded_rect_corner (cur_clip, 3), NULL);
|
||||
|
||||
if (n_corners == 0)
|
||||
goto trivial;
|
||||
|
||||
if (corners[0] && !graphene_rect_contains_rect (&transformed_clip, &rounded_rect_corner (cur_clip, 0)))
|
||||
goto rtt;
|
||||
if (corners[1] && !graphene_rect_contains_rect (&transformed_clip, &rounded_rect_corner (cur_clip, 1)))
|
||||
goto rtt;
|
||||
if (corners[2] && !graphene_rect_contains_rect (&transformed_clip, &rounded_rect_corner (cur_clip, 2)))
|
||||
goto rtt;
|
||||
if (corners[3] && !graphene_rect_contains_rect (&transformed_clip, &rounded_rect_corner (cur_clip, 3)))
|
||||
goto rtt;
|
||||
|
||||
/* We do intersect with at least one of the corners, but in such a way that the
|
||||
* intersection between the two clips can still be represented by a single rounded
|
||||
* rect in a trivial way. do that. */
|
||||
{
|
||||
GskRoundedRect real_intersection;
|
||||
memset (&intersection, 0, sizeof (GskRoundedRect));
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&builder->current_clip->bounds,
|
||||
&intersection.bounds);
|
||||
|
||||
graphene_rect_intersection (&transformed_clip, &cur_clip->bounds, &real_intersection.bounds);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (corners[i])
|
||||
real_intersection.corner[i] = cur_clip->corner[i];
|
||||
else
|
||||
real_intersection.corner[i].width = real_intersection.corner[i].height = 0;
|
||||
}
|
||||
|
||||
/* Draw with that new clip */
|
||||
ops_push_clip (builder, &real_intersection);
|
||||
ops_push_clip (builder, &intersection);
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
ops_pop_clip (builder);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (intersect_rounded_rectilinear (&transformed_clip,
|
||||
builder->current_clip,
|
||||
&intersection))
|
||||
{
|
||||
ops_push_clip (builder, &intersection);
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
ops_pop_clip (builder);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* well fuck */
|
||||
const float scale = ops_get_scale (builder);
|
||||
gboolean is_offscreen;
|
||||
TextureRegion region;
|
||||
GskRoundedRect scaled_clip;
|
||||
|
||||
rtt:
|
||||
{
|
||||
/* well fuck */
|
||||
const float scale = ops_get_scale (builder);
|
||||
gboolean is_offscreen;
|
||||
TextureRegion region;
|
||||
GskRoundedRect scaled_clip;
|
||||
memset (&scaled_clip, 0, sizeof (GskRoundedRect));
|
||||
|
||||
memset (&scaled_clip, 0, sizeof (GskRoundedRect));
|
||||
scaled_clip.bounds.origin.x = clip->origin.x * scale;
|
||||
scaled_clip.bounds.origin.y = clip->origin.y * scale;
|
||||
scaled_clip.bounds.size.width = clip->size.width * scale;
|
||||
scaled_clip.bounds.size.height = clip->size.height * scale;
|
||||
|
||||
scaled_clip.bounds.origin.x = clip->origin.x * scale;
|
||||
scaled_clip.bounds.origin.y = clip->origin.y * scale;
|
||||
scaled_clip.bounds.size.width = clip->size.width * scale;
|
||||
scaled_clip.bounds.size.height = clip->size.height * scale;
|
||||
ops_push_clip (builder, &scaled_clip);
|
||||
if (!add_offscreen_ops (self, builder, &child->bounds,
|
||||
child,
|
||||
®ion, &is_offscreen,
|
||||
RESET_OPACITY | FORCE_OFFSCREEN))
|
||||
g_assert_not_reached ();
|
||||
ops_pop_clip (builder);
|
||||
|
||||
ops_push_clip (builder, &scaled_clip);
|
||||
if (!add_offscreen_ops (self, builder, &child->bounds,
|
||||
child,
|
||||
®ion, &is_offscreen,
|
||||
RESET_OPACITY | FORCE_OFFSCREEN))
|
||||
g_assert_not_reached ();
|
||||
ops_pop_clip (builder);
|
||||
ops_set_program (builder, &self->programs->blit_program);
|
||||
ops_set_texture (builder, region.texture_id);
|
||||
|
||||
ops_set_program (builder, &self->programs->blit_program);
|
||||
ops_set_texture (builder, region.texture_id);
|
||||
|
||||
load_offscreen_vertex_data (ops_draw (builder, NULL), child, builder);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
trivial:
|
||||
memset (&child_clip, 0, sizeof (GskRoundedRect));
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&builder->current_clip->bounds,
|
||||
&child_clip.bounds);
|
||||
|
||||
ops_push_clip (builder, &child_clip);
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
ops_pop_clip (builder);
|
||||
return;
|
||||
load_offscreen_vertex_data (ops_draw (builder, NULL), child, builder);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -1294,6 +1292,29 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
return;
|
||||
|
||||
ops_transform_bounds_modelview (builder, &clip->bounds, &transformed_clip.bounds);
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
transformed_clip.corner[i].width = clip->corner[i].width * scale;
|
||||
transformed_clip.corner[i].height = clip->corner[i].height * scale;
|
||||
}
|
||||
|
||||
if (builder->clip_is_rectilinear)
|
||||
{
|
||||
GskRoundedRect intersected_clip;
|
||||
|
||||
if (intersect_rounded_rectilinear (&builder->current_clip->bounds,
|
||||
&transformed_clip,
|
||||
&intersected_clip))
|
||||
{
|
||||
ops_push_clip (builder, &intersected_clip);
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
ops_pop_clip (builder);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* After this point we are really working with a new and a current clip
|
||||
* which both have rounded corners. */
|
||||
|
||||
if (!ops_has_clip (builder))
|
||||
need_offscreen = FALSE;
|
||||
@@ -1307,12 +1328,16 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
{
|
||||
/* If they don't intersect at all, we can simply set
|
||||
* the new clip and add the render ops */
|
||||
for (i = 0; i < 4; i ++)
|
||||
|
||||
/* If the new clip entirely contains the current clip, the intersection is simply
|
||||
* the current clip, so we can ignore the new one */
|
||||
if (rounded_inner_rect_contains_rect (&transformed_clip, &builder->current_clip->bounds))
|
||||
{
|
||||
transformed_clip.corner[i].width = clip->corner[i].width * scale;
|
||||
transformed_clip.corner[i].height = clip->corner[i].height * scale;
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Intersect current and new clip */
|
||||
ops_push_clip (builder, &transformed_clip);
|
||||
gsk_gl_renderer_add_render_ops (self, child, builder);
|
||||
ops_pop_clip (builder);
|
||||
@@ -1354,7 +1379,6 @@ render_rounded_clip_node (GskGLRenderer *self,
|
||||
|
||||
load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
|
||||
}
|
||||
/* Else this node is entirely out of the current clip node and we don't draw it anyway. */
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -1762,7 +1786,6 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static GdkRGBA COLOR_WHITE = { 1, 1, 1, 1 };
|
||||
static inline void
|
||||
render_outset_shadow_node (GskGLRenderer *self,
|
||||
@@ -1783,19 +1806,32 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
OpShadow *shadow;
|
||||
int blurred_texture_id;
|
||||
int cached_tid;
|
||||
bool do_slicing;
|
||||
|
||||
/* scaled_outline is the minimal outline we need to draw the given drop shadow,
|
||||
* enlarged by the spread and offset by the blur radius. */
|
||||
scaled_outline = *outline;
|
||||
/* Shrink our outline to the minimum size that can still hold all the border radii */
|
||||
gsk_rounded_rect_shrink_to_minimum (&scaled_outline);
|
||||
/* Increase by the spread */
|
||||
gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
|
||||
/* Grow bounds but don't grow corners */
|
||||
graphene_rect_inset (&scaled_outline.bounds, - extra_blur_pixels, - extra_blur_pixels);
|
||||
/* For the center part, we add a few pixels */
|
||||
scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE;
|
||||
scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE;
|
||||
|
||||
if (outline->bounds.size.width < blur_extra ||
|
||||
outline->bounds.size.height < blur_extra)
|
||||
{
|
||||
do_slicing = false;
|
||||
gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shrink our outline to the minimum size that can still hold all the border radii */
|
||||
gsk_rounded_rect_shrink_to_minimum (&scaled_outline);
|
||||
/* Increase by the spread */
|
||||
gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
|
||||
/* Grow bounds but don't grow corners */
|
||||
graphene_rect_inset (&scaled_outline.bounds, - blur_extra / 2.0, - blur_extra / 2.0);
|
||||
/* For the center part, we add a few pixels */
|
||||
scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE;
|
||||
scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE;
|
||||
|
||||
do_slicing = true;
|
||||
}
|
||||
|
||||
texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale);
|
||||
texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale);
|
||||
@@ -1880,6 +1916,41 @@ render_outset_shadow_node (GskGLRenderer *self,
|
||||
blurred_texture_id = cached_tid;
|
||||
}
|
||||
|
||||
|
||||
if (!do_slicing)
|
||||
{
|
||||
const float min_x = floorf (builder->dx + outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx);
|
||||
const float min_y = floorf (builder->dy + outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy);
|
||||
float x1, x2, y1, y2, tx1, tx2, ty1, ty2;
|
||||
|
||||
ops_set_program (builder, &self->programs->outset_shadow_program);
|
||||
ops_set_color (builder, color);
|
||||
ops_set_texture (builder, blurred_texture_id);
|
||||
|
||||
shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
|
||||
shadow->outline = transform_rect (self, builder, outline);
|
||||
|
||||
tx1 = 0; tx2 = 1;
|
||||
ty1 = 0; ty2 = 1;
|
||||
|
||||
x1 = min_x;
|
||||
x2 = min_x + texture_width / scale;
|
||||
y1 = min_y;
|
||||
y2 = min_y + texture_height / scale;
|
||||
|
||||
ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
|
||||
{ { x1, y1 }, { tx1, ty2 }, },
|
||||
{ { x1, y2 }, { tx1, ty1 }, },
|
||||
{ { x2, y1 }, { tx2, ty2 }, },
|
||||
|
||||
{ { x2, y2 }, { tx2, ty1 }, },
|
||||
{ { x1, y2 }, { tx1, ty1 }, },
|
||||
{ { x2, y1 }, { tx2, ty2 }, },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ops_set_program (builder, &self->programs->outset_shadow_program);
|
||||
ops_set_color (builder, color);
|
||||
ops_set_texture (builder, blurred_texture_id);
|
||||
@@ -3317,19 +3388,8 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
bounds->origin.y * scale,
|
||||
width, height));
|
||||
|
||||
if (flags & CENTER_CHILD)
|
||||
{
|
||||
ops_offset (builder,
|
||||
(bounds->size.width - child_node->bounds.size.width) / 2.0 -
|
||||
child_node->bounds.origin.x,
|
||||
(bounds->size.height - child_node->bounds.size.height) / 2.0 -
|
||||
child_node->bounds.origin.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
}
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
|
||||
if (flags & RESET_OPACITY)
|
||||
prev_opacity = ops_set_opacity (builder, 1.0);
|
||||
|
||||
+2
-1
@@ -123,7 +123,8 @@ gsk_transform_alloc (const GskTransformClass *transform_class,
|
||||
|
||||
self->transform_class = transform_class;
|
||||
self->category = next ? MIN (category, next->category) : category;
|
||||
self->next = gsk_transform_is_identity (next) ? NULL : next;
|
||||
self->next = gsk_transform_is_identity (next) ? NULL : gsk_transform_ref (next);
|
||||
g_clear_pointer (&next, gsk_transform_unref);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -233,10 +233,6 @@
|
||||
#include <gtk/gtkslicelistmodel.h>
|
||||
#include <gtk/gtksnapshot.h>
|
||||
#include <gtk/gtksorter.h>
|
||||
#include <gtk/gtksor2listmodel.h>
|
||||
#include <gtk/gtksor3listmodel.h>
|
||||
#include <gtk/gtksor4listmodel.h>
|
||||
#include <gtk/gtksor5listmodel.h>
|
||||
#include <gtk/gtksortlistmodel.h>
|
||||
#include <gtk/gtkstacksidebar.h>
|
||||
#include <gtk/gtksizegroup.h>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright © 2010 Codethink Limited
|
||||
* Copyright © 2013 Canonical Limited
|
||||
* Copyright © 2020 Emmanuel Gil Peyrot
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -24,12 +25,42 @@
|
||||
#include "gtknative.h"
|
||||
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <gdk/wayland/gdkdisplay-wayland.h>
|
||||
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
|
||||
|
||||
typedef GtkApplicationImplDBusClass GtkApplicationImplWaylandClass;
|
||||
typedef struct
|
||||
{
|
||||
GtkApplicationImplDBusClass parent_class;
|
||||
|
||||
/* stores the dbus version of the overriden methods */
|
||||
guint (*dbus_inhibit) (GtkApplicationImpl *impl,
|
||||
GtkWindow *window,
|
||||
GtkApplicationInhibitFlags flags,
|
||||
const gchar *reason);
|
||||
void (*dbus_uninhibit) (GtkApplicationImpl *impl,
|
||||
guint cookie);
|
||||
} GtkApplicationImplWaylandClass;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint cookie;
|
||||
guint dbus_cookie;
|
||||
GtkApplicationInhibitFlags flags;
|
||||
GdkSurface *surface;
|
||||
|
||||
} GtkApplicationWaylandInhibitor;
|
||||
|
||||
static void
|
||||
gtk_application_wayland_inhibitor_free (GtkApplicationWaylandInhibitor *inhibitor)
|
||||
{
|
||||
g_slice_free (GtkApplicationWaylandInhibitor, inhibitor);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkApplicationImplDBus dbus;
|
||||
GSList *inhibitors;
|
||||
guint next_cookie;
|
||||
|
||||
} GtkApplicationImplWayland;
|
||||
|
||||
@@ -72,6 +103,70 @@ gtk_application_impl_wayland_before_emit (GtkApplicationImpl *impl,
|
||||
gdk_wayland_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_application_impl_wayland_inhibit (GtkApplicationImpl *impl,
|
||||
GtkWindow *window,
|
||||
GtkApplicationInhibitFlags flags,
|
||||
const gchar *reason)
|
||||
{
|
||||
GtkApplicationImplWayland *wayland = (GtkApplicationImplWayland *) impl;
|
||||
GdkSurface *surface;
|
||||
GtkApplicationWaylandInhibitor *inhibitor;
|
||||
gboolean success;
|
||||
|
||||
if (!flags)
|
||||
return 0;
|
||||
|
||||
inhibitor = g_slice_new (GtkApplicationWaylandInhibitor);
|
||||
inhibitor->cookie = ++wayland->next_cookie;
|
||||
inhibitor->flags = flags;
|
||||
wayland->inhibitors = g_slist_prepend (wayland->inhibitors, inhibitor);
|
||||
|
||||
if (flags & GTK_APPLICATION_INHIBIT_IDLE)
|
||||
{
|
||||
surface = gtk_native_get_surface (GTK_NATIVE (window));
|
||||
if (GDK_IS_WAYLAND_SURFACE (surface))
|
||||
{
|
||||
success = gdk_wayland_surface_inhibit_idle (surface);
|
||||
if (success)
|
||||
{
|
||||
flags &= ~GTK_APPLICATION_INHIBIT_IDLE;
|
||||
inhibitor->surface = surface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inhibitor->dbus_cookie = ((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_inhibit (impl, window, flags, reason);
|
||||
|
||||
return inhibitor->cookie;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_impl_wayland_uninhibit (GtkApplicationImpl *impl,
|
||||
guint cookie)
|
||||
{
|
||||
GtkApplicationImplWayland *wayland = (GtkApplicationImplWayland *) impl;
|
||||
GSList *iter;
|
||||
|
||||
for (iter = wayland->inhibitors; iter; iter = iter->next)
|
||||
{
|
||||
GtkApplicationWaylandInhibitor *inhibitor = iter->data;
|
||||
|
||||
if (inhibitor->cookie == cookie)
|
||||
{
|
||||
if (inhibitor->dbus_cookie)
|
||||
((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_uninhibit (impl, inhibitor->dbus_cookie);
|
||||
if (inhibitor->surface)
|
||||
gdk_wayland_surface_uninhibit_idle (inhibitor->surface);
|
||||
gtk_application_wayland_inhibitor_free (inhibitor);
|
||||
wayland->inhibitors = g_slist_delete_link (wayland->inhibitors, iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_warning ("Invalid inhibitor cookie");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_impl_wayland_init (GtkApplicationImplWayland *wayland)
|
||||
{
|
||||
@@ -82,8 +177,15 @@ gtk_application_impl_wayland_class_init (GtkApplicationImplWaylandClass *class)
|
||||
{
|
||||
GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
|
||||
|
||||
class->dbus_inhibit = impl_class->inhibit;
|
||||
class->dbus_uninhibit = impl_class->uninhibit;
|
||||
|
||||
impl_class->handle_window_realize =
|
||||
gtk_application_impl_wayland_handle_window_realize;
|
||||
impl_class->before_emit =
|
||||
gtk_application_impl_wayland_before_emit;
|
||||
impl_class->inhibit =
|
||||
gtk_application_impl_wayland_inhibit;
|
||||
impl_class->uninhibit =
|
||||
gtk_application_impl_wayland_uninhibit;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ gtk_application_accels_set_accels_for_action (GtkApplicationAccels *accels,
|
||||
}
|
||||
|
||||
g_list_store_remove (G_LIST_STORE (accels->shortcuts), i);
|
||||
g_object_unref (shortcut_i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -27,20 +27,19 @@
|
||||
* SECTION:gtkbitset
|
||||
* @title: GtkBitset
|
||||
* @short_description: Sets of integers
|
||||
* @see_also: GtkSelectionModel
|
||||
* @see_also: #GtkSelectionModel
|
||||
*
|
||||
* #GtkBitset is a data structure for representing a set of unsigned integers.
|
||||
* Another name for this data structure is "bitmap".
|
||||
*
|
||||
* This version is based on [roaring bitmaps](https://roaringbitmap.org/).
|
||||
* The current implemenation is based on [roaring bitmaps](https://roaringbitmap.org/).
|
||||
*
|
||||
* A bitset allows adding a set of integers and provides support for set operations
|
||||
* like unions, intersections and checks for equality or if a value is contained
|
||||
* in the set. #GtkBitset also contains various functions to query metadata about
|
||||
* the bitset, such as the minimum or maximum values or its size.
|
||||
*
|
||||
* The fastest way to iterate values in a bitset is #GtkBitsetIter which allows
|
||||
* quick iteration of all the values in a bitset.
|
||||
* The fastest way to iterate values in a bitset is #GtkBitsetIter.
|
||||
*
|
||||
* The main use case for #GtkBitset is implementing complex selections for
|
||||
* #GtkSelectionModel.
|
||||
|
||||
+15
-1
@@ -130,7 +130,21 @@ void gtk_bitset_splice (GtkBitset
|
||||
guint removed,
|
||||
guint added);
|
||||
|
||||
typedef struct {gpointer private_data[10]; } GtkBitsetIter;
|
||||
/**
|
||||
* GtkBitsetIter:
|
||||
*
|
||||
* An opaque, stack-allocated struct for iterating
|
||||
* over the elements of a #GtkBitset. Before a GtkBitsetIter
|
||||
* can be used, it needs to be initialized with
|
||||
* gtk_bitset_iter_init_first(), gtk_bitset_iter_init_last()
|
||||
* or gtk_bitset_iter_init_at().
|
||||
*/
|
||||
typedef struct _GtkBitsetIter GtkBitsetIter;
|
||||
|
||||
struct _GtkBitsetIter
|
||||
{
|
||||
gpointer private_data[10];
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_bitset_iter_init_first (GtkBitsetIter *iter,
|
||||
|
||||
@@ -369,6 +369,8 @@ gtk_bookmark_list_start_loading (GtkBookmarkList *self)
|
||||
self);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
g_strfreev (uris);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+6
-14
@@ -28,7 +28,6 @@
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtknative.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkboxlayout
|
||||
@@ -250,10 +249,8 @@ gtk_box_layout_compute_size (GtkBoxLayout *self,
|
||||
required_nat += (n_visible_children - 1) * spacing;
|
||||
}
|
||||
|
||||
if (minimum != NULL)
|
||||
*minimum = required_min;
|
||||
if (natural != NULL)
|
||||
*natural = required_nat;
|
||||
*minimum = required_min;
|
||||
*natural = required_nat;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -420,15 +417,10 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
|
||||
}
|
||||
}
|
||||
|
||||
if (minimum != NULL)
|
||||
*minimum = computed_minimum;
|
||||
if (natural != NULL)
|
||||
*natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
|
||||
|
||||
if (min_baseline != NULL)
|
||||
*min_baseline = computed_minimum_baseline;
|
||||
if (nat_baseline != NULL)
|
||||
*nat_baseline = computed_natural_baseline;
|
||||
*minimum = computed_minimum;
|
||||
*natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
|
||||
*min_baseline = computed_minimum_baseline;
|
||||
*nat_baseline = computed_natural_baseline;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -294,6 +294,17 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_BUTTON_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("button"));
|
||||
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_space, 0,
|
||||
"activate", NULL);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_KP_Space, 0,
|
||||
"activate", NULL);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_Return, 0,
|
||||
"activate", NULL);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_ISO_Enter, 0,
|
||||
"activate", NULL);
|
||||
gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_KP_Enter, 0,
|
||||
"activate", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -62,10 +62,12 @@ gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
|
||||
{
|
||||
GtkColumnViewColumn *column = g_list_model_get_item (columns, i);
|
||||
|
||||
gtk_column_list_item_factory_add_column (self,
|
||||
gtk_column_list_item_factory_add_column (self,
|
||||
list_item->owner,
|
||||
column,
|
||||
FALSE);
|
||||
|
||||
g_object_unref (column);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-10
@@ -60,7 +60,7 @@
|
||||
* GtkColumnView allows the user to select items according to the selection
|
||||
* characteristics of the model. If the provided model is not a #GtkSelectionModel,
|
||||
* GtkColumnView will wrap it in a #GtkSingleSelection. For models that allow
|
||||
* multiple selected items, it is possible to turn on _rubberband selection_,
|
||||
* multiple selected items, it is possible to turn on *rubberband selection*,
|
||||
* using #GtkColumnView:enable-rubberband.
|
||||
*
|
||||
* The column view supports sorting that can be customized by the user by
|
||||
@@ -1241,7 +1241,7 @@ gtk_column_view_set_model (GtkColumnView *self,
|
||||
*
|
||||
* Gets the list of columns in this column view. This list is constant over
|
||||
* the lifetime of @self and can be used to monitor changes to the columns
|
||||
* of @self by connecting to the GListModel:items-changed signal.
|
||||
* of @self by connecting to the #GListModel:items-changed signal.
|
||||
*
|
||||
* Returns: (transfer none): The list managing the columns
|
||||
**/
|
||||
@@ -1263,7 +1263,7 @@ gtk_column_view_get_columns (GtkColumnView *self)
|
||||
*/
|
||||
void
|
||||
gtk_column_view_set_show_row_separators (GtkColumnView *self,
|
||||
gboolean show_row_separators)
|
||||
gboolean show_row_separators)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
|
||||
|
||||
@@ -1302,7 +1302,7 @@ gtk_column_view_get_show_row_separators (GtkColumnView *self)
|
||||
*/
|
||||
void
|
||||
gtk_column_view_set_show_column_separators (GtkColumnView *self,
|
||||
gboolean show_column_separators)
|
||||
gboolean show_column_separators)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
|
||||
|
||||
@@ -1486,17 +1486,26 @@ gtk_column_view_get_list_view (GtkColumnView *self)
|
||||
* gtk_column_view_get_sorter:
|
||||
* @self: a #GtkColumnView
|
||||
*
|
||||
* Returns the sorter associated with users sorting choices in
|
||||
* the column view.
|
||||
* Returns a special sorter that reflects the users sorting
|
||||
* choices in the column view.
|
||||
*
|
||||
* To allow users to customizable sorting by clicking on column
|
||||
* headers, this sorter needs to be set on the sort
|
||||
* model(s) underneath the model that is displayed
|
||||
* by the view.
|
||||
* headers, this sorter needs to be set on the sort model underneath
|
||||
* the model that is displayed by the view.
|
||||
*
|
||||
* See gtk_column_view_column_get_sorter() for setting up
|
||||
* See gtk_column_view_column_set_sorter() for setting up
|
||||
* per-column sorting.
|
||||
*
|
||||
* Here is an example:
|
||||
* |[
|
||||
* gtk_column_view_column_set_sorter (column, sorter);
|
||||
* gtk_column_view_append_column (view, column);
|
||||
* model = gtk_sort_list_model_new (store,
|
||||
* gtk_column_view_get_sorter (view));
|
||||
* selection = gtk_no_selection_new (model);
|
||||
* gtk_column_view_set_model (view, selection);
|
||||
* ]|
|
||||
*
|
||||
* Returns: (transfer none): the #GtkSorter of @self
|
||||
*/
|
||||
GtkSorter *
|
||||
|
||||
@@ -105,6 +105,7 @@ void gtk_column_view_set_reorderable (GtkColumnView
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_column_view_get_reorderable (GtkColumnView *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_column_view_set_enable_rubberband (GtkColumnView *self,
|
||||
gboolean enable_rubberband);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -85,6 +85,7 @@ void gtk_column_view_column_set_header_menu (GtkColu
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GMenuModel * gtk_column_view_column_get_header_menu (GtkColumnViewColumn *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_column_view_column_set_fixed_width (GtkColumnViewColumn *self,
|
||||
int fixed_width);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -115,6 +115,14 @@ gtk_column_view_sorter_dispose (GObject *object)
|
||||
{
|
||||
GtkColumnViewSorter *self = GTK_COLUMN_VIEW_SORTER (object);
|
||||
|
||||
/* The sorter is owned by the columview and is unreffed
|
||||
* after the columns, so the sequence must be empty at
|
||||
* this point.
|
||||
* The sorter can outlive the columview it comes from
|
||||
* (the model might still have a ref), but that does
|
||||
* not change the fact that all columns will be gone.
|
||||
*/
|
||||
g_assert (g_sequence_is_empty (self->sorters));
|
||||
g_clear_pointer (&self->sorters, g_sequence_free);
|
||||
|
||||
G_OBJECT_CLASS (gtk_column_view_sorter_parent_class)->dispose (object);
|
||||
|
||||
+17
-18
@@ -560,10 +560,12 @@ css_provider_commit (GtkCssProvider *css_provider,
|
||||
|
||||
if (ruleset->styles == NULL)
|
||||
{
|
||||
for (i = 0; i < n_selectors; i++)
|
||||
_gtk_css_selector_free (selectors[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_selectors; i ++)
|
||||
for (i = 0; i < n_selectors; i++)
|
||||
{
|
||||
GtkCssRuleset *new;
|
||||
|
||||
@@ -766,7 +768,11 @@ parse_selector_list (GtkCssScanner *scanner,
|
||||
GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser);
|
||||
|
||||
if (select == NULL)
|
||||
return 0;
|
||||
{
|
||||
for (int i = 0; i < n_selectors; i++)
|
||||
g_clear_pointer (&out_selectors[i], _gtk_css_selector_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_selectors[n_selectors] = select;
|
||||
n_selectors++;
|
||||
@@ -776,6 +782,8 @@ parse_selector_list (GtkCssScanner *scanner,
|
||||
gtk_css_parser_error_syntax (scanner->parser,
|
||||
"Only %u selectors per ruleset allowed",
|
||||
MAX_SELECTOR_LIST_LENGTH);
|
||||
for (int i = 0; i < MAX_SELECTOR_LIST_LENGTH; i++)
|
||||
g_clear_pointer (&out_selectors[i], _gtk_css_selector_free);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -804,10 +812,7 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
|
||||
name = gtk_css_parser_consume_ident (scanner->parser);
|
||||
if (name == NULL)
|
||||
{
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
goto out;
|
||||
|
||||
property = _gtk_style_property_lookup (name);
|
||||
|
||||
@@ -819,25 +824,18 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
if (!gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COLON))
|
||||
{
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected ':'");
|
||||
g_free (name);
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
value = _gtk_style_property_parse_value (property,
|
||||
scanner->parser);
|
||||
value = _gtk_style_property_parse_value (property, scanner->parser);
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
}
|
||||
goto out;
|
||||
|
||||
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
|
||||
{
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Junk at end of value for %s", property->name);
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (gtk_keep_css_sections)
|
||||
@@ -882,6 +880,7 @@ parse_declaration (GtkCssScanner *scanner,
|
||||
gtk_css_parser_error_value (scanner->parser, "No property named \"%s\"", name);
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (name);
|
||||
|
||||
gtk_css_parser_end_block (scanner->parser);
|
||||
@@ -916,7 +915,7 @@ parse_ruleset (GtkCssScanner *scanner)
|
||||
{
|
||||
guint i;
|
||||
gtk_css_parser_error_syntax (scanner->parser, "Expected '{' after selectors");
|
||||
for (i = 0; i < n_selectors; i ++)
|
||||
for (i = 0; i < n_selectors; i++)
|
||||
_gtk_css_selector_free (selectors[i]);
|
||||
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
|
||||
gtk_css_parser_skip (scanner->parser);
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
#include "gtk/gtkcsstypesprivate.h"
|
||||
#include "gtk/gtkcssparserprivate.h"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE gpointer
|
||||
#define GTK_VECTOR_TYPE_NAME GtkCssSelectorMatches
|
||||
#define GTK_VECTOR_NAME gtk_css_selector_matches
|
||||
#define GTK_VECTOR_PREALLOC 32
|
||||
#include "gtk/gtkvectorimpl.c"
|
||||
#define GDK_ARRAY_ELEMENT_TYPE gpointer
|
||||
#define GDK_ARRAY_TYPE_NAME GtkCssSelectorMatches
|
||||
#define GDK_ARRAY_NAME gtk_css_selector_matches
|
||||
#define GDK_ARRAY_PREALLOC 32
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
* @Title: GtkCustomFilter
|
||||
* @Short_description: Filtering with callbacks
|
||||
*
|
||||
* #GtkCustomFilter is a #GtkFilter that uses a callback to determine whether
|
||||
* to include an item or not.
|
||||
* #GtkCustomFilter is a #GtkFilter that uses a callback to determine
|
||||
* whether to include an item or not.
|
||||
*/
|
||||
struct _GtkCustomFilter
|
||||
{
|
||||
@@ -98,11 +98,13 @@ gtk_custom_filter_init (GtkCustomFilter *self)
|
||||
* gtk_custom_filter_new:
|
||||
* @match_func: (nullable): function to filter items
|
||||
* @user_data: (nullable): user data to pass to @match_func
|
||||
* @user_destroy: destory notify
|
||||
* @user_destroy: destroy notify for @user_data
|
||||
*
|
||||
* Creates a new filter using the given @match_func to filter
|
||||
* items.
|
||||
*
|
||||
* If @match_func is %NULL, the filter matches all items.
|
||||
*
|
||||
* If the filter func changes its filtering behavior,
|
||||
* gtk_filter_changed() needs to be called.
|
||||
*
|
||||
@@ -127,10 +129,12 @@ gtk_custom_filter_new (GtkCustomFilterFunc match_func,
|
||||
* @self: a #GtkCustomFilter
|
||||
* @match_func: (nullable): function to filter items
|
||||
* @user_data: (nullable): user data to pass to @match_func
|
||||
* @user_destroy: destory notify
|
||||
* @user_destroy: destroy notify for @user_data
|
||||
*
|
||||
* Sets (or unsets) the function used for filtering items.
|
||||
*
|
||||
*
|
||||
* If @match_func is %NULL, the filter matches all items.
|
||||
*
|
||||
* If the filter func changes its filtering behavior,
|
||||
* gtk_filter_changed() needs to be called.
|
||||
*
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
/**
|
||||
* SECTION:gtkcustomsorter
|
||||
* @Title: GtkCustomSorter
|
||||
* @Short_description: Sorting with a callback
|
||||
* @Short_description: Sorting with a callbacks
|
||||
*
|
||||
* GtkCustomSorter is a #GtkSorter implementation that sorts
|
||||
* via a traditional #GCompareDataFunc callback.
|
||||
@@ -108,8 +108,10 @@ gtk_custom_sorter_init (GtkCustomSorter *self)
|
||||
* Creates a new #GtkSorter that works by calling
|
||||
* @sort_func to compare items.
|
||||
*
|
||||
* Returns: a new #GTkSorter
|
||||
*/
|
||||
* If @sort_func is %NULL, all items are considered equal.
|
||||
*
|
||||
* Returns: a new #GtkSorter
|
||||
*/
|
||||
GtkSorter *
|
||||
gtk_custom_sorter_new (GCompareDataFunc sort_func,
|
||||
gpointer user_data,
|
||||
@@ -129,10 +131,12 @@ gtk_custom_sorter_new (GCompareDataFunc sort_func,
|
||||
* @self: a #GtkCustomSorter
|
||||
* @sort_func: (nullable): function to sort items
|
||||
* @user_data: (nullable): user data to pass to @match_func
|
||||
* @user_destroy: destory notify
|
||||
* @user_destroy: destroy notify for @user_data
|
||||
*
|
||||
* Sets (or unsets) the function used for sorting items.
|
||||
*
|
||||
*
|
||||
* If @sort_func is %NULL, all items are considered equal.
|
||||
*
|
||||
* If the sort func changes its sorting behavior,
|
||||
* gtk_sorter_changed() needs to be called.
|
||||
*
|
||||
|
||||
+4
-5
@@ -48,11 +48,10 @@ typedef enum {
|
||||
GTK_DEBUG_INTERACTIVE = 1 << 10,
|
||||
GTK_DEBUG_TOUCHSCREEN = 1 << 11,
|
||||
GTK_DEBUG_ACTIONS = 1 << 12,
|
||||
GTK_DEBUG_RESIZE = 1 << 13,
|
||||
GTK_DEBUG_LAYOUT = 1 << 14,
|
||||
GTK_DEBUG_SNAPSHOT = 1 << 15,
|
||||
GTK_DEBUG_CONSTRAINTS = 1 << 16,
|
||||
GTK_DEBUG_BUILDER_OBJECTS = 1 << 17,
|
||||
GTK_DEBUG_LAYOUT = 1 << 13,
|
||||
GTK_DEBUG_SNAPSHOT = 1 << 14,
|
||||
GTK_DEBUG_CONSTRAINTS = 1 << 15,
|
||||
GTK_DEBUG_BUILDER_OBJECTS = 1 << 16,
|
||||
} GtkDebugFlag;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
+229
-4
@@ -62,6 +62,7 @@ enum {
|
||||
PROP_IO_PRIORITY,
|
||||
PROP_ITEM_TYPE,
|
||||
PROP_LOADING,
|
||||
PROP_MONITORED,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
@@ -70,8 +71,10 @@ struct _GtkDirectoryList
|
||||
GObject parent_instance;
|
||||
|
||||
char *attributes;
|
||||
int io_priority;
|
||||
GFile *file;
|
||||
GFileMonitor *monitor;
|
||||
gboolean monitored;
|
||||
int io_priority;
|
||||
|
||||
GCancellable *cancellable;
|
||||
GError *error; /* Error while loading */
|
||||
@@ -147,13 +150,17 @@ gtk_directory_list_set_property (GObject *object,
|
||||
gtk_directory_list_set_io_priority (self, g_value_get_int (value));
|
||||
break;
|
||||
|
||||
case PROP_MONITORED:
|
||||
gtk_directory_list_set_monitored (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
gtk_directory_list_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
@@ -187,6 +194,10 @@ gtk_directory_list_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gtk_directory_list_is_loading (self));
|
||||
break;
|
||||
|
||||
case PROP_MONITORED:
|
||||
g_value_set_boolean (value, gtk_directory_list_get_monitored (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -204,12 +215,27 @@ gtk_directory_list_stop_loading (GtkDirectoryList *self)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void directory_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event,
|
||||
gpointer data);
|
||||
|
||||
static void
|
||||
gtk_directory_list_stop_monitoring (GtkDirectoryList *self)
|
||||
{
|
||||
if (self->monitor)
|
||||
g_signal_handlers_disconnect_by_func (self->monitor, directory_changed, self);
|
||||
g_clear_object (&self->monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_directory_list_dispose (GObject *object)
|
||||
{
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (object);
|
||||
|
||||
gtk_directory_list_stop_loading (self);
|
||||
gtk_directory_list_stop_monitoring (self);
|
||||
|
||||
g_clear_object (&self->file);
|
||||
g_clear_pointer (&self->attributes, g_free);
|
||||
@@ -301,6 +327,18 @@ gtk_directory_list_class_init (GtkDirectoryListClass *class)
|
||||
FALSE,
|
||||
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkDirectoryList:monitored:
|
||||
*
|
||||
* %TRUE if the directory is monitored for changed
|
||||
*/
|
||||
properties[PROP_MONITORED] =
|
||||
g_param_spec_boolean ("monitored",
|
||||
P_("monitored"),
|
||||
P_("TRUE if the directory is monitored for changes"),
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
@@ -309,6 +347,7 @@ gtk_directory_list_init (GtkDirectoryList *self)
|
||||
{
|
||||
self->items = g_sequence_new (g_object_unref);
|
||||
self->io_priority = G_PRIORITY_DEFAULT;
|
||||
self->monitored = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,7 +363,6 @@ gtk_directory_list_init (GtkDirectoryList *self)
|
||||
GtkDirectoryList *
|
||||
gtk_directory_list_new (const char *attributes,
|
||||
GFile *file)
|
||||
|
||||
{
|
||||
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
|
||||
|
||||
@@ -410,7 +448,7 @@ gtk_directory_list_got_files_cb (GObject *source,
|
||||
{
|
||||
GFileInfo *info;
|
||||
GFile *file;
|
||||
|
||||
|
||||
info = l->data;
|
||||
file = g_file_enumerator_get_child (enumerator, info);
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
@@ -496,6 +534,143 @@ gtk_directory_list_start_loading (GtkDirectoryList *self)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOADING]);
|
||||
}
|
||||
|
||||
static void
|
||||
got_new_file_info_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file = G_FILE (source);
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
|
||||
GFileInfo *info;
|
||||
guint position;
|
||||
|
||||
info = g_file_query_info_finish (file, res, NULL);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
position = g_sequence_get_length (self->items);
|
||||
g_sequence_append (self->items, info);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
got_existing_file_info_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GFile *file = G_FILE (source);
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
|
||||
GFileInfo *info;
|
||||
GSequenceIter *iter;
|
||||
|
||||
info = g_file_query_info_finish (file, res, NULL);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->items);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
GFileInfo *item = g_sequence_get (iter);
|
||||
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
|
||||
if (g_file_equal (f, file))
|
||||
{
|
||||
guint position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_set (iter, g_object_ref (info));
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_directory_list_remove_file (GtkDirectoryList *self,
|
||||
GFile *file)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
|
||||
for (iter = g_sequence_get_begin_iter (self->items);
|
||||
!g_sequence_iter_is_end (iter);
|
||||
iter = g_sequence_iter_next (iter))
|
||||
{
|
||||
GFileInfo *item = g_sequence_get (iter);
|
||||
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
|
||||
if (g_file_equal (f, file))
|
||||
{
|
||||
guint position = g_sequence_iter_get_position (iter);
|
||||
g_sequence_remove (iter);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
directory_changed (GFileMonitor *monitor,
|
||||
GFile *file,
|
||||
GFile *other_file,
|
||||
GFileMonitorEvent event,
|
||||
gpointer data)
|
||||
{
|
||||
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
|
||||
switch (event)
|
||||
{
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
g_file_query_info_async (file,
|
||||
self->attributes,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
self->io_priority,
|
||||
self->cancellable,
|
||||
got_new_file_info_cb,
|
||||
self);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
gtk_directory_list_remove_file (self, file);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
|
||||
g_file_query_info_async (file,
|
||||
self->attributes,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
self->io_priority,
|
||||
self->cancellable,
|
||||
got_existing_file_info_cb,
|
||||
self);
|
||||
break;
|
||||
|
||||
case G_FILE_MONITOR_EVENT_CHANGED:
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
|
||||
case G_FILE_MONITOR_EVENT_UNMOUNTED:
|
||||
case G_FILE_MONITOR_EVENT_MOVED:
|
||||
case G_FILE_MONITOR_EVENT_RENAMED:
|
||||
case G_FILE_MONITOR_EVENT_MOVED_IN:
|
||||
case G_FILE_MONITOR_EVENT_MOVED_OUT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_directory_list_start_monitoring (GtkDirectoryList *self)
|
||||
{
|
||||
g_assert (self->monitor == NULL);
|
||||
self->monitor = g_file_monitor_directory (self->file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
g_signal_connect (self->monitor, "changed", G_CALLBACK (directory_changed), self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_directory_list_update_monitoring (GtkDirectoryList *self)
|
||||
{
|
||||
gtk_directory_list_stop_monitoring (self);
|
||||
if (self->file && self->monitored)
|
||||
gtk_directory_list_start_monitoring (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_directory_list_set_file:
|
||||
* @self: a #GtkDirectoryList
|
||||
@@ -520,6 +695,7 @@ gtk_directory_list_set_file (GtkDirectoryList *self,
|
||||
|
||||
g_set_object (&self->file, file);
|
||||
|
||||
gtk_directory_list_update_monitoring (self);
|
||||
gtk_directory_list_start_loading (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILE]);
|
||||
@@ -679,3 +855,52 @@ gtk_directory_list_get_error (GtkDirectoryList *self)
|
||||
return self->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_directory_list_set_monitored:
|
||||
* @self: a #GtkDirectoryList
|
||||
* @monitored: %TRUE to monitor the directory for changes
|
||||
*
|
||||
* Sets whether the directory list will monitor the directory
|
||||
* for changes. If monitoring is enabled, the
|
||||
* #GListModel::items-changed signal will be emitted when the
|
||||
* directory contents change.
|
||||
*
|
||||
* When monitoring is turned on after the initial creation
|
||||
* of the directory list, the directory is reloaded to avoid
|
||||
* missing files that appeared between the initial loading
|
||||
* and when monitoring was turned on.
|
||||
*/
|
||||
void
|
||||
gtk_directory_list_set_monitored (GtkDirectoryList *self,
|
||||
gboolean monitored)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_DIRECTORY_LIST (self));
|
||||
|
||||
if (self->monitored == monitored)
|
||||
return;
|
||||
|
||||
self->monitored = monitored;
|
||||
|
||||
gtk_directory_list_update_monitoring (self);
|
||||
if (monitored)
|
||||
gtk_directory_list_start_loading (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MONITORED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_directory_list_get_monitored:
|
||||
* @self: a #GtkDirectoryList
|
||||
*
|
||||
* Returns whether the directory list is monitoring
|
||||
* the directory for changes.
|
||||
*
|
||||
* Returns: %TRUE if the directory is monitored
|
||||
*/
|
||||
gboolean
|
||||
gtk_directory_list_get_monitored (GtkDirectoryList *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_DIRECTORY_LIST (self), TRUE);
|
||||
|
||||
return self->monitored;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,12 @@ gboolean gtk_directory_list_is_loading (GtkDirectoryLis
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GError * gtk_directory_list_get_error (GtkDirectoryList *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_directory_list_set_monitored (GtkDirectoryList *self,
|
||||
gboolean monitored);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_directory_list_get_monitored (GtkDirectoryList *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_DIRECTORY_LIST_H__ */
|
||||
|
||||
+3
-4
@@ -70,7 +70,7 @@
|
||||
* useful if the list of options is long. To enable the search entry,
|
||||
* use gtk_drop_down_set_enable_search().
|
||||
*
|
||||
* * # CSS nodes
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkDropDown has a single CSS node with name dropdown,
|
||||
* with the button and popover nodes as children.
|
||||
@@ -205,9 +205,8 @@ update_filter (GtkDropDown *self)
|
||||
|
||||
if (self->expression)
|
||||
{
|
||||
filter = gtk_string_filter_new ();
|
||||
filter = gtk_string_filter_new (gtk_expression_ref (self->expression));
|
||||
gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), self->expression);
|
||||
}
|
||||
else
|
||||
filter = gtk_every_filter_new ();
|
||||
@@ -927,7 +926,7 @@ gtk_drop_down_get_expression (GtkDropDown *self)
|
||||
/**
|
||||
* gtk_drop_down_set_from_strings:
|
||||
* @self: a #GtkDropDown
|
||||
* @texts: a %NULL-terminated string array
|
||||
* @texts: (array zero-terminated=1) (element-type utf8): a %NULL-terminated string array
|
||||
*
|
||||
* Populates @self with the strings in @text,
|
||||
* by creating a suitable model and factory.
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "gtkshortcut.h"
|
||||
#include "gtkshortcuttrigger.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkeventcontrollerfocus.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,22 @@
|
||||
* to click or press the Enter key. The default bindings
|
||||
* for leaving the edit mode are the Enter key (to save
|
||||
* the results) or the Escape key (to cancel the editing).
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* |[<!-- language="plain" -->
|
||||
* editablelabel[.editing]
|
||||
* ╰── stack
|
||||
* ├── label
|
||||
* ╰── text
|
||||
* ]|
|
||||
*
|
||||
* GtkEditableLabel has a main node with the name editablelabel.
|
||||
* When the entry is in editing mode, it gets the .editing style
|
||||
* class.
|
||||
*
|
||||
* For all the subnodes added to the text node in various situations,
|
||||
* see #GtkText.
|
||||
*/
|
||||
|
||||
struct _GtkEditableLabel
|
||||
@@ -177,12 +194,20 @@ gtk_editable_label_prepare_drag (GtkDragSource *source,
|
||||
gtk_label_get_label (GTK_LABEL (self->label)));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_label_focus_out (GtkEventController *controller,
|
||||
GtkEditableLabel *self)
|
||||
{
|
||||
gtk_editable_label_stop_editing (self, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_editable_label_init (GtkEditableLabel *self)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
GtkDropTarget *target;
|
||||
GtkDragSource *source;
|
||||
GtkEventController *controller;
|
||||
|
||||
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
|
||||
|
||||
@@ -212,6 +237,10 @@ gtk_editable_label_init (GtkEditableLabel *self)
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (gtk_editable_label_prepare_drag), self);
|
||||
gtk_widget_add_controller (self->label, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
controller = gtk_event_controller_focus_new ();
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (gtk_editable_label_focus_out), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
gtk_editable_init_delegate (GTK_EDITABLE (self));
|
||||
}
|
||||
|
||||
@@ -444,6 +473,8 @@ gtk_editable_label_start_editing (GtkEditableLabel *self)
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "entry");
|
||||
gtk_widget_grab_focus (self->entry);
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "editing");
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITING]);
|
||||
}
|
||||
|
||||
@@ -480,5 +511,8 @@ gtk_editable_label_stop_editing (GtkEditableLabel *self,
|
||||
}
|
||||
|
||||
gtk_widget_grab_focus (GTK_WIDGET (self));
|
||||
|
||||
gtk_widget_remove_css_class (GTK_WIDGET (self), "editing");
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITING]);
|
||||
}
|
||||
|
||||
+83
-9
@@ -53,26 +53,26 @@
|
||||
*
|
||||
* Here is an example of a complex expression:
|
||||
* |[
|
||||
* color_expr = gtk_property_expression_new (GTK_TYPE_LIST_ITEM,
|
||||
* NULL, "item");
|
||||
* expression = gtk_property_expression_new (GTK_TYPE_COLOR,
|
||||
* color_expr,
|
||||
* "name");
|
||||
* color_expr = gtk_property_expression_new (GTK_TYPE_LIST_ITEM,
|
||||
* NULL, "item");
|
||||
* expression = gtk_property_expression_new (GTK_TYPE_COLOR,
|
||||
* color_expr, "name");
|
||||
* ]|
|
||||
*
|
||||
* when evaluated with `this` being a GtkListItem, it will obtain the
|
||||
* "item" property from the GtkListItem, and then obtain the "name" property
|
||||
* from the resulting object (which is assumed to be of type GTK_TYPE_COLOR).
|
||||
*
|
||||
* A more concise way to describe this would be
|
||||
* |[
|
||||
* this->item->name
|
||||
* this->item->name
|
||||
* ]|
|
||||
*
|
||||
* The most likely place where you will encounter expressions is in the context
|
||||
* of list models and list widgets using them. For example, #GtkDropDown is
|
||||
* evaluating a GtkExpression to obtain strings from the items in its model
|
||||
* that it can then use to match against the contents of its search entry.
|
||||
* #GtkStringFilter is using a GtkExpression for a similar reason.
|
||||
* #GtkStringFilter is using a GtkExpression for similar reasons.
|
||||
*
|
||||
* By default, expressions are not paying attention to changes and evaluation is
|
||||
* just a snapshot of the current state at a given time. To get informed about
|
||||
@@ -127,11 +127,11 @@
|
||||
* attribute to specify the object type, and a `name` attribute to specify the property
|
||||
* to look up. The content of <lookup> can either be an element specfiying the expression
|
||||
* to use the object, or a string that specifies the name of the object to use.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
* |[
|
||||
* <lookup name='search'>string_filter</lookup>
|
||||
* |]
|
||||
* ]|
|
||||
*
|
||||
* To create a constant expression, use the <constant> element. If the type attribute
|
||||
* is specified, the element content is interpreted as a value of that type. Otherwise,
|
||||
@@ -855,6 +855,24 @@ gtk_constant_expression_new_for_value (const GValue *value)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constant_expression_get_value:
|
||||
* @expression: a constant #GtkExpression
|
||||
*
|
||||
* Gets the value that a constant expression evaluates to.
|
||||
*
|
||||
* Returns: (transfer none): the value
|
||||
*/
|
||||
const GValue *
|
||||
gtk_constant_expression_get_value (GtkExpression *expression)
|
||||
{
|
||||
GtkConstantExpression *self = (GtkConstantExpression *) expression;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_CONSTANT_EXPRESSION), NULL);
|
||||
|
||||
return &self->value;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ GtkObjectExpression */
|
||||
@@ -1002,6 +1020,24 @@ gtk_object_expression_new (GObject *object)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_object_expression_get_object:
|
||||
* @expression: an object #GtkExpression
|
||||
*
|
||||
* Gets the object that the expression evaluates to.
|
||||
*
|
||||
* Returns: (transfer none): the object, or %NULL
|
||||
*/
|
||||
GObject *
|
||||
gtk_object_expression_get_object (GtkExpression *expression)
|
||||
{
|
||||
GtkObjectExpression *self = (GtkObjectExpression *) expression;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_OBJECT_EXPRESSION), NULL);
|
||||
|
||||
return self->object;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ GtkPropertyExpression */
|
||||
@@ -1307,6 +1343,44 @@ gtk_property_expression_new_for_pspec (GtkExpression *expression,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_property_expression_get_expression:
|
||||
* @expression: a property #GtkExpression
|
||||
*
|
||||
* Gets the expression specifying the object of
|
||||
* a property expression.
|
||||
*
|
||||
* Returns: (transfer none): the object expression
|
||||
*/
|
||||
GtkExpression *
|
||||
gtk_property_expression_get_expression (GtkExpression *expression)
|
||||
{
|
||||
GtkPropertyExpression *self = (GtkPropertyExpression *) expression;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_PROPERTY_EXPRESSION), NULL);
|
||||
|
||||
return self->expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_property_expression_get_pspec:
|
||||
* @expression: a property #GtkExpression
|
||||
*
|
||||
* Gets the #GParamSpec specifying the property of
|
||||
* a property expression.
|
||||
*
|
||||
* Returns: (transfer none): the #GParamSpec
|
||||
*/
|
||||
GParamSpec *
|
||||
gtk_property_expression_get_pspec (GtkExpression *expression)
|
||||
{
|
||||
GtkPropertyExpression *self = (GtkPropertyExpression *) expression;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_PROPERTY_EXPRESSION), NULL);
|
||||
|
||||
return self->pspec;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ GtkClosureExpression */
|
||||
|
||||
@@ -93,6 +93,11 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkExpression * gtk_property_expression_new_for_pspec (GtkExpression *expression,
|
||||
GParamSpec *pspec);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkExpression * gtk_property_expression_get_expression (GtkExpression *expression);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GParamSpec * gtk_property_expression_get_pspec (GtkExpression *expression);
|
||||
|
||||
#define GTK_TYPE_CONSTANT_EXPRESSION (gtk_constant_expression_get_type())
|
||||
typedef struct _GtkConstantExpression GtkConstantExpression;
|
||||
|
||||
@@ -105,6 +110,9 @@ GtkExpression * gtk_constant_expression_new (GType
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkExpression * gtk_constant_expression_new_for_value (const GValue *value);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const GValue * gtk_constant_expression_get_value (GtkExpression *expression);
|
||||
|
||||
#define GTK_TYPE_OBJECT_EXPRESSION (gtk_object_expression_get_type())
|
||||
typedef struct _GtkObjectExpression GtkObjectExpression;
|
||||
|
||||
@@ -114,6 +122,9 @@ GType gtk_object_expression_get_type (void) G_GNUC_CO
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkExpression * gtk_object_expression_new (GObject *object);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GObject * gtk_object_expression_get_object (GtkExpression *expression);
|
||||
|
||||
#define GTK_TYPE_CLOSURE_EXPRESSION (gtk_closure_expression_get_type())
|
||||
typedef struct _GtkClosureExpression GtkClosureExpression;
|
||||
|
||||
|
||||
+13
-105
@@ -79,75 +79,6 @@ G_DEFINE_INTERFACE (GtkFileChooser, gtk_file_chooser, G_TYPE_OBJECT);
|
||||
static void
|
||||
gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
|
||||
{
|
||||
GType iface_type = G_TYPE_FROM_INTERFACE (iface);
|
||||
|
||||
/**
|
||||
* GtkFileChooser::current-folder-changed:
|
||||
* @chooser: the object which received the signal.
|
||||
*
|
||||
* This signal is emitted when the current folder in a #GtkFileChooser
|
||||
* changes. This can happen due to the user performing some action that
|
||||
* changes folders, such as selecting a bookmark or visiting a folder on the
|
||||
* file list. It can also happen as a result of calling a function to
|
||||
* explicitly change the current folder in a file chooser.
|
||||
*
|
||||
* Normally you do not need to connect to this signal, unless you need to keep
|
||||
* track of which folder a file chooser is showing.
|
||||
*
|
||||
* See also: gtk_file_chooser_set_current_folder(),
|
||||
* gtk_file_chooser_get_current_folder(),
|
||||
*/
|
||||
g_signal_new (I_("current-folder-changed"),
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileChooserIface, current_folder_changed),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkFileChooser::selection-changed:
|
||||
* @chooser: the object which received the signal.
|
||||
*
|
||||
* This signal is emitted when there is a change in the set of selected files
|
||||
* in a #GtkFileChooser. This can happen when the user modifies the selection
|
||||
* with the mouse or the keyboard, or when explicitly calling functions to
|
||||
* change the selection.
|
||||
*
|
||||
* Normally you do not need to connect to this signal, as it is easier to wait
|
||||
* for the file chooser to finish running, and then to get the list of
|
||||
* selected files using the functions mentioned below.
|
||||
*/
|
||||
g_signal_new (I_("selection-changed"),
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileChooserIface, selection_changed),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkFileChooser::file-activated:
|
||||
* @chooser: the object which received the signal.
|
||||
*
|
||||
* This signal is emitted when the user "activates" a file in the file
|
||||
* chooser. This can happen by double-clicking on a file in the file list, or
|
||||
* by pressing `Enter`.
|
||||
*
|
||||
* Normally you do not need to connect to this signal. It is used internally
|
||||
* by #GtkFileChooserDialog to know when to activate the default button in the
|
||||
* dialog.
|
||||
*
|
||||
* See also: gtk_file_chooser_get_file(), gtk_file_chooser_get_files()
|
||||
*/
|
||||
g_signal_new (I_("file-activated"),
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileChooserIface, file_activated),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_enum ("action",
|
||||
P_("Action"),
|
||||
@@ -508,16 +439,15 @@ gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
|
||||
/**
|
||||
* gtk_file_chooser_get_files:
|
||||
* @chooser: a #GtkFileChooser
|
||||
*
|
||||
* Lists all the selected files and subfolders in the current folder of @chooser
|
||||
* as #GFile.
|
||||
*
|
||||
* Returns: (element-type GFile) (transfer full): a list
|
||||
* containing a #GFile for each selected file and subfolder in the
|
||||
* current folder. Free the returned list with g_slist_free(), and
|
||||
* the files with g_object_unref().
|
||||
**/
|
||||
GSList *
|
||||
* Lists all the selected files and subfolders in the current folder
|
||||
* of @chooser as #GFile.
|
||||
*
|
||||
* Returns: (transfer full): a list model containing a #GFile for each
|
||||
* selected file and subfolder in the current folder. Free the returned
|
||||
* list with g_object_unref().
|
||||
*/
|
||||
GListModel *
|
||||
gtk_file_chooser_get_files (GtkFileChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||
@@ -597,41 +527,19 @@ gtk_file_chooser_set_file (GtkFileChooser *chooser,
|
||||
GFile *
|
||||
gtk_file_chooser_get_file (GtkFileChooser *chooser)
|
||||
{
|
||||
GSList *list;
|
||||
GListModel *list;
|
||||
GFile *result = NULL;
|
||||
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||
|
||||
list = gtk_file_chooser_get_files (chooser);
|
||||
if (list)
|
||||
{
|
||||
result = list->data;
|
||||
list = g_slist_delete_link (list, list);
|
||||
|
||||
g_slist_free_full (list, g_object_unref);
|
||||
}
|
||||
if (g_list_model_get_n_items (list) > 0)
|
||||
result = g_list_model_get_item (list, 0);
|
||||
g_object_unref (list);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _gtk_file_chooser_get_file_system:
|
||||
* @chooser: a #GtkFileChooser
|
||||
*
|
||||
* Gets the #GtkFileSystem of @chooser; this is an internal
|
||||
* implementation detail, used for conversion between paths
|
||||
* and filenames and URIs.
|
||||
*
|
||||
* Returns: the file system for @chooser.
|
||||
**/
|
||||
GtkFileSystem *
|
||||
_gtk_file_chooser_get_file_system (GtkFileChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||
|
||||
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_file_system (chooser);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_chooser_add_shortcut_folder:
|
||||
* @chooser: a #GtkFileChooser
|
||||
|
||||
+61
-68
@@ -72,7 +72,8 @@ GType gtk_file_chooser_get_type (void) G_GNUC_CONST;
|
||||
* @GTK_FILE_CHOOSER_ERROR_BAD_FILENAME: Indicates a malformed filename.
|
||||
* @GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS: Indicates a duplicate path (e.g. when
|
||||
* adding a bookmark).
|
||||
* @GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME: Indicates an incomplete hostname (e.g. "http://foo" without a slash after that).
|
||||
* @GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME: Indicates an incomplete hostname
|
||||
* (e.g. "http://foo" without a slash after that).
|
||||
*
|
||||
* These identify the various errors that can occur while calling
|
||||
* #GtkFileChooser functions.
|
||||
@@ -87,108 +88,100 @@ typedef enum {
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GQuark gtk_file_chooser_error_quark (void);
|
||||
|
||||
/* Configuration
|
||||
*/
|
||||
/* Configuration */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_action (GtkFileChooser *chooser,
|
||||
GtkFileChooserAction action);
|
||||
GtkFileChooserAction action);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkFileChooserAction gtk_file_chooser_get_action (GtkFileChooser *chooser);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
|
||||
gboolean select_multiple);
|
||||
gboolean select_multiple);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_create_folders (GtkFileChooser *chooser,
|
||||
gboolean create_folders);
|
||||
gboolean create_folders);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser);
|
||||
gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser);
|
||||
|
||||
/* Suggested name for the Save-type actions
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
|
||||
const gchar *name);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gchar *gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
|
||||
/* Suggested name for the Save-type actions */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
|
||||
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
|
||||
const char *name);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_unselect_all (GtkFileChooser *chooser);
|
||||
char * gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
|
||||
|
||||
/* GFile manipulation */
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
|
||||
GFile *file);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GSList * gtk_file_chooser_get_files (GtkFileChooser *chooser);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
|
||||
|
||||
/* List of user selectable filters
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel *gtk_file_chooser_get_filters (GtkFileChooser *chooser);
|
||||
GListModel * gtk_file_chooser_get_files (GtkFileChooser *chooser);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
|
||||
|
||||
/* List of user selectable filters */
|
||||
|
||||
/* Current filter
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
|
||||
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_file_chooser_get_filters (GtkFileChooser *chooser);
|
||||
|
||||
/* Current filter */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkFileFilter * gtk_file_chooser_get_filter (GtkFileChooser *chooser);
|
||||
|
||||
/* Per-application shortcut folders */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
|
||||
GFile *folder,
|
||||
GError **error);
|
||||
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
|
||||
GFile *folder,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||
GFile *folder,
|
||||
GError **error);
|
||||
gboolean gtk_file_chooser_remove_shortcut_folder
|
||||
(GtkFileChooser *chooser,
|
||||
GFile *folder,
|
||||
GError **error);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel *gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
|
||||
GListModel * gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
|
||||
|
||||
/* Custom widgets */
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
|
||||
const char *id,
|
||||
const char *label,
|
||||
const char **options,
|
||||
const char **option_labels);
|
||||
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
|
||||
const char *id,
|
||||
const char *label,
|
||||
const char **options,
|
||||
const char **option_labels);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_remove_choice (GtkFileChooser *chooser,
|
||||
const char *id);
|
||||
void gtk_file_chooser_remove_choice (GtkFileChooser *chooser,
|
||||
const char *id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_file_chooser_set_choice (GtkFileChooser *chooser,
|
||||
const char *id,
|
||||
const char *option);
|
||||
void gtk_file_chooser_set_choice (GtkFileChooser *chooser,
|
||||
const char *id,
|
||||
const char *option);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char *gtk_file_chooser_get_choice (GtkFileChooser *chooser,
|
||||
const char *id);
|
||||
const char * gtk_file_chooser_get_choice (GtkFileChooser *chooser,
|
||||
const char *id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+790
-583
File diff suppressed because it is too large
Load Diff
+11
-43
@@ -25,8 +25,6 @@
|
||||
#include "gtkfilechooserwidget.h"
|
||||
#include "gtkfilechooserwidgetprivate.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooserembed.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkintl.h"
|
||||
@@ -265,12 +263,9 @@ static void gtk_file_chooser_dialog_size_allocate (GtkWidget *wid
|
||||
int width,
|
||||
int height,
|
||||
int baseline);
|
||||
static void file_chooser_widget_file_activated (GtkFileChooser *chooser,
|
||||
GtkFileChooserDialog *dialog);
|
||||
static void file_chooser_widget_response_requested (GtkWidget *widget,
|
||||
GtkFileChooserDialog *dialog);
|
||||
static void file_chooser_widget_selection_changed (GtkWidget *widget,
|
||||
GtkFileChooserDialog *dialog);
|
||||
static void gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameters);
|
||||
|
||||
static void response_cb (GtkDialog *dialog,
|
||||
gint response_id);
|
||||
@@ -310,9 +305,8 @@ gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserDialog, widget);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserDialog, buttons);
|
||||
gtk_widget_class_bind_template_callback (widget_class, response_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_file_activated);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_response_requested);
|
||||
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_selection_changed);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "response.activate", NULL, gtk_file_chooser_dialog_activate_response);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -367,38 +361,12 @@ is_accept_response_id (gint response_id)
|
||||
response_id == GTK_RESPONSE_APPLY);
|
||||
}
|
||||
|
||||
/* Callback used when the user activates a file in the file chooser widget */
|
||||
static void
|
||||
file_chooser_widget_file_activated (GtkFileChooser *chooser,
|
||||
GtkFileChooserDialog *dialog)
|
||||
{
|
||||
gtk_widget_activate_default (GTK_WIDGET (chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_widget_selection_changed (GtkWidget *widget,
|
||||
GtkFileChooserDialog *dialog)
|
||||
{
|
||||
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
|
||||
GtkWidget *button;
|
||||
GSList *files;
|
||||
gboolean sensitive;
|
||||
|
||||
button = get_accept_action_widget (GTK_DIALOG (dialog), FALSE);
|
||||
if (button == NULL)
|
||||
return;
|
||||
|
||||
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->widget));
|
||||
sensitive = (files != NULL);
|
||||
gtk_widget_set_sensitive (button, sensitive);
|
||||
|
||||
g_slist_free_full (files, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_widget_response_requested (GtkWidget *widget,
|
||||
GtkFileChooserDialog *dialog)
|
||||
gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameters)
|
||||
{
|
||||
GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
|
||||
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
|
||||
GtkWidget *button;
|
||||
|
||||
@@ -641,7 +609,7 @@ gtk_file_chooser_dialog_map (GtkWidget *widget)
|
||||
setup_save_entry (dialog);
|
||||
ensure_default_response (dialog);
|
||||
|
||||
_gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
|
||||
gtk_file_chooser_widget_initial_focus (GTK_FILE_CHOOSER_WIDGET (priv->widget));
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
|
||||
}
|
||||
@@ -705,7 +673,7 @@ response_cb (GtkDialog *dialog,
|
||||
/* Act only on response IDs we recognize */
|
||||
if (is_accept_response_id (response_id) &&
|
||||
!priv->response_requested &&
|
||||
!_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
|
||||
!gtk_file_chooser_widget_should_respond (GTK_FILE_CHOOSER_WIDGET (priv->widget)))
|
||||
{
|
||||
g_signal_stop_emission_by_name (dialog, "response");
|
||||
}
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkfilechooserembed.h: Abstract sizing interface for file selector implementations
|
||||
* Copyright (C) 2004, 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 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtkfilechooserembed.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
static void gtk_file_chooser_embed_class_init (gpointer g_iface);
|
||||
static gboolean delegate_should_respond (GtkFileChooserEmbed *chooser_embed);
|
||||
static void delegate_initial_focus (GtkFileChooserEmbed *chooser_embed);
|
||||
static void delegate_response_requested (GtkFileChooserEmbed *chooser_embed,
|
||||
gpointer data);
|
||||
|
||||
static GtkFileChooserEmbed *
|
||||
get_delegate (GtkFileChooserEmbed *receiver)
|
||||
{
|
||||
return g_object_get_data (G_OBJECT (receiver), "gtk-file-chooser-embed-delegate");
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_chooser_embed_delegate_iface_init:
|
||||
* @iface: a #GtkFileChoserEmbedIface structure
|
||||
*
|
||||
* An interface-initialization function for use in cases where an object is
|
||||
* simply delegating the methods, signals of the #GtkFileChooserEmbed interface
|
||||
* to another object. _gtk_file_chooser_embed_set_delegate() must be called on
|
||||
* each instance of the object so that the delegate object can be found.
|
||||
**/
|
||||
void
|
||||
_gtk_file_chooser_embed_delegate_iface_init (GtkFileChooserEmbedIface *iface)
|
||||
{
|
||||
iface->should_respond = delegate_should_respond;
|
||||
iface->initial_focus = delegate_initial_focus;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_chooser_embed_set_delegate:
|
||||
* @receiver: a GOobject implementing #GtkFileChooserEmbed
|
||||
* @delegate: another GObject implementing #GtkFileChooserEmbed
|
||||
*
|
||||
* Establishes that calls on @receiver for #GtkFileChooser methods should be
|
||||
* delegated to @delegate, and that #GtkFileChooser signals emitted on @delegate
|
||||
* should be forwarded to @receiver. Must be used in conjunction with
|
||||
* _gtk_file_chooser_embed_delegate_iface_init().
|
||||
**/
|
||||
void
|
||||
_gtk_file_chooser_embed_set_delegate (GtkFileChooserEmbed *receiver,
|
||||
GtkFileChooserEmbed *delegate)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (receiver));
|
||||
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (delegate));
|
||||
|
||||
g_object_set_data (G_OBJECT (receiver), I_("gtk-file-chooser-embed-delegate"), delegate);
|
||||
|
||||
g_signal_connect (delegate, "response-requested",
|
||||
G_CALLBACK (delegate_response_requested), receiver);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static gboolean
|
||||
delegate_should_respond (GtkFileChooserEmbed *chooser_embed)
|
||||
{
|
||||
return _gtk_file_chooser_embed_should_respond (get_delegate (chooser_embed));
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_initial_focus (GtkFileChooserEmbed *chooser_embed)
|
||||
{
|
||||
_gtk_file_chooser_embed_initial_focus (get_delegate (chooser_embed));
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_response_requested (GtkFileChooserEmbed *chooser_embed,
|
||||
gpointer data)
|
||||
{
|
||||
g_signal_emit_by_name (data, "response-requested");
|
||||
}
|
||||
|
||||
|
||||
/* publicly callable functions */
|
||||
|
||||
GType
|
||||
_gtk_file_chooser_embed_get_type (void)
|
||||
{
|
||||
static GType file_chooser_embed_type = 0;
|
||||
|
||||
if (!file_chooser_embed_type)
|
||||
{
|
||||
const GTypeInfo file_chooser_embed_info =
|
||||
{
|
||||
sizeof (GtkFileChooserEmbedIface), /* class_size */
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc)gtk_file_chooser_embed_class_init, /* class_init */
|
||||
};
|
||||
|
||||
file_chooser_embed_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
I_("GtkFileChooserEmbed"),
|
||||
&file_chooser_embed_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (file_chooser_embed_type, GTK_TYPE_WIDGET);
|
||||
}
|
||||
|
||||
return file_chooser_embed_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_chooser_embed_class_init (gpointer g_iface)
|
||||
{
|
||||
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
||||
|
||||
g_signal_new (I_("response-requested"),
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileChooserEmbedIface, response_requested),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed), FALSE);
|
||||
|
||||
return GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->should_respond (chooser_embed);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed));
|
||||
|
||||
GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->initial_focus (chooser_embed);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkfilechooserembed.h: Abstract sizing interface for file selector implementations
|
||||
* Copyright (C) 2004, 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 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_FILE_CHOOSER_EMBED_H__
|
||||
#define __GTK_FILE_CHOOSER_EMBED_H__
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_FILE_CHOOSER_EMBED (_gtk_file_chooser_embed_get_type ())
|
||||
#define GTK_FILE_CHOOSER_EMBED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER_EMBED, GtkFileChooserEmbed))
|
||||
#define GTK_IS_FILE_CHOOSER_EMBED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_CHOOSER_EMBED))
|
||||
#define GTK_FILE_CHOOSER_EMBED_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_FILE_CHOOSER_EMBED, GtkFileChooserEmbedIface))
|
||||
|
||||
typedef struct _GtkFileChooserEmbed GtkFileChooserEmbed;
|
||||
typedef struct _GtkFileChooserEmbedIface GtkFileChooserEmbedIface;
|
||||
|
||||
|
||||
struct _GtkFileChooserEmbedIface
|
||||
{
|
||||
GTypeInterface base_iface;
|
||||
|
||||
/* Methods
|
||||
*/
|
||||
gboolean (*should_respond) (GtkFileChooserEmbed *chooser_embed);
|
||||
|
||||
void (*initial_focus) (GtkFileChooserEmbed *chooser_embed);
|
||||
/* Signals
|
||||
*/
|
||||
void (*response_requested) (GtkFileChooserEmbed *chooser_embed);
|
||||
};
|
||||
|
||||
GType _gtk_file_chooser_embed_get_type (void) G_GNUC_CONST;
|
||||
|
||||
gboolean _gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed);
|
||||
|
||||
void _gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed);
|
||||
|
||||
void _gtk_file_chooser_embed_delegate_iface_init (GtkFileChooserEmbedIface *iface);
|
||||
void _gtk_file_chooser_embed_set_delegate (GtkFileChooserEmbed *receiver,
|
||||
GtkFileChooserEmbed *delegate);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_CHOOSER_EMBED_H__ */
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "gtkcelllayout.h"
|
||||
#include "gtkcellrenderertext.h"
|
||||
#include "gtkentryprivate.h"
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtksizerequest.h"
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#ifndef __GTK_FILE_CHOOSER_ENTRY_H__
|
||||
#define __GTK_FILE_CHOOSER_ENTRY_H__
|
||||
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtkfilechooser.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -148,7 +148,7 @@ void
|
||||
gtk_file_chooser_error_stack_set_custom_error (GtkFileChooserErrorStack *self,
|
||||
const char *label_text)
|
||||
{
|
||||
GtkWidget *label = gtk_stack_get_child_by_name (GTK_STACK (self->stack), "cutsom");
|
||||
GtkWidget *label = gtk_stack_get_child_by_name (GTK_STACK (self->stack), "custom");
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (label), label_text);
|
||||
|
||||
|
||||
+15
-26
@@ -28,8 +28,6 @@
|
||||
#include "gtkfilechooserwidget.h"
|
||||
#include "gtkfilechooserwidgetprivate.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooserembed.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkintl.h"
|
||||
@@ -158,21 +156,8 @@
|
||||
* possible to use with #GtkFileChooserNative, as such use would
|
||||
* prohibit the use of a native dialog.
|
||||
*
|
||||
* There is no support for the signals that are emitted when the user
|
||||
* navigates in the dialog, including:
|
||||
* * #GtkFileChooser::current-folder-changed
|
||||
* * #GtkFileChooser::selection-changed
|
||||
* * #GtkFileChooser::file-activated
|
||||
*
|
||||
* You can also not use the methods that directly control user navigation:
|
||||
* * gtk_file_chooser_unselect_filename()
|
||||
* * gtk_file_chooser_select_all()
|
||||
* * gtk_file_chooser_unselect_all()
|
||||
*
|
||||
* If you need any of the above you will have to use #GtkFileChooserDialog directly.
|
||||
*
|
||||
* No operations that change the dialog work while the dialog is visible. Set
|
||||
* all the properties that are required before showing the dialog.
|
||||
* No operations that change the dialog work while the dialog is visible.
|
||||
* Set all the properties that are required before showing the dialog.
|
||||
*
|
||||
* ## Win32 details ## {#gtkfilechooserdialognative-win32}
|
||||
*
|
||||
@@ -180,7 +165,7 @@
|
||||
* used. It supports many of the features that #GtkFileChooserDialog
|
||||
* does, but there are some things it does not handle:
|
||||
*
|
||||
* * Any #GtkFileFilter added using a mimetype or custom filter.
|
||||
* * Any #GtkFileFilter added using a mimetype
|
||||
*
|
||||
* If any of these features are used the regular #GtkFileChooserDialog
|
||||
* will be used in place of the native one.
|
||||
@@ -190,10 +175,7 @@
|
||||
* When the org.freedesktop.portal.FileChooser portal is available on the
|
||||
* session bus, it is used to bring up an out-of-process file chooser. Depending
|
||||
* on the kind of session the application is running in, this may or may not
|
||||
* be a GTK+ file chooser. In this situation, the following things are not
|
||||
* supported and will be silently ignored:
|
||||
*
|
||||
* * Any #GtkFileFilter added with a custom filter.
|
||||
* be a GTK file chooser.
|
||||
*
|
||||
* ## macOS details ## {#gtkfilechooserdialognative-macos}
|
||||
*
|
||||
@@ -201,8 +183,6 @@
|
||||
* file chooser dialogs. Some features provided by #GtkFileChooserDialog are
|
||||
* not supported:
|
||||
*
|
||||
* * Any #GtkFileFilter added with a custom filter.
|
||||
*
|
||||
* * Shortcut folders.
|
||||
*/
|
||||
|
||||
@@ -683,7 +663,7 @@ gtk_file_chooser_native_set_current_name (GtkFileChooser *chooser,
|
||||
g_clear_object (&self->current_file);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
static GListModel *
|
||||
gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
|
||||
{
|
||||
GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
|
||||
@@ -693,7 +673,16 @@ gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
|
||||
case MODE_PORTAL:
|
||||
case MODE_WIN32:
|
||||
case MODE_QUARTZ:
|
||||
return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);
|
||||
{
|
||||
GListStore *store;
|
||||
GSList *l;
|
||||
|
||||
store = g_list_store_new (G_TYPE_FILE);
|
||||
for (l = self->custom_files; l; l = l->next)
|
||||
g_list_store_append (store, l->data);
|
||||
|
||||
return G_LIST_MODEL (store);
|
||||
}
|
||||
|
||||
case MODE_FALLBACK:
|
||||
default:
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include "gtkfilechooserwidget.h"
|
||||
#include "gtkfilechooserwidgetprivate.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooserembed.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include "gtkfilechooserwidget.h"
|
||||
#include "gtkfilechooserwidgetprivate.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooserembed.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include "gtkfilechooserwidget.h"
|
||||
#include "gtkfilechooserwidgetprivate.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooserembed.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkintl.h"
|
||||
@@ -908,6 +906,7 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
|
||||
filechooser_win32_thread_data_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
g_object_unref (filter);
|
||||
}
|
||||
self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#define __GTK_FILE_CHOOSER_PRIVATE_H__
|
||||
|
||||
#include "gtkfilechooser.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkliststore.h"
|
||||
#include "gtkrecentmanager.h"
|
||||
@@ -72,8 +71,7 @@ struct _GtkFileChooserIface
|
||||
GFile *file);
|
||||
void (*select_all) (GtkFileChooser *chooser);
|
||||
void (*unselect_all) (GtkFileChooser *chooser);
|
||||
GSList * (*get_files) (GtkFileChooser *chooser);
|
||||
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
|
||||
GListModel * (*get_files) (GtkFileChooser *chooser);
|
||||
void (*add_filter) (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
void (*remove_filter) (GtkFileChooser *chooser,
|
||||
@@ -109,8 +107,13 @@ struct _GtkFileChooserIface
|
||||
const char *id);
|
||||
};
|
||||
|
||||
GtkFileSystem *_gtk_file_chooser_get_file_system (GtkFileChooser *chooser);
|
||||
|
||||
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
|
||||
void gtk_file_chooser_unselect_all (GtkFileChooser *chooser);
|
||||
gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser,
|
||||
GFile *file,
|
||||
GError **error);
|
||||
void gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
|
||||
GFile *file);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_CHOOSER_PRIVATE_H__ */
|
||||
|
||||
+75
-44
@@ -20,7 +20,6 @@
|
||||
#include "config.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilechooser.h"
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
@@ -39,8 +38,7 @@ static void delegate_unselect_file (GtkFileChooser *choose
|
||||
GFile *file);
|
||||
static void delegate_select_all (GtkFileChooser *chooser);
|
||||
static void delegate_unselect_all (GtkFileChooser *chooser);
|
||||
static GSList * delegate_get_files (GtkFileChooser *chooser);
|
||||
static GtkFileSystem *delegate_get_file_system (GtkFileChooser *chooser);
|
||||
static GListModel * delegate_get_files (GtkFileChooser *chooser);
|
||||
static void delegate_add_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter);
|
||||
static void delegate_remove_filter (GtkFileChooser *chooser,
|
||||
@@ -56,12 +54,6 @@ static GListModel * delegate_get_shortcut_folders (GtkFileChooser *choose
|
||||
static void delegate_notify (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
static void delegate_current_folder_changed (GtkFileChooser *chooser,
|
||||
gpointer data);
|
||||
static void delegate_selection_changed (GtkFileChooser *chooser,
|
||||
gpointer data);
|
||||
static void delegate_file_activated (GtkFileChooser *chooser,
|
||||
gpointer data);
|
||||
|
||||
static void delegate_add_choice (GtkFileChooser *chooser,
|
||||
const char *id,
|
||||
@@ -134,7 +126,6 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
|
||||
iface->select_all = delegate_select_all;
|
||||
iface->unselect_all = delegate_unselect_all;
|
||||
iface->get_files = delegate_get_files;
|
||||
iface->get_file_system = delegate_get_file_system;
|
||||
iface->add_filter = delegate_add_filter;
|
||||
iface->remove_filter = delegate_remove_filter;
|
||||
iface->get_filters = delegate_get_filters;
|
||||
@@ -168,12 +159,6 @@ _gtk_file_chooser_set_delegate (GtkFileChooser *receiver,
|
||||
g_object_set_data (G_OBJECT (receiver), I_("gtk-file-chooser-delegate"), delegate);
|
||||
g_signal_connect (delegate, "notify",
|
||||
G_CALLBACK (delegate_notify), receiver);
|
||||
g_signal_connect (delegate, "current-folder-changed",
|
||||
G_CALLBACK (delegate_current_folder_changed), receiver);
|
||||
g_signal_connect (delegate, "selection-changed",
|
||||
G_CALLBACK (delegate_selection_changed), receiver);
|
||||
g_signal_connect (delegate, "file-activated",
|
||||
G_CALLBACK (delegate_file_activated), receiver);
|
||||
}
|
||||
|
||||
GQuark
|
||||
@@ -221,18 +206,12 @@ delegate_unselect_all (GtkFileChooser *chooser)
|
||||
gtk_file_chooser_unselect_all (get_delegate (chooser));
|
||||
}
|
||||
|
||||
static GSList *
|
||||
static GListModel *
|
||||
delegate_get_files (GtkFileChooser *chooser)
|
||||
{
|
||||
return gtk_file_chooser_get_files (get_delegate (chooser));
|
||||
}
|
||||
|
||||
static GtkFileSystem *
|
||||
delegate_get_file_system (GtkFileChooser *chooser)
|
||||
{
|
||||
return _gtk_file_chooser_get_file_system (get_delegate (chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_add_filter (GtkFileChooser *chooser,
|
||||
GtkFileFilter *filter)
|
||||
@@ -315,27 +294,6 @@ delegate_notify (GObject *object,
|
||||
g_object_notify (data, pspec->name);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_selection_changed (GtkFileChooser *chooser,
|
||||
gpointer data)
|
||||
{
|
||||
g_signal_emit_by_name (data, "selection-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_current_folder_changed (GtkFileChooser *chooser,
|
||||
gpointer data)
|
||||
{
|
||||
g_signal_emit_by_name (data, "current-folder-changed");
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_file_activated (GtkFileChooser *chooser,
|
||||
gpointer data)
|
||||
{
|
||||
g_signal_emit_by_name (data, "file-activated");
|
||||
}
|
||||
|
||||
GSettings *
|
||||
_gtk_file_chooser_get_settings_for_widget (GtkWidget *widget)
|
||||
{
|
||||
@@ -444,3 +402,76 @@ delegate_get_choice (GtkFileChooser *chooser,
|
||||
{
|
||||
return gtk_file_chooser_get_choice (get_delegate (chooser), id);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_info_consider_as_directory (GFileInfo *info)
|
||||
{
|
||||
GFileType type = g_file_info_get_file_type (info);
|
||||
|
||||
return (type == G_FILE_TYPE_DIRECTORY ||
|
||||
type == G_FILE_TYPE_MOUNTABLE ||
|
||||
type == G_FILE_TYPE_SHORTCUT);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_has_native_path (GFile *file)
|
||||
{
|
||||
char *local_file_path;
|
||||
gboolean has_native_path;
|
||||
|
||||
/* Don't use g_file_is_native(), as we want to support FUSE paths if available */
|
||||
local_file_path = g_file_get_path (file);
|
||||
has_native_path = (local_file_path != NULL);
|
||||
g_free (local_file_path);
|
||||
|
||||
return has_native_path;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_consider_as_remote (GFile *file)
|
||||
{
|
||||
GFileInfo *info;
|
||||
gboolean is_remote;
|
||||
|
||||
info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, NULL, NULL);
|
||||
if (info)
|
||||
{
|
||||
is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE);
|
||||
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
is_remote = FALSE;
|
||||
|
||||
return is_remote;
|
||||
}
|
||||
|
||||
GIcon *
|
||||
_gtk_file_info_get_icon (GFileInfo *info,
|
||||
int icon_size,
|
||||
int scale)
|
||||
{
|
||||
GIcon *icon;
|
||||
GdkPixbuf *pixbuf;
|
||||
const gchar *thumbnail_path;
|
||||
|
||||
thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
|
||||
|
||||
if (thumbnail_path)
|
||||
{
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path,
|
||||
icon_size*scale, icon_size*scale,
|
||||
NULL);
|
||||
|
||||
if (pixbuf != NULL)
|
||||
return G_ICON (pixbuf);
|
||||
}
|
||||
|
||||
icon = g_file_info_get_icon (info);
|
||||
if (icon)
|
||||
return g_object_ref (icon);
|
||||
|
||||
/* Use general fallback for all files without icon */
|
||||
icon = g_themed_icon_new ("text-x-generic");
|
||||
return icon;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,13 @@ GSettings *_gtk_file_chooser_get_settings_for_widget (GtkWidget *widget);
|
||||
|
||||
gchar * _gtk_file_chooser_label_for_file (GFile *file);
|
||||
|
||||
gboolean _gtk_file_info_consider_as_directory (GFileInfo *info);
|
||||
gboolean _gtk_file_has_native_path (GFile *file);
|
||||
gboolean _gtk_file_consider_as_remote (GFile *file);
|
||||
GIcon * _gtk_file_info_get_icon (GFileInfo *info,
|
||||
int icon_size,
|
||||
int scale);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_CHOOSER_UTILS_H__ */
|
||||
|
||||
+260
-329
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,12 @@ void
|
||||
gtk_file_chooser_widget_set_save_entry (GtkFileChooserWidget *chooser,
|
||||
GtkWidget *entry);
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_widget_should_respond (GtkFileChooserWidget *chooser);
|
||||
|
||||
void
|
||||
gtk_file_chooser_widget_initial_focus (GtkFileChooserWidget *chooser);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_CHOOSER_WIDGET_PRIVATE_H__ */
|
||||
|
||||
@@ -1,823 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkfilesystem.c: Filesystem abstraction functions.
|
||||
* Copyright (C) 2003, Red Hat, Inc.
|
||||
* Copyright (C) 2007-2008 Carlos Garnacho
|
||||
*
|
||||
* 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 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* 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: Carlos Garnacho <carlos@imendio.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkfilesystem.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "gtkfilechooser.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
|
||||
/* #define DEBUG_MODE */
|
||||
#ifdef DEBUG_MODE
|
||||
#define DEBUG(x) g_debug (x);
|
||||
#else
|
||||
#define DEBUG(x)
|
||||
#endif
|
||||
|
||||
#define FILES_PER_QUERY 100
|
||||
|
||||
/* The pointers we return for a GtkFileSystemVolume are opaque tokens; they are
|
||||
* really pointers to GDrive, GVolume or GMount objects. We need an extra
|
||||
* token for the fake “File System” volume. So, we’ll return a pointer to
|
||||
* this particular string.
|
||||
*/
|
||||
static const gchar *root_volume_token = N_("File System");
|
||||
#define IS_ROOT_VOLUME(volume) ((gpointer) (volume) == (gpointer) root_volume_token)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_FILE,
|
||||
PROP_ENUMERATOR,
|
||||
PROP_ATTRIBUTES
|
||||
};
|
||||
|
||||
enum {
|
||||
VOLUMES_CHANGED,
|
||||
FS_LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
FILES_ADDED,
|
||||
FILES_REMOVED,
|
||||
FILES_CHANGED,
|
||||
FINISHED_LOADING,
|
||||
DELETED,
|
||||
FOLDER_LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint fs_signals [FS_LAST_SIGNAL] = { 0, };
|
||||
|
||||
typedef struct AsyncFuncData AsyncFuncData;
|
||||
|
||||
struct GtkFileSystemPrivate
|
||||
{
|
||||
GVolumeMonitor *volume_monitor;
|
||||
|
||||
/* This list contains elements that can be
|
||||
* of type GDrive, GVolume and GMount
|
||||
*/
|
||||
GSList *volumes;
|
||||
};
|
||||
|
||||
struct AsyncFuncData
|
||||
{
|
||||
GtkFileSystem *file_system;
|
||||
GFile *file;
|
||||
GCancellable *cancellable;
|
||||
|
||||
gpointer callback;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkFileSystem, _gtk_file_system, G_TYPE_OBJECT)
|
||||
|
||||
|
||||
/* GtkFileSystem methods */
|
||||
static void
|
||||
volumes_changed (GVolumeMonitor *volume_monitor,
|
||||
gpointer volume,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileSystem *file_system = user_data;
|
||||
|
||||
g_signal_emit (file_system, fs_signals[VOLUMES_CHANGED], 0, volume);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_dispose (GObject *object)
|
||||
{
|
||||
GtkFileSystem *file_system = GTK_FILE_SYSTEM (object);
|
||||
GtkFileSystemPrivate *priv = file_system->priv;
|
||||
|
||||
DEBUG ("dispose");
|
||||
|
||||
if (priv->volumes)
|
||||
{
|
||||
g_slist_free_full (priv->volumes, g_object_unref);
|
||||
priv->volumes = NULL;
|
||||
}
|
||||
|
||||
if (priv->volume_monitor)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->volume_monitor, volumes_changed, object);
|
||||
g_object_unref (priv->volume_monitor);
|
||||
priv->volume_monitor = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (_gtk_file_system_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_file_system_class_init (GtkFileSystemClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = gtk_file_system_dispose;
|
||||
|
||||
fs_signals[VOLUMES_CHANGED] =
|
||||
g_signal_new (I_("volumes-changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileSystemClass, volumes_changed),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mount_referenced_by_volume_activation_root (GList *volumes, GMount *mount)
|
||||
{
|
||||
GList *l;
|
||||
GFile *mount_root;
|
||||
gboolean ret;
|
||||
|
||||
ret = FALSE;
|
||||
|
||||
mount_root = g_mount_get_root (mount);
|
||||
|
||||
for (l = volumes; l != NULL; l = l->next)
|
||||
{
|
||||
GVolume *volume = G_VOLUME (l->data);
|
||||
GFile *volume_activation_root;
|
||||
|
||||
volume_activation_root = g_volume_get_activation_root (volume);
|
||||
if (volume_activation_root != NULL)
|
||||
{
|
||||
if (g_file_has_prefix (volume_activation_root, mount_root))
|
||||
{
|
||||
ret = TRUE;
|
||||
g_object_unref (volume_activation_root);
|
||||
break;
|
||||
}
|
||||
g_object_unref (volume_activation_root);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (mount_root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
get_volumes_list (GtkFileSystem *file_system)
|
||||
{
|
||||
GtkFileSystemPrivate *priv = file_system->priv;
|
||||
GList *l, *ll;
|
||||
GList *drives;
|
||||
GList *volumes;
|
||||
GList *mounts;
|
||||
GDrive *drive;
|
||||
GVolume *volume;
|
||||
GMount *mount;
|
||||
|
||||
if (priv->volumes)
|
||||
{
|
||||
g_slist_free_full (priv->volumes, g_object_unref);
|
||||
priv->volumes = NULL;
|
||||
}
|
||||
|
||||
/* first go through all connected drives */
|
||||
drives = g_volume_monitor_get_connected_drives (priv->volume_monitor);
|
||||
|
||||
for (l = drives; l != NULL; l = l->next)
|
||||
{
|
||||
drive = l->data;
|
||||
volumes = g_drive_get_volumes (drive);
|
||||
|
||||
if (volumes)
|
||||
{
|
||||
for (ll = volumes; ll != NULL; ll = ll->next)
|
||||
{
|
||||
volume = ll->data;
|
||||
mount = g_volume_get_mount (volume);
|
||||
|
||||
if (mount)
|
||||
{
|
||||
/* Show mounted volume */
|
||||
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
|
||||
g_object_unref (mount);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do show the unmounted volumes in the sidebar;
|
||||
* this is so the user can mount it (in case automounting
|
||||
* is off).
|
||||
*
|
||||
* Also, even if automounting is enabled, this gives a visual
|
||||
* cue that the user should remember to yank out the media if
|
||||
* he just unmounted it.
|
||||
*/
|
||||
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume));
|
||||
}
|
||||
|
||||
g_object_unref (volume);
|
||||
}
|
||||
|
||||
g_list_free (volumes);
|
||||
}
|
||||
else if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive))
|
||||
{
|
||||
/* If the drive has no mountable volumes and we cannot detect media change.. we
|
||||
* display the drive in the sidebar so the user can manually poll the drive by
|
||||
* right clicking and selecting "Rescan..."
|
||||
*
|
||||
* This is mainly for drives like floppies where media detection doesn't
|
||||
* work.. but it's also for human beings who like to turn off media detection
|
||||
* in the OS to save battery juice.
|
||||
*/
|
||||
|
||||
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (drive));
|
||||
}
|
||||
|
||||
g_object_unref (drive);
|
||||
}
|
||||
|
||||
g_list_free (drives);
|
||||
|
||||
/* add all volumes that is not associated with a drive */
|
||||
volumes = g_volume_monitor_get_volumes (priv->volume_monitor);
|
||||
|
||||
for (l = volumes; l != NULL; l = l->next)
|
||||
{
|
||||
volume = l->data;
|
||||
drive = g_volume_get_drive (volume);
|
||||
|
||||
if (drive)
|
||||
{
|
||||
g_object_unref (drive);
|
||||
continue;
|
||||
}
|
||||
|
||||
mount = g_volume_get_mount (volume);
|
||||
|
||||
if (mount)
|
||||
{
|
||||
/* show this mount */
|
||||
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
|
||||
g_object_unref (mount);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* see comment above in why we add an icon for a volume */
|
||||
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume));
|
||||
}
|
||||
|
||||
g_object_unref (volume);
|
||||
}
|
||||
|
||||
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
|
||||
mounts = g_volume_monitor_get_mounts (priv->volume_monitor);
|
||||
|
||||
for (l = mounts; l != NULL; l = l->next)
|
||||
{
|
||||
mount = l->data;
|
||||
volume = g_mount_get_volume (mount);
|
||||
|
||||
if (volume)
|
||||
{
|
||||
g_object_unref (volume);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if there's exists one or more volumes with an activation root inside the mount,
|
||||
* don't display the mount
|
||||
*/
|
||||
if (mount_referenced_by_volume_activation_root (volumes, mount))
|
||||
{
|
||||
g_object_unref (mount);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* show this mount */
|
||||
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
|
||||
g_object_unref (mount);
|
||||
}
|
||||
|
||||
g_list_free (volumes);
|
||||
|
||||
g_list_free (mounts);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_file_system_init (GtkFileSystem *file_system)
|
||||
{
|
||||
GtkFileSystemPrivate *priv;
|
||||
|
||||
DEBUG ("init");
|
||||
|
||||
file_system->priv = priv = _gtk_file_system_get_instance_private (file_system);
|
||||
|
||||
/* Volumes */
|
||||
priv->volume_monitor = g_volume_monitor_get ();
|
||||
|
||||
g_signal_connect (priv->volume_monitor, "mount-added",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "mount-removed",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "mount-changed",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "volume-added",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "volume-removed",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "volume-changed",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "drive-connected",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "drive-disconnected",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
g_signal_connect (priv->volume_monitor, "drive-changed",
|
||||
G_CALLBACK (volumes_changed), file_system);
|
||||
}
|
||||
|
||||
/* GtkFileSystem public methods */
|
||||
GtkFileSystem *
|
||||
_gtk_file_system_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_FILE_SYSTEM, NULL);
|
||||
}
|
||||
|
||||
GSList *
|
||||
_gtk_file_system_list_volumes (GtkFileSystem *file_system)
|
||||
{
|
||||
GtkFileSystemPrivate *priv = file_system->priv;
|
||||
GSList *list;
|
||||
|
||||
DEBUG ("list_volumes");
|
||||
|
||||
get_volumes_list (file_system);
|
||||
|
||||
list = g_slist_copy (priv->volumes);
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
/* Prepend root volume */
|
||||
list = g_slist_prepend (list, (gpointer) root_volume_token);
|
||||
#endif
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void
|
||||
free_async_data (AsyncFuncData *async_data)
|
||||
{
|
||||
g_object_unref (async_data->file_system);
|
||||
g_object_unref (async_data->file);
|
||||
g_object_unref (async_data->cancellable);
|
||||
|
||||
g_free (async_data);
|
||||
}
|
||||
|
||||
static void
|
||||
query_info_callback (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
AsyncFuncData *async_data;
|
||||
GError *error = NULL;
|
||||
GFileInfo *file_info;
|
||||
GFile *file;
|
||||
|
||||
DEBUG ("query_info_callback");
|
||||
|
||||
file = G_FILE (source_object);
|
||||
async_data = (AsyncFuncData *) user_data;
|
||||
file_info = g_file_query_info_finish (file, result, &error);
|
||||
|
||||
if (async_data->callback)
|
||||
{
|
||||
((GtkFileSystemGetInfoCallback) async_data->callback) (async_data->cancellable,
|
||||
file_info, error, async_data->data);
|
||||
}
|
||||
|
||||
if (file_info)
|
||||
g_object_unref (file_info);
|
||||
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
|
||||
free_async_data (async_data);
|
||||
}
|
||||
|
||||
GCancellable *
|
||||
_gtk_file_system_get_info (GtkFileSystem *file_system,
|
||||
GFile *file,
|
||||
const gchar *attributes,
|
||||
GtkFileSystemGetInfoCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
AsyncFuncData *async_data;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
async_data = g_new0 (AsyncFuncData, 1);
|
||||
async_data->file_system = g_object_ref (file_system);
|
||||
async_data->file = g_object_ref (file);
|
||||
async_data->cancellable = g_object_ref (cancellable);
|
||||
|
||||
async_data->callback = callback;
|
||||
async_data->data = data;
|
||||
|
||||
g_file_query_info_async (file,
|
||||
attributes,
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
query_info_callback,
|
||||
async_data);
|
||||
|
||||
return cancellable;
|
||||
}
|
||||
|
||||
static void
|
||||
drive_poll_for_media_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
AsyncFuncData *async_data;
|
||||
GError *error = NULL;
|
||||
|
||||
g_drive_poll_for_media_finish (G_DRIVE (source_object), result, &error);
|
||||
async_data = (AsyncFuncData *) user_data;
|
||||
|
||||
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable,
|
||||
(GtkFileSystemVolume *) source_object,
|
||||
error, async_data->data);
|
||||
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
static void
|
||||
volume_mount_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
AsyncFuncData *async_data;
|
||||
GError *error = NULL;
|
||||
|
||||
g_volume_mount_finish (G_VOLUME (source_object), result, &error);
|
||||
async_data = (AsyncFuncData *) user_data;
|
||||
|
||||
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable,
|
||||
(GtkFileSystemVolume *) source_object,
|
||||
error, async_data->data);
|
||||
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
GCancellable *
|
||||
_gtk_file_system_mount_volume (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GMountOperation *mount_operation,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
AsyncFuncData *async_data;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
DEBUG ("volume_mount");
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
async_data = g_new0 (AsyncFuncData, 1);
|
||||
async_data->file_system = g_object_ref (file_system);
|
||||
async_data->cancellable = g_object_ref (cancellable);
|
||||
|
||||
async_data->callback = callback;
|
||||
async_data->data = data;
|
||||
|
||||
if (G_IS_DRIVE (volume))
|
||||
{
|
||||
/* this path happens for drives that are not polled by the OS and where the last media
|
||||
* check indicated that no media was available. So the thing to do here is to
|
||||
* invoke poll_for_media() on the drive
|
||||
*/
|
||||
g_drive_poll_for_media (G_DRIVE (volume), cancellable, drive_poll_for_media_cb, async_data);
|
||||
handled = TRUE;
|
||||
}
|
||||
else if (G_IS_VOLUME (volume))
|
||||
{
|
||||
g_volume_mount (G_VOLUME (volume), G_MOUNT_MOUNT_NONE, mount_operation, cancellable, volume_mount_cb, async_data);
|
||||
handled = TRUE;
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
free_async_data (async_data);
|
||||
|
||||
return cancellable;
|
||||
}
|
||||
|
||||
static void
|
||||
enclosing_volume_mount_cb (GObject *source_object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileSystemVolume *volume;
|
||||
AsyncFuncData *async_data;
|
||||
GError *error = NULL;
|
||||
|
||||
async_data = (AsyncFuncData *) user_data;
|
||||
g_file_mount_enclosing_volume_finish (G_FILE (source_object), result, &error);
|
||||
volume = _gtk_file_system_get_volume_for_file (async_data->file_system, G_FILE (source_object));
|
||||
|
||||
/* Silently drop G_IO_ERROR_ALREADY_MOUNTED error for gvfs backends without visible mounts. */
|
||||
/* Better than doing query_info with additional I/O every time. */
|
||||
if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED))
|
||||
g_clear_error (&error);
|
||||
|
||||
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, volume,
|
||||
error, async_data->data);
|
||||
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
|
||||
_gtk_file_system_volume_unref (volume);
|
||||
}
|
||||
|
||||
GCancellable *
|
||||
_gtk_file_system_mount_enclosing_volume (GtkFileSystem *file_system,
|
||||
GFile *file,
|
||||
GMountOperation *mount_operation,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data)
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
AsyncFuncData *async_data;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
|
||||
g_return_val_if_fail (G_IS_FILE (file), NULL);
|
||||
|
||||
DEBUG ("mount_enclosing_volume");
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
async_data = g_new0 (AsyncFuncData, 1);
|
||||
async_data->file_system = g_object_ref (file_system);
|
||||
async_data->file = g_object_ref (file);
|
||||
async_data->cancellable = g_object_ref (cancellable);
|
||||
|
||||
async_data->callback = callback;
|
||||
async_data->data = data;
|
||||
|
||||
g_file_mount_enclosing_volume (file,
|
||||
G_MOUNT_MOUNT_NONE,
|
||||
mount_operation,
|
||||
cancellable,
|
||||
enclosing_volume_mount_cb,
|
||||
async_data);
|
||||
return cancellable;
|
||||
}
|
||||
|
||||
GtkFileSystemVolume *
|
||||
_gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
|
||||
GFile *file)
|
||||
{
|
||||
GMount *mount;
|
||||
|
||||
DEBUG ("get_volume_for_file");
|
||||
|
||||
mount = g_file_find_enclosing_mount (file, NULL, NULL);
|
||||
|
||||
if (!mount && g_file_is_native (file))
|
||||
return (GtkFileSystemVolume *) root_volume_token;
|
||||
|
||||
return (GtkFileSystemVolume *) mount;
|
||||
}
|
||||
|
||||
/* GtkFileSystemVolume public methods */
|
||||
gchar *
|
||||
_gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume)
|
||||
{
|
||||
DEBUG ("volume_get_display_name");
|
||||
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
return g_strdup (_(root_volume_token));
|
||||
if (G_IS_DRIVE (volume))
|
||||
return g_drive_get_name (G_DRIVE (volume));
|
||||
else if (G_IS_MOUNT (volume))
|
||||
return g_mount_get_name (G_MOUNT (volume));
|
||||
else if (G_IS_VOLUME (volume))
|
||||
return g_volume_get_name (G_VOLUME (volume));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume)
|
||||
{
|
||||
gboolean mounted;
|
||||
|
||||
DEBUG ("volume_is_mounted");
|
||||
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
return TRUE;
|
||||
|
||||
mounted = FALSE;
|
||||
|
||||
if (G_IS_MOUNT (volume))
|
||||
mounted = TRUE;
|
||||
else if (G_IS_VOLUME (volume))
|
||||
{
|
||||
GMount *mount;
|
||||
|
||||
mount = g_volume_get_mount (G_VOLUME (volume));
|
||||
|
||||
if (mount)
|
||||
{
|
||||
mounted = TRUE;
|
||||
g_object_unref (mount);
|
||||
}
|
||||
}
|
||||
|
||||
return mounted;
|
||||
}
|
||||
|
||||
GFile *
|
||||
_gtk_file_system_volume_get_root (GtkFileSystemVolume *volume)
|
||||
{
|
||||
GFile *file = NULL;
|
||||
|
||||
DEBUG ("volume_get_base");
|
||||
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
return g_file_new_for_uri ("file:///");
|
||||
|
||||
if (G_IS_MOUNT (volume))
|
||||
file = g_mount_get_root (G_MOUNT (volume));
|
||||
else if (G_IS_VOLUME (volume))
|
||||
{
|
||||
GMount *mount;
|
||||
|
||||
mount = g_volume_get_mount (G_VOLUME (volume));
|
||||
|
||||
if (mount)
|
||||
{
|
||||
file = g_mount_get_root (mount);
|
||||
g_object_unref (mount);
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
GIcon *
|
||||
_gtk_file_system_volume_get_icon (GtkFileSystemVolume *volume)
|
||||
{
|
||||
GIcon *icon = NULL;
|
||||
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
icon = g_themed_icon_new ("drive-harddisk");
|
||||
else if (G_IS_DRIVE (volume))
|
||||
icon = g_drive_get_icon (G_DRIVE (volume));
|
||||
else if (G_IS_VOLUME (volume))
|
||||
icon = g_volume_get_icon (G_VOLUME (volume));
|
||||
else if (G_IS_MOUNT (volume))
|
||||
icon = g_mount_get_icon (G_MOUNT (volume));
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
GIcon *
|
||||
_gtk_file_system_volume_get_symbolic_icon (GtkFileSystemVolume *volume)
|
||||
{
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
return g_themed_icon_new ("drive-harddisk-symbolic");
|
||||
else if (G_IS_DRIVE (volume))
|
||||
return g_drive_get_symbolic_icon (G_DRIVE (volume));
|
||||
else if (G_IS_VOLUME (volume))
|
||||
return g_volume_get_symbolic_icon (G_VOLUME (volume));
|
||||
else if (G_IS_MOUNT (volume))
|
||||
return g_mount_get_symbolic_icon (G_MOUNT (volume));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkFileSystemVolume *
|
||||
_gtk_file_system_volume_ref (GtkFileSystemVolume *volume)
|
||||
{
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
return volume;
|
||||
|
||||
if (G_IS_MOUNT (volume) ||
|
||||
G_IS_VOLUME (volume) ||
|
||||
G_IS_DRIVE (volume))
|
||||
g_object_ref (volume);
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_file_system_volume_unref (GtkFileSystemVolume *volume)
|
||||
{
|
||||
/* Root volume doesn't need to be freed */
|
||||
if (IS_ROOT_VOLUME (volume))
|
||||
return;
|
||||
|
||||
if (G_IS_MOUNT (volume) ||
|
||||
G_IS_VOLUME (volume) ||
|
||||
G_IS_DRIVE (volume))
|
||||
g_object_unref (volume);
|
||||
}
|
||||
|
||||
/* GFileInfo helper functions */
|
||||
GIcon *
|
||||
_gtk_file_info_get_icon (GFileInfo *info,
|
||||
int icon_size,
|
||||
int scale)
|
||||
{
|
||||
GIcon *icon;
|
||||
GdkPixbuf *pixbuf;
|
||||
const gchar *thumbnail_path;
|
||||
|
||||
thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
|
||||
|
||||
if (thumbnail_path)
|
||||
{
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path,
|
||||
icon_size*scale, icon_size*scale,
|
||||
NULL);
|
||||
|
||||
if (pixbuf != NULL)
|
||||
return G_ICON (pixbuf);
|
||||
}
|
||||
|
||||
icon = g_file_info_get_icon (info);
|
||||
if (icon)
|
||||
return g_object_ref (icon);
|
||||
|
||||
/* Use general fallback for all files without icon */
|
||||
icon = g_themed_icon_new ("text-x-generic");
|
||||
return icon;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_info_consider_as_directory (GFileInfo *info)
|
||||
{
|
||||
GFileType type = g_file_info_get_file_type (info);
|
||||
|
||||
return (type == G_FILE_TYPE_DIRECTORY ||
|
||||
type == G_FILE_TYPE_MOUNTABLE ||
|
||||
type == G_FILE_TYPE_SHORTCUT);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_has_native_path (GFile *file)
|
||||
{
|
||||
char *local_file_path;
|
||||
gboolean has_native_path;
|
||||
|
||||
/* Don't use g_file_is_native(), as we want to support FUSE paths if available */
|
||||
local_file_path = g_file_get_path (file);
|
||||
has_native_path = (local_file_path != NULL);
|
||||
g_free (local_file_path);
|
||||
|
||||
return has_native_path;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_file_consider_as_remote (GFile *file)
|
||||
{
|
||||
GFileInfo *info;
|
||||
gboolean is_remote;
|
||||
|
||||
info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, NULL, NULL);
|
||||
if (info)
|
||||
{
|
||||
is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE);
|
||||
|
||||
g_object_unref (info);
|
||||
}
|
||||
else
|
||||
is_remote = FALSE;
|
||||
|
||||
return is_remote;
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkfilesystem.h: Filesystem abstraction functions.
|
||||
* Copyright (C) 2003, 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 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
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_FILE_SYSTEM_H__
|
||||
#define __GTK_FILE_SYSTEM_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtkwidget.h> /* For icon handling */
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_FILE_SYSTEM (_gtk_file_system_get_type ())
|
||||
#define GTK_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystem))
|
||||
#define GTK_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_FILE_SYSTEM, GtkFileSystemClass))
|
||||
#define GTK_IS_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_FILE_SYSTEM))
|
||||
#define GTK_IS_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GTK_TYPE_FILE_SYSTEM))
|
||||
#define GTK_FILE_SYSTEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystemClass))
|
||||
|
||||
typedef struct GtkFileSystem GtkFileSystem;
|
||||
typedef struct GtkFileSystemPrivate GtkFileSystemPrivate;
|
||||
typedef struct GtkFileSystemClass GtkFileSystemClass;
|
||||
|
||||
|
||||
typedef struct GtkFileSystemVolume GtkFileSystemVolume; /* opaque struct */
|
||||
|
||||
|
||||
struct GtkFileSystem
|
||||
{
|
||||
GObject parent_object;
|
||||
|
||||
GtkFileSystemPrivate *priv;
|
||||
};
|
||||
|
||||
struct GtkFileSystemClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*volumes_changed) (GtkFileSystem *file_system);
|
||||
};
|
||||
|
||||
|
||||
typedef void (* GtkFileSystemGetInfoCallback) (GCancellable *cancellable,
|
||||
GFileInfo *file_info,
|
||||
const GError *error,
|
||||
gpointer data);
|
||||
typedef void (* GtkFileSystemVolumeMountCallback) (GCancellable *cancellable,
|
||||
GtkFileSystemVolume *volume,
|
||||
const GError *error,
|
||||
gpointer data);
|
||||
|
||||
/* GtkFileSystem methods */
|
||||
GType _gtk_file_system_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkFileSystem * _gtk_file_system_new (void);
|
||||
|
||||
GSList * _gtk_file_system_list_volumes (GtkFileSystem *file_system);
|
||||
|
||||
GCancellable * _gtk_file_system_get_info (GtkFileSystem *file_system,
|
||||
GFile *file,
|
||||
const gchar *attributes,
|
||||
GtkFileSystemGetInfoCallback callback,
|
||||
gpointer data);
|
||||
GCancellable * _gtk_file_system_mount_volume (GtkFileSystem *file_system,
|
||||
GtkFileSystemVolume *volume,
|
||||
GMountOperation *mount_operation,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data);
|
||||
GCancellable * _gtk_file_system_mount_enclosing_volume (GtkFileSystem *file_system,
|
||||
GFile *file,
|
||||
GMountOperation *mount_operation,
|
||||
GtkFileSystemVolumeMountCallback callback,
|
||||
gpointer data);
|
||||
|
||||
GtkFileSystemVolume * _gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
|
||||
GFile *file);
|
||||
|
||||
/* GtkFileSystemVolume methods */
|
||||
gchar * _gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume);
|
||||
gboolean _gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume);
|
||||
GFile * _gtk_file_system_volume_get_root (GtkFileSystemVolume *volume);
|
||||
GIcon * _gtk_file_system_volume_get_symbolic_icon (GtkFileSystemVolume *volume);
|
||||
GIcon * _gtk_file_system_volume_get_icon (GtkFileSystemVolume *volume);
|
||||
|
||||
GtkFileSystemVolume *_gtk_file_system_volume_ref (GtkFileSystemVolume *volume);
|
||||
void _gtk_file_system_volume_unref (GtkFileSystemVolume *volume);
|
||||
|
||||
/* GFileInfo helper functions */
|
||||
GIcon * _gtk_file_info_get_icon (GFileInfo *info,
|
||||
int icon_size,
|
||||
int scale);
|
||||
|
||||
gboolean _gtk_file_info_consider_as_directory (GFileInfo *info);
|
||||
|
||||
/* GFile helper functions */
|
||||
gboolean _gtk_file_has_native_path (GFile *file);
|
||||
|
||||
gboolean _gtk_file_consider_as_remote (GFile *file);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_SYSTEM_H__ */
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtktreedatalist.h"
|
||||
|
||||
+13
-12
@@ -30,20 +30,21 @@
|
||||
* @Short_description: Filtering items
|
||||
* @See_also: #GtkFilerListModel
|
||||
*
|
||||
* #GtkFilter is the way to describe filters to be used in #GtkFilterListModel.
|
||||
*
|
||||
* The model will use a filter to determine if it should filter items or not
|
||||
* by calling gtk_filter_match() for each item and only keeping the ones
|
||||
* visible that the function returns %TRUE for.
|
||||
* A #GtkFilter object describes the filtering to be performed by a
|
||||
* #GtkFilterListModel.
|
||||
*
|
||||
* The model will use the filter to determine if it should include items
|
||||
* or not by calling gtk_filter_match() for each item and only keeping the
|
||||
* ones that the function returns %TRUE for.
|
||||
*
|
||||
* Filters may change what items they match through their lifetime. In that
|
||||
* case, they can call gtk_filter_changed() which will emit the #GtkFilter:changed
|
||||
* signal to notify that previous filter results are no longer valid and that
|
||||
* items should be checked via gtk_filter_match() again.
|
||||
* case, they will emit the #GtkFilter:changed signal to notify that previous
|
||||
* filter results are no longer valid and that items should be checked again
|
||||
* via gtk_filter_match().
|
||||
*
|
||||
* GTK provides various premade filter implementations for common filtering
|
||||
* GTK provides various pre-made filter implementations for common filtering
|
||||
* operations. These filters often include properties that can be linked to
|
||||
* various widgets to easily allow searches.
|
||||
* various widgets to easily allow searches.
|
||||
*
|
||||
* However, in particular for large lists or complex search methods, it is
|
||||
* also possible to subclass #GtkFilter and provide one's own filter.
|
||||
@@ -118,7 +119,7 @@ gtk_filter_init (GtkFilter *self)
|
||||
* @self: a #GtkFilter
|
||||
* @item: (type GObject) (transfer none): The item to check
|
||||
*
|
||||
* Checks if the given @item is matched by the filter or not.
|
||||
* Checks if the given @item is matched by the filter or not.
|
||||
*
|
||||
* Returns: %TRUE if the filter matches the item and a filter model should
|
||||
* keep it, %FALSE if not.
|
||||
@@ -140,7 +141,7 @@ gtk_filter_match (GtkFilter *self,
|
||||
* Gets the known strictness of @filters. If the strictness is not known,
|
||||
* %GTK_FILTER_MATCH_SOME is returned.
|
||||
*
|
||||
* This value may change after emission of the GtkFilter:changed signal.
|
||||
* This value may change after emission of the #GtkFilter:changed signal.
|
||||
*
|
||||
* This function is meant purely for optimization purposes, filters can
|
||||
* choose to omit implementing it, but #GtkFilterListModel uses it.
|
||||
|
||||
@@ -178,7 +178,7 @@ gtk_filter_list_model_run_filter (GtkFilterListModel *self,
|
||||
}
|
||||
|
||||
if (more)
|
||||
gtk_bitset_remove_range_closed (self->pending, 0, pos);
|
||||
gtk_bitset_remove_range_closed (self->pending, 0, pos - 1);
|
||||
else
|
||||
g_clear_pointer (&self->pending, gtk_bitset_unref);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||
@@ -494,7 +494,7 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
G_GNUC_FALLTHROUGH;
|
||||
/* fall thru */
|
||||
case GTK_FILTER_CHANGE_DIFFERENT:
|
||||
self->matches = gtk_bitset_new_empty ();
|
||||
pending = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||
@@ -575,7 +575,7 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
|
||||
properties[PROP_INCREMENTAL] =
|
||||
g_param_spec_boolean ("incremental",
|
||||
P_("Incremental"),
|
||||
P_("Filer items incrementally"),
|
||||
P_("Filter items incrementally"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
@@ -771,8 +771,8 @@ gtk_filter_list_model_get_model (GtkFilterListModel *self)
|
||||
* @self: a #GtkFilterListModel
|
||||
* @incremental: %TRUE to enable incremental filtering
|
||||
*
|
||||
* When incremental filtering is enabled, the filterlistmodel will not run
|
||||
* filters immediately, but will instead queue an idle handler that
|
||||
* When incremental filtering is enabled, the GtkFilterListModel will not
|
||||
* run filters immediately, but will instead queue an idle handler that
|
||||
* incrementally filters the items and adds them to the list. This of course
|
||||
* means that items are not instantly added to the list, but only appear
|
||||
* incrementally.
|
||||
@@ -837,8 +837,14 @@ gtk_filter_list_model_get_incremental (GtkFilterListModel *self)
|
||||
*
|
||||
* You can use this value to check if @self is busy filtering by
|
||||
* comparing the return value to 0 or you can compute the percentage
|
||||
* of the filter remaining by dividing the return value by
|
||||
* g_list_model_get_n_items(gtk_filter_list_model_get_model (self)).
|
||||
* of the filter remaining by dividing the return value by the total
|
||||
* number of items in the underlying model:
|
||||
*
|
||||
* |[
|
||||
* pending = gtk_filter_list_model_get_pending (self);
|
||||
* model = gtk_filter_list_model_get_model (self);
|
||||
* percentage = pending / (double) g_list_model_get_n_items (model);
|
||||
* ]|
|
||||
*
|
||||
* Returns: The number of items not yet filtered
|
||||
**/
|
||||
|
||||
@@ -300,7 +300,7 @@ gtk_flatten_list_model_add_items (GtkFlattenListModel *self,
|
||||
G_CALLBACK (gtk_flatten_list_model_items_changed_cb),
|
||||
node);
|
||||
node->list = self;
|
||||
added +=g_list_model_get_n_items (node->model);
|
||||
added += g_list_model_get_n_items (node->model);
|
||||
}
|
||||
|
||||
return added;
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@
|
||||
/**
|
||||
* SECTION:gtkgridview
|
||||
* @title: GtkGridView
|
||||
* @short_description: A widget for displaying lists in a grid
|
||||
* @short_description: A widget for displaying grids
|
||||
* @see_also: #GListModel, #GtkListView, #GtkColumnView
|
||||
*
|
||||
* GtkGridView is a widget to present a view into a large dynamic grid of items.
|
||||
|
||||
+12
-12
@@ -55,13 +55,13 @@
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE char *
|
||||
#define GTK_VECTOR_NULL_TERMINATED 1
|
||||
#define GTK_VECTOR_FREE_FUNC g_free
|
||||
#define GTK_VECTOR_TYPE_NAME GtkStrvBuilder
|
||||
#define GTK_VECTOR_NAME gtk_strv_builder
|
||||
#define GTK_VECTOR_PREALLOC 16
|
||||
#include "gtkvectorimpl.c"
|
||||
#define GDK_ARRAY_ELEMENT_TYPE char *
|
||||
#define GDK_ARRAY_NULL_TERMINATED 1
|
||||
#define GDK_ARRAY_FREE_FUNC g_free
|
||||
#define GDK_ARRAY_TYPE_NAME GtkStrvBuilder
|
||||
#define GDK_ARRAY_NAME gtk_strv_builder
|
||||
#define GDK_ARRAY_PREALLOC 16
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
/**
|
||||
* SECTION:gtkicontheme
|
||||
@@ -3858,11 +3858,11 @@ gtk_icon_paintable_ensure_texture (GtkIconPaintable *self)
|
||||
|
||||
static void
|
||||
init_color_matrix (graphene_matrix_t *color_matrix,
|
||||
graphene_vec4_t *color_offset,
|
||||
const GdkRGBA *foreground_color,
|
||||
const GdkRGBA *success_color,
|
||||
const GdkRGBA *warning_color,
|
||||
const GdkRGBA *error_color)
|
||||
graphene_vec4_t *color_offset,
|
||||
const GdkRGBA *foreground_color,
|
||||
const GdkRGBA *success_color,
|
||||
const GdkRGBA *warning_color,
|
||||
const GdkRGBA *error_color)
|
||||
{
|
||||
GdkRGBA fg_default = { 0.7450980392156863, 0.7450980392156863, 0.7450980392156863, 1.0};
|
||||
GdkRGBA success_default = { 0.3046921492332342,0.6015716792553597, 0.023437857633325704, 1.0};
|
||||
|
||||
+13
-2
@@ -725,6 +725,8 @@ static const GtkBuildableParser offset_parser =
|
||||
offset_start_element
|
||||
};
|
||||
|
||||
static GtkBuildableIface *parent_buildable_iface;
|
||||
|
||||
static gboolean
|
||||
gtk_level_bar_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
GtkBuilder *builder,
|
||||
@@ -735,6 +737,10 @@ gtk_level_bar_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||
{
|
||||
OffsetsParserData *data;
|
||||
|
||||
if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
|
||||
tagname, parser, parser_data))
|
||||
return TRUE;
|
||||
|
||||
if (child)
|
||||
return FALSE;
|
||||
|
||||
@@ -767,7 +773,11 @@ gtk_level_bar_buildable_custom_finished (GtkBuildable *buildable,
|
||||
self = data->self;
|
||||
|
||||
if (strcmp (tagname, "offsets") != 0)
|
||||
goto out;
|
||||
{
|
||||
parent_buildable_iface->custom_finished (buildable, builder, child,
|
||||
tagname, user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
for (l = data->offsets; l != NULL; l = l->next)
|
||||
{
|
||||
@@ -775,7 +785,6 @@ gtk_level_bar_buildable_custom_finished (GtkBuildable *buildable,
|
||||
gtk_level_bar_add_offset_value (self, offset->name, offset->value);
|
||||
}
|
||||
|
||||
out:
|
||||
g_list_free_full (data->offsets, (GDestroyNotify) gtk_level_bar_offset_free);
|
||||
g_slice_free (OffsetsParserData, data);
|
||||
}
|
||||
@@ -783,6 +792,8 @@ gtk_level_bar_buildable_custom_finished (GtkBuildable *buildable,
|
||||
static void
|
||||
gtk_level_bar_buildable_init (GtkBuildableIface *iface)
|
||||
{
|
||||
parent_buildable_iface = g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->custom_tag_start = gtk_level_bar_buildable_custom_tag_start;
|
||||
iface->custom_finished = gtk_level_bar_buildable_custom_finished;
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
/**
|
||||
* SECTION:gtklistitem
|
||||
* @title: GtkListItem
|
||||
* @short_description: Object used to represent items of a ListModel
|
||||
* @short_description: Object used to represent items of a list model
|
||||
* @see_also: #GtkListView, #GListModel
|
||||
*
|
||||
* #GtkListItem is the object that list-handling containers such
|
||||
|
||||
@@ -577,13 +577,11 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model,
|
||||
GtkListItemManager *self)
|
||||
{
|
||||
GHashTable *change;
|
||||
GHashTableIter iter;
|
||||
gpointer list_item;
|
||||
GSList *l;
|
||||
guint n_items;
|
||||
|
||||
n_items = g_list_model_get_n_items (G_LIST_MODEL (self->model));
|
||||
change = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
change = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify )gtk_widget_unparent);
|
||||
|
||||
gtk_list_item_manager_remove_items (self, change, position, removed);
|
||||
gtk_list_item_manager_add_items (self, position, added);
|
||||
@@ -727,12 +725,6 @@ gtk_list_item_manager_model_items_changed_cb (GListModel *model,
|
||||
tracker->widget = GTK_LIST_ITEM_WIDGET (item->widget);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, change);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &list_item))
|
||||
{
|
||||
gtk_list_item_manager_release_list_item (self, NULL, list_item);
|
||||
}
|
||||
|
||||
g_hash_table_unref (change);
|
||||
|
||||
gtk_widget_queue_resize (self->widget);
|
||||
@@ -1073,10 +1065,12 @@ gtk_list_item_manager_release_list_item (GtkListItemManager *self,
|
||||
|
||||
if (change != NULL)
|
||||
{
|
||||
if (g_hash_table_insert (change, gtk_list_item_widget_get_item (GTK_LIST_ITEM_WIDGET (item)), item))
|
||||
return;
|
||||
|
||||
g_warning ("FIXME: Handle the same item multiple times in the list.\nLars says this totally should not happen, but here we are.");
|
||||
if (!g_hash_table_replace (change, gtk_list_item_widget_get_item (GTK_LIST_ITEM_WIDGET (item)), item))
|
||||
{
|
||||
g_warning ("FIXME: Handle the same item multiple times in the list.\nLars says this totally should not happen, but here we are.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_widget_unparent (item);
|
||||
|
||||
+6
-7
@@ -137,12 +137,12 @@
|
||||
#include "a11y/gtkaccessibility.h"
|
||||
#include "inspector/window.h"
|
||||
|
||||
#define GTK_VECTOR_ELEMENT_TYPE GtkWidget *
|
||||
#define GTK_VECTOR_TYPE_NAME GtkWidgetStack
|
||||
#define GTK_VECTOR_NAME gtk_widget_stack
|
||||
#define GTK_VECTOR_FREE_FUNC g_object_unref
|
||||
#define GTK_VECTOR_PREALLOC 16
|
||||
#include "gtkvectorimpl.c"
|
||||
#define GDK_ARRAY_ELEMENT_TYPE GtkWidget *
|
||||
#define GDK_ARRAY_TYPE_NAME GtkWidgetStack
|
||||
#define GDK_ARRAY_NAME gtk_widget_stack
|
||||
#define GDK_ARRAY_FREE_FUNC g_object_unref
|
||||
#define GDK_ARRAY_PREALLOC 16
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
static GtkWindowGroup *gtk_main_get_window_group (GtkWidget *widget);
|
||||
|
||||
@@ -181,7 +181,6 @@ static const GdkDebugKey gtk_debug_keys[] = {
|
||||
{ "no-css-cache", GTK_DEBUG_NO_CSS_CACHE, "Disable style property cache" },
|
||||
{ "interactive", GTK_DEBUG_INTERACTIVE, "Enable the GTK inspector" },
|
||||
{ "touchscreen", GTK_DEBUG_TOUCHSCREEN, "Pretend the pointer is a touchscreen" },
|
||||
{ "resize", GTK_DEBUG_RESIZE, "Highlight resizing widgets" },
|
||||
{ "layout", GTK_DEBUG_LAYOUT, "Show layout borders" },
|
||||
{ "snapshot", GTK_DEBUG_SNAPSHOT, "Generate debug render nodes" },
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user