Compare commits

..

21 Commits

Author SHA1 Message Date
Matthias Clasen 8815e1bb0c Add another incremental sort model
This one uses a very simple iterative mergesort.
2020-07-08 01:59:52 -04:00
Benjamin Otte a57e0a4bf6 Add a 4th sortmodel implementation
This one tracks the original positions on top of just the items so that
it can remove items.

It now takes twice as much memory but removes half of a million items in
50ms.
2020-07-08 04:46:55 +02:00
Matthias Clasen b74b0edf0d wip: incremental sort 2020-07-08 04:32:42 +02:00
Benjamin Otte 36fac37cda testsuite: Add some sorting performance tests 2020-07-08 04:12:33 +02:00
Benjamin Otte 91e2661306 stringlist: Convert to array
Stringlists are usually built and then never modified, and accessing
items through an array is faster.
2020-07-08 04:12:33 +02:00
Benjamin Otte 559ea908de gtk: Add a 2nd sortmodel implementation
This is the dumbest possible sortmodel using an array:
Just grab all the items, put them in the array, qsort() the array.
2020-07-08 04:12:33 +02:00
Benjamin Otte f0b146d7c8 demo: Add faster sorters
This is just the existing sorters, but without the overhead of GObject
properties.
2020-07-08 00:44:40 +02:00
Benjamin Otte a030197974 sorter: Remove a return_if_fail()
It's too expsensive.
2020-07-08 00:44:40 +02:00
Benjamin Otte bf2bf948ab xxx: vector_set_size 2020-07-08 00:44:40 +02:00
Benjamin Otte 5cb49363fa sortlistmodel: Remove forgotten G_PARAM_CONSTRUCT_ONLY 2020-07-08 00:44:40 +02:00
Benjamin Otte 802c99d4b4 testsuite: Add some vector performance tests
They're not very conclusive though, because the testing isn't
fine-grained enough for these microbenchmarks.
2020-07-07 02:23:09 +02:00
Benjamin Otte 173534710a snapshot: Use GtkVector for the state stack 2020-07-07 02:23:09 +02:00
Benjamin Otte 347959a112 vector: Add a bunch of new features
* GTK_VECTOR_BY_VALUE
   #define this to get GArrray-like behavior
 * gtk_vector_splice (v, 0, 0, NULL, 25)
   Adding items but passing NULL as the items will zero() them.
 * gtk_vector_set_size()
   A nicer way to call gtk_vector_splice()
2020-07-07 02:23:09 +02:00
Benjamin Otte 1ae939cf5a icontheme: Use GtkVector 2020-07-07 02:23:09 +02:00
Benjamin Otte edf523fe30 vector: Add null-termination 2020-07-07 02:23:09 +02:00
Benjamin Otte bfe2970a98 snapshot: Port node list to vector 2020-07-07 02:23:09 +02:00
Benjamin Otte c7749b9098 snapshot: Move structs into .c file
They aren't used anywhere else.
2020-07-07 02:23:09 +02:00
Benjamin Otte 2226fe0fca Remove preallocated array code
Now with GtkVector, we can use that one instead.
2020-07-07 02:23:09 +02:00
Benjamin Otte cbf9375f97 main: Use a GtkVector 2020-07-07 02:23:09 +02:00
Benjamin Otte 5297eb36b9 cssselector: Use GtkVector 2020-07-07 02:23:09 +02:00
Benjamin Otte b69e7777cd Add GtkVector
This is a scary idea where you #define a bunch of preprocessor values
and then #include "gtkvectorimpl.c" and end up with a dynamic array for
that data type.
2020-07-07 02:23:09 +02:00
227 changed files with 13365 additions and 11781 deletions
+2 -18
View File
@@ -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: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v20"
MESON_TEST_TIMEOUT_MULTIPLIER: 2
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v17"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
@@ -180,22 +180,6 @@ 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
View File
-9
View File
@@ -35,13 +35,4 @@ 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
-2
View File
@@ -41,14 +41,12 @@ 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 -1
View File
@@ -1,4 +1,4 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v20
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
-6
View File
@@ -7,14 +7,10 @@ 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 \
@@ -34,7 +30,6 @@ case "${backend}" in
export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -53,7 +48,6 @@ case "${backend}" in
export BROADWAY_DISPLAY=:5
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
-77
View File
@@ -1,80 +1,3 @@
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
=================================
+31 -45
View File
@@ -1,38 +1,29 @@
{
"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",
@@ -48,18 +39,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"
}
]
},
@@ -67,7 +58,7 @@
"name" : "libsass",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -82,7 +73,7 @@
"name" : "sassc",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -94,23 +85,18 @@
]
},
{
"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" : "''"
}
}
]
}
+3 -15
View File
@@ -15,13 +15,7 @@ if 'DESTDIR' not in os.environ:
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings 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,
subprocess.call(['glib-compile-schemas',
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
print('Updating icon cache...')
@@ -30,14 +24,8 @@ if 'DESTDIR' not in os.environ:
print('Updating module cache for print backends...')
os.makedirs(gtk_printmodule_dir, exist_ok=True)
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])
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])
+12 -78
View File
@@ -597,83 +597,6 @@ 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 *
@@ -747,7 +670,18 @@ do_dnd (GtkWidget *do_widget)
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box3);
for (i = 0; colors[i]; i++)
gtk_box_append (GTK_BOX (box3), color_swatch_new (colors[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), css_button_new ("rainbow1"));
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
+64 -5
View File
@@ -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_sort_list_model_new (gtk_color_list_new (0), NULL));
model = G_LIST_MODEL (gtk_sor5_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,6 +835,54 @@ 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 *
@@ -950,8 +998,7 @@ do_listview_colors (GtkWidget *do_widget)
g_object_unref (selection_filter);
g_object_unref (no_selection);
model = gtk_multi_selection_get_model (GTK_MULTI_SELECTION (model));
g_object_ref (model);
g_object_get (model, "model", &model, NULL);
selection_info_toggle = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (selection_info_toggle), "emblem-important-symbolic");
@@ -965,7 +1012,7 @@ do_listview_colors (GtkWidget *do_widget)
button = gtk_button_new_with_mnemonic ("_Refill");
g_signal_connect (button, "clicked",
G_CALLBACK (refill),
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
gtk_sor5_list_model_get_model (GTK_SOR5_LIST_MODEL (model)));
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
@@ -988,7 +1035,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_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
gtk_sor5_list_model_get_model (GTK_SOR5_LIST_MODEL (model)));
g_signal_connect (dropdown, "notify::selected",
G_CALLBACK (limit_changed_cb2),
label);
@@ -1023,18 +1070,30 @@ 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);
+3 -3
View File
@@ -1,11 +1,11 @@
listview.viewswitcher {
list.viewswitcher {
border: 1px solid gray;
}
listview.viewswitcher > row {
list.viewswitcher > row {
padding: 5px;
}
listview.viewswitcher row:selected {
list.viewswitcher row:selected {
background: gray;
}
+5 -1
View File
@@ -215,6 +215,7 @@ transform_settings_to_keys (GBinding *binding,
GtkFilterListModel *filter_model;
GtkFilter *filter;
GtkNoSelection *selection_model;
GtkExpression *expression;
char **keys;
guint i;
@@ -245,8 +246,11 @@ transform_settings_to_keys (GBinding *binding,
gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data)));
g_object_unref (store);
filter = gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
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_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
gtk_expression_unref (expression);
g_object_unref (sort_model);
g_set_object (&current_filter, filter);
+5 -2
View File
@@ -160,6 +160,7 @@ 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");
@@ -176,7 +177,10 @@ do_listview_words (GtkWidget *do_widget)
g_strfreev (words);
}
filter = gtk_string_filter_new (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string"));
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_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
gtk_filter_list_model_set_incremental (filter_model, TRUE);
@@ -211,7 +215,6 @@ 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 (
+4 -113
View File
@@ -18,7 +18,6 @@ static gchar *current_file = NULL;
static GtkWidget *notebook;
static GtkSingleSelection *selection;
static GtkWidget *toplevel;
static char **search_needle;
typedef struct _GtkDemo GtkDemo;
struct _GtkDemo
@@ -946,18 +945,7 @@ selection_cb (GtkSingleSelection *sel,
gpointer user_data)
{
GtkTreeListRow *row = gtk_single_selection_get_selected_item (sel);
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);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
if (demo->filename)
load_file (demo->name, demo->filename);
@@ -965,84 +953,6 @@ 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)
{
@@ -1097,25 +1007,13 @@ 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, *search_entry, *search_bar;
GtkFilterListModel *filter_model;
GtkFilter *filter;
GtkWidget *window, *listview;
static GActionEntry win_entries[] = {
{ "run", activate_run, NULL, NULL, NULL }
@@ -1136,8 +1034,6 @@ 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,
@@ -1146,13 +1042,7 @@ activate (GApplication *app)
get_child_model,
NULL,
NULL);
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));
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
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));
@@ -1249,6 +1139,7 @@ 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);
}
+5 -22
View File
@@ -55,29 +55,12 @@
<property name="hscrollbar-policy">never</property>
<property name="min-content-width">150</property>
<child>
<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 class="GtkListView" id="listview">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>
</object>
</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>
</property>
</object>
</child>
</object>
@@ -1,88 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 7.4 KiB

@@ -1,44 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 4.0 KiB

@@ -1,4 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 801 B

-9
View File
@@ -19,12 +19,3 @@ 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
+1 -1
View File
@@ -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", "org.gtk.gtk4.NodeEditor.Devel",
"logo-icon-name", "text-editor-symbolic",
"title", "About GTK Node Editor",
"system-information", s->str,
NULL);
@@ -1,179 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 18 KiB

@@ -1,100 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 9.4 KiB

@@ -1,21 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 1.3 KiB

-9
View File
@@ -12,12 +12,3 @@ 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=org.gtk.PrintEditor4.Devel
Icon=text-editor-symbolic
Terminal=false
Type=Application
StartupNotify=true
+1 -3
View File
@@ -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", "org.gtk.PrintEditor4.Devel",
"logo-icon-name", "text-editor-symbolic",
"title", "About GTK Print Editor",
"system-information", sysinfo->str,
NULL);
@@ -781,8 +781,6 @@ 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);
+2 -4
View File
@@ -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,9 +93,7 @@
<xi:include href="xml/gtklistview.xml" />
<xi:include href="xml/gtkgridview.xml" />
<xi:include href="xml/gtkcolumnview.xml" />
<section>
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
</section>
<xi:include href="xml/gtkcolumnviewcolumn.xml" />
<xi:include href="xml/gtkdropdown.xml" />
</chapter>
+5 -19
View File
@@ -1300,6 +1300,10 @@ 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
@@ -1312,7 +1316,7 @@ gtk_file_chooser_get_filter
<SUBSECTION>
gtk_file_chooser_add_shortcut_folder
gtk_file_chooser_remove_shortcut_folder
gtk_file_chooser_get_shortcut_folders
gtk_file_chooser_list_shortcut_folders
<SUBSECTION>
gtk_file_chooser_add_choice
gtk_file_chooser_remove_choice
@@ -1440,8 +1444,6 @@ 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>
@@ -3420,7 +3422,6 @@ 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
@@ -7542,27 +7543,12 @@ 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
-7
View File
@@ -19,7 +19,6 @@ 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
@@ -30,7 +29,6 @@ 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
@@ -48,7 +46,6 @@ 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
@@ -57,7 +54,6 @@ 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
@@ -154,7 +150,6 @@ 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
@@ -177,7 +172,6 @@ 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
@@ -235,7 +229,6 @@ 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
+1 -1
View File
@@ -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
### Reduce the use of generic container APIs</title>
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
+1 -1
View File
@@ -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 |
-283
View File
@@ -1,283 +0,0 @@
/*
* 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
View File
@@ -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”
-6
View File
@@ -544,12 +544,6 @@ 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));
-2
View File
@@ -35,7 +35,6 @@
#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>
@@ -110,7 +109,6 @@ 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;
+13 -69
View File
@@ -191,9 +191,6 @@ 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
@@ -1651,38 +1648,6 @@ 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)
{
@@ -1737,7 +1702,19 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
if (app_id == NULL)
app_id = "GTK+ Application";
gdk_wayland_surface_set_application_id (surface, app_id);
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 ();
}
maybe_set_gtk_surface_dbus_properties (surface);
maybe_set_gtk_surface_modal (surface);
@@ -1987,39 +1964,6 @@ 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,
-7
View File
@@ -74,15 +74,8 @@ 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__ */
-1
View File
@@ -54,7 +54,6 @@ proto_sources = [
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
['server-decoration', 'private' ],
['xdg-output', 'unstable', 'v1', ],
['idle-inhibit', 'unstable', 'v1', ],
]
gdk_wayland_gen_headers = []
-2
View File
@@ -653,8 +653,6 @@ 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
+2 -14
View File
@@ -1874,7 +1874,6 @@ 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"
@@ -1891,18 +1890,6 @@ 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))
@@ -1929,11 +1916,12 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
device,
source_device,
xev->time,
state,
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
(double) xev->event_x / scale,
(double) xev->event_y / scale,
translate_crossing_mode (xev->mode),
translate_notify_type (xev->detail));
}
break;
case XI_FocusIn:
+1 -1
View File
@@ -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 && _gdk_x11_surface_syncs_frames (surface))
if (context_x11->xdamage != 0)
{
g_assert (context_x11->frame_fence == 0);
+4 -4
View File
@@ -360,8 +360,8 @@ gdk_x11_surface_begin_frame (GdkSurface *surface,
}
}
gboolean
_gdk_x11_surface_syncs_frames (GdkSurface *surface)
static gboolean
should_sync_frame_drawing (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 = _gdk_x11_surface_syncs_frames (surface);
gboolean frame_sync_negotiated = should_sync_frame_drawing (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 (_gdk_x11_surface_syncs_frames (surface))
if (should_sync_frame_drawing (surface))
{
impl->toplevel->frame_pending = TRUE;
gdk_surface_freeze_updates (surface);
-2
View File
@@ -179,7 +179,6 @@ 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);
@@ -189,7 +188,6 @@ void gdk_x11_surface_move (GdkSurface *surface,
void gdk_x11_surface_check_monitor (GdkSurface *surface,
GdkMonitor *monitor);
G_END_DECLS
#endif /* __GDK_X11_SURFACE__ */
+121 -181
View File
@@ -70,6 +70,7 @@ typedef enum
RESET_CLIP = 1 << 1,
RESET_OPACITY = 1 << 2,
DUMP_FRAMEBUFFER = 1 << 3,
CENTER_CHILD = 1 << 4,
NO_CACHE_PLZ = 1 << 5,
} OffscreenFlags;
@@ -905,7 +906,6 @@ upload_texture (GskGLRenderer *self,
}
else
{
out_region->texture_id =
gsk_gl_driver_get_texture_for_texture (self->gl_driver,
texture,
@@ -1152,59 +1152,6 @@ 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,
@@ -1212,57 +1159,112 @@ render_clipped_child (GskGLRenderer *self,
GskRenderNode *child)
{
graphene_rect_t transformed_clip;
GskRoundedRect intersection;
GskRoundedRect child_clip;
ops_transform_bounds_modelview (builder, clip, &transformed_clip);
if (builder->clip_is_rectilinear)
{
memset (&intersection, 0, sizeof (GskRoundedRect));
graphene_rect_intersection (&transformed_clip,
&builder->current_clip->bounds,
&intersection.bounds);
goto trivial;
ops_push_clip (builder, &intersection);
{
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;
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);
gsk_gl_renderer_add_render_ops (self, child, builder);
ops_pop_clip (builder);
}
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;
return;
}
memset (&scaled_clip, 0, sizeof (GskRoundedRect));
rtt:
{
/* well fuck */
const float scale = ops_get_scale (builder);
gboolean is_offscreen;
TextureRegion region;
GskRoundedRect scaled_clip;
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;
memset (&scaled_clip, 0, sizeof (GskRoundedRect));
ops_push_clip (builder, &scaled_clip);
if (!add_offscreen_ops (self, builder, &child->bounds,
child,
&region, &is_offscreen,
RESET_OPACITY | FORCE_OFFSCREEN))
g_assert_not_reached ();
ops_pop_clip (builder);
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_set_program (builder, &self->programs->blit_program);
ops_set_texture (builder, region.texture_id);
ops_push_clip (builder, &scaled_clip);
if (!add_offscreen_ops (self, builder, &child->bounds,
child,
&region, &is_offscreen,
RESET_OPACITY | FORCE_OFFSCREEN))
g_assert_not_reached ();
ops_pop_clip (builder);
load_offscreen_vertex_data (ops_draw (builder, NULL), child, builder);
}
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;
}
static inline void
@@ -1292,29 +1294,6 @@ 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;
@@ -1328,16 +1307,12 @@ 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 */
/* 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))
for (i = 0; i < 4; i ++)
{
gsk_gl_renderer_add_render_ops (self, child, builder);
return;
transformed_clip.corner[i].width = clip->corner[i].width * scale;
transformed_clip.corner[i].height = clip->corner[i].height * scale;
}
/* 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);
@@ -1379,6 +1354,7 @@ 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
@@ -1786,6 +1762,7 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
}
static GdkRGBA COLOR_WHITE = { 1, 1, 1, 1 };
static inline void
render_outset_shadow_node (GskGLRenderer *self,
@@ -1806,32 +1783,19 @@ 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;
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;
}
/* 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;
texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale);
texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale);
@@ -1916,41 +1880,6 @@ 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);
@@ -3388,8 +3317,19 @@ add_offscreen_ops (GskGLRenderer *self,
bounds->origin.y * scale,
width, height));
builder->dx = 0;
builder->dy = 0;
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;
}
if (flags & RESET_OPACITY)
prev_opacity = ops_set_opacity (builder, 1.0);
+1 -2
View File
@@ -123,8 +123,7 @@ 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 : gsk_transform_ref (next);
g_clear_pointer (&next, gsk_transform_unref);
self->next = gsk_transform_is_identity (next) ? NULL : next;
return self;
}
+4
View File
@@ -233,6 +233,10 @@
#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 -103
View File
@@ -1,7 +1,6 @@
/*
* 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
@@ -25,42 +24,12 @@
#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 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 GtkApplicationImplDBusClass GtkApplicationImplWaylandClass;
typedef struct
{
GtkApplicationImplDBus dbus;
GSList *inhibitors;
guint next_cookie;
} GtkApplicationImplWayland;
@@ -103,70 +72,6 @@ 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)
{
@@ -177,15 +82,8 @@ 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;
}
-1
View File
@@ -109,7 +109,6 @@ 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;
}
+4 -3
View File
@@ -27,19 +27,20 @@
* 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".
*
* The current implemenation is based on [roaring bitmaps](https://roaringbitmap.org/).
* This version 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.
* The fastest way to iterate values in a bitset is #GtkBitsetIter which allows
* quick iteration of all the values in a bitset.
*
* The main use case for #GtkBitset is implementing complex selections for
* #GtkSelectionModel.
+1 -15
View File
@@ -130,21 +130,7 @@ void gtk_bitset_splice (GtkBitset
guint removed,
guint added);
/**
* 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];
};
typedef struct {gpointer private_data[10]; } GtkBitsetIter;
GDK_AVAILABLE_IN_ALL
gboolean gtk_bitset_iter_init_first (GtkBitsetIter *iter,
-2
View File
@@ -369,8 +369,6 @@ gtk_bookmark_list_start_loading (GtkBookmarkList *self)
self);
g_object_unref (file);
}
g_strfreev (uris);
}
else
{
+14 -6
View File
@@ -28,6 +28,7 @@
#include "gtkstylecontextprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#include "gtknative.h"
/**
* SECTION:gtkboxlayout
@@ -249,8 +250,10 @@ gtk_box_layout_compute_size (GtkBoxLayout *self,
required_nat += (n_visible_children - 1) * spacing;
}
*minimum = required_min;
*natural = required_nat;
if (minimum != NULL)
*minimum = required_min;
if (natural != NULL)
*natural = required_nat;
}
static void
@@ -417,10 +420,15 @@ gtk_box_layout_compute_opposite_size (GtkBoxLayout *self,
}
}
*minimum = computed_minimum;
*natural = MAX (computed_natural, computed_natural_below + computed_natural_above);
*min_baseline = computed_minimum_baseline;
*nat_baseline = computed_natural_baseline;
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;
}
static void
-11
View File
@@ -294,17 +294,6 @@ 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
+1 -3
View File
@@ -62,12 +62,10 @@ 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);
}
}
+10 -19
View File
@@ -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,26 +1486,17 @@ gtk_column_view_get_list_view (GtkColumnView *self)
* gtk_column_view_get_sorter:
* @self: a #GtkColumnView
*
* Returns a special sorter that reflects the users sorting
* choices in the column view.
* Returns the sorter associated with 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 underneath
* the model that is displayed by the view.
* headers, this sorter needs to be set on the sort
* model(s) underneath the model that is displayed
* by the view.
*
* See gtk_column_view_column_set_sorter() for setting up
* See gtk_column_view_column_get_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 *
-1
View File
@@ -105,7 +105,6 @@ 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
-1
View File
@@ -85,7 +85,6 @@ 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
-8
View File
@@ -115,14 +115,6 @@ 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);
+18 -17
View File
@@ -560,12 +560,10 @@ 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;
@@ -768,11 +766,7 @@ parse_selector_list (GtkCssScanner *scanner,
GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser);
if (select == NULL)
{
for (int i = 0; i < n_selectors; i++)
g_clear_pointer (&out_selectors[i], _gtk_css_selector_free);
return 0;
}
return 0;
out_selectors[n_selectors] = select;
n_selectors++;
@@ -782,8 +776,6 @@ 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;
}
}
@@ -812,7 +804,10 @@ parse_declaration (GtkCssScanner *scanner,
name = gtk_css_parser_consume_ident (scanner->parser);
if (name == NULL)
goto out;
{
gtk_css_parser_end_block (scanner->parser);
return;
}
property = _gtk_style_property_lookup (name);
@@ -824,18 +819,25 @@ parse_declaration (GtkCssScanner *scanner,
if (!gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COLON))
{
gtk_css_parser_error_syntax (scanner->parser, "Expected ':'");
goto out;
g_free (name);
gtk_css_parser_end_block (scanner->parser);
return;
}
value = _gtk_style_property_parse_value (property, scanner->parser);
value = _gtk_style_property_parse_value (property,
scanner->parser);
if (value == NULL)
goto out;
{
gtk_css_parser_end_block (scanner->parser);
return;
}
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);
goto out;
gtk_css_parser_end_block (scanner->parser);
return;
}
if (gtk_keep_css_sections)
@@ -880,7 +882,6 @@ 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);
@@ -915,7 +916,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);
+5 -5
View File
@@ -22,11 +22,11 @@
#include "gtk/gtkcsstypesprivate.h"
#include "gtk/gtkcssparserprivate.h"
#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"
#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"
G_BEGIN_DECLS
+5 -9
View File
@@ -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,13 +98,11 @@ 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: destroy notify for @user_data
* @user_destroy: destory notify
*
* 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.
*
@@ -129,12 +127,10 @@ 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: destroy notify for @user_data
* @user_destroy: destory notify
*
* 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.
*
+5 -9
View File
@@ -27,7 +27,7 @@
/**
* SECTION:gtkcustomsorter
* @Title: GtkCustomSorter
* @Short_description: Sorting with a callbacks
* @Short_description: Sorting with a callback
*
* GtkCustomSorter is a #GtkSorter implementation that sorts
* via a traditional #GCompareDataFunc callback.
@@ -108,10 +108,8 @@ gtk_custom_sorter_init (GtkCustomSorter *self)
* Creates a new #GtkSorter that works by calling
* @sort_func to compare items.
*
* If @sort_func is %NULL, all items are considered equal.
*
* Returns: a new #GtkSorter
*/
* Returns: a new #GTkSorter
*/
GtkSorter *
gtk_custom_sorter_new (GCompareDataFunc sort_func,
gpointer user_data,
@@ -131,12 +129,10 @@ 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: destroy notify for @user_data
* @user_destroy: destory notify
*
* 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.
*
+5 -4
View File
@@ -48,10 +48,11 @@ typedef enum {
GTK_DEBUG_INTERACTIVE = 1 << 10,
GTK_DEBUG_TOUCHSCREEN = 1 << 11,
GTK_DEBUG_ACTIONS = 1 << 12,
GTK_DEBUG_LAYOUT = 1 << 13,
GTK_DEBUG_SNAPSHOT = 1 << 14,
GTK_DEBUG_CONSTRAINTS = 1 << 15,
GTK_DEBUG_BUILDER_OBJECTS = 1 << 16,
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,
} GtkDebugFlag;
#ifdef G_ENABLE_DEBUG
+4 -229
View File
@@ -62,7 +62,6 @@ enum {
PROP_IO_PRIORITY,
PROP_ITEM_TYPE,
PROP_LOADING,
PROP_MONITORED,
NUM_PROPERTIES
};
@@ -71,10 +70,8 @@ struct _GtkDirectoryList
GObject parent_instance;
char *attributes;
GFile *file;
GFileMonitor *monitor;
gboolean monitored;
int io_priority;
GFile *file;
GCancellable *cancellable;
GError *error; /* Error while loading */
@@ -150,17 +147,13 @@ 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,
@@ -194,10 +187,6 @@ 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;
@@ -215,27 +204,12 @@ 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);
@@ -327,18 +301,6 @@ 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);
}
@@ -347,7 +309,6 @@ gtk_directory_list_init (GtkDirectoryList *self)
{
self->items = g_sequence_new (g_object_unref);
self->io_priority = G_PRIORITY_DEFAULT;
self->monitored = TRUE;
}
/**
@@ -363,6 +324,7 @@ 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);
@@ -448,7 +410,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));
@@ -534,143 +496,6 @@ 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
@@ -695,7 +520,6 @@ 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]);
@@ -855,52 +679,3 @@ 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;
}
-6
View File
@@ -62,12 +62,6 @@ 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__ */
+4 -3
View File
@@ -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,8 +205,9 @@ update_filter (GtkDropDown *self)
if (self->expression)
{
filter = gtk_string_filter_new (gtk_expression_ref (self->expression));
filter = gtk_string_filter_new ();
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 ();
@@ -926,7 +927,7 @@ gtk_drop_down_get_expression (GtkDropDown *self)
/**
* gtk_drop_down_set_from_strings:
* @self: a #GtkDropDown
* @texts: (array zero-terminated=1) (element-type utf8): a %NULL-terminated string array
* @texts: a %NULL-terminated string array
*
* Populates @self with the strings in @text,
* by creating a suitable model and factory.
-34
View File
@@ -30,7 +30,6 @@
#include "gtkshortcut.h"
#include "gtkshortcuttrigger.h"
#include "gtkwidgetprivate.h"
#include "gtkeventcontrollerfocus.h"
#include "gtkintl.h"
/**
@@ -49,22 +48,6 @@
* 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
@@ -194,20 +177,12 @@ 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);
@@ -237,10 +212,6 @@ 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));
}
@@ -473,8 +444,6 @@ 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]);
}
@@ -511,8 +480,5 @@ 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]);
}
+9 -83
View File
@@ -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 similar reasons.
* #GtkStringFilter is using a GtkExpression for a similar reason.
*
* 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,24 +855,6 @@ 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 */
@@ -1020,24 +1002,6 @@ 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 */
@@ -1343,44 +1307,6 @@ 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 */
-11
View File
@@ -93,11 +93,6 @@ 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;
@@ -110,9 +105,6 @@ 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;
@@ -122,9 +114,6 @@ 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;
+105 -13
View File
@@ -79,6 +79,75 @@ 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"),
@@ -439,15 +508,16 @@ 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.
*
* 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 *
* 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 *
gtk_file_chooser_get_files (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
@@ -527,19 +597,41 @@ gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *
gtk_file_chooser_get_file (GtkFileChooser *chooser)
{
GListModel *list;
GSList *list;
GFile *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
list = gtk_file_chooser_get_files (chooser);
if (g_list_model_get_n_items (list) > 0)
result = g_list_model_get_item (list, 0);
g_object_unref (list);
if (list)
{
result = list->data;
list = g_slist_delete_link (list, list);
g_slist_free_full (list, g_object_unref);
}
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
+68 -61
View File
@@ -72,8 +72,7 @@ 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.
@@ -88,100 +87,108 @@ 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 */
/* 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);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
const char *name);
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
char * gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
void gtk_file_chooser_unselect_all (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
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
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 */
GListModel *gtk_file_chooser_get_filters (GtkFileChooser *chooser);
/* Current filter
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
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);
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);
/* Custom widgets */
GListModel *gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
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
+583 -790
View File
File diff suppressed because it is too large Load Diff
+43 -11
View File
@@ -25,6 +25,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -263,9 +265,12 @@ static void gtk_file_chooser_dialog_size_allocate (GtkWidget *wid
int width,
int height,
int baseline);
static void gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
const char *action_name,
GVariant *parameters);
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 response_cb (GtkDialog *dialog,
gint response_id);
@@ -305,8 +310,9 @@ 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_install_action (widget_class, "response.activate", NULL, gtk_file_chooser_dialog_activate_response);
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);
}
static void
@@ -361,12 +367,38 @@ 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
gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
const char *action_name,
GVariant *parameters)
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)
{
GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
GtkWidget *button;
@@ -609,7 +641,7 @@ gtk_file_chooser_dialog_map (GtkWidget *widget)
setup_save_entry (dialog);
ensure_default_response (dialog);
gtk_file_chooser_widget_initial_focus (GTK_FILE_CHOOSER_WIDGET (priv->widget));
_gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
}
@@ -673,7 +705,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_widget_should_respond (GTK_FILE_CHOOSER_WIDGET (priv->widget)))
!_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
{
g_signal_stop_emission_by_name (dialog, "response");
}
+152
View File
@@ -0,0 +1,152 @@
/* 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);
}
+61
View File
@@ -0,0 +1,61 @@
/* 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__ */
+1 -1
View File
@@ -25,7 +25,7 @@
#include "gtkcelllayout.h"
#include "gtkcellrenderertext.h"
#include "gtkentryprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilesystemmodel.h"
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtksizerequest.h"
+1
View File
@@ -19,6 +19,7 @@
#ifndef __GTK_FILE_CHOOSER_ENTRY_H__
#define __GTK_FILE_CHOOSER_ENTRY_H__
#include "gtkfilesystem.h"
#include "gtkfilechooser.h"
G_BEGIN_DECLS
+1 -1
View File
@@ -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), "custom");
GtkWidget *label = gtk_stack_get_child_by_name (GTK_STACK (self->stack), "cutsom");
gtk_label_set_text (GTK_LABEL (label), label_text);
+26 -15
View File
@@ -28,6 +28,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -156,8 +158,21 @@
* possible to use with #GtkFileChooserNative, as such use would
* prohibit the use of a native dialog.
*
* No operations that change the dialog work while the dialog is visible.
* Set all the properties that are required before showing the 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.
*
* ## Win32 details ## {#gtkfilechooserdialognative-win32}
*
@@ -165,7 +180,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
* * Any #GtkFileFilter added using a mimetype or custom filter.
*
* If any of these features are used the regular #GtkFileChooserDialog
* will be used in place of the native one.
@@ -175,7 +190,10 @@
* 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.
* 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.
*
* ## macOS details ## {#gtkfilechooserdialognative-macos}
*
@@ -183,6 +201,8 @@
* file chooser dialogs. Some features provided by #GtkFileChooserDialog are
* not supported:
*
* * Any #GtkFileFilter added with a custom filter.
*
* * Shortcut folders.
*/
@@ -663,7 +683,7 @@ gtk_file_chooser_native_set_current_name (GtkFileChooser *chooser,
g_clear_object (&self->current_file);
}
static GListModel *
static GSList *
gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
{
GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
@@ -673,16 +693,7 @@ gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
case MODE_PORTAL:
case MODE_WIN32:
case MODE_QUARTZ:
{
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);
}
return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);
case MODE_FALLBACK:
default:
+2
View File
@@ -28,6 +28,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
+2
View File
@@ -28,6 +28,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
+2 -1
View File
@@ -34,6 +34,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -906,7 +908,6 @@ 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));
}
+5 -8
View File
@@ -20,6 +20,7 @@
#define __GTK_FILE_CHOOSER_PRIVATE_H__
#include "gtkfilechooser.h"
#include "gtkfilesystem.h"
#include "gtkfilesystemmodel.h"
#include "gtkliststore.h"
#include "gtkrecentmanager.h"
@@ -71,7 +72,8 @@ struct _GtkFileChooserIface
GFile *file);
void (*select_all) (GtkFileChooser *chooser);
void (*unselect_all) (GtkFileChooser *chooser);
GListModel * (*get_files) (GtkFileChooser *chooser);
GSList * (*get_files) (GtkFileChooser *chooser);
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
void (*add_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
void (*remove_filter) (GtkFileChooser *chooser,
@@ -107,13 +109,8 @@ struct _GtkFileChooserIface
const char *id);
};
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);
GtkFileSystem *_gtk_file_chooser_get_file_system (GtkFileChooser *chooser);
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_PRIVATE_H__ */
+44 -75
View File
@@ -20,6 +20,7 @@
#include "config.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooser.h"
#include "gtkfilesystem.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -38,7 +39,8 @@ static void delegate_unselect_file (GtkFileChooser *choose
GFile *file);
static void delegate_select_all (GtkFileChooser *chooser);
static void delegate_unselect_all (GtkFileChooser *chooser);
static GListModel * delegate_get_files (GtkFileChooser *chooser);
static GSList * delegate_get_files (GtkFileChooser *chooser);
static GtkFileSystem *delegate_get_file_system (GtkFileChooser *chooser);
static void delegate_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
static void delegate_remove_filter (GtkFileChooser *chooser,
@@ -54,6 +56,12 @@ 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,
@@ -126,6 +134,7 @@ _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;
@@ -159,6 +168,12 @@ _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
@@ -206,12 +221,18 @@ delegate_unselect_all (GtkFileChooser *chooser)
gtk_file_chooser_unselect_all (get_delegate (chooser));
}
static GListModel *
static GSList *
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)
@@ -294,6 +315,27 @@ 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)
{
@@ -402,76 +444,3 @@ 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;
}
-7
View File
@@ -49,13 +49,6 @@ 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__ */
+329 -260
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -30,12 +30,6 @@ 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__ */
+823
View File
@@ -0,0 +1,823 @@
/* 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, well 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;
}
+116
View File
@@ -0,0 +1,116 @@
/* 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__ */
+1 -1
View File
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include "gtkfilechooserutils.h"
#include "gtkfilesystem.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtktreedatalist.h"
+12 -13
View File
@@ -30,21 +30,20 @@
* @Short_description: Filtering items
* @See_also: #GtkFilerListModel
*
* 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.
* #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.
*
* Filters may change what items they match through their lifetime. In that
* 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().
* 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.
*
* GTK provides various pre-made filter implementations for common filtering
* GTK provides various premade 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.
@@ -119,7 +118,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.
@@ -141,7 +140,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.
+7 -13
View File
@@ -178,7 +178,7 @@ gtk_filter_list_model_run_filter (GtkFilterListModel *self,
}
if (more)
gtk_bitset_remove_range_closed (self->pending, 0, pos - 1);
gtk_bitset_remove_range_closed (self->pending, 0, pos);
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 ();
/* fall thru */
G_GNUC_FALLTHROUGH;
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_("Filter items incrementally"),
P_("Filer 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 GtkFilterListModel will not
* run filters immediately, but will instead queue an idle handler that
* When incremental filtering is enabled, the filterlistmodel 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,14 +837,8 @@ 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 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);
* ]|
* of the filter remaining by dividing the return value by
* g_list_model_get_n_items(gtk_filter_list_model_get_model (self)).
*
* Returns: The number of items not yet filtered
**/
+1 -1
View File
@@ -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
View File
@@ -45,7 +45,7 @@
/**
* SECTION:gtkgridview
* @title: GtkGridView
* @short_description: A widget for displaying grids
* @short_description: A widget for displaying lists in a grid
* @see_also: #GListModel, #GtkListView, #GtkColumnView
*
* GtkGridView is a widget to present a view into a large dynamic grid of items.
+12 -12
View File
@@ -55,13 +55,13 @@
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkprofilerprivate.h"
#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"
#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"
/**
* 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};
+2 -13
View File
@@ -725,8 +725,6 @@ 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,
@@ -737,10 +735,6 @@ 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;
@@ -773,11 +767,7 @@ gtk_level_bar_buildable_custom_finished (GtkBuildable *buildable,
self = data->self;
if (strcmp (tagname, "offsets") != 0)
{
parent_buildable_iface->custom_finished (buildable, builder, child,
tagname, user_data);
return;
}
goto out;
for (l = data->offsets; l != NULL; l = l->next)
{
@@ -785,6 +775,7 @@ 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);
}
@@ -792,8 +783,6 @@ 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
View File
@@ -26,7 +26,7 @@
/**
* SECTION:gtklistitem
* @title: GtkListItem
* @short_description: Object used to represent items of a list model
* @short_description: Object used to represent items of a ListModel
* @see_also: #GtkListView, #GListModel
*
* #GtkListItem is the object that list-handling containers such
+13 -7
View File
@@ -577,11 +577,13 @@ 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_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify )gtk_widget_unparent);
change = g_hash_table_new (g_direct_hash, g_direct_equal);
gtk_list_item_manager_remove_items (self, change, position, removed);
gtk_list_item_manager_add_items (self, position, added);
@@ -725,6 +727,12 @@ 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);
@@ -1065,12 +1073,10 @@ gtk_list_item_manager_release_list_item (GtkListItemManager *self,
if (change != NULL)
{
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;
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.");
}
gtk_widget_unparent (item);
+7 -6
View File
@@ -137,12 +137,12 @@
#include "a11y/gtkaccessibility.h"
#include "inspector/window.h"
#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"
#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"
static GtkWindowGroup *gtk_main_get_window_group (GtkWidget *widget);
@@ -181,6 +181,7 @@ 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