Compare commits
203 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd206f3b7a | |||
| 8f2ad8f154 | |||
| 2f894bb4ef | |||
| 2509fe0d17 | |||
| 83a5611ce8 | |||
| af088d5e11 | |||
| a6e1c5c96a | |||
| 3c8c54ed15 | |||
| c4d3d72c57 | |||
| cd79159420 | |||
| 071c6c60c0 | |||
| fc24f401b7 | |||
| 6c96e51b07 | |||
| e703163bc4 | |||
| ad549cbded | |||
| 673beef210 | |||
| 55baa1f2e1 | |||
| b13f05537b | |||
| 0834dac6ee | |||
| 3c31f72219 | |||
| a0f63160d6 | |||
| c99d85954a | |||
| 33f31d06f9 | |||
| bf4b40f17e | |||
| 7aba9e3295 | |||
| 3080cb7acd | |||
| 4b404f0dea | |||
| 0c1c0524c7 | |||
| b58ef290dc | |||
| 1387fba7f8 | |||
| 34b9ec5be2 | |||
| cefdfbd894 | |||
| 3676ddbdff | |||
| 7c1a0e0c15 | |||
| 19bb043a85 | |||
| fecc80b59c | |||
| 1648dc36f8 | |||
| a27a2cbf40 | |||
| e418656a04 | |||
| d4ec1afe44 | |||
| 374d97008b | |||
| fecc923c2c | |||
| 703ed608c0 | |||
| 99f07c7c0a | |||
| 51b4d70b8f | |||
| 746d12fc43 | |||
| 96ce9e10b8 | |||
| 3090795351 | |||
| 815b54f3df | |||
| 9ad27e4371 | |||
| a6e1804474 | |||
| 7ae549e253 | |||
| 434d8ef0ea | |||
| 31a6d73635 | |||
| 958ecf2855 | |||
| fb12ad807a | |||
| 965c52d369 | |||
| 474872563f | |||
| b92e52bf0e | |||
| d226dc3812 | |||
| 46e0fde606 | |||
| 1e7f525e0e | |||
| d43e0fb9a7 | |||
| 6fb6f47fc8 | |||
| 0f7d8e04d8 | |||
| c9fca559dc | |||
| b9d1b5d6a3 | |||
| 5f75ba46a5 | |||
| 2507301983 | |||
| 41aeff331d | |||
| 3aab48ec16 | |||
| ad0348b85e | |||
| 6a134551b9 | |||
| 0e1ae6ad11 | |||
| 5baf4b4b2e | |||
| 63560061e8 | |||
| be721f5797 | |||
| 0073bb79a7 | |||
| f59b506674 | |||
| 88b4404296 | |||
| e20bc7723a | |||
| 7edf8841fb | |||
| 6b5b7eab04 | |||
| c775262e9d | |||
| 553fde9761 | |||
| f2593dec4b | |||
| ab5a6ed0f1 | |||
| dd3cdc52f5 | |||
| 5a3156a8b7 | |||
| a4c2f19155 | |||
| be8fb1e9b8 | |||
| 52c97dbf67 | |||
| 57ebf26f15 | |||
| 32247bc50e | |||
| ad940bc892 | |||
| 7d34e7e0f7 | |||
| b2f43076bd | |||
| 202e889577 | |||
| a8690c84ab | |||
| 35244f4b59 | |||
| 503c3ec04d | |||
| 4a5a466975 | |||
| e694511da3 | |||
| 0a94827b9c | |||
| 735cf301a4 | |||
| e8a29f90d1 | |||
| 182cc74834 | |||
| 7801dd8944 | |||
| 38e090f5c1 | |||
| 998c382037 | |||
| ac81e71f78 | |||
| de271c9a30 | |||
| bf3cf8bb29 | |||
| 63fa5b7f52 | |||
| 96add330f5 | |||
| 44aa6a891a | |||
| 7a30a21405 | |||
| 2b3eadcfa4 | |||
| 352443d5a5 | |||
| 3574fde770 | |||
| 793689789c | |||
| 120396fa40 | |||
| d61ec38974 | |||
| 2a463baed0 | |||
| 348acde6bd | |||
| 5ba793842b | |||
| 149b608bfc | |||
| 3348ea81f2 | |||
| 63e69131bd | |||
| d42a34b0b3 | |||
| 5ee10fc669 | |||
| b0a4917ce4 | |||
| 47e22d6301 | |||
| b970b60503 | |||
| 7406f8165d | |||
| 9435e689c3 | |||
| 66c947b86b | |||
| ad1af87834 | |||
| 68700f8722 | |||
| f76270167c | |||
| 2a442c4fbb | |||
| 9356dfc404 | |||
| 7eb8439047 | |||
| 0ccf9ad8fc | |||
| c52978dfa4 | |||
| 52dfa54301 | |||
| b6f9e00a9e | |||
| 8780aa02d7 | |||
| 8d5a39d765 | |||
| 446e6a8d62 | |||
| 9b1bee99b8 | |||
| 77cf0f1719 | |||
| fc1f1366b4 | |||
| 6efd1a9dad | |||
| 8349ae2bc4 | |||
| 7c5c843b5b | |||
| bc11bc4f8d | |||
| be24e4a1f7 | |||
| 918ff1d0f4 | |||
| 20723613bc | |||
| 604aafe15d | |||
| 4041ca0f69 | |||
| 3526d8b299 | |||
| e8adfa2a88 | |||
| 7fab1b85ad | |||
| 5aeabdb3d4 | |||
| 6f01f846dc | |||
| 3c4f6144a0 | |||
| ae71d338d7 | |||
| 8b469a2727 | |||
| 53813f24f0 | |||
| 1fde83f12b | |||
| 1f7783224b | |||
| 0d04ceda76 | |||
| 9396ccf9ff | |||
| 5a68639788 | |||
| 85df554ec1 | |||
| 8776ebfe90 | |||
| 83eee03b0f | |||
| d7bba4ebac | |||
| 40e2b5b153 | |||
| f7a7313758 | |||
| 2d9ce0357f | |||
| 0ea05896df | |||
| 8c638df147 | |||
| 6605ded4c9 | |||
| ba1a9530c8 | |||
| a9fcea369e | |||
| ca2787fbba | |||
| 6d2c897dfc | |||
| 01f81b2d77 | |||
| 8a3c5c63e8 | |||
| 089d0caa5e | |||
| d0c4413033 | |||
| 410fa9871f | |||
| 9fd4b215ee | |||
| 19aaa8fee5 | |||
| 43c1a433aa | |||
| ff8d88b097 | |||
| 30525835f3 | |||
| 818ca63d35 | |||
| b9551a8952 | |||
| e600fcbcc5 |
+30
-8
@@ -22,9 +22,9 @@ stages:
|
||||
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false -Dwayland:werror=false"
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dcairo:werror=false -Dgi-docgen:werror=false -Dgraphene:werror=false -Dlibepoxy:werror=false -Dlibsass:werror=false -Dpango:werror=false -Dsassc:werror=false -Dgdk-pixbuf:werror=false -Dglib:werror=false -Dlibcloudproviders:werror=false -Dlibpng:werror=false -Dlibtiff:werror=false -Dsysprof:werror=false -Dwayland-protocols:werror=false -Dharfbuzz:werror=false -Dfreetype2:werror=false -Dfontconfig:werror=false -Dfribidi:werror=false -Dlibffi:werror=false -Dlibjpeg-turbo:werror=false -Dmutest:werror=false -Dpixman:werror=false -Dproxy-libintl:werror=false"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v40"
|
||||
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
||||
@@ -113,7 +113,12 @@ release-build:
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson subprojects download
|
||||
- meson subprojects update --reset
|
||||
- meson setup ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS} _build
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
${EXTRA_MESON_FLAGS}
|
||||
${BACKEND_FLAGS}
|
||||
${FEATURE_FLAGS}
|
||||
_build
|
||||
- meson compile -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
|
||||
@@ -201,7 +206,7 @@ macos:
|
||||
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||
- export MESON_FORCE_BACKTRACE=1
|
||||
script:
|
||||
- meson setup
|
||||
- meson setup ${COMMON_MESON_FLAGS}
|
||||
-Dx11-backend=false
|
||||
-Dbroadway-backend=true
|
||||
-Dmacos-backend=true
|
||||
@@ -210,6 +215,10 @@ macos:
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
-Dlibjpeg-turbo:simd=disabled
|
||||
-Ddemos=false
|
||||
-Dbuild-tests=false
|
||||
-Dbuild-examples=false
|
||||
-Dbuild-testsuite=false
|
||||
_build
|
||||
- meson compile -C _build
|
||||
artifacts:
|
||||
@@ -338,7 +347,10 @@ static-scan:
|
||||
script:
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson setup ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} _scan_build
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
${EXTRA_MESON_FLAGS}
|
||||
_scan_build
|
||||
- ninja -C _scan_build scan-build
|
||||
artifacts:
|
||||
paths:
|
||||
@@ -368,12 +380,22 @@ reference:
|
||||
image: $FEDORA_IMAGE
|
||||
stage: docs
|
||||
needs: []
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release --force-fallback-for=gdk-pixbuf,pango"
|
||||
script:
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
- pip3 install --user meson~=0.64
|
||||
- meson setup ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true -Dgdk-pixbuf:gtk_doc=true -Dpango:gtk_doc=true _build
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
--buildtype=release
|
||||
--force-fallback-for=gdk-pixbuf,pango
|
||||
-Dintrospection=enabled
|
||||
-Dgtk_doc=true
|
||||
-Dgdk-pixbuf:gtk_doc=true
|
||||
-Dpango:gtk_doc=true
|
||||
-Ddemos=false
|
||||
-Dbuild-examples=false
|
||||
-Dbuild-tests=false
|
||||
-Dbuild-testsuite=false
|
||||
_build
|
||||
- meson compile -C _build
|
||||
- mkdir -p _reference/
|
||||
- mv _build/docs/reference/gdk/gdk4/ _reference/gdk4/
|
||||
|
||||
+54
-22
@@ -1,11 +1,11 @@
|
||||
/* Pickers
|
||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog
|
||||
/* Pickers and Launchers
|
||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
|
||||
*
|
||||
* These widgets are mainly intended for use in preference dialogs.
|
||||
* The dialogs are mainly intended for use in preference dialogs.
|
||||
* They allow to select colors, fonts and applications.
|
||||
*
|
||||
* This demo shows both the default appearance for these dialogs,
|
||||
* as well as some of the customizations that are possible.
|
||||
* The launchers let you open files or URIs in applications that
|
||||
* can handle them.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -73,9 +73,9 @@ open_file (GtkButton *picker,
|
||||
}
|
||||
|
||||
static void
|
||||
launch_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
open_app_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFileLauncher *launcher = GTK_FILE_LAUNCHER (source);
|
||||
GError *error = NULL;
|
||||
@@ -97,7 +97,35 @@ open_app (GtkButton *picker)
|
||||
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
|
||||
launcher = gtk_file_launcher_new (file);
|
||||
|
||||
gtk_file_launcher_launch (launcher, parent, NULL, launch_done, NULL);
|
||||
gtk_file_launcher_launch (launcher, parent, NULL, open_app_done, NULL);
|
||||
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
static void
|
||||
open_uri_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkUriLauncher *launcher = GTK_URI_LAUNCHER (source);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gtk_uri_launcher_launch_finish (launcher, result, &error))
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
launch_uri (GtkButton *picker)
|
||||
{
|
||||
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
|
||||
GtkUriLauncher *launcher;
|
||||
|
||||
launcher = gtk_uri_launcher_new ("http://www.gtk.org");
|
||||
|
||||
gtk_uri_launcher_launch (launcher, parent, NULL, open_uri_done, NULL);
|
||||
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
@@ -113,7 +141,7 @@ do_pickers (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Pickers");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Pickers and Launchers");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
@@ -121,8 +149,8 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_end (table, 20);
|
||||
gtk_widget_set_margin_top (table, 20);
|
||||
gtk_widget_set_margin_bottom (table, 20);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 3);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 10);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
|
||||
gtk_window_set_child (GTK_WINDOW (window), table);
|
||||
|
||||
label = gtk_label_new ("Color:");
|
||||
@@ -149,7 +177,7 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
|
||||
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
button = gtk_button_new_from_icon_name ("document-open-symbolic");
|
||||
label = gtk_label_new ("None");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.);
|
||||
@@ -158,19 +186,23 @@ do_pickers (GtkWidget *do_widget)
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_file), label);
|
||||
gtk_box_append (GTK_BOX (picker), label);
|
||||
gtk_box_append (GTK_BOX (picker), button);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Application:");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 4, 1, 1);
|
||||
|
||||
app_picker = gtk_button_new_from_icon_name ("emblem-system-symbolic");
|
||||
gtk_widget_set_halign (app_picker, GTK_ALIGN_END);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
|
||||
gtk_grid_attach (GTK_GRID (table), app_picker, 1, 4, 1, 1);
|
||||
gtk_box_append (GTK_BOX (picker), app_picker);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
||||
|
||||
|
||||
label = gtk_label_new ("URI:");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 3, 1, 1);
|
||||
|
||||
picker = gtk_button_new_with_label ("www.gtk.org");
|
||||
g_signal_connect (picker, "clicked", G_CALLBACK (launch_uri), NULL);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 3, 1, 1);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -2056,6 +2056,67 @@ hide_widget (GtkWidget *widget)
|
||||
gtk_widget_set_visible (widget, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
load_texture_thread (GTask *task,
|
||||
gpointer source_object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
const char *resource_path = (const char *) task_data;
|
||||
GBytes *bytes;
|
||||
GdkTexture *texture;
|
||||
GError *error = NULL;
|
||||
|
||||
bytes = g_resources_lookup_data (resource_path, 0, &error);
|
||||
if (!bytes)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
texture = gdk_texture_new_from_bytes (bytes, &error);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_pointer (task, texture, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
load_texture_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *picture = GTK_WIDGET (source);
|
||||
GdkTexture *texture;
|
||||
GError *error = NULL;
|
||||
|
||||
texture = g_task_propagate_pointer (G_TASK (result), &error);
|
||||
if (!texture)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_picture_set_paintable (GTK_PICTURE (picture), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
load_texture_in_thread (GtkWidget *picture,
|
||||
const char *resource_path)
|
||||
{
|
||||
GTask *task = g_task_new (picture, NULL, load_texture_done, NULL);
|
||||
g_task_set_task_data (task, (gpointer)resource_path, NULL);
|
||||
g_task_run_in_thread (task, load_texture_thread);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *app)
|
||||
{
|
||||
@@ -2155,6 +2216,13 @@ activate (GApplication *app)
|
||||
|
||||
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
|
||||
|
||||
load_texture_in_thread ((GtkWidget *)gtk_builder_get_object (builder, "notebook_sunset"),
|
||||
"/org/gtk/WidgetFactory4/sunset.jpg");
|
||||
load_texture_in_thread ((GtkWidget *)gtk_builder_get_object (builder, "notebook_nyc"),
|
||||
"/org/gtk/WidgetFactory4/nyc.jpg");
|
||||
load_texture_in_thread ((GtkWidget *)gtk_builder_get_object (builder, "notebook_beach"),
|
||||
"/org/gtk/WidgetFactory4/beach.jpg");
|
||||
|
||||
if (g_strcmp0 (PROFILE, "devel") == 0)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (window), "devel");
|
||||
|
||||
|
||||
@@ -1263,8 +1263,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/sunset.jpg</property>
|
||||
<object class="GtkPicture" id="notebook_sunset">
|
||||
<property name="content-fit">cover</property>
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
@@ -1290,8 +1289,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/nyc.jpg</property>
|
||||
<object class="GtkPicture" id="notebook_nyc">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
@@ -1316,8 +1314,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<child>
|
||||
<object class="GtkNotebookPage">
|
||||
<property name="child">
|
||||
<object class="GtkPicture">
|
||||
<property name="file">resource:///org/gtk/WidgetFactory4/beach.jpg</property>
|
||||
<object class="GtkPicture" id="notebook_beach">
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="on_picture_drag_prepare" swapped="no"/>
|
||||
|
||||
@@ -18,12 +18,12 @@ search_index = true
|
||||
docs_url = "https://docs.gtk.org/gobject/"
|
||||
|
||||
[dependencies."Gio-2.0"]
|
||||
name = "GIO"
|
||||
name = "Gio"
|
||||
description = "GObject Interfaces and Objects, Networking, IPC, and I/O"
|
||||
docs_url = "https://docs.gtk.org/gio/"
|
||||
|
||||
[dependencies."cairo-1.0"]
|
||||
name = "Cairo"
|
||||
name = "cairo"
|
||||
description = "A 2D graphics library with support for multiple output devices"
|
||||
docs_url = "https://www.cairographics.org/manual/"
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ dependencies = ["Graphene-1.0", "Gdk-4.0"]
|
||||
docs_url = "https://ebassi.github.io/graphene/docs/"
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
name = "Gdk"
|
||||
description = "The GTK windowing system abstraction"
|
||||
docs_url = "https://docs.gtk.org/gdk4/"
|
||||
|
||||
|
||||
@@ -236,23 +236,17 @@ By default, GTK will try to build with support for the Vulkan graphics
|
||||
API in addition to cairo and OpenGL. This option can be used to explicitly
|
||||
control whether Vulkan should be used.
|
||||
|
||||
### `xinerama`
|
||||
|
||||
By default, GTK will try to link against the Xinerama libraries
|
||||
if they are found. This option can be used to explicitly control
|
||||
whether Xinerama should be used.
|
||||
|
||||
### `media`
|
||||
### `media-gstreamer` and `media-ffmpeg`
|
||||
|
||||
By default, GTK will try to build the gstreamer backend for
|
||||
media playback support. This option can be used to explicitly
|
||||
media playback support. These option can be used to explicitly
|
||||
control which media backends should be built.
|
||||
|
||||
### `print`
|
||||
### `print-cups`
|
||||
|
||||
By default, GTK will try to build various print backends
|
||||
if their dependencies are found. This option can be used
|
||||
to explicitly control which print backends should be built.
|
||||
to explicitly control whether the cups print backend should be built.
|
||||
|
||||
### `cloudproviders`
|
||||
|
||||
@@ -274,18 +268,13 @@ support in the file chooser.
|
||||
This option controls whether GTK should use colord for color
|
||||
calibration support in the cups print backend.
|
||||
|
||||
### `gtk_doc` and `man-pages`
|
||||
### `gtk_doc`, `man-pages` and `update_screenshots`
|
||||
|
||||
The *gtk-doc* package is used to generate the reference documentation
|
||||
included with GTK. By default support for *gtk-doc* is disabled
|
||||
The *gi-docgen* package is used to generate the reference documentation
|
||||
included with GTK. By default support for *gi-docgen* is disabled
|
||||
because it requires various extra dependencies to be installed.
|
||||
If you have *gtk-doc* and *pandoc* installed and are modifying GTK,
|
||||
you may want to enable *gtk-doc* support by passing in `-Dgtk_doc=true`.
|
||||
|
||||
Additionally, some tools provided by GTK have their own
|
||||
manual pages generated using a similar set of dependencies;
|
||||
if you have *xsltproc* then you can generate manual pages by
|
||||
passing `-Dman-pages=true` when configuring the build.
|
||||
Introspection needs to be enabled, since the documentation is generated
|
||||
from introspection data.
|
||||
|
||||
### `introspection`
|
||||
|
||||
@@ -294,9 +283,14 @@ is mainly useful for shortening turnaround times on developer
|
||||
systems. Installed builds of GTK should always have introspection
|
||||
support.
|
||||
|
||||
### `build-tests`, `demos`
|
||||
### `build-testsuite`
|
||||
|
||||
By default, GTK will build quite a few tests and demos.
|
||||
If you want to run the testsuite to ensure that your GTK build
|
||||
works, you should enable it with this option.
|
||||
|
||||
### `build-tests`, `build-examples`, `demos`
|
||||
|
||||
By default, GTK will build quite a few tests, examples and demos.
|
||||
While these are useful on a developer system, they are not
|
||||
needed when GTK is built e.g. for a flatpak runtime. These
|
||||
options allow to disable building tests and demos.
|
||||
|
||||
@@ -377,7 +377,7 @@ demonstrates input event handling with event controllers.
|
||||
|
||||
### Drawing in response to input
|
||||
|
||||
Create a new file with the following content named `example-4.c`.
|
||||
Create a new file with the following content named `example-3.c`.
|
||||
|
||||
```c
|
||||
#include <gtk/gtk.h>
|
||||
@@ -572,7 +572,7 @@ main (int argc,
|
||||
You can compile the program above with GCC using:
|
||||
|
||||
```
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-4 example-4.c $( pkg-config --libs gtk4 )
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-3 example-3.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
## Building user interfaces
|
||||
@@ -587,7 +587,7 @@ XML format that can be parsed by the [class@Gtk.Builder] class.
|
||||
|
||||
### Packing buttons with GtkBuilder
|
||||
|
||||
Create a new file with the following content named `example-3.c`.
|
||||
Create a new file with the following content named `example-4.c`.
|
||||
|
||||
```c
|
||||
#include <gtk/gtk.h>
|
||||
@@ -697,7 +697,7 @@ Create a new file with the following content named `builder.ui`.
|
||||
You can compile the program above with GCC using:
|
||||
|
||||
```
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-3 example-3.c $( pkg-config --libs gtk4 )
|
||||
gcc $( pkg-config --cflags gtk4 ) -o example-4 example-4.c $( pkg-config --libs gtk4 )
|
||||
```
|
||||
|
||||
Note that `GtkBuilder` can also be used to construct objects that are
|
||||
|
||||
@@ -14,12 +14,12 @@ search_index = true
|
||||
dependencies = ["Gdk-4.0", "Gsk-4.0"]
|
||||
|
||||
[dependencies."Gdk-4.0"]
|
||||
name = "GDK"
|
||||
name = "Gdk"
|
||||
description = "The GTK windowing system abstraction"
|
||||
docs_url = "https://docs.gtk.org/gdk4/"
|
||||
|
||||
[dependencies."Gsk-4.0"]
|
||||
name = "GSK"
|
||||
name = "Gsk"
|
||||
description = "The GTK rendering abstraction"
|
||||
docs_url = "https://docs.gtk.org/gsk4/"
|
||||
|
||||
|
||||
@@ -105,3 +105,7 @@ retire it. If you need such a widget, it is relatively trivial to create one
|
||||
using a [class@Gtk.Revealer] with labels and buttons.
|
||||
|
||||
Other libraries, such as libadwaita, may provide replacements as well.
|
||||
|
||||
## gtk_show_uri is being replaced
|
||||
|
||||
Instead of gtk_show_uri(), you should use GtkUriLauncher or GtkFileLauncher.
|
||||
|
||||
+6
-7
@@ -471,8 +471,8 @@ gdk_display_get_event (GdkDisplay *display)
|
||||
* Appends the given event onto the front of the event
|
||||
* queue for @display.
|
||||
*
|
||||
* This function is only useful in very special situations
|
||||
* and should not be used by applications.
|
||||
* Deprecated: 4.10: This function is only useful in very
|
||||
* special situations and should not be used by applications.
|
||||
**/
|
||||
void
|
||||
gdk_display_put_event (GdkDisplay *display,
|
||||
@@ -1148,6 +1148,8 @@ _gdk_display_get_next_serial (GdkDisplay *display)
|
||||
* with custom startup-notification identifier unless
|
||||
* [method@Gtk.Window.set_auto_startup_notification]
|
||||
* is called to disable that feature.
|
||||
*
|
||||
* Deprecated: 4.10. Using gdk_toplevel_set_startup_id() is sufficient.
|
||||
*/
|
||||
void
|
||||
gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
@@ -1775,11 +1777,11 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
gpointer
|
||||
gdk_display_get_egl_display (GdkDisplay *self)
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!priv->egl_display &&
|
||||
!gdk_display_prepare_gl (self, NULL))
|
||||
return NULL;
|
||||
@@ -2013,10 +2015,7 @@ gdk_display_get_monitors (GdkDisplay *self)
|
||||
* Gets the monitor in which the largest area of @surface
|
||||
* resides.
|
||||
*
|
||||
* Returns a monitor close to @surface if it is outside
|
||||
* of all monitors.
|
||||
*
|
||||
* Returns: (transfer none): the monitor with the largest
|
||||
* Returns: (transfer none) (nullable): the monitor with the largest
|
||||
* overlap with @surface
|
||||
*/
|
||||
GdkMonitor *
|
||||
|
||||
+2
-2
@@ -83,7 +83,7 @@ GdkClipboard * gdk_display_get_clipboard (GdkDisplay
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkClipboard * gdk_display_get_primary_clipboard (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10_FOR(gdk_toplevel_set_startup_id)
|
||||
void gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
const char *startup_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
@@ -104,7 +104,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkMonitor * gdk_display_get_monitor_at_surface (GdkDisplay *display,
|
||||
GdkSurface *surface);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gdk_display_put_event (GdkDisplay *display,
|
||||
GdkEvent *event);
|
||||
|
||||
|
||||
@@ -621,8 +621,11 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (timings)
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
|
||||
+1
-1
@@ -504,8 +504,8 @@ gdk_gl_context_real_is_shared (GdkGLContext *self,
|
||||
static gboolean
|
||||
gdk_gl_context_real_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
#ifdef HAVE_EGL
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->egl_context == NULL)
|
||||
|
||||
+3
-3
@@ -586,7 +586,7 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
|
||||
{
|
||||
const char *s = token->string.string;
|
||||
const char *s = gtk_css_token_get_string (token);
|
||||
|
||||
switch (strlen (s))
|
||||
{
|
||||
@@ -637,13 +637,13 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
|
||||
{
|
||||
*rgba = (GdkRGBA) { 0, 0, 0, 0 };
|
||||
}
|
||||
else if (gdk_rgba_parse (rgba, token->string.string))
|
||||
else if (gdk_rgba_parse (rgba, gtk_css_token_get_string (token)))
|
||||
{
|
||||
/* everything's fine */
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", token->string.string);
|
||||
gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", gtk_css_token_get_string (token));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -463,7 +463,7 @@ gdk_texture_new_from_resource (const char *resource_path)
|
||||
* Creates a new texture by loading an image from a file.
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
* are PNG, JPEG and TIFF, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
@@ -556,7 +556,7 @@ gdk_texture_new_from_bytes_pixbuf (GBytes *bytes,
|
||||
* Creates a new texture by loading an image from memory,
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
* are PNG, JPEG and TIFF, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
@@ -602,7 +602,7 @@ gdk_texture_new_from_bytes (GBytes *bytes,
|
||||
* Creates a new texture by loading an image from a file.
|
||||
*
|
||||
* The file format is detected automatically. The supported formats
|
||||
* are PNG and JPEG, though more formats might be available.
|
||||
* are PNG, JPEG and TIFF, though more formats might be available.
|
||||
*
|
||||
* If %NULL is returned, then @error will be set.
|
||||
*
|
||||
|
||||
@@ -576,6 +576,8 @@ typedef NSString *CALayerContentsGravity;
|
||||
initialResizeLocation = convert_nspoint_to_screen (self, [self mouseLocationOutsideOfEventStream]);
|
||||
}
|
||||
|
||||
// NSDraggingDestination protocol
|
||||
|
||||
-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPoint location = [sender draggingLocation];
|
||||
@@ -665,9 +667,9 @@ typedef NSString *CALayerContentsGravity;
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
}
|
||||
// NSDraggingSource protocol
|
||||
// ...
|
||||
// end
|
||||
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask
|
||||
{
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
#include "gdkmacoscursor-private.h"
|
||||
|
||||
@interface NSCursor()
|
||||
-(long long)_coreCursorType;
|
||||
@end
|
||||
|
||||
/* OS X only exports a number of cursor types in its public NSCursor interface.
|
||||
* By overriding the private _coreCursorType method, we can tell OS X to load
|
||||
* one of its internal cursors instead (since cursor images are loaded on demand
|
||||
|
||||
@@ -218,6 +218,12 @@ drag_ungrab (GdkMacosDrag *self)
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
if (self->drag_seat)
|
||||
{
|
||||
gdk_seat_ungrab (self->drag_seat);
|
||||
g_clear_object (&self->drag_seat);
|
||||
}
|
||||
|
||||
display = gdk_drag_get_display (GDK_DRAG (self));
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), GDK_CURRENT_TIME);
|
||||
}
|
||||
@@ -536,7 +542,11 @@ gdk_macos_drag_finalize (GObject *object)
|
||||
GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
|
||||
|
||||
g_clear_object (&self->cursor);
|
||||
g_clear_object (&self->drag_seat);
|
||||
if (self->drag_seat)
|
||||
{
|
||||
gdk_seat_ungrab (self->drag_seat);
|
||||
g_clear_object (&self->drag_seat);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_macos_drag_parent_class)->finalize (object);
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
_gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
|
||||
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
|
||||
GDK_SURFACE_DRAG,
|
||||
surface,
|
||||
NULL,
|
||||
sx, sy, 1, 1);
|
||||
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
|
||||
"drag-surface", drag_surface,
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "gdkvulkancontext-wayland.h"
|
||||
#include "gdkwaylandmonitor.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdktoplevel-wayland-private.h"
|
||||
#include <wayland/pointer-gestures-unstable-v1-client-protocol.h>
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
|
||||
@@ -367,10 +367,10 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
GdkWaylandDrag *drag_wayland;
|
||||
GdkDrag *drag;
|
||||
GdkSeat *seat;
|
||||
GdkWaylandDisplay *display_wayland;
|
||||
GdkDisplay *display;
|
||||
GdkCursor *cursor;
|
||||
|
||||
display_wayland = GDK_WAYLAND_DISPLAY (gdk_device_get_display (device));
|
||||
display = gdk_device_get_display (device);
|
||||
seat = gdk_device_get_seat (device);
|
||||
|
||||
drag_wayland = g_object_new (GDK_TYPE_WAYLAND_DRAG,
|
||||
@@ -382,17 +382,13 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
|
||||
drag = GDK_DRAG (drag_wayland);
|
||||
|
||||
drag_wayland->dnd_surface = create_dnd_surface (gdk_surface_get_display (surface));
|
||||
drag_wayland->dnd_surface = _gdk_wayland_display_create_surface (display, GDK_SURFACE_DRAG, NULL, 0, 0, 100, 100);
|
||||
drag_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface);
|
||||
|
||||
|
||||
gdk_wayland_drag_create_data_source (drag);
|
||||
|
||||
if (display_wayland->data_device_manager_version >=
|
||||
WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
|
||||
{
|
||||
wl_data_source_set_actions (drag_wayland->data_source,
|
||||
gdk_to_wl_actions (actions));
|
||||
}
|
||||
if (GDK_WAYLAND_DISPLAY (display)->data_device_manager_version >= WL_DATA_SOURCE_SET_ACTIONS_SINCE_VERSION)
|
||||
wl_data_source_set_actions (drag_wayland->data_source, gdk_to_wl_actions (actions));
|
||||
|
||||
gdk_wayland_seat_set_drag (seat, drag);
|
||||
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright © 2022 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 "gdksurface-wayland.h"
|
||||
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkdragsurfaceprivate.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkframeclockidleprivate.h"
|
||||
#include "gdkglcontext-wayland.h"
|
||||
#include "gdkmonitor-wayland.h"
|
||||
#include "gdkpopupprivate.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkseat-wayland.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gdksurface-wayland-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkWaylandSurface parent_instance;
|
||||
} GdkWaylandDragSurface;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkWaylandSurfaceClass parent_class;
|
||||
} GdkWaylandDragSurfaceClass;
|
||||
|
||||
static void gdk_wayland_drag_surface_iface_init (GdkDragSurfaceInterface *iface);
|
||||
|
||||
#define GDK_IS_WAYLAND_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_DRAG_SURFACE))
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkWaylandDragSurface, gdk_wayland_drag_surface, GDK_TYPE_WAYLAND_SURFACE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE,
|
||||
gdk_wayland_drag_surface_iface_init))
|
||||
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_surface_init (GdkWaylandDragSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (impl->next_layout.surface_geometry_dirty)
|
||||
{
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
impl->scale);
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_surface_class_init (GdkWaylandDragSurfaceClass *class)
|
||||
{
|
||||
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class);
|
||||
|
||||
surface_class->compute_size = gdk_wayland_drag_surface_compute_size;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_notify_mapped (GdkSurface *surface)
|
||||
{
|
||||
if (surface->destroyed)
|
||||
return;
|
||||
|
||||
if (!GDK_SURFACE_IS_MAPPED (surface))
|
||||
gdk_surface_set_is_mapped (surface, TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkSurface *surface = GDK_SURFACE (drag_surface);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->display_server.wl_surface)
|
||||
gdk_wayland_surface_create_wl_surface (surface);
|
||||
|
||||
impl->next_layout.configured_width = width;
|
||||
impl->next_layout.configured_height = height;
|
||||
impl->next_layout.surface_geometry_dirty = TRUE;
|
||||
gdk_surface_request_layout (surface);
|
||||
|
||||
maybe_notify_mapped (surface);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_drag_surface_iface_init (GdkDragSurfaceInterface *iface)
|
||||
{
|
||||
iface->present = gdk_wayland_drag_surface_present;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -191,8 +191,6 @@ void gdk_wayland_surface_restore_shortcuts (GdkSurface *surface,
|
||||
|
||||
void gdk_wayland_surface_update_scale (GdkSurface *surface);
|
||||
|
||||
GdkSurface * create_dnd_surface (GdkDisplay *display);
|
||||
|
||||
GdkModifierType gdk_wayland_keymap_get_gdk_modifiers (GdkKeymap *keymap,
|
||||
guint32 mods);
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright © 2022 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum _PopupState
|
||||
{
|
||||
POPUP_STATE_IDLE,
|
||||
POPUP_STATE_WAITING_FOR_REPOSITIONED,
|
||||
POPUP_STATE_WAITING_FOR_CONFIGURE,
|
||||
POPUP_STATE_WAITING_FOR_FRAME,
|
||||
} PopupState;
|
||||
|
||||
struct _GdkWaylandSurface
|
||||
{
|
||||
GdkSurface parent_instance;
|
||||
|
||||
struct {
|
||||
GSList *outputs;
|
||||
struct wl_surface *wl_surface;
|
||||
struct xdg_surface *xdg_surface;
|
||||
struct zxdg_surface_v6 *zxdg_surface_v6;
|
||||
struct wl_egl_window *egl_window;
|
||||
} display_server;
|
||||
|
||||
struct wl_event_queue *event_queue;
|
||||
|
||||
unsigned int initial_configure_received : 1;
|
||||
unsigned int has_uncommitted_ack_configure : 1;
|
||||
unsigned int mapped : 1;
|
||||
unsigned int awaiting_frame : 1;
|
||||
unsigned int awaiting_frame_frozen : 1;
|
||||
|
||||
int pending_buffer_offset_x;
|
||||
int pending_buffer_offset_y;
|
||||
|
||||
gint64 pending_frame_counter;
|
||||
guint32 scale;
|
||||
|
||||
int shadow_left;
|
||||
int shadow_right;
|
||||
int shadow_top;
|
||||
int shadow_bottom;
|
||||
|
||||
cairo_region_t *opaque_region;
|
||||
gboolean opaque_region_dirty;
|
||||
|
||||
cairo_region_t *input_region;
|
||||
gboolean input_region_dirty;
|
||||
|
||||
GdkRectangle last_sent_window_geometry;
|
||||
|
||||
struct {
|
||||
gboolean is_initial_configure;
|
||||
uint32_t serial;
|
||||
gboolean is_dirty;
|
||||
} pending;
|
||||
|
||||
struct {
|
||||
int configured_width;
|
||||
int configured_height;
|
||||
gboolean surface_geometry_dirty;
|
||||
} next_layout;
|
||||
|
||||
uint32_t last_configure_serial;
|
||||
|
||||
int state_freeze_count;
|
||||
};
|
||||
|
||||
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
|
||||
struct _GdkWaylandSurfaceClass
|
||||
{
|
||||
GdkSurfaceClass parent_class;
|
||||
|
||||
void (* handle_configure) (GdkWaylandSurface *surface);
|
||||
|
||||
void (* handle_frame) (GdkWaylandSurface *surface);
|
||||
|
||||
void (* hide_surface) (GdkWaylandSurface *surface);
|
||||
};
|
||||
|
||||
#define GDK_WAYLAND_SURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass))
|
||||
|
||||
#define GDK_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass))
|
||||
|
||||
void gdk_wayland_surface_create_wl_surface (GdkSurface *surface);
|
||||
void gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int scale);
|
||||
void gdk_wayland_surface_create_xdg_surface_resources (GdkSurface *surface);
|
||||
void _gdk_wayland_surface_save_size (GdkSurface *surface);
|
||||
|
||||
void gdk_wayland_surface_hide_surface (GdkSurface *surface);
|
||||
void gdk_wayland_surface_move_resize (GdkSurface *surface,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
|
||||
GdkRectangle *geometry);
|
||||
void gdk_wayland_surface_freeze_state (GdkSurface *surface);
|
||||
void gdk_wayland_surface_thaw_state (GdkSurface *surface);
|
||||
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DRAG_SURFACE (gdk_wayland_drag_surface_get_type ())
|
||||
GType gdk_wayland_drag_surface_get_type (void) G_GNUC_CONST;
|
||||
+208
-4262
File diff suppressed because it is too large
Load Diff
@@ -21,26 +21,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkwaylandsurface.h"
|
||||
#include "gdkwaylandtoplevel.h"
|
||||
#include "gdkwaylandpopup.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel,
|
||||
const char *application_id,
|
||||
const char *app_menu_path,
|
||||
const char *menubar_path,
|
||||
const char *window_object_path,
|
||||
const char *application_object_path,
|
||||
const char *unique_bus_name);
|
||||
|
||||
void gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel);
|
||||
|
||||
gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
|
||||
|
||||
|
||||
struct gtk_surface1 * gdk_wayland_toplevel_get_gtk_surface (GdkWaylandToplevel *wayland_toplevel);
|
||||
|
||||
void gdk_wayland_surface_ensure_wl_egl_window (GdkSurface *surface);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright © 2022 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
void gdk_wayland_toplevel_set_geometry_hints (GdkWaylandToplevel *toplevel,
|
||||
const GdkGeometry *geometry,
|
||||
GdkSurfaceHints geom_mask);
|
||||
|
||||
struct gtk_surface1 *
|
||||
gdk_wayland_toplevel_get_gtk_surface (GdkWaylandToplevel *wayland_toplevel);
|
||||
|
||||
void gdk_wayland_toplevel_set_dbus_properties (GdkToplevel *toplevel,
|
||||
const char *application_id,
|
||||
const char *app_menu_path,
|
||||
const char *menubar_path,
|
||||
const char *window_object_path,
|
||||
const char *application_object_path,
|
||||
const char *unique_bus_name);
|
||||
|
||||
void gdk_wayland_toplevel_announce_csd (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_announce_ssd (GdkToplevel *toplevel);
|
||||
|
||||
gboolean gdk_wayland_toplevel_inhibit_idle (GdkToplevel *toplevel);
|
||||
void gdk_wayland_toplevel_uninhibit_idle (GdkToplevel *toplevel);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,10 +31,12 @@
|
||||
|
||||
#include <gdk/wayland/gdkwaylanddevice.h>
|
||||
#include <gdk/wayland/gdkwaylanddisplay.h>
|
||||
#include <gdk/wayland/gdkwaylandglcontext.h>
|
||||
#include <gdk/wayland/gdkwaylandmonitor.h>
|
||||
#include <gdk/wayland/gdkwaylandpopup.h>
|
||||
#include <gdk/wayland/gdkwaylandseat.h>
|
||||
#include <gdk/wayland/gdkwaylandsurface.h>
|
||||
#include <gdk/wayland/gdkwaylandglcontext.h>
|
||||
#include <gdk/wayland/gdkwaylandtoplevel.h>
|
||||
|
||||
#undef __GDKWAYLAND_H_INSIDE__
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2013 Jan Arne Petersen
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/wayland/gdkwayland.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/wayland/gdkwaylandsurface.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkWaylandPopup GdkWaylandPopup;
|
||||
#else
|
||||
typedef GdkPopup GdkWaylandPopup;
|
||||
#endif
|
||||
|
||||
#define GDK_TYPE_WAYLAND_POPUP (gdk_wayland_popup_get_type())
|
||||
#define GDK_WAYLAND_POPUP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_POPUP, GdkWaylandPopup))
|
||||
#define GDK_IS_WAYLAND_POPUP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_POPUP))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_wayland_popup_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -30,59 +30,20 @@ G_BEGIN_DECLS
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkWaylandSurface GdkWaylandSurface;
|
||||
typedef struct _GdkWaylandToplevel GdkWaylandToplevel;
|
||||
typedef struct _GdkWaylandPopup GdkWaylandPopup;
|
||||
#else
|
||||
typedef GdkSurface GdkWaylandSurface;
|
||||
typedef GdkToplevel GdkWaylandToplevel;
|
||||
typedef GdkPopup GdkWaylandPopup;
|
||||
#endif
|
||||
|
||||
#define GDK_TYPE_WAYLAND_SURFACE (gdk_wayland_surface_get_type())
|
||||
#define GDK_WAYLAND_SURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurface))
|
||||
#define GDK_IS_WAYLAND_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_SURFACE))
|
||||
|
||||
#define GDK_TYPE_WAYLAND_TOPLEVEL (gdk_wayland_toplevel_get_type())
|
||||
#define GDK_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_TOPLEVEL, GdkWaylandToplevel))
|
||||
#define GDK_IS_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_TOPLEVEL))
|
||||
|
||||
#define GDK_TYPE_WAYLAND_POPUP (gdk_wayland_popup_get_type())
|
||||
#define GDK_WAYLAND_POPUP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_POPUP, GdkWaylandPopup))
|
||||
#define GDK_IS_WAYLAND_POPUP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_POPUP))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_wayland_surface_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_wayland_toplevel_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_wayland_popup_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
struct wl_surface *gdk_wayland_surface_get_wl_surface (GdkSurface *surface);
|
||||
|
||||
typedef void (*GdkWaylandToplevelExported) (GdkToplevel *toplevel,
|
||||
const char *handle,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
|
||||
GdkWaylandToplevelExported callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_func);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel,
|
||||
const char *parent_handle_str);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
|
||||
const char *application_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_WAYLAND_SURFACE_H__ */
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2013 Jan Arne Petersen
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/wayland/gdkwayland.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/wayland/gdkwaylandsurface.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef GTK_COMPILATION
|
||||
typedef struct _GdkWaylandToplevel GdkWaylandToplevel;
|
||||
#else
|
||||
typedef GdkToplevel GdkWaylandToplevel;
|
||||
#endif
|
||||
|
||||
#define GDK_TYPE_WAYLAND_TOPLEVEL (gdk_wayland_toplevel_get_type())
|
||||
#define GDK_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_TOPLEVEL, GdkWaylandToplevel))
|
||||
#define GDK_IS_WAYLAND_TOPLEVEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_TOPLEVEL))
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gdk_wayland_toplevel_get_type (void);
|
||||
|
||||
|
||||
typedef void (*GdkWaylandToplevelExported) (GdkToplevel *toplevel,
|
||||
const char *handle,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_wayland_toplevel_export_handle (GdkToplevel *toplevel,
|
||||
GdkWaylandToplevelExported callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify destroy_func);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_toplevel_unexport_handle (GdkToplevel *toplevel);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_wayland_toplevel_set_transient_for_exported (GdkToplevel *toplevel,
|
||||
const char *parent_handle_str);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_toplevel_set_application_id (GdkToplevel *toplevel,
|
||||
const char *application_id);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -8,14 +8,17 @@ gdk_wayland_sources = files([
|
||||
'gdkdevice-wayland.c',
|
||||
'gdkdisplay-wayland.c',
|
||||
'gdkdrag-wayland.c',
|
||||
'gdkdragsurface-wayland.c',
|
||||
'gdkdrop-wayland.c',
|
||||
'gdkeventsource.c',
|
||||
'gdkglcontext-wayland.c',
|
||||
'gdkkeys-wayland.c',
|
||||
'gdkmonitor-wayland.c',
|
||||
'gdkprimary-wayland.c',
|
||||
'gdkvulkancontext-wayland.c',
|
||||
'gdksurface-wayland.c',
|
||||
'gdktoplevel-wayland.c',
|
||||
'gdkpopup-wayland.c',
|
||||
'gdkvulkancontext-wayland.c',
|
||||
'wm-button-layout-translation.c',
|
||||
])
|
||||
|
||||
@@ -24,8 +27,10 @@ gdk_wayland_public_headers = files([
|
||||
'gdkwaylanddisplay.h',
|
||||
'gdkwaylandglcontext.h',
|
||||
'gdkwaylandmonitor.h',
|
||||
'gdkwaylandpopup.h',
|
||||
'gdkwaylandseat.h',
|
||||
'gdkwaylandsurface.h',
|
||||
'gdkwaylandtoplevel.h',
|
||||
])
|
||||
|
||||
install_headers(gdk_wayland_public_headers, 'gdkwayland.h', subdir: 'gtk-4.0/gdk/wayland/')
|
||||
|
||||
@@ -283,6 +283,9 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
|
||||
GFileInfo *fileinfo;
|
||||
GdkAppLaunchContext *ctx;
|
||||
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
ctx = GDK_APP_LAUNCH_CONTEXT (context);
|
||||
|
||||
display = ctx->display;
|
||||
|
||||
@@ -1450,7 +1450,9 @@ _gdk_device_manager_xi2_handle_focus (GdkSurface *surface,
|
||||
GdkEvent *event;
|
||||
|
||||
event = gdk_focus_event_new (surface, device, focus_in);
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gdk_display_put_event (gdk_surface_get_display (surface), event);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,9 @@ handle_focus_change (GdkEvent *event)
|
||||
focus_event = gdk_focus_event_new (gdk_event_get_surface (event),
|
||||
gdk_event_get_device (event),
|
||||
focus_in);
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gdk_display_put_event (gdk_event_get_display (event), focus_event);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
gdk_event_unref (focus_event);
|
||||
}
|
||||
}
|
||||
@@ -206,7 +208,9 @@ handle_touch_synthetic_crossing (GdkEvent *event)
|
||||
|
||||
if (crossing)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gdk_display_put_event (gdk_seat_get_display (seat), crossing);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
gdk_event_unref (crossing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -982,7 +982,7 @@ gdk_x11_selection_output_streams_request (GdkDisplay *display,
|
||||
GOutputStream *stream;
|
||||
|
||||
if (special_targets[i].mime_type)
|
||||
mime_type = gdk_intern_mime_type (special_targets[i].mime_type);
|
||||
gdk_intern_mime_type (special_targets[i].mime_type);
|
||||
stream = gdk_x11_selection_output_stream_new (display,
|
||||
notify,
|
||||
requestor,
|
||||
|
||||
@@ -2648,6 +2648,7 @@ gdk_x11_surface_set_startup_id (GdkSurface *surface,
|
||||
const char *startup_id)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
char *free_this = NULL;
|
||||
|
||||
g_return_if_fail (GDK_IS_SURFACE (surface));
|
||||
|
||||
@@ -2664,6 +2665,23 @@ gdk_x11_surface_set_startup_id (GdkSurface *surface,
|
||||
else
|
||||
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_SURFACE_XID (surface),
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
|
||||
|
||||
if (startup_id == NULL)
|
||||
{
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
startup_id = free_this = display_x11->startup_notification_id;
|
||||
display_x11->startup_notification_id = NULL;
|
||||
|
||||
if (startup_id == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_x11_display_broadcast_startup_message (display, "remove",
|
||||
"ID", startup_id,
|
||||
NULL);
|
||||
|
||||
g_free (free_this);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -184,7 +184,7 @@ gsk_gl_driver_shader_weak_cb (gpointer data,
|
||||
}
|
||||
}
|
||||
|
||||
G_GNUC_NULL_TERMINATED static inline GBytes *
|
||||
G_GNUC_UNUSED G_GNUC_NULL_TERMINATED static inline GBytes *
|
||||
join_sources (GBytes *first_bytes,
|
||||
...)
|
||||
{
|
||||
|
||||
@@ -418,7 +418,7 @@ parse_string (GtkCssParser *parser,
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
|
||||
return FALSE;
|
||||
|
||||
s = g_strdup (token->string.string);
|
||||
s = g_strdup (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
g_free (*(char **) out_string);
|
||||
@@ -931,7 +931,7 @@ parse_declarations (GtkCssParser *parser,
|
||||
{
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||
gtk_css_parser_error_syntax (parser, "No variable named \"%s\"",
|
||||
gtk_css_parser_get_token (parser)->string.string);
|
||||
gtk_css_token_get_string (gtk_css_parser_get_token (parser)));
|
||||
else
|
||||
gtk_css_parser_error_syntax (parser, "Expected a variable name");
|
||||
}
|
||||
@@ -1894,7 +1894,7 @@ parse_node (GtkCssParser *parser,
|
||||
|
||||
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
|
||||
gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name",
|
||||
gtk_css_parser_get_token (parser)->string.string);
|
||||
gtk_css_token_get_string (gtk_css_parser_get_token (parser)));
|
||||
else
|
||||
gtk_css_parser_error_syntax (parser, "Expected a node name");
|
||||
|
||||
|
||||
@@ -444,6 +444,9 @@ gtk_at_spi_cache_remove_context (GtkAtSpiCache *self,
|
||||
g_return_if_fail (GTK_IS_AT_SPI_CONTEXT (context));
|
||||
|
||||
const char *path = gtk_at_spi_context_get_context_path (context);
|
||||
if (path == NULL)
|
||||
return;
|
||||
|
||||
if (!g_hash_table_contains (self->contexts_by_path, path))
|
||||
return;
|
||||
|
||||
|
||||
@@ -690,7 +690,8 @@ gtk_at_spi_root_constructed (GObject *gobject)
|
||||
/* No need to validate the path */
|
||||
self->base_path = g_strconcat (app_path, "/a11y", NULL);
|
||||
}
|
||||
else
|
||||
|
||||
if (self->base_path == NULL)
|
||||
{
|
||||
const char *program_name = g_get_prgname ();
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/* GSK - The GIMP Toolkit
|
||||
* Copyright (C) 2019 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* 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 "gtkcsslocationprivate.h"
|
||||
|
||||
/**
|
||||
* GtkCssLocation:
|
||||
* @bytes: number of bytes parsed since the beginning
|
||||
* @chars: number of characters parsed since the beginning
|
||||
* @lines: number of full lines that have been parsed. If you want to
|
||||
* display this as a line number, you need to add 1 to this.
|
||||
* @line_bytes: Number of bytes parsed since the last line break
|
||||
* @line_chars: Number of characters parsed since the last line break
|
||||
*
|
||||
* Represents a location in a file or other source of data parsed
|
||||
* by the CSS engine.
|
||||
*
|
||||
* The @bytes and @line_bytes offsets are meant to be used to
|
||||
* programmatically match data. The @lines and @line_chars offsets
|
||||
* can be used for printing the location in a file.
|
||||
*
|
||||
* Note that the @lines parameter starts from 0 and is increased
|
||||
* whenever a CSS line break is encountered. (CSS defines the C character
|
||||
* sequences "\r\n", "\r", "\n" and "\f" as newlines.)
|
||||
* If your document uses different rules for line breaking, you might want
|
||||
* run into problems here.
|
||||
*/
|
||||
|
||||
void
|
||||
gtk_css_location_init (GtkCssLocation *location)
|
||||
{
|
||||
memset (location, 0, sizeof (GtkCssLocation));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_location_advance (GtkCssLocation *location,
|
||||
gsize bytes,
|
||||
gsize chars)
|
||||
{
|
||||
location->bytes += bytes;
|
||||
location->chars += chars;
|
||||
location->line_bytes += bytes;
|
||||
location->line_chars += chars;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_location_advance_newline (GtkCssLocation *location,
|
||||
gboolean is_windows)
|
||||
{
|
||||
gtk_css_location_advance (location, is_windows ? 2 : 1, is_windows ? 2 : 1);
|
||||
|
||||
location->lines++;
|
||||
location->line_bytes = 0;
|
||||
location->line_chars = 0;
|
||||
}
|
||||
|
||||
@@ -25,13 +25,33 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_css_location_init (GtkCssLocation *location);
|
||||
static inline void
|
||||
gtk_css_location_init (GtkCssLocation *location)
|
||||
{
|
||||
memset (location, 0, sizeof (GtkCssLocation));
|
||||
}
|
||||
|
||||
void gtk_css_location_advance (GtkCssLocation *location,
|
||||
gsize bytes,
|
||||
gsize chars);
|
||||
void gtk_css_location_advance_newline (GtkCssLocation *location,
|
||||
gboolean is_windows);
|
||||
static inline void
|
||||
gtk_css_location_advance (GtkCssLocation *location,
|
||||
gsize bytes,
|
||||
gsize chars)
|
||||
{
|
||||
location->bytes += bytes;
|
||||
location->chars += chars;
|
||||
location->line_bytes += bytes;
|
||||
location->line_chars += chars;
|
||||
}
|
||||
|
||||
static inline void
|
||||
gtk_css_location_advance_newline (GtkCssLocation *location,
|
||||
gboolean is_windows)
|
||||
{
|
||||
location->bytes += is_windows ? 2 : 1;
|
||||
location->chars += is_windows ? 2 : 1;
|
||||
location->line_bytes = 0;
|
||||
location->line_chars = 0;
|
||||
location->lines++;
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+11
-12
@@ -642,13 +642,13 @@ gtk_css_parser_consume_function (GtkCssParser *self,
|
||||
{
|
||||
const GtkCssToken *token;
|
||||
gboolean result = FALSE;
|
||||
char *function_name;
|
||||
char function_name[64];
|
||||
guint arg;
|
||||
|
||||
token = gtk_css_parser_get_token (self);
|
||||
g_return_val_if_fail (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION), FALSE);
|
||||
|
||||
function_name = g_strdup (token->string.string);
|
||||
g_strlcpy (function_name, gtk_css_token_get_string (token), 64);
|
||||
gtk_css_parser_start_block (self);
|
||||
|
||||
arg = 0;
|
||||
@@ -691,7 +691,6 @@ gtk_css_parser_consume_function (GtkCssParser *self,
|
||||
}
|
||||
|
||||
gtk_css_parser_end_block (self);
|
||||
g_free (function_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -734,7 +733,7 @@ gtk_css_parser_has_ident (GtkCssParser *self,
|
||||
token = gtk_css_parser_get_token (self);
|
||||
|
||||
return gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
g_ascii_strcasecmp (token->string.string, ident) == 0;
|
||||
g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -756,7 +755,7 @@ gtk_css_parser_has_integer (GtkCssParser *self)
|
||||
* Checks if the next token is a function with the given @name.
|
||||
*
|
||||
* Returns: %TRUE if the next token is a function with the given @name
|
||||
**/
|
||||
*/
|
||||
gboolean
|
||||
gtk_css_parser_has_function (GtkCssParser *self,
|
||||
const char *name)
|
||||
@@ -766,7 +765,7 @@ gtk_css_parser_has_function (GtkCssParser *self,
|
||||
token = gtk_css_parser_get_token (self);
|
||||
|
||||
return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION) &&
|
||||
g_ascii_strcasecmp (token->string.string, name) == 0;
|
||||
g_ascii_strcasecmp (gtk_css_token_get_string (token), name) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -819,7 +818,7 @@ gtk_css_parser_try_ident (GtkCssParser *self,
|
||||
token = gtk_css_parser_get_token (self);
|
||||
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) ||
|
||||
g_ascii_strcasecmp (token->string.string, ident) != 0)
|
||||
g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) != 0)
|
||||
return FALSE;
|
||||
|
||||
gtk_css_parser_consume_token (self);
|
||||
@@ -846,7 +845,7 @@ gtk_css_parser_try_at_keyword (GtkCssParser *self,
|
||||
token = gtk_css_parser_get_token (self);
|
||||
|
||||
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_AT_KEYWORD) ||
|
||||
g_ascii_strcasecmp (token->string.string, keyword) != 0)
|
||||
g_ascii_strcasecmp (gtk_css_token_get_string (token), keyword) != 0)
|
||||
return FALSE;
|
||||
|
||||
gtk_css_parser_consume_token (self);
|
||||
@@ -908,7 +907,7 @@ gtk_css_parser_consume_ident (GtkCssParser *self)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ident = g_strdup (token->string.string);
|
||||
ident = g_strdup (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (self);
|
||||
|
||||
return ident;
|
||||
@@ -939,7 +938,7 @@ gtk_css_parser_consume_string (GtkCssParser *self)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ident = g_strdup (token->string.string);
|
||||
ident = g_strdup (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (self);
|
||||
|
||||
return ident;
|
||||
@@ -963,7 +962,7 @@ gtk_css_parser_parse_url_arg (GtkCssParser *parser,
|
||||
* gtk_css_parser_consume_url:
|
||||
* @self: a `GtkCssParser`
|
||||
*
|
||||
* If the parser matches the <url> token from the [CSS
|
||||
* If the parser matches the `<url>` token from the [CSS
|
||||
* specification](https://drafts.csswg.org/css-values-4/#url-value),
|
||||
* consumes it, resolves the URL and returns the resulting `GFile`.
|
||||
* On failure, an error is emitted and %NULL is returned.
|
||||
@@ -980,7 +979,7 @@ gtk_css_parser_consume_url (GtkCssParser *self)
|
||||
|
||||
if (gtk_css_token_is (token, GTK_CSS_TOKEN_URL))
|
||||
{
|
||||
url = g_strdup (token->string.string);
|
||||
url = g_strdup (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (self);
|
||||
}
|
||||
else if (gtk_css_token_is_function (token, "url"))
|
||||
|
||||
+49
-51
@@ -50,18 +50,14 @@ gtk_css_token_clear (GtkCssToken *token)
|
||||
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
|
||||
case GTK_CSS_TOKEN_HASH_ID:
|
||||
case GTK_CSS_TOKEN_URL:
|
||||
g_free (token->string.string);
|
||||
if (token->string.len >= 16)
|
||||
g_free (token->string.u.string);
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_INTEGER_DIMENSION:
|
||||
case GTK_CSS_TOKEN_SIGNED_DIMENSION:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_DIMENSION:
|
||||
g_free (token->dimension.dimension);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
case GTK_CSS_TOKEN_EOF:
|
||||
case GTK_CSS_TOKEN_WHITESPACE:
|
||||
case GTK_CSS_TOKEN_OPEN_PARENS:
|
||||
@@ -91,6 +87,9 @@ gtk_css_token_clear (GtkCssToken *token)
|
||||
case GTK_CSS_TOKEN_BAD_URL:
|
||||
case GTK_CSS_TOKEN_COMMENT:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
token->type = GTK_CSS_TOKEN_EOF;
|
||||
@@ -296,7 +295,7 @@ gtk_css_token_is_ident (const GtkCssToken *token,
|
||||
const char *ident)
|
||||
{
|
||||
return gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)
|
||||
&& (g_ascii_strcasecmp (token->string.string, ident) == 0);
|
||||
&& (g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -304,7 +303,7 @@ gtk_css_token_is_function (const GtkCssToken *token,
|
||||
const char *ident)
|
||||
{
|
||||
return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION)
|
||||
&& (g_ascii_strcasecmp (token->string.string, ident) == 0);
|
||||
&& (g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -324,33 +323,33 @@ gtk_css_token_print (const GtkCssToken *token,
|
||||
switch (token->type)
|
||||
{
|
||||
case GTK_CSS_TOKEN_STRING:
|
||||
append_string (string, token->string.string);
|
||||
append_string (string, gtk_css_token_get_string (token));
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_IDENT:
|
||||
append_ident (string, token->string.string);
|
||||
append_ident (string, gtk_css_token_get_string (token));
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_URL:
|
||||
g_string_append (string, "url(");
|
||||
append_ident (string, token->string.string);
|
||||
append_ident (string, gtk_css_token_get_string (token));
|
||||
g_string_append (string, ")");
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_FUNCTION:
|
||||
append_ident (string, token->string.string);
|
||||
append_ident (string, gtk_css_token_get_string (token));
|
||||
g_string_append_c (string, '(');
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_AT_KEYWORD:
|
||||
g_string_append_c (string, '@');
|
||||
append_ident (string, token->string.string);
|
||||
append_ident (string, gtk_css_token_get_string (token));
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
|
||||
case GTK_CSS_TOKEN_HASH_ID:
|
||||
g_string_append_c (string, '#');
|
||||
append_ident (string, token->string.string);
|
||||
append_ident (string, gtk_css_token_get_string (token));
|
||||
break;
|
||||
|
||||
case GTK_CSS_TOKEN_DELIM:
|
||||
@@ -492,7 +491,7 @@ gtk_css_token_to_string (const GtkCssToken *token)
|
||||
static void
|
||||
gtk_css_token_init_string (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
char *string)
|
||||
GString *string)
|
||||
{
|
||||
token->type = type;
|
||||
|
||||
@@ -505,7 +504,11 @@ gtk_css_token_init_string (GtkCssToken *token,
|
||||
case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
|
||||
case GTK_CSS_TOKEN_HASH_ID:
|
||||
case GTK_CSS_TOKEN_URL:
|
||||
token->string.string = string;
|
||||
token->string.len = string->len;
|
||||
if (string->len < 16)
|
||||
g_strlcpy (token->string.u.buf, string->str, 16);
|
||||
else
|
||||
token->string.u.string = g_strdup (string->str);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -545,7 +548,7 @@ static void
|
||||
gtk_css_token_init_dimension (GtkCssToken *token,
|
||||
GtkCssTokenType type,
|
||||
double value,
|
||||
char *dimension)
|
||||
GString *string)
|
||||
{
|
||||
token->type = type;
|
||||
|
||||
@@ -556,7 +559,7 @@ gtk_css_token_init_dimension (GtkCssToken *token,
|
||||
case GTK_CSS_TOKEN_SIGNED_DIMENSION:
|
||||
case GTK_CSS_TOKEN_SIGNLESS_DIMENSION:
|
||||
token->dimension.value = value;
|
||||
token->dimension.dimension = dimension;
|
||||
g_strlcpy (token->dimension.dimension, string->str, 8);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -630,7 +633,7 @@ gtk_css_tokenizer_parse_error (GError **error,
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_newline (char c)
|
||||
{
|
||||
return c == '\n'
|
||||
@@ -638,7 +641,7 @@ is_newline (char c)
|
||||
|| c == '\f';
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_whitespace (char c)
|
||||
{
|
||||
return is_newline (c)
|
||||
@@ -646,13 +649,13 @@ is_whitespace (char c)
|
||||
|| c == ' ';
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_multibyte (char c)
|
||||
{
|
||||
return c & 0x80;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_name_start (char c)
|
||||
{
|
||||
return is_multibyte (c)
|
||||
@@ -660,7 +663,7 @@ is_name_start (char c)
|
||||
|| c == '_';
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_name (char c)
|
||||
{
|
||||
return is_name_start (c)
|
||||
@@ -668,7 +671,7 @@ is_name (char c)
|
||||
|| c == '-';
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_non_printable (char c)
|
||||
{
|
||||
return (c >= 0 && c <= 0x08)
|
||||
@@ -678,7 +681,7 @@ is_non_printable (char c)
|
||||
|| c == 0x7F;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
is_valid_escape (const char *data,
|
||||
const char *end)
|
||||
{
|
||||
@@ -703,7 +706,7 @@ gtk_css_tokenizer_remaining (GtkCssTokenizer *tokenizer)
|
||||
return tokenizer->end - tokenizer->data;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static inline gboolean
|
||||
gtk_css_tokenizer_has_valid_escape (GtkCssTokenizer *tokenizer)
|
||||
{
|
||||
return is_valid_escape (tokenizer->data, tokenizer->end);
|
||||
@@ -875,7 +878,7 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
|
||||
return value;
|
||||
}
|
||||
|
||||
static char *
|
||||
static void
|
||||
gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
{
|
||||
g_string_set_size (tokenizer->name_buffer, 0);
|
||||
@@ -911,8 +914,6 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
|
||||
}
|
||||
}
|
||||
while (tokenizer->data != tokenizer->end);
|
||||
|
||||
return g_strndup (tokenizer->name_buffer->str, tokenizer->name_buffer->len);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1005,7 +1006,8 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, url);
|
||||
g_string_free (url, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1015,12 +1017,12 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer *tokenizer,
|
||||
GtkCssToken *token,
|
||||
GError **error)
|
||||
{
|
||||
char *name = gtk_css_tokenizer_read_name (tokenizer);
|
||||
gtk_css_tokenizer_read_name (tokenizer);
|
||||
|
||||
if (*tokenizer->data == '(')
|
||||
{
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
if (g_ascii_strcasecmp (name, "url") == 0)
|
||||
if (g_ascii_strcasecmp (tokenizer->name_buffer->str, "url") == 0)
|
||||
{
|
||||
const char *data = tokenizer->data;
|
||||
|
||||
@@ -1028,18 +1030,15 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer *tokenizer,
|
||||
data++;
|
||||
|
||||
if (*data != '"' && *data != '\'')
|
||||
{
|
||||
g_free (name);
|
||||
return gtk_css_tokenizer_read_url (tokenizer, token, error);
|
||||
}
|
||||
return gtk_css_tokenizer_read_url (tokenizer, token, error);
|
||||
}
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, name);
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, tokenizer->name_buffer);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, name);
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, tokenizer->name_buffer);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1129,7 +1128,8 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
|
||||
else
|
||||
type = has_sign ? GTK_CSS_TOKEN_SIGNED_DIMENSION : GTK_CSS_TOKEN_SIGNLESS_DIMENSION;
|
||||
|
||||
gtk_css_token_init_dimension (token, type, value, gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_tokenizer_read_name (tokenizer);
|
||||
gtk_css_token_init_dimension (token, type, value, tokenizer->name_buffer);
|
||||
}
|
||||
else if (gtk_css_tokenizer_remaining (tokenizer) > 0 && *tokenizer->data == '%')
|
||||
{
|
||||
@@ -1145,7 +1145,7 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
|
||||
else
|
||||
type = has_sign ? GTK_CSS_TOKEN_SIGNED_NUMBER : GTK_CSS_TOKEN_SIGNLESS_NUMBER;
|
||||
|
||||
gtk_css_token_init_number (token, type,value);
|
||||
gtk_css_token_init_number (token, type, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1196,7 +1196,8 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer,
|
||||
GtkCssToken *token,
|
||||
GError **error)
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
g_string_set_size (tokenizer->name_buffer, 0);
|
||||
|
||||
char end = *tokenizer->data;
|
||||
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
@@ -1222,23 +1223,22 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer *tokenizer,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_unichar (string, gtk_css_tokenizer_read_escape (tokenizer));
|
||||
g_string_append_unichar (tokenizer->name_buffer, gtk_css_tokenizer_read_escape (tokenizer));
|
||||
}
|
||||
}
|
||||
else if (is_newline (*tokenizer->data))
|
||||
{
|
||||
g_string_free (string, TRUE);
|
||||
gtk_css_token_init (token, GTK_CSS_TOKEN_BAD_STRING);
|
||||
gtk_css_tokenizer_parse_error (error, "Newlines inside strings must be escaped");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_css_tokenizer_consume_char (tokenizer, string);
|
||||
gtk_css_tokenizer_consume_char (tokenizer, tokenizer->name_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, g_string_free (string, FALSE));
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, tokenizer->name_buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1322,9 +1322,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
else
|
||||
type = GTK_CSS_TOKEN_HASH_UNRESTRICTED;
|
||||
|
||||
gtk_css_token_init_string (token,
|
||||
type,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_tokenizer_read_name (tokenizer);
|
||||
gtk_css_token_init_string (token, type, tokenizer->name_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1404,9 +1403,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer,
|
||||
gtk_css_tokenizer_consume_ascii (tokenizer);
|
||||
if (gtk_css_tokenizer_has_identifier (tokenizer))
|
||||
{
|
||||
gtk_css_token_init_string (token,
|
||||
GTK_CSS_TOKEN_AT_KEYWORD,
|
||||
gtk_css_tokenizer_read_name (tokenizer));
|
||||
gtk_css_tokenizer_read_name (tokenizer);
|
||||
gtk_css_token_init_string (token, GTK_CSS_TOKEN_AT_KEYWORD, tokenizer->name_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -81,7 +81,11 @@ typedef struct _GtkCssDimensionToken GtkCssDimensionToken;
|
||||
|
||||
struct _GtkCssStringToken {
|
||||
GtkCssTokenType type;
|
||||
char *string;
|
||||
int len;
|
||||
union {
|
||||
char buf[16];
|
||||
char *string;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct _GtkCssDelimToken {
|
||||
@@ -97,7 +101,7 @@ struct _GtkCssNumberToken {
|
||||
struct _GtkCssDimensionToken {
|
||||
GtkCssTokenType type;
|
||||
double value;
|
||||
char *dimension;
|
||||
char dimension[8];
|
||||
};
|
||||
|
||||
union _GtkCssToken {
|
||||
@@ -108,6 +112,15 @@ union _GtkCssToken {
|
||||
GtkCssDimensionToken dimension;
|
||||
};
|
||||
|
||||
static inline const char *
|
||||
gtk_css_token_get_string (const GtkCssToken *token)
|
||||
{
|
||||
if (token->string.len < 16)
|
||||
return token->string.u.buf;
|
||||
else
|
||||
return token->string.u.string;
|
||||
}
|
||||
|
||||
void gtk_css_token_clear (GtkCssToken *token);
|
||||
|
||||
gboolean gtk_css_token_is_finite (const GtkCssToken *token) G_GNUC_PURE;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
gtk_css_public_sources = files([
|
||||
'gtkcsslocation.c',
|
||||
'gtkcsserror.c',
|
||||
'gtkcsssection.c',
|
||||
])
|
||||
|
||||
@@ -59,8 +59,8 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
* ## GtkComboBoxText as GtkBuildable
|
||||
*
|
||||
* The `GtkComboBoxText` implementation of the `GtkBuildable` interface supports
|
||||
* adding items directly using the <items> element and specifying <item>
|
||||
* elements for each item. Each <item> element can specify the “id”
|
||||
* adding items directly using the `<items>` element and specifying `<item>`
|
||||
* elements for each item. Each `<item>` element can specify the “id”
|
||||
* corresponding to the appended text and also supports the regular
|
||||
* translation attributes “translatable”, “context” and “comments”.
|
||||
*
|
||||
|
||||
@@ -99,7 +99,8 @@ window_handle_exported (GtkWindow *window,
|
||||
* This is the recommended call to be used as it passes information
|
||||
* necessary for sandbox helpers to parent their dialogs properly.
|
||||
*
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch] instead
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch] or
|
||||
* [method@Gtk.UriLauncher.launch] instead
|
||||
*/
|
||||
void
|
||||
gtk_show_uri_full (GtkWindow *parent,
|
||||
@@ -147,7 +148,8 @@ gtk_show_uri_full (GtkWindow *parent,
|
||||
* Returns: %TRUE if the URI was shown successfully.
|
||||
* Otherwise, %FALSE is returned and @error is set
|
||||
*
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch_finish] instead
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch_finish] or
|
||||
* [method@Gtk.UriLauncher.launch_finish] instead
|
||||
*/
|
||||
gboolean
|
||||
gtk_show_uri_full_finish (GtkWindow *parent,
|
||||
@@ -191,7 +193,8 @@ show_uri_done (GObject *object,
|
||||
* This function launches the default application for showing
|
||||
* a given uri, or shows an error dialog if that fails.
|
||||
*
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch] instead
|
||||
* Deprecated: 4.10: Use [method@Gtk.FileLauncher.launch] or
|
||||
* [method@Gtk.UriLauncher.launch] instead
|
||||
*/
|
||||
void
|
||||
gtk_show_uri (GtkWindow *parent,
|
||||
|
||||
@@ -47,8 +47,8 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
* ## GtkTreeStore as GtkBuildable
|
||||
*
|
||||
* The GtkTreeStore implementation of the `GtkBuildable` interface allows
|
||||
* to specify the model columns with a <columns> element that may contain
|
||||
* multiple <column> elements, each specifying one model column. The “type”
|
||||
* to specify the model columns with a `<columns>` element that may contain
|
||||
* multiple `<column>` elements, each specifying one model column. The “type”
|
||||
* attribute specifies the data type for the column.
|
||||
*
|
||||
* An example of a UI Definition fragment for a tree store:
|
||||
|
||||
+10
-8
@@ -587,10 +587,12 @@ gdk_paintable_new_from_bytes_scaled (GBytes *bytes,
|
||||
|
||||
if (gdk_texture_can_load (bytes))
|
||||
{
|
||||
/* We know these formats can't be scaled */
|
||||
texture = gdk_texture_new_from_bytes (bytes, NULL);
|
||||
if (texture == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We know these formats can't be scaled */
|
||||
paintable = GDK_PAINTABLE (texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -610,15 +612,15 @@ gdk_paintable_new_from_bytes_scaled (GBytes *bytes,
|
||||
|
||||
texture = gdk_texture_new_for_pixbuf (gdk_pixbuf_loader_get_pixbuf (loader));
|
||||
g_object_unref (loader);
|
||||
|
||||
if (loader_data.scale_factor != 1)
|
||||
paintable = gtk_scaler_new (GDK_PAINTABLE (texture), loader_data.scale_factor);
|
||||
else
|
||||
paintable = g_object_ref (GDK_PAINTABLE (texture));
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
if (loader_data.scale_factor != 1)
|
||||
paintable = gtk_scaler_new (GDK_PAINTABLE (texture), loader_data.scale_factor);
|
||||
else
|
||||
paintable = g_object_ref ((GdkPaintable *)texture);
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
return paintable;
|
||||
}
|
||||
|
||||
|
||||
+79
-11
@@ -103,6 +103,7 @@ enum {
|
||||
typedef struct {
|
||||
GtkWindow *parent;
|
||||
GFile *file;
|
||||
char *uri;
|
||||
gboolean open_folder;
|
||||
GDBusConnection *connection;
|
||||
GCancellable *cancellable;
|
||||
@@ -125,6 +126,7 @@ open_uri_data_free (OpenUriData *data)
|
||||
gtk_window_unexport_handle (data->parent);
|
||||
g_clear_object (&data->parent);
|
||||
g_clear_object (&data->file);
|
||||
g_free (data->uri);
|
||||
g_clear_object (&data->cancellable);
|
||||
g_clear_object (&data->task);
|
||||
g_free (data->handle);
|
||||
@@ -258,13 +260,13 @@ canceled (GCancellable *cancellable,
|
||||
}
|
||||
|
||||
static void
|
||||
open_uri (GFile *file,
|
||||
gboolean open_folder,
|
||||
open_uri (OpenUriData *data,
|
||||
const char *parent_window,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
const char *activation_token,
|
||||
GAsyncReadyCallback callback)
|
||||
{
|
||||
OpenUriData *data = user_data;
|
||||
GFile *file = data->file;
|
||||
gboolean open_folder = data->open_folder;
|
||||
GTask *task;
|
||||
GVariant *opts = NULL;
|
||||
int i;
|
||||
@@ -276,9 +278,9 @@ open_uri (GFile *file,
|
||||
connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (openuri));
|
||||
data->connection = g_object_ref (connection);
|
||||
|
||||
task = g_task_new (NULL, NULL, callback, user_data);
|
||||
task = g_task_new (NULL, NULL, callback, data);
|
||||
g_task_set_check_cancellable (task, FALSE);
|
||||
g_task_set_task_data (task, user_data, NULL);
|
||||
g_task_set_task_data (task, data, NULL);
|
||||
if (data->cancellable)
|
||||
data->cancel_handler = g_signal_connect (data->cancellable, "cancelled", G_CALLBACK (canceled), task);
|
||||
|
||||
@@ -306,9 +308,12 @@ open_uri (GFile *file,
|
||||
g_variant_builder_add (&opt_builder, "{sv}", "handle_token", g_variant_new_string (token));
|
||||
g_free (token);
|
||||
|
||||
if (activation_token)
|
||||
g_variant_builder_add (&opt_builder, "{sv}", "activation_token", g_variant_new_string (activation_token));
|
||||
|
||||
opts = g_variant_builder_end (&opt_builder);
|
||||
|
||||
if (g_file_is_native (file))
|
||||
if (file && g_file_is_native (file))
|
||||
{
|
||||
const char *path = NULL;
|
||||
GUnixFDList *fd_list = NULL;
|
||||
@@ -362,12 +367,15 @@ open_uri (GFile *file,
|
||||
}
|
||||
else
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
char *uri = NULL;
|
||||
|
||||
if (file)
|
||||
uri = g_file_get_uri (file);
|
||||
|
||||
data->call = OPEN_URI;
|
||||
gxdp_open_uri_call_open_uri (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
uri,
|
||||
uri ? uri : data->uri,
|
||||
opts,
|
||||
NULL,
|
||||
open_call_done,
|
||||
@@ -408,8 +416,28 @@ window_handle_exported (GtkWindow *window,
|
||||
gpointer user_data)
|
||||
{
|
||||
OpenUriData *data = user_data;
|
||||
GdkDisplay *display;
|
||||
GAppLaunchContext *context;
|
||||
char *activation_token = NULL;
|
||||
|
||||
open_uri (data->file, data->open_folder, handle, open_uri_done, data);
|
||||
if (window)
|
||||
display = gtk_widget_get_display (GTK_WIDGET (window));
|
||||
else
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
/* FIXME
|
||||
* Call the vfunc directly since g_app_launch_context_get_startup_notify_id
|
||||
* has NULL checks.
|
||||
*
|
||||
* We should have a more direct way to do this.
|
||||
*/
|
||||
context = G_APP_LAUNCH_CONTEXT (gdk_display_get_app_launch_context (display));
|
||||
activation_token = G_APP_LAUNCH_CONTEXT_GET_CLASS (context)->get_startup_notify_id (context, NULL, NULL);
|
||||
g_object_unref (context);
|
||||
|
||||
open_uri (data, handle, activation_token, open_uri_done);
|
||||
|
||||
g_free (activation_token);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -447,5 +475,45 @@ gboolean
|
||||
g_openuri_portal_open_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == g_openuri_portal_open_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
void
|
||||
g_openuri_portal_open_uri_async (const char *uri,
|
||||
GtkWindow *parent,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
OpenUriData *data;
|
||||
|
||||
if (!init_openuri_portal ())
|
||||
{
|
||||
g_task_report_new_error (NULL, callback, user_data, NULL,
|
||||
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
|
||||
"The OpenURI portal is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
data = g_new0 (OpenUriData, 1);
|
||||
data->parent = parent ? g_object_ref (parent) : NULL;
|
||||
data->uri = g_strdup (uri);
|
||||
data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
data->task = g_task_new (parent, cancellable, callback, user_data);
|
||||
g_task_set_check_cancellable (data->task, FALSE);
|
||||
g_task_set_source_tag (data->task, g_openuri_portal_open_uri_async);
|
||||
|
||||
if (!parent || !gtk_window_export_handle (parent, window_handle_exported, data))
|
||||
window_handle_exported (parent, NULL, data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_openuri_portal_open_uri_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == g_openuri_portal_open_uri_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,15 @@ void g_openuri_portal_open_async (GFile *file,
|
||||
gboolean g_openuri_portal_open_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void g_openuri_portal_open_uri_async (const char *uri,
|
||||
GtkWindow *window,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean g_openuri_portal_open_uri_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -286,6 +286,7 @@
|
||||
#include <gtk/deprecated/gtktreeviewcolumn.h>
|
||||
#include <gtk/gtktypebuiltins.h>
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkurilauncher.h>
|
||||
#include <gtk/gtkversion.h>
|
||||
#include <gtk/gtkvideo.h>
|
||||
#include <gtk/gtkviewport.h>
|
||||
|
||||
@@ -44,13 +44,13 @@
|
||||
#include "gtkorientable.h"
|
||||
#include "gtkscrolledwindow.h"
|
||||
#include "gtktextview.h"
|
||||
#include "gtkfilelauncher.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtktogglebutton.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkstack.h"
|
||||
#include "gtkstackswitcher.h"
|
||||
#include "gtksettings.h"
|
||||
#include "gtkurilauncher.h"
|
||||
#include "gtkheaderbar.h"
|
||||
#include "gtkprivate.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
@@ -932,16 +932,13 @@ static gboolean
|
||||
gtk_about_dialog_activate_link (GtkAboutDialog *about,
|
||||
const char *uri)
|
||||
{
|
||||
GtkFileLauncher *launcher;
|
||||
GFile *file;
|
||||
GtkUriLauncher *launcher;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
launcher = gtk_file_launcher_new (file);
|
||||
launcher = gtk_uri_launcher_new (uri);
|
||||
|
||||
gtk_file_launcher_launch (launcher, GTK_WINDOW (about), NULL, NULL, NULL);
|
||||
gtk_uri_launcher_launch (launcher, GTK_WINDOW (about), NULL, NULL, NULL);
|
||||
|
||||
g_object_unref (launcher);
|
||||
g_object_unref (file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+9
-9
@@ -139,7 +139,7 @@ gtk_accessible_update_state (GtkAccessible *self,
|
||||
GtkAccessibleState first_state,
|
||||
...)
|
||||
{
|
||||
GtkAccessibleState state;
|
||||
int state;
|
||||
GtkATContext *context;
|
||||
va_list args;
|
||||
|
||||
@@ -157,7 +157,7 @@ gtk_accessible_update_state (GtkAccessible *self,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GtkAccessibleValue *value =
|
||||
gtk_accessible_value_collect_for_state (state, &error, &args);
|
||||
gtk_accessible_value_collect_for_state ((GtkAccessibleState) state, &error, &args);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
@@ -168,7 +168,7 @@ gtk_accessible_update_state (GtkAccessible *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
gtk_at_context_set_accessible_state (context, state, value);
|
||||
gtk_at_context_set_accessible_state (context, (GtkAccessibleState) state, value);
|
||||
|
||||
if (value != NULL)
|
||||
gtk_accessible_value_unref (value);
|
||||
@@ -286,7 +286,7 @@ gtk_accessible_update_property (GtkAccessible *self,
|
||||
GtkAccessibleProperty first_property,
|
||||
...)
|
||||
{
|
||||
GtkAccessibleProperty property;
|
||||
int property;
|
||||
GtkATContext *context;
|
||||
va_list args;
|
||||
|
||||
@@ -304,7 +304,7 @@ gtk_accessible_update_property (GtkAccessible *self,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GtkAccessibleValue *value =
|
||||
gtk_accessible_value_collect_for_property (property, &error, &args);
|
||||
gtk_accessible_value_collect_for_property ((GtkAccessibleProperty) property, &error, &args);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
@@ -315,7 +315,7 @@ gtk_accessible_update_property (GtkAccessible *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
gtk_at_context_set_accessible_property (context, property, value);
|
||||
gtk_at_context_set_accessible_property (context, (GtkAccessibleProperty) property, value);
|
||||
|
||||
if (value != NULL)
|
||||
gtk_accessible_value_unref (value);
|
||||
@@ -433,7 +433,7 @@ gtk_accessible_update_relation (GtkAccessible *self,
|
||||
GtkAccessibleRelation first_relation,
|
||||
...)
|
||||
{
|
||||
GtkAccessibleRelation relation;
|
||||
int relation;
|
||||
GtkATContext *context;
|
||||
va_list args;
|
||||
|
||||
@@ -451,7 +451,7 @@ gtk_accessible_update_relation (GtkAccessible *self,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GtkAccessibleValue *value =
|
||||
gtk_accessible_value_collect_for_relation (relation, &error, &args);
|
||||
gtk_accessible_value_collect_for_relation ((GtkAccessibleRelation) relation, &error, &args);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
@@ -462,7 +462,7 @@ gtk_accessible_update_relation (GtkAccessible *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
gtk_at_context_set_accessible_relation (context, relation, value);
|
||||
gtk_at_context_set_accessible_relation (context, (GtkAccessibleRelation) relation, value);
|
||||
|
||||
if (value != NULL)
|
||||
gtk_accessible_value_unref (value);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <gdk/wayland/gdkdisplay-wayland.h>
|
||||
#include <gdk/wayland/gdksurface-wayland.h>
|
||||
#include <gdk/wayland/gdktoplevel-wayland-private.h>
|
||||
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -342,17 +342,6 @@ static void
|
||||
gtk_application_after_emit (GApplication *application,
|
||||
GVariant *platform_data)
|
||||
{
|
||||
const char *startup_notification_id = NULL;
|
||||
|
||||
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
|
||||
if (startup_notification_id)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
if (display)
|
||||
gdk_display_notify_startup_complete (display, startup_notification_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ gtk_buildable_set_buildable_id (GtkBuildable *buildable,
|
||||
* Gets the ID of the @buildable object.
|
||||
*
|
||||
* `GtkBuilder` sets the name based on the ID attribute
|
||||
* of the <object> tag used to construct the @buildable.
|
||||
* of the `<object>` tag used to construct the @buildable.
|
||||
*
|
||||
* Returns: (nullable): the ID of the buildable object
|
||||
**/
|
||||
@@ -193,7 +193,7 @@ gtk_buildable_construct_child (GtkBuildable *buildable,
|
||||
* @data: (out): return location for user data that will be passed in
|
||||
* to parser functions
|
||||
*
|
||||
* This is called for each unknown element under <child>.
|
||||
* This is called for each unknown element under `<child>`.
|
||||
*
|
||||
* Returns: %TRUE if an object has a custom implementation, %FALSE
|
||||
* if it doesn't.
|
||||
|
||||
+3
-3
@@ -109,14 +109,14 @@ struct _GtkBuildableParser
|
||||
* interface is created.
|
||||
* @construct_child: Constructs a child of a buildable that has been
|
||||
* specified as “constructor” in the UI definition. This can be used to
|
||||
* reference a widget created in a <ui> tag which is outside
|
||||
* reference a widget created in a `<ui>` tag which is outside
|
||||
* of the normal GtkBuilder UI definition hierarchy. A reference to the
|
||||
* constructed object is returned and becomes owned by the caller.
|
||||
* @custom_tag_start: Implement this if the buildable needs to parse
|
||||
* content below <child>. To handle an element, the implementation
|
||||
* content below `<child>`. To handle an element, the implementation
|
||||
* must fill in the @parser and @user_data and return %TRUE.
|
||||
* `GtkWidget` implements this to parse accessible attributes specified
|
||||
* in <accessibility> elements.
|
||||
* in `<accessibility>` elements.
|
||||
* Note that @user_data must be freed in @custom_tag_end or @custom_finished.
|
||||
* @custom_tag_end: Called for the end tag of each custom element that is
|
||||
* handled by the buildable (see @custom_tag_start).
|
||||
|
||||
+2
-2
@@ -192,9 +192,9 @@
|
||||
*
|
||||
* Beyond this general structure, several object classes define their
|
||||
* own XML DTD fragments for filling in the ANY placeholders in the DTD
|
||||
* above. Note that a custom element in a <child> element gets parsed by
|
||||
* above. Note that a custom element in a `<child>` element gets parsed by
|
||||
* the custom tag handler of the parent object, while a custom element in
|
||||
* an <object> element gets parsed by the custom tag handler of the object.
|
||||
* an `<object>` element gets parsed by the custom tag handler of the object.
|
||||
*
|
||||
* These XML fragments are explained in the documentation of the
|
||||
* respective objects.
|
||||
|
||||
@@ -57,7 +57,7 @@ typedef enum { /*< prefix=GTK_BUILDER_CLOSURE >*/
|
||||
* correct function name for registering the type and then use dlsym() to load it.
|
||||
* The default implementation just tries g_type_from_name() and otherwise fails.
|
||||
* @get_type_from_function: Try to lookup a `GType` via the given function name, specified
|
||||
* explicitly in a GtkBuilder file, like via the "type-func" attribute in the "<object>" tag.
|
||||
* explicitly in a GtkBuilder file, like via the "type-func" attribute in the `<object>` tag.
|
||||
* This function is very rarely used.
|
||||
* The C implementation will use dlsym() and call the resulting function as a `GTypeFunc`.
|
||||
* The default implementation will fail and just return %G_TYPE_INVALID.
|
||||
|
||||
+34
-2
@@ -1438,7 +1438,8 @@ gtk_calendar_select_day (GtkCalendar *calendar,
|
||||
else
|
||||
gtk_widget_remove_css_class (label, "other-month");
|
||||
|
||||
if (calendar->marked_date[day-1])
|
||||
if (calendar->marked_date[day-1] &&
|
||||
calendar->day_month[y][x] == MONTH_CURRENT)
|
||||
gtk_widget_set_state_flags (label, GTK_STATE_FLAG_CHECKED, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (label, GTK_STATE_FLAG_CHECKED);
|
||||
@@ -1524,6 +1525,14 @@ gtk_calendar_clear_marks (GtkCalendar *calendar)
|
||||
|
||||
g_return_if_fail (GTK_IS_CALENDAR (calendar));
|
||||
|
||||
for (int y = 0; y < 6; y ++)
|
||||
for (int x = 0; x < 7; x ++)
|
||||
{
|
||||
GtkWidget *label = calendar->day_number_labels[y][x];
|
||||
|
||||
gtk_widget_unset_state_flags (label, GTK_STATE_FLAG_CHECKED);
|
||||
}
|
||||
|
||||
for (day = 0; day < 31; day++)
|
||||
{
|
||||
calendar->marked_date[day] = FALSE;
|
||||
@@ -1533,12 +1542,33 @@ gtk_calendar_clear_marks (GtkCalendar *calendar)
|
||||
calendar_queue_refresh (calendar);
|
||||
}
|
||||
|
||||
static void
|
||||
update_mark_state (GtkCalendar *calendar,
|
||||
guint day,
|
||||
gboolean mark)
|
||||
{
|
||||
for (int y = 0; y < 6; y ++)
|
||||
for (int x = 0; x < 7; x ++)
|
||||
{
|
||||
GtkWidget *label = calendar->day_number_labels[y][x];
|
||||
|
||||
if (day != calendar->day[y][x])
|
||||
continue;
|
||||
|
||||
if (mark && calendar->marked_date[day-1] &&
|
||||
calendar->day_month[y][x] == MONTH_CURRENT)
|
||||
gtk_widget_set_state_flags (label, GTK_STATE_FLAG_CHECKED, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (label, GTK_STATE_FLAG_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_calendar_mark_day:
|
||||
* @calendar: a `GtkCalendar`
|
||||
* @day: the day number to mark between 1 and 31.
|
||||
*
|
||||
* Places a visual marker on a particular day.
|
||||
* Places a visual marker on a particular day of the current month.
|
||||
*/
|
||||
void
|
||||
gtk_calendar_mark_day (GtkCalendar *calendar,
|
||||
@@ -1550,6 +1580,7 @@ gtk_calendar_mark_day (GtkCalendar *calendar,
|
||||
{
|
||||
calendar->marked_date[day - 1] = TRUE;
|
||||
calendar->num_marked_dates++;
|
||||
update_mark_state (calendar, day, TRUE);
|
||||
calendar_invalidate_day_num (calendar, day);
|
||||
}
|
||||
}
|
||||
@@ -1592,6 +1623,7 @@ gtk_calendar_unmark_day (GtkCalendar *calendar,
|
||||
{
|
||||
calendar->marked_date[day - 1] = FALSE;
|
||||
calendar->num_marked_dates--;
|
||||
update_mark_state (calendar, day, FALSE);
|
||||
calendar_invalidate_day_num (calendar, day);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@
|
||||
*
|
||||
* The `GtkCenterBox` implementation of the `GtkBuildable` interface
|
||||
* supports placing children in the 3 positions by specifying “start”, “center”
|
||||
* or “end” as the “type” attribute of a <child> element.
|
||||
* or “end” as the “type” attribute of a `<child>` element.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
|
||||
@@ -1325,9 +1325,7 @@ gtk_compose_table_check (const GtkComposeTable *table,
|
||||
if (n_compose == 1)
|
||||
return TRUE;
|
||||
|
||||
seq = NULL;
|
||||
match = FALSE;
|
||||
value = 0;
|
||||
|
||||
for (i = n_compose - 1; i < table->max_seq_len; i++)
|
||||
{
|
||||
|
||||
@@ -937,9 +937,12 @@ gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source,
|
||||
gtk_internal_return_val_if_fail (GTK_IS_CSS_ANIMATED_STYLE (source), NULL);
|
||||
gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (base_style), NULL);
|
||||
|
||||
if (timestamp == 0 || timestamp == source->current_time)
|
||||
if (timestamp == 0)
|
||||
return g_object_ref (source->style);
|
||||
|
||||
if (timestamp == source->current_time)
|
||||
return g_object_ref (GTK_CSS_STYLE (source));
|
||||
|
||||
gtk_internal_return_val_if_fail (timestamp > source->current_time, NULL);
|
||||
|
||||
animations = NULL;
|
||||
|
||||
@@ -722,7 +722,7 @@ _gtk_css_color_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
const GtkCssToken *token = gtk_css_parser_get_token (parser);
|
||||
|
||||
value = _gtk_css_color_value_new_name (token->string.string);
|
||||
value = _gtk_css_color_value_new_name (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
|
||||
return value;
|
||||
|
||||
+10
-10
@@ -947,7 +947,7 @@ gtk_css_selector_parse_selector_class (GtkCssParser *parser,
|
||||
selector = gtk_css_selector_new (negate ? >K_CSS_SELECTOR_NOT_CLASS
|
||||
: >K_CSS_SELECTOR_CLASS,
|
||||
selector);
|
||||
selector->style_class.style_class = g_quark_from_string (token->string.string);
|
||||
selector->style_class.style_class = g_quark_from_string (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
return selector;
|
||||
}
|
||||
@@ -1060,7 +1060,7 @@ parse_n_plus_b (GtkCssParser *parser,
|
||||
return parse_plus_b (parser, TRUE, b);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "n-", b))
|
||||
string_has_number (gtk_css_token_get_string (token), "n-", b))
|
||||
{
|
||||
*a = before;
|
||||
*b = -*b;
|
||||
@@ -1156,7 +1156,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
|
||||
}
|
||||
else if (!seen_sign &&
|
||||
gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "-n-", b))
|
||||
string_has_number (gtk_css_token_get_string (token), "-n-", b))
|
||||
{
|
||||
*a = -1;
|
||||
*b = -*b;
|
||||
@@ -1169,7 +1169,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
|
||||
return parse_n_plus_b (parser, seen_sign ? seen_sign : 1, a, b);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "n-", b))
|
||||
string_has_number (gtk_css_token_get_string (token), "n-", b))
|
||||
{
|
||||
*a = seen_sign ? seen_sign : 1;
|
||||
*b = -*b;
|
||||
@@ -1177,7 +1177,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
|
||||
return TRUE;
|
||||
}
|
||||
else if (!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
|
||||
string_has_number (token->string.string, "-n-", b))
|
||||
string_has_number (gtk_css_token_get_string (token), "-n-", b))
|
||||
{
|
||||
*a = -1;
|
||||
*b = -*b;
|
||||
@@ -1288,7 +1288,7 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
|
||||
{
|
||||
if (g_ascii_strcasecmp (pseudo_classes[i].name, token->string.string) == 0)
|
||||
if (g_ascii_strcasecmp (pseudo_classes[i].name, gtk_css_token_get_string (token)) == 0)
|
||||
{
|
||||
if (pseudo_classes[i].state_flag)
|
||||
{
|
||||
@@ -1380,13 +1380,13 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_NAME, selector);
|
||||
selector->name.name = g_quark_from_string (token->string.string);
|
||||
selector->name.name = g_quark_from_string (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NOT_ID, selector);
|
||||
selector->id.name = g_quark_from_string (token->string.string);
|
||||
selector->id.name = g_quark_from_string (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '.'))
|
||||
@@ -1499,13 +1499,13 @@ gtk_css_selector_parse_simple_selector (GtkCssParser *parser,
|
||||
else if (!parsed_something && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NAME, selector);
|
||||
selector->name.name = g_quark_from_string (token->string.string);
|
||||
selector->name.name = g_quark_from_string (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
|
||||
{
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_ID, selector);
|
||||
selector->id.name = g_quark_from_string (token->string.string);
|
||||
selector->id.name = g_quark_from_string (gtk_css_token_get_string (token));
|
||||
gtk_css_parser_consume_token (parser);
|
||||
}
|
||||
else if (gtk_css_token_is_delim (token, '.'))
|
||||
|
||||
+19
-1
@@ -40,6 +40,8 @@
|
||||
#include "gtksettingsprivate.h"
|
||||
#include "gtkgesturesingle.h"
|
||||
|
||||
#define MIN_TIME_TO_DND 100
|
||||
|
||||
/**
|
||||
* GtkDragSource:
|
||||
*
|
||||
@@ -135,6 +137,8 @@ struct _GtkDragSource
|
||||
double start_x;
|
||||
double start_y;
|
||||
|
||||
guint timeout_id;
|
||||
|
||||
GdkDrag *drag;
|
||||
};
|
||||
|
||||
@@ -192,6 +196,7 @@ gtk_drag_source_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&source->content);
|
||||
g_clear_object (&source->paintable);
|
||||
g_clear_handle_id (&source->timeout_id, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (gtk_drag_source_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -264,6 +269,16 @@ gtk_drag_source_filter_event (GtkEventController *controller,
|
||||
return GTK_EVENT_CONTROLLER_CLASS (gtk_drag_source_parent_class)->filter_event (controller, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_timeout (gpointer user_data)
|
||||
{
|
||||
GtkDragSource *source = user_data;
|
||||
|
||||
source->timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_source_begin (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence)
|
||||
@@ -272,6 +287,7 @@ gtk_drag_source_begin (GtkGesture *gesture,
|
||||
GdkEventSequence *current;
|
||||
|
||||
current = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
source->timeout_id = g_timeout_add (MIN_TIME_TO_DND, drag_timeout, source);
|
||||
|
||||
gtk_gesture_get_point (gesture, current, &source->start_x, &source->start_y);
|
||||
}
|
||||
@@ -291,7 +307,8 @@ gtk_drag_source_update (GtkGesture *gesture,
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
if (gtk_drag_check_threshold_double (widget, source->start_x, source->start_y, x, y))
|
||||
if (gtk_drag_check_threshold_double (widget, source->start_x, source->start_y, x, y) &&
|
||||
!source->timeout_id)
|
||||
{
|
||||
gtk_drag_source_drag_begin (source);
|
||||
}
|
||||
@@ -465,6 +482,7 @@ drag_end (GtkDragSource *source,
|
||||
|
||||
gdk_drag_drop_done (source->drag, success);
|
||||
g_clear_object (&source->drag);
|
||||
g_clear_handle_id (&source->timeout_id, g_source_remove);
|
||||
g_object_unref (source);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -135,8 +135,8 @@
|
||||
* # GtkEntry as GtkBuildable
|
||||
*
|
||||
* The `GtkEntry` implementation of the `GtkBuildable` interface supports a
|
||||
* custom <attributes> element, which supports any number of <attribute>
|
||||
* elements. The <attribute> element has attributes named “name“, “value“,
|
||||
* custom `<attributes>` element, which supports any number of `<attribute>`
|
||||
* elements. The `<attribute>` element has attributes named “name“, “value“,
|
||||
* “start“ and “end“ and allows you to specify `PangoAttribute` values for
|
||||
* this label.
|
||||
*
|
||||
|
||||
+2
-2
@@ -79,8 +79,8 @@
|
||||
*
|
||||
* The `GtkExpander` implementation of the `GtkBuildable` interface supports
|
||||
* placing a child in the label position by specifying “label” as the
|
||||
* “type” attribute of a <child> element. A normal content child can be
|
||||
* specified without specifying a <child> type attribute.
|
||||
* “type” attribute of a `<child>` element. A normal content child can be
|
||||
* specified without specifying a `<child>` type attribute.
|
||||
*
|
||||
* An example of a UI definition fragment with GtkExpander:
|
||||
*
|
||||
|
||||
@@ -602,6 +602,10 @@ filechooser_win32_thread (gpointer _data)
|
||||
if (FAILED (hr))
|
||||
g_warning_hr ("Can't set file types", hr);
|
||||
|
||||
hr = IFileDialog_SetDefaultExtension (pfd, L"");
|
||||
if (FAILED (hr))
|
||||
g_warning_hr ("Can't set default extension", hr);
|
||||
|
||||
if (data->self->current_filter)
|
||||
{
|
||||
GListModel *filters;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define __GTK_FILE_CHOOSER_PRIVATE_H__
|
||||
|
||||
#include "deprecated/gtkfilechooser.h"
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkfilesystemmodelprivate.h"
|
||||
#include "deprecated/gtkliststore.h"
|
||||
#include "gtkrecentmanager.h"
|
||||
#include "gtksearchengineprivate.h"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "deprecated/gtkfilechooser.h"
|
||||
#include "gtkfilechooserentry.h"
|
||||
#include "gtkfilechooserutils.h"
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkfilesystemmodelprivate.h"
|
||||
#include "gtkfilethumbnail.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkgesturelongpress.h"
|
||||
@@ -4914,17 +4914,31 @@ gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser)
|
||||
static void
|
||||
switch_to_selected_folder (GtkFileChooserWidget *impl)
|
||||
{
|
||||
GFileInfo *info;
|
||||
GFile *file;
|
||||
GtkBitsetIter iter;
|
||||
GtkBitset *bitset;
|
||||
unsigned int i;
|
||||
|
||||
g_assert (!impl->select_multiple);
|
||||
g_assert (GTK_IS_SINGLE_SELECTION (impl->selection_model));
|
||||
bitset = gtk_selection_model_get_selection (impl->selection_model);
|
||||
|
||||
info = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (impl->selection_model));
|
||||
g_assert (info != NULL);
|
||||
for (gtk_bitset_iter_init_first (&iter, bitset, &i);
|
||||
gtk_bitset_iter_is_valid (&iter);
|
||||
gtk_bitset_iter_next (&iter, &i))
|
||||
{
|
||||
GFileInfo *info;
|
||||
|
||||
file = _gtk_file_info_get_file (info);
|
||||
change_folder_and_display_error (impl, file, FALSE);
|
||||
info = g_list_model_get_item (G_LIST_MODEL (impl->selection_model), i);
|
||||
if (_gtk_file_info_consider_as_directory (info))
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = _gtk_file_info_get_file (info);
|
||||
change_folder_and_display_error (impl, file, FALSE);
|
||||
g_object_unref (info);
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_object (&info);
|
||||
}
|
||||
}
|
||||
|
||||
/* Gets the display name of the selected file in the file list; assumes single
|
||||
|
||||
+1
-94
@@ -56,7 +56,6 @@ struct _GtkFileDialog
|
||||
unsigned int modal : 1;
|
||||
|
||||
GListModel *filters;
|
||||
GListModel *shortcut_folders;
|
||||
GtkFileFilter *default_filter;
|
||||
GFile *initial_folder;
|
||||
char *initial_name;
|
||||
@@ -73,7 +72,6 @@ enum
|
||||
PROP_INITIAL_FOLDER,
|
||||
PROP_INITIAL_NAME,
|
||||
PROP_MODAL,
|
||||
PROP_SHORTCUT_FOLDERS,
|
||||
PROP_TITLE,
|
||||
|
||||
NUM_PROPERTIES
|
||||
@@ -97,7 +95,6 @@ gtk_file_dialog_finalize (GObject *object)
|
||||
g_free (self->title);
|
||||
g_free (self->accept_label);
|
||||
g_clear_object (&self->filters);
|
||||
g_clear_object (&self->shortcut_folders);
|
||||
g_clear_object (&self->default_filter);
|
||||
g_clear_object (&self->initial_folder);
|
||||
g_free (self->initial_name);
|
||||
@@ -127,10 +124,6 @@ gtk_file_dialog_get_property (GObject *object,
|
||||
g_value_set_object (value, self->filters);
|
||||
break;
|
||||
|
||||
case PROP_SHORTCUT_FOLDERS:
|
||||
g_value_set_object (value, self->shortcut_folders);
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_FILTER:
|
||||
g_value_set_object (value, self->default_filter);
|
||||
break;
|
||||
@@ -179,10 +172,6 @@ gtk_file_dialog_set_property (GObject *object,
|
||||
gtk_file_dialog_set_filters (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_SHORTCUT_FOLDERS:
|
||||
gtk_file_dialog_set_shortcut_folders (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_FILTER:
|
||||
gtk_file_dialog_set_default_filter (self, g_value_get_object (value));
|
||||
break;
|
||||
@@ -256,18 +245,6 @@ gtk_file_dialog_class_init (GtkFileDialogClass *class)
|
||||
G_TYPE_LIST_MODEL,
|
||||
G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkFileDialog:shortcut-folders: (attributes org.gtk.Property.get=gtk_file_dialog_get_shortcut_folders org.gtk.Property.set=gtk_file_dialog_set_shortcut_folders)
|
||||
*
|
||||
* The list of shortcut folders.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
properties[PROP_SHORTCUT_FOLDERS] =
|
||||
g_param_spec_object ("shortcut-folders", NULL, NULL,
|
||||
G_TYPE_LIST_MODEL,
|
||||
G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkFileDialog:default-filter: (attributes org.gtk.Property.get=gtk_file_dialog_get_default_filter org.gtk.Property.set=gtk_file_dialog_set_default_filter)
|
||||
*
|
||||
@@ -365,30 +342,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_set_shortcut_folders (GtkFileChooser *chooser,
|
||||
GListModel *shortcut_folders)
|
||||
{
|
||||
if (!shortcut_folders)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < g_list_model_get_n_items (shortcut_folders); i++)
|
||||
{
|
||||
GFile *folder = g_list_model_get_item (shortcut_folders, i);
|
||||
GError *error = NULL;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
if (!gtk_file_chooser_add_shortcut_folder (chooser, folder, &error))
|
||||
{
|
||||
g_critical ("%s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
g_object_unref (folder);
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ API: Constructor */
|
||||
|
||||
@@ -546,49 +499,6 @@ gtk_file_dialog_set_filters (GtkFileDialog *self,
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILTERS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_dialog_get_shortcut_folders:
|
||||
* @self: a `GtkFileDialog`
|
||||
*
|
||||
* Gets the shortcut folders that will be available to
|
||||
* the user in the file chooser dialog.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the shortcut
|
||||
* folders, as a `GListModel` of `GFiles`
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GListModel *
|
||||
gtk_file_dialog_get_shortcut_folders (GtkFileDialog *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_DIALOG (self), NULL);
|
||||
|
||||
return self->shortcut_folders;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_dialog_set_shortcut_folders:
|
||||
* @self: a `GtkFileDialog`
|
||||
* @shortcut_folders: a `GListModel` of `GFiles`
|
||||
*
|
||||
* Sets the shortcut folders that will be available to
|
||||
* the user in the file chooser dialog.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
void
|
||||
gtk_file_dialog_set_shortcut_folders (GtkFileDialog *self,
|
||||
GListModel *shortcut_folders)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_DIALOG (self));
|
||||
g_return_if_fail (G_IS_LIST_MODEL (shortcut_folders));
|
||||
|
||||
if (!g_set_object (&self->shortcut_folders, shortcut_folders))
|
||||
return;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHORTCUT_FOLDERS]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_dialog_get_default_filter:
|
||||
* @self: a `GtkFileDialog`
|
||||
@@ -956,12 +866,9 @@ create_file_chooser (GtkFileDialog *self,
|
||||
}
|
||||
}
|
||||
|
||||
file_chooser_set_shortcut_folders (GTK_FILE_CHOOSER (chooser), self->shortcut_folders);
|
||||
if (self->initial_folder)
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), self->initial_folder, NULL);
|
||||
if (self->initial_file)
|
||||
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (chooser), self->initial_file, NULL);
|
||||
else if (self->initial_name)
|
||||
if (self->initial_name && action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (chooser), self->initial_name);
|
||||
|
||||
return chooser;
|
||||
|
||||
+6
-15
@@ -64,15 +64,6 @@ GDK_AVAILABLE_IN_4_10
|
||||
void gtk_file_dialog_set_default_filter (GtkFileDialog *self,
|
||||
GtkFileFilter *filter);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GListModel * gtk_file_dialog_get_shortcut_folders
|
||||
(GtkFileDialog *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gtk_file_dialog_set_shortcut_folders
|
||||
(GtkFileDialog *self,
|
||||
GListModel *shortcut_folders);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GFile * gtk_file_dialog_get_initial_folder (GtkFileDialog *self);
|
||||
|
||||
@@ -94,6 +85,12 @@ GDK_AVAILABLE_IN_4_10
|
||||
void gtk_file_dialog_set_initial_file (GtkFileDialog *self,
|
||||
GFile *file);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
const char * gtk_file_dialog_get_accept_label (GtkFileDialog *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gtk_file_dialog_set_accept_label (GtkFileDialog *self,
|
||||
const char *accept_label);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gtk_file_dialog_open (GtkFileDialog *self,
|
||||
@@ -159,11 +156,5 @@ GListModel * gtk_file_dialog_select_multiple_folders_finish
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
const char * gtk_file_dialog_get_accept_label (GtkFileDialog *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gtk_file_dialog_set_accept_label (GtkFileDialog *self,
|
||||
const char *accept_label);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
/**
|
||||
* GtkFileLauncher:
|
||||
*
|
||||
* A `GtkFileLauncher` object collects the arguments that are needed to open a uri
|
||||
* with an application.
|
||||
* A `GtkFileLauncher` object collects the arguments that are needed to open a
|
||||
* file with an application.
|
||||
*
|
||||
* Depending on system configuration, user preferences and available APIs, this
|
||||
* may or may not show an app chooser dialog or launch the default application
|
||||
@@ -40,6 +40,8 @@
|
||||
* This API follows the GIO async pattern, and the result can be obtained by
|
||||
* calling [method@Gtk.FileLauncher.launch_finish].
|
||||
*
|
||||
* To launch uris that don't represent files, use [class@Gtk.UriLauncher].
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
|
||||
@@ -70,7 +72,9 @@ gtk_file_launcher_init (GtkFileLauncher *self)
|
||||
static void
|
||||
gtk_file_launcher_finalize (GObject *object)
|
||||
{
|
||||
//GtkFileLauncher *self = GTK_FILE_LAUNCHER (object);
|
||||
GtkFileLauncher *self = GTK_FILE_LAUNCHER (object);
|
||||
|
||||
g_clear_object (&self->file);
|
||||
|
||||
G_OBJECT_CLASS (gtk_file_launcher_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
+271
-355
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkfilesystemmodelprivate.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -38,16 +38,15 @@
|
||||
#define FILES_PER_QUERY 100
|
||||
|
||||
typedef struct _FileModelNode FileModelNode;
|
||||
typedef struct _GtkFileSystemModelClass GtkFileSystemModelClass;
|
||||
|
||||
struct _FileModelNode
|
||||
{
|
||||
GFile * file; /* file represented by this node or NULL for editable */
|
||||
GFile * file; /* file represented by this node */
|
||||
GFileInfo * info; /* info for this file or NULL if unknown */
|
||||
|
||||
guint row; /* if valid (see model->n_valid_indexes), visible nodes before and including
|
||||
* this one - see the "Structure" comment above.
|
||||
*/
|
||||
* this one - see the "Structure" comment above.
|
||||
*/
|
||||
|
||||
guint visible :1; /* if the file is currently visible */
|
||||
guint filtered_out :1;/* if the file is currently filtered out (i.e. it didn't pass the filters) */
|
||||
@@ -67,10 +66,10 @@ struct _GtkFileSystemModel
|
||||
GArray * files; /* array of FileModelNode containing all our files */
|
||||
guint n_nodes_valid; /* count of valid nodes (i.e. those whose node->row is accurate) */
|
||||
GHashTable * file_lookup; /* mapping of GFile => array index in model->files
|
||||
* This hash table doesn't always have the same number of entries as the files array;
|
||||
* The hash table gets re-populated in node_get_for_file() if this mismatch is
|
||||
* detected.
|
||||
*/
|
||||
* This hash table doesn't always have the same number of entries as the files array;
|
||||
* The hash table gets re-populated in node_get_for_file() if this mismatch is
|
||||
* detected.
|
||||
*/
|
||||
|
||||
GtkFileFilter * filter; /* filter to use for deciding which nodes are visible */
|
||||
|
||||
@@ -84,46 +83,9 @@ struct _GtkFileSystemModel
|
||||
guint filter_folders :1;/* whether filter applies to folders */
|
||||
};
|
||||
|
||||
#define GTK_FILE_SYSTEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModelClass))
|
||||
#define GTK_IS_FILE_SYSTEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SYSTEM_MODEL))
|
||||
#define GTK_FILE_SYSTEM_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModelClass))
|
||||
|
||||
struct _GtkFileSystemModelClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
|
||||
void (*finished_loading) (GtkFileSystemModel *model, GError *error);
|
||||
};
|
||||
|
||||
static void freeze_updates (GtkFileSystemModel *model);
|
||||
static void thaw_updates (GtkFileSystemModel *model);
|
||||
|
||||
static guint node_get_for_file (GtkFileSystemModel *model,
|
||||
GFile *file);
|
||||
|
||||
static void add_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info);
|
||||
static void remove_file (GtkFileSystemModel *model,
|
||||
GFile *file);
|
||||
|
||||
/* iter setup:
|
||||
* @user_data: the model
|
||||
* @user_data2: GUINT_TO_POINTER of array index of current entry
|
||||
*
|
||||
* All other fields are unused. Note that the array index does not correspond
|
||||
* 1:1 with the path index as entries might not be visible.
|
||||
*/
|
||||
#define ITER_INDEX(iter) GPOINTER_TO_UINT((iter)->user_data2)
|
||||
#define ITER_IS_VALID(model, iter) ((model) == (iter)->user_data)
|
||||
#define ITER_INIT_FROM_INDEX(model, _iter, _index) G_STMT_START {\
|
||||
g_assert (_index < (model)->files->len); \
|
||||
(_iter)->user_data = (model); \
|
||||
(_iter)->user_data2 = GUINT_TO_POINTER (_index); \
|
||||
}G_STMT_END
|
||||
|
||||
/*** FileModelNode ***/
|
||||
|
||||
/* Get a FileModelNode structure given an index in the model->files array of nodes */
|
||||
@@ -140,7 +102,9 @@ static void remove_file (GtkFileSystemModel *model,
|
||||
* G_MAXUINT for both arguments for “validate everything”.
|
||||
*/
|
||||
static void
|
||||
node_validate_rows (GtkFileSystemModel *model, guint up_to_index, guint up_to_row)
|
||||
node_validate_rows (GtkFileSystemModel *model,
|
||||
guint up_to_index,
|
||||
guint up_to_row)
|
||||
{
|
||||
guint i, row;
|
||||
|
||||
@@ -167,7 +131,8 @@ node_validate_rows (GtkFileSystemModel *model, guint up_to_index, guint up_to_ro
|
||||
}
|
||||
|
||||
static guint G_GNUC_UNUSED
|
||||
node_get_tree_row (GtkFileSystemModel *model, guint index)
|
||||
node_get_tree_row (GtkFileSystemModel *model,
|
||||
guint index)
|
||||
{
|
||||
if (model->n_nodes_valid <= index)
|
||||
node_validate_rows (model, index, G_MAXUINT);
|
||||
@@ -175,14 +140,18 @@ node_get_tree_row (GtkFileSystemModel *model, guint index)
|
||||
return get_node (model, index)->row - 1;
|
||||
}
|
||||
|
||||
static void
|
||||
node_invalidate_index (GtkFileSystemModel *model, guint id)
|
||||
static void
|
||||
node_invalidate_index (GtkFileSystemModel *model,
|
||||
guint id)
|
||||
{
|
||||
model->n_nodes_valid = MIN (model->n_nodes_valid, id);
|
||||
}
|
||||
|
||||
static void
|
||||
node_set_visible_and_filtered_out (GtkFileSystemModel *model, guint id, gboolean visible, gboolean filtered_out)
|
||||
node_set_visible_and_filtered_out (GtkFileSystemModel *model,
|
||||
guint id,
|
||||
gboolean visible,
|
||||
gboolean filtered_out)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
|
||||
@@ -218,7 +187,8 @@ node_set_visible_and_filtered_out (GtkFileSystemModel *model, guint id, gboolean
|
||||
}
|
||||
|
||||
static gboolean
|
||||
node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
|
||||
node_should_be_filtered_out (GtkFileSystemModel *model,
|
||||
guint id)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
|
||||
@@ -234,7 +204,9 @@ node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
node_should_be_visible (GtkFileSystemModel *model, guint id, gboolean filtered_out)
|
||||
node_should_be_visible (GtkFileSystemModel *model,
|
||||
guint id,
|
||||
gboolean filtered_out)
|
||||
{
|
||||
FileModelNode *node = get_node (model, id);
|
||||
gboolean result;
|
||||
@@ -266,7 +238,8 @@ node_should_be_visible (GtkFileSystemModel *model, guint id, gboolean filtered_o
|
||||
}
|
||||
|
||||
static void
|
||||
node_compute_visibility_and_filters (GtkFileSystemModel *model, guint id)
|
||||
node_compute_visibility_and_filters (GtkFileSystemModel *model,
|
||||
guint id)
|
||||
{
|
||||
gboolean filtered_out;
|
||||
gboolean visible;
|
||||
@@ -277,6 +250,36 @@ node_compute_visibility_and_filters (GtkFileSystemModel *model, guint id)
|
||||
node_set_visible_and_filtered_out (model, id, visible, filtered_out);
|
||||
}
|
||||
|
||||
static guint
|
||||
node_get_for_file (GtkFileSystemModel *model,
|
||||
GFile *file)
|
||||
{
|
||||
gpointer position;
|
||||
int i;
|
||||
|
||||
if (g_hash_table_lookup_extended (model->file_lookup,
|
||||
file, NULL,
|
||||
&position))
|
||||
return GPOINTER_TO_UINT (position);
|
||||
|
||||
/* The invariant here is that the files in model->files[n] for n < g_hash_table_size (model->file_lookup)
|
||||
* are already added to the hash table. this loop merely rebuilds our (file -> index) mapping on demand.
|
||||
*
|
||||
* If we exit the loop, the next pending batch of mappings will be resolved when this function gets called again
|
||||
* with another file that is not yet in the mapping.
|
||||
*/
|
||||
for (i = g_hash_table_size (model->file_lookup); i < model->files->len; i++)
|
||||
{
|
||||
FileModelNode *node = get_node (model, i);
|
||||
|
||||
g_hash_table_insert (model->file_lookup, node->file, GUINT_TO_POINTER (i));
|
||||
if (g_file_equal (node->file, file))
|
||||
return i;
|
||||
}
|
||||
|
||||
return GTK_INVALID_LIST_POSITION;
|
||||
}
|
||||
|
||||
/*** GListModel ***/
|
||||
|
||||
static GType
|
||||
@@ -290,7 +293,7 @@ list_model_get_n_items (GListModel *list_model)
|
||||
{
|
||||
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (list_model);
|
||||
|
||||
return model->files->len - 1;
|
||||
return model->files->len;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
@@ -302,10 +305,10 @@ list_model_get_item (GListModel *list_model,
|
||||
|
||||
/* The first items of GtkFileSystemModel is not really a file,
|
||||
* so ignore it. */
|
||||
if (position + 1 >= model->files->len)
|
||||
if (position >= model->files->len)
|
||||
return NULL;
|
||||
|
||||
node = get_node (model, position + 1);
|
||||
node = get_node (model, position);
|
||||
return g_object_ref (node->info);
|
||||
}
|
||||
|
||||
@@ -327,28 +330,165 @@ enum {
|
||||
|
||||
static guint file_system_model_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkFileSystemModel, gtk_file_system_model, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
|
||||
g_list_model_iface_init))
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkFileSystemModel, _gtk_file_system_model, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
|
||||
g_list_model_iface_init))
|
||||
static void
|
||||
freeze_updates (GtkFileSystemModel *model)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
model->frozen++;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (model->frozen)
|
||||
{
|
||||
model->filter_on_thaw = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
freeze_updates (model);
|
||||
|
||||
for (i = 0; i < model->files->len; i++)
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
|
||||
model->filter_on_thaw = FALSE;
|
||||
thaw_updates (model);
|
||||
}
|
||||
|
||||
static void
|
||||
thaw_updates (GtkFileSystemModel *model)
|
||||
{
|
||||
gboolean stuff_added;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (model->frozen > 0);
|
||||
|
||||
model->frozen--;
|
||||
if (model->frozen > 0)
|
||||
return;
|
||||
|
||||
stuff_added = model->files->len > 0 &&
|
||||
get_node (model, model->files->len - 1)->frozen_add;
|
||||
|
||||
if (model->filter_on_thaw)
|
||||
gtk_file_system_model_refilter_all (model);
|
||||
if (stuff_added)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < model->files->len; i++)
|
||||
{
|
||||
FileModelNode *node = get_node (model, i);
|
||||
|
||||
if (!node->frozen_add)
|
||||
continue;
|
||||
node->frozen_add = FALSE;
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint position;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (G_IS_FILE_INFO (info));
|
||||
|
||||
node = g_slice_alloc0 (sizeof (FileModelNode));
|
||||
node->file = g_object_ref (file);
|
||||
if (info)
|
||||
{
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
node->info = g_object_ref (info);
|
||||
}
|
||||
node->frozen_add = model->frozen ? TRUE : FALSE;
|
||||
|
||||
g_array_append_vals (model->files, node, 1);
|
||||
g_slice_free1 (sizeof (FileModelNode), node);
|
||||
|
||||
position = model->files->len - 1;
|
||||
|
||||
if (!model->frozen)
|
||||
node_compute_visibility_and_filters (model, position);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (model), position, 0, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_file_lookup (GtkFileSystemModel *model, guint id, int increment)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
gpointer value;
|
||||
|
||||
g_hash_table_iter_init (&iter, model->file_lookup);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
guint index = GPOINTER_TO_UINT (value);
|
||||
|
||||
if (index >= id)
|
||||
{
|
||||
index += increment;
|
||||
g_hash_table_iter_replace (&iter, GUINT_TO_POINTER (index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_file (GtkFileSystemModel *model,
|
||||
GFile *file)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint id;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
|
||||
id = node_get_for_file (model, file);
|
||||
if (id == 0)
|
||||
return;
|
||||
|
||||
node = get_node (model, id);
|
||||
|
||||
node_invalidate_index (model, id);
|
||||
|
||||
g_hash_table_remove (model->file_lookup, file);
|
||||
g_clear_object (&node->file);
|
||||
adjust_file_lookup (model, id, -1);
|
||||
|
||||
g_clear_object (&node->info);
|
||||
|
||||
g_array_remove_index (model->files, id);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (model), id - 1, 1, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_model_dispose (GObject *object)
|
||||
{
|
||||
GtkFileSystemModel *model = GTK_FILE_SYSTEM_MODEL (object);
|
||||
|
||||
if (model->dir_thaw_source)
|
||||
{
|
||||
g_source_remove (model->dir_thaw_source);
|
||||
model->dir_thaw_source = 0;
|
||||
}
|
||||
g_clear_handle_id (&model->dir_thaw_source, g_source_remove);
|
||||
|
||||
g_cancellable_cancel (model->cancellable);
|
||||
if (model->dir_monitor)
|
||||
g_file_monitor_cancel (model->dir_monitor);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_file_system_model_parent_class)->dispose (object);
|
||||
G_OBJECT_CLASS (gtk_file_system_model_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -373,11 +513,11 @@ gtk_file_system_model_finalize (GObject *object)
|
||||
g_clear_pointer (&model->file_lookup, g_hash_table_destroy);
|
||||
g_clear_object (&model->filter);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_file_system_model_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gtk_file_system_model_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
|
||||
gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
@@ -386,16 +526,15 @@ _gtk_file_system_model_class_init (GtkFileSystemModelClass *class)
|
||||
|
||||
file_system_model_signals[FINISHED_LOADING] =
|
||||
g_signal_new (I_("finished-loading"),
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkFileSystemModelClass, finished_loading),
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_ERROR);
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_file_system_model_init (GtkFileSystemModel *model)
|
||||
gtk_file_system_model_init (GtkFileSystemModel *model)
|
||||
{
|
||||
model->show_files = TRUE;
|
||||
model->show_folders = TRUE;
|
||||
@@ -409,7 +548,9 @@ _gtk_file_system_model_init (GtkFileSystemModel *model)
|
||||
/*** API ***/
|
||||
|
||||
static void
|
||||
gtk_file_system_model_closed_enumerator (GObject *object, GAsyncResult *res, gpointer data)
|
||||
gtk_file_system_model_closed_enumerator (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
g_file_enumerator_close_finish (G_FILE_ENUMERATOR (object), res, NULL);
|
||||
}
|
||||
@@ -426,7 +567,9 @@ thaw_func (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer data)
|
||||
gtk_file_system_model_got_files (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer data)
|
||||
{
|
||||
GFileEnumerator *enumerator = G_FILE_ENUMERATOR (object);
|
||||
GtkFileSystemModel *model = data;
|
||||
@@ -452,7 +595,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
|
||||
const char *name;
|
||||
GFileInfo *info;
|
||||
GFile *file;
|
||||
|
||||
|
||||
info = walk->data;
|
||||
name = g_file_info_get_name (info);
|
||||
if (name == NULL)
|
||||
@@ -469,11 +612,11 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
|
||||
g_list_free (files);
|
||||
|
||||
g_file_enumerator_next_files_async (enumerator,
|
||||
g_file_is_native (model->dir) ? 50 * FILES_PER_QUERY : FILES_PER_QUERY,
|
||||
IO_PRIORITY,
|
||||
model->cancellable,
|
||||
gtk_file_system_model_got_files,
|
||||
model);
|
||||
g_file_is_native (model->dir) ? 50 * FILES_PER_QUERY : FILES_PER_QUERY,
|
||||
IO_PRIORITY,
|
||||
model->cancellable,
|
||||
gtk_file_system_model_got_files,
|
||||
model);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -486,8 +629,7 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
|
||||
NULL);
|
||||
if (model->dir_thaw_source != 0)
|
||||
{
|
||||
g_source_remove (model->dir_thaw_source);
|
||||
model->dir_thaw_source = 0;
|
||||
g_clear_handle_id (&model->dir_thaw_source, g_source_remove);
|
||||
thaw_updates (model);
|
||||
}
|
||||
|
||||
@@ -499,10 +641,36 @@ gtk_file_system_model_got_files (GObject *object, GAsyncResult *res, gpointer da
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_model_update_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint id;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (G_IS_FILE_INFO (info));
|
||||
|
||||
id = node_get_for_file (model, file);
|
||||
if (id == GTK_INVALID_LIST_POSITION)
|
||||
{
|
||||
add_file (model, file, info);
|
||||
id = node_get_for_file (model, file);
|
||||
}
|
||||
|
||||
node = get_node (model, id);
|
||||
|
||||
g_set_object (&node->info, info);
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
}
|
||||
|
||||
/* Helper for gtk_file_system_model_query_done and
|
||||
* gtk_file_system_model_one_query_done */
|
||||
static void
|
||||
query_done_helper (GObject * object,
|
||||
query_done_helper (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer data,
|
||||
gboolean do_thaw_updates)
|
||||
@@ -514,7 +682,7 @@ query_done_helper (GObject * object,
|
||||
info = g_file_query_info_finish (file, res, NULL);
|
||||
if (info)
|
||||
{
|
||||
_gtk_file_system_model_update_file (model, file, info);
|
||||
gtk_file_system_model_update_file (model, file, info);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
@@ -608,7 +776,7 @@ gtk_file_system_model_got_enumerator (GObject *dir, GAsyncResult *res, gpointer
|
||||
static void
|
||||
gtk_file_system_model_set_directory (GtkFileSystemModel *model,
|
||||
GFile * dir,
|
||||
const char * attributes)
|
||||
const char * attributes)
|
||||
{
|
||||
g_assert (G_IS_FILE (dir));
|
||||
|
||||
@@ -642,9 +810,6 @@ _gtk_file_system_model_new (void)
|
||||
model = g_object_new (GTK_TYPE_FILE_SYSTEM_MODEL, NULL);
|
||||
|
||||
model->files = g_array_sized_new (FALSE, FALSE, sizeof (FileModelNode), FILES_PER_QUERY);
|
||||
/* add editable node at start */
|
||||
g_array_set_size (model->files, 1);
|
||||
memset (get_node (model, 0), 0, sizeof (FileModelNode));
|
||||
|
||||
return model;
|
||||
}
|
||||
@@ -678,27 +843,6 @@ _gtk_file_system_model_new_for_directory (GFile *dir,
|
||||
return model;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (model->frozen)
|
||||
{
|
||||
model->filter_on_thaw = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
freeze_updates (model);
|
||||
|
||||
/* start at index 1, don't change the editable */
|
||||
for (i = 1; i < model->files->len; i++)
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
|
||||
model->filter_on_thaw = FALSE;
|
||||
thaw_updates (model);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_set_show_hidden:
|
||||
* @model: a `GtkFileSystemModel`
|
||||
@@ -709,7 +853,7 @@ gtk_file_system_model_refilter_all (GtkFileSystemModel *model)
|
||||
**/
|
||||
void
|
||||
_gtk_file_system_model_set_show_hidden (GtkFileSystemModel *model,
|
||||
gboolean show_hidden)
|
||||
gboolean show_hidden)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
@@ -732,7 +876,7 @@ _gtk_file_system_model_set_show_hidden (GtkFileSystemModel *model,
|
||||
*/
|
||||
void
|
||||
_gtk_file_system_model_set_show_folders (GtkFileSystemModel *model,
|
||||
gboolean show_folders)
|
||||
gboolean show_folders)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
@@ -755,7 +899,7 @@ _gtk_file_system_model_set_show_folders (GtkFileSystemModel *model,
|
||||
*/
|
||||
void
|
||||
_gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
|
||||
gboolean show_files)
|
||||
gboolean show_files)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
@@ -779,7 +923,7 @@ _gtk_file_system_model_set_show_files (GtkFileSystemModel *model,
|
||||
*/
|
||||
void
|
||||
_gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model,
|
||||
gboolean filter_folders)
|
||||
gboolean filter_folders)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
@@ -811,36 +955,6 @@ _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model)
|
||||
return model->cancellable;
|
||||
}
|
||||
|
||||
static guint
|
||||
node_get_for_file (GtkFileSystemModel *model,
|
||||
GFile * file)
|
||||
{
|
||||
guint i;
|
||||
|
||||
i = GPOINTER_TO_UINT (g_hash_table_lookup (model->file_lookup, file));
|
||||
if (i != 0)
|
||||
return i;
|
||||
|
||||
/* Node 0 is the editable row and has no associated file or entry in the table, so we start counting from 1.
|
||||
*
|
||||
* The invariant here is that the files in model->files[n] for n < g_hash_table_size (model->file_lookup)
|
||||
* are already added to the hash table. this loop merely rebuilds our (file -> index) mapping on demand.
|
||||
*
|
||||
* If we exit the loop, the next pending batch of mappings will be resolved when this function gets called again
|
||||
* with another file that is not yet in the mapping.
|
||||
*/
|
||||
for (i = g_hash_table_size (model->file_lookup) + 1; i < model->files->len; i++)
|
||||
{
|
||||
FileModelNode *node = get_node (model, i);
|
||||
|
||||
g_hash_table_insert (model->file_lookup, node->file, GUINT_TO_POINTER (i));
|
||||
if (g_file_equal (node->file, file))
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
GFileInfo *
|
||||
_gtk_file_system_model_get_info_for_file (GtkFileSystemModel *model,
|
||||
GFile *file)
|
||||
@@ -853,157 +967,23 @@ _gtk_file_system_model_get_info_for_file (GtkFileSystemModel *model,
|
||||
|
||||
i = node_get_for_file (model, file);
|
||||
|
||||
if (i == 0)
|
||||
if (i == GTK_INVALID_LIST_POSITION)
|
||||
return NULL;
|
||||
|
||||
node = get_node (model, i);
|
||||
return node->info;
|
||||
}
|
||||
|
||||
/* When an element is added or removed to the model->files array, we need to
|
||||
* update the model->file_lookup mappings of (node, index), as the indexes
|
||||
* change. This function adds the specified increment to the index in that pair
|
||||
* if the index is equal or after the specified id. We use this to slide the
|
||||
* mappings up or down when a node is added or removed, respectively.
|
||||
*/
|
||||
static void
|
||||
adjust_file_lookup (GtkFileSystemModel *model, guint id, int increment)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
gpointer value;
|
||||
|
||||
g_hash_table_iter_init (&iter, model->file_lookup);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
guint index = GPOINTER_TO_UINT (value);
|
||||
|
||||
if (index >= id)
|
||||
{
|
||||
index += increment;
|
||||
g_hash_table_iter_replace (&iter, GUINT_TO_POINTER (index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add_file:
|
||||
* _gtk_file_system_model_update_files:
|
||||
* @model: the model
|
||||
* @file: the file to add
|
||||
* @info: the information to associate with the file
|
||||
* @files: the files
|
||||
* @infos: the new file infos
|
||||
*
|
||||
* Adds the given @file with its associated @info to the @model.
|
||||
* If the model is frozen, the file will only show up after it is thawn.
|
||||
* Tells the file system model that the files changed and that the
|
||||
* new @infos should be used for it now. If these files are not
|
||||
* part of @model, it will get added automatically.
|
||||
**/
|
||||
static void
|
||||
add_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint position;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (G_IS_FILE_INFO (info));
|
||||
|
||||
node = g_slice_alloc0 (sizeof (FileModelNode));
|
||||
node->file = g_object_ref (file);
|
||||
if (info)
|
||||
{
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
node->info = g_object_ref (info);
|
||||
}
|
||||
node->frozen_add = model->frozen ? TRUE : FALSE;
|
||||
|
||||
g_array_append_vals (model->files, node, 1);
|
||||
g_slice_free1 (sizeof (FileModelNode), node);
|
||||
|
||||
position = model->files->len - 1;
|
||||
|
||||
if (!model->frozen)
|
||||
node_compute_visibility_and_filters (model, model->files->len -1);
|
||||
|
||||
/* Ignore the first item */
|
||||
g_list_model_items_changed (G_LIST_MODEL (model), position - 1, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove_file:
|
||||
* @model: the model
|
||||
* @file: file to remove from the model. The file must have been
|
||||
* added to the model previously
|
||||
*
|
||||
* Removes the given file from the model. If the file is not part of
|
||||
* @model, this function does nothing.
|
||||
**/
|
||||
static void
|
||||
remove_file (GtkFileSystemModel *model,
|
||||
GFile *file)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint id;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
|
||||
id = node_get_for_file (model, file);
|
||||
if (id == 0)
|
||||
return;
|
||||
|
||||
node = get_node (model, id);
|
||||
|
||||
node_invalidate_index (model, id);
|
||||
|
||||
g_hash_table_remove (model->file_lookup, file);
|
||||
g_object_unref (node->file);
|
||||
adjust_file_lookup (model, id, -1);
|
||||
|
||||
if (node->info)
|
||||
g_object_unref (node->info);
|
||||
|
||||
g_array_remove_index (model->files, id);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (model), id - 1, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_update_file:
|
||||
* @model: the model
|
||||
* @file: the file
|
||||
* @info: the new file info
|
||||
*
|
||||
* Tells the file system model that the file changed and that the
|
||||
* new @info should be used for it now. If the file is not part of
|
||||
* @model, it will get added automatically.
|
||||
**/
|
||||
void
|
||||
_gtk_file_system_model_update_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info)
|
||||
{
|
||||
FileModelNode *node;
|
||||
guint id;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (G_IS_FILE_INFO (info));
|
||||
|
||||
id = node_get_for_file (model, file);
|
||||
if (id == 0)
|
||||
{
|
||||
add_file (model, file, info);
|
||||
id = node_get_for_file (model, file);
|
||||
}
|
||||
|
||||
node = get_node (model, id);
|
||||
|
||||
g_set_object (&node->info, info);
|
||||
|
||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_file_system_model_update_files (GtkFileSystemModel *model,
|
||||
GList *files,
|
||||
@@ -1016,7 +996,7 @@ _gtk_file_system_model_update_files (GtkFileSystemModel *model,
|
||||
freeze_updates (model);
|
||||
|
||||
for (l = files, i = infos; l; l = l->next, i = i->next)
|
||||
_gtk_file_system_model_update_file (model, (GFile *)l->data, (GFileInfo *)i->data);
|
||||
gtk_file_system_model_update_file (model, (GFile *)l->data, (GFileInfo *)i->data);
|
||||
|
||||
thaw_updates (model);
|
||||
}
|
||||
@@ -1032,80 +1012,16 @@ _gtk_file_system_model_update_files (GtkFileSystemModel *model,
|
||||
**/
|
||||
void
|
||||
_gtk_file_system_model_set_filter (GtkFileSystemModel *model,
|
||||
GtkFileFilter * filter)
|
||||
GtkFileFilter * filter)
|
||||
{
|
||||
GtkFileFilter *old_filter;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (filter == NULL || GTK_IS_FILE_FILTER (filter));
|
||||
|
||||
if (filter)
|
||||
g_object_ref (filter);
|
||||
|
||||
old_filter = model->filter;
|
||||
model->filter = filter;
|
||||
|
||||
if (old_filter)
|
||||
g_object_unref (old_filter);
|
||||
g_set_object (&model->filter, filter);
|
||||
|
||||
gtk_file_system_model_refilter_all (model);
|
||||
}
|
||||
|
||||
/**
|
||||
* freeze_updates:
|
||||
* @model: a `GtkFileSystemModel`
|
||||
*
|
||||
* Freezes most updates on the model, so that performing multiple operations on
|
||||
* the files in the model do not cause any events. Use thaw_updates() to resume
|
||||
* proper operations. It is fine to call this function multiple times as long as
|
||||
* freeze and thaw calls are balanced.
|
||||
**/
|
||||
static void
|
||||
freeze_updates (GtkFileSystemModel *model)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
|
||||
model->frozen++;
|
||||
}
|
||||
|
||||
/**
|
||||
* thaw_updates:
|
||||
* @model: a `GtkFileSystemModel`
|
||||
*
|
||||
* Undoes the effect of a previous call to freeze_updates()
|
||||
**/
|
||||
static void
|
||||
thaw_updates (GtkFileSystemModel *model)
|
||||
{
|
||||
gboolean stuff_added;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model));
|
||||
g_return_if_fail (model->frozen > 0);
|
||||
|
||||
model->frozen--;
|
||||
if (model->frozen > 0)
|
||||
return;
|
||||
|
||||
stuff_added = get_node (model, model->files->len - 1)->frozen_add;
|
||||
|
||||
if (model->filter_on_thaw)
|
||||
gtk_file_system_model_refilter_all (model);
|
||||
if (stuff_added)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < model->files->len; i++)
|
||||
{
|
||||
FileModelNode *node = get_node (model, i);
|
||||
|
||||
if (!node->frozen_add)
|
||||
continue;
|
||||
node->frozen_add = FALSE;
|
||||
node_compute_visibility_and_filters (model, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_file_system_model_add_and_query_file:
|
||||
* @model: a `GtkFileSystemModel`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkfilesystemmodel.h: GtkTreeModel wrapping a GtkFileSystem
|
||||
* gtkfilesystemmodelprivate.h: GtkTreeModel wrapping a GtkFileSystem
|
||||
* Copyright (C) 2003, Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -16,21 +16,16 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_FILE_SYSTEM_MODEL_H__
|
||||
#define __GTK_FILE_SYSTEM_MODEL_H__
|
||||
#ifndef __GTK_FILE_SYSTEM_MODEL_PRIVATE_H__
|
||||
#define __GTK_FILE_SYSTEM_MODEL_PRIVATE_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtkfilefilter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_FILE_SYSTEM_MODEL (_gtk_file_system_model_get_type ())
|
||||
#define GTK_FILE_SYSTEM_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModel))
|
||||
#define GTK_IS_FILE_SYSTEM_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_SYSTEM_MODEL))
|
||||
|
||||
typedef struct _GtkFileSystemModel GtkFileSystemModel;
|
||||
|
||||
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
|
||||
#define GTK_TYPE_FILE_SYSTEM_MODEL (gtk_file_system_model_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkFileSystemModel, gtk_file_system_model, GTK, FILE_SYSTEM_MODEL, GObject)
|
||||
|
||||
GtkFileSystemModel *_gtk_file_system_model_new (void);
|
||||
GtkFileSystemModel *_gtk_file_system_model_new_for_directory(GFile *dir,
|
||||
@@ -46,9 +41,6 @@ void _gtk_file_system_model_add_and_query_file (GtkFileSystemMod
|
||||
void _gtk_file_system_model_add_and_query_files (GtkFileSystemModel *model,
|
||||
GList *files,
|
||||
const char *attributes);
|
||||
void _gtk_file_system_model_update_file (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
GFileInfo *info);
|
||||
void _gtk_file_system_model_update_files (GtkFileSystemModel *model,
|
||||
GList *files,
|
||||
GList *infos);
|
||||
@@ -67,4 +59,4 @@ void _gtk_file_system_model_set_filter (GtkFileSystemModel
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_SYSTEM_MODEL_H__ */
|
||||
#endif /* __GTK_FILE_SYSTEM_MODEL_PRIVATE_H__ */
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkfilesystemmodelprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
+2
-2
@@ -51,8 +51,8 @@
|
||||
*
|
||||
* The `GtkFrame` implementation of the `GtkBuildable` interface supports
|
||||
* placing a child in the label position by specifying “label” as the
|
||||
* “type” attribute of a <child> element. A normal content child can
|
||||
* be specified without specifying a <child> type attribute.
|
||||
* “type” attribute of a `<child>` element. A normal content child can
|
||||
* be specified without specifying a `<child>` type attribute.
|
||||
*
|
||||
* An example of a UI definition fragment with GtkFrame:
|
||||
* ```xml
|
||||
|
||||
@@ -627,6 +627,8 @@ gtk_grid_view_compute_n_columns (GtkGridView *self,
|
||||
|
||||
n_columns = CLAMP (n_columns, self->min_columns, self->max_columns);
|
||||
|
||||
g_assert (n_columns > 0);
|
||||
|
||||
return n_columns;
|
||||
}
|
||||
|
||||
@@ -869,6 +871,8 @@ gtk_grid_view_size_allocate (GtkWidget *widget,
|
||||
i = 0;
|
||||
row_height = 0;
|
||||
|
||||
g_assert (self->n_columns > 0);
|
||||
|
||||
for (cell = gtk_list_item_manager_get_first (self->item_manager);
|
||||
cell != NULL;
|
||||
cell = gtk_rb_tree_node_get_next (cell))
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@
|
||||
*
|
||||
* The `GtkHeaderBar` implementation of the `GtkBuildable` interface supports
|
||||
* adding children at the start or end sides by specifying “start” or “end” as
|
||||
* the “type” attribute of a <child> element, or setting the title widget by
|
||||
* the “type” attribute of a `<child>` element, or setting the title widget by
|
||||
* specifying “title” value.
|
||||
*
|
||||
* By default the `GtkHeaderBar` uses a `GtkLabel` displaying the title of the
|
||||
|
||||
+12
-4
@@ -188,6 +188,7 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
|
||||
guint32 image_list_offset, n_images;
|
||||
int i, j;
|
||||
GHashTable *icons = NULL;
|
||||
GString *string;
|
||||
|
||||
directory_index = get_directory_index (cache, directory);
|
||||
|
||||
@@ -197,6 +198,8 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
|
||||
hash_offset = GET_UINT32 (cache->buffer, 4);
|
||||
n_buckets = GET_UINT32 (cache->buffer, hash_offset);
|
||||
|
||||
string = g_string_new ("");
|
||||
|
||||
for (i = 0; i < n_buckets; i++)
|
||||
{
|
||||
chain_offset = GET_UINT32 (cache->buffer, hash_offset + 4 + 4 * i);
|
||||
@@ -223,15 +226,18 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
|
||||
const char *name = cache->buffer + name_offset;
|
||||
const char *interned_name;
|
||||
guint32 hash_flags = 0;
|
||||
int len;
|
||||
|
||||
/* Icons named foo.symbolic.png are stored in the cache as "foo.symbolic" with ICON_CACHE_FLAG_PNG,
|
||||
* but we convert it internally to ICON_CACHE_FLAG_SYMBOLIC_PNG.
|
||||
* Otherwise we use the same enum values and names as on disk. */
|
||||
if (g_str_has_suffix (name, ".symbolic") && (flags & ICON_CACHE_FLAG_PNG_SUFFIX) != 0)
|
||||
|
||||
len = strlen (name);
|
||||
if (g_str_equal (name + len - strlen (".symbolic"), ".symbolic") && (flags & ICON_CACHE_FLAG_PNG_SUFFIX) != 0)
|
||||
{
|
||||
char *converted_name = g_strndup (name, strlen (name) - 9);
|
||||
interned_name = gtk_string_set_add (set, converted_name);
|
||||
g_free (converted_name);
|
||||
g_string_set_size (string, 0);
|
||||
g_string_append_len (string, name, len - strlen (".symbolic"));
|
||||
interned_name = gtk_string_set_add (set, string->str);
|
||||
flags |= ICON_CACHE_FLAG_SYMBOLIC_PNG_SUFFIX;
|
||||
flags &= ~ICON_CACHE_FLAG_PNG_SUFFIX;
|
||||
}
|
||||
@@ -249,5 +255,7 @@ gtk_icon_cache_list_icons_in_directory (GtkIconCache *cache,
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (string, TRUE);
|
||||
|
||||
return icons;
|
||||
}
|
||||
|
||||
+118
-121
@@ -130,10 +130,35 @@ struct _GtkStringSet {
|
||||
int used_in_chunk;
|
||||
};
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static void
|
||||
dump_string_set (GtkStringSet *set)
|
||||
{
|
||||
GtkStringSetChunk *chunk = set->chunks;
|
||||
unsigned int n_chunks = 0;
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
|
||||
while (chunk)
|
||||
{
|
||||
n_chunks++;
|
||||
chunk = chunk->next;
|
||||
}
|
||||
g_print ("%u strings, %u chunks\n", g_hash_table_size (set->hash), n_chunks);
|
||||
|
||||
g_hash_table_iter_init (&iter, set->hash);
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
{
|
||||
char *string = key;
|
||||
g_print ("%s\n", string);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_string_set_init (GtkStringSet *set)
|
||||
{
|
||||
set->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
|
||||
set->hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
set->chunks = NULL;
|
||||
set->used_in_chunk = STRING_SET_CHUNK_SIZE; /* To trigger a grow directly */
|
||||
}
|
||||
@@ -306,6 +331,8 @@ struct _GtkIconTheme
|
||||
GtkIconPaintable *lru_cache[LRU_CACHE_SIZE]; /* Protected by icon_cache lock */
|
||||
int lru_cache_current; /* Protected by icon_cache lock */
|
||||
|
||||
GtkStringSet icons;
|
||||
|
||||
char *current_theme;
|
||||
char **search_path;
|
||||
char **resource_path;
|
||||
@@ -409,7 +436,6 @@ typedef struct
|
||||
|
||||
GArray *dir_sizes; /* IconThemeDirSize */
|
||||
GArray *dirs; /* IconThemeDir */
|
||||
GtkStringSet icons;
|
||||
} IconTheme;
|
||||
|
||||
typedef struct
|
||||
@@ -465,8 +491,6 @@ static GtkIconPaintable *theme_lookup_icon (IconTheme *the
|
||||
int size,
|
||||
int scale,
|
||||
gboolean allow_svg);
|
||||
static gboolean theme_has_icon (IconTheme *theme,
|
||||
const char *icon_name);
|
||||
static void theme_subdir_load (GtkIconTheme *self,
|
||||
IconTheme *theme,
|
||||
GKeyFile *theme_file,
|
||||
@@ -477,7 +501,8 @@ static gboolean rescan_themes (GtkIconTheme *sel
|
||||
static GtkIconPaintable *icon_paintable_new (const char *icon_name,
|
||||
int desired_size,
|
||||
int desired_scale);
|
||||
static IconCacheFlag suffix_from_name (const char *name);
|
||||
static inline IconCacheFlag
|
||||
suffix_from_name (const char *name);
|
||||
static void icon_ensure_texture__locked (GtkIconPaintable *icon,
|
||||
gboolean in_thread);
|
||||
static void gtk_icon_theme_unset_display (GtkIconTheme *self);
|
||||
@@ -1358,6 +1383,7 @@ blow_themes (GtkIconTheme *self)
|
||||
g_list_free_full (self->themes, (GDestroyNotify) theme_destroy);
|
||||
g_array_set_size (self->dir_mtimes, 0);
|
||||
g_hash_table_destroy (self->unthemed_icons);
|
||||
gtk_string_set_destroy (&self->icons);
|
||||
}
|
||||
self->themes = NULL;
|
||||
self->unthemed_icons = NULL;
|
||||
@@ -1715,7 +1741,6 @@ insert_theme (GtkIconTheme *self,
|
||||
IconTheme *theme = NULL;
|
||||
char *path;
|
||||
GKeyFile *theme_file;
|
||||
GError *error = NULL;
|
||||
GStatBuf stat_buf;
|
||||
|
||||
for (l = self->themes; l != NULL; l = l->next)
|
||||
@@ -1725,6 +1750,7 @@ insert_theme (GtkIconTheme *self,
|
||||
return;
|
||||
}
|
||||
|
||||
theme_file = NULL;
|
||||
for (i = 0; self->search_path[i]; i++)
|
||||
{
|
||||
IconThemeDirMtime dir_mtime;
|
||||
@@ -1736,6 +1762,22 @@ insert_theme (GtkIconTheme *self,
|
||||
{
|
||||
dir_mtime.mtime = stat_buf.st_mtime;
|
||||
dir_mtime.exists = TRUE;
|
||||
|
||||
if (!theme_file)
|
||||
{
|
||||
char *file = g_build_filename (path, "index.theme", NULL);
|
||||
if (g_file_test (file, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
theme_file = g_key_file_new ();
|
||||
g_key_file_set_list_separator (theme_file, ',');
|
||||
if (!g_key_file_load_from_file (theme_file, file, 0, NULL))
|
||||
{
|
||||
g_key_file_free (theme_file);
|
||||
theme_file = NULL;
|
||||
}
|
||||
}
|
||||
g_free (file);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1746,25 +1788,6 @@ insert_theme (GtkIconTheme *self,
|
||||
g_array_insert_val (self->dir_mtimes, 0, dir_mtime);
|
||||
}
|
||||
|
||||
theme_file = NULL;
|
||||
for (i = 0; self->search_path[i] && !theme_file; i++)
|
||||
{
|
||||
path = g_build_filename (self->search_path[i], theme_name, "index.theme", NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
theme_file = g_key_file_new ();
|
||||
g_key_file_set_list_separator (theme_file, ',');
|
||||
if (!g_key_file_load_from_file (theme_file, path, 0, &error))
|
||||
{
|
||||
g_key_file_free (theme_file);
|
||||
theme_file = NULL;
|
||||
g_error_free (error);
|
||||
error = NULL;
|
||||
}
|
||||
}
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
if (theme_file == NULL)
|
||||
{
|
||||
if (strcmp (theme_name, FALLBACK_ICON_THEME) == 0)
|
||||
@@ -1837,34 +1860,25 @@ free_unthemed_icon (UnthemedIcon *unthemed_icon)
|
||||
g_slice_free (UnthemedIcon, unthemed_icon);
|
||||
}
|
||||
|
||||
static void
|
||||
strip_suffix_inline (char *filename)
|
||||
static inline void
|
||||
strip_suffix_inline (char *filename,
|
||||
IconCacheFlag suffix)
|
||||
{
|
||||
char *dot;
|
||||
|
||||
if (g_str_has_suffix (filename, ".symbolic.png"))
|
||||
filename[strlen(filename)-13] = 0;
|
||||
|
||||
dot = strrchr (filename, '.');
|
||||
|
||||
if (dot != NULL)
|
||||
*dot = 0;
|
||||
if (suffix & ICON_CACHE_FLAG_SYMBOLIC_PNG_SUFFIX)
|
||||
filename[strlen (filename) - strlen (".symbolic.png")] = 0;
|
||||
else if (suffix & (ICON_CACHE_FLAG_XPM_SUFFIX|
|
||||
ICON_CACHE_FLAG_SVG_SUFFIX|
|
||||
ICON_CACHE_FLAG_PNG_SUFFIX))
|
||||
filename[strlen (filename) - 4] = 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
strip_suffix (const char *filename)
|
||||
static inline char *
|
||||
strip_suffix (const char *filename,
|
||||
IconCacheFlag suffix)
|
||||
{
|
||||
const char *dot;
|
||||
|
||||
if (g_str_has_suffix (filename, ".symbolic.png"))
|
||||
return g_strndup (filename, strlen(filename)-13);
|
||||
|
||||
dot = strrchr (filename, '.');
|
||||
|
||||
if (dot == NULL)
|
||||
return g_strdup (filename);
|
||||
|
||||
return g_strndup (filename, dot - filename);
|
||||
char *dup = g_strdup (filename);
|
||||
strip_suffix_inline (dup, suffix);
|
||||
return dup;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1884,7 +1898,7 @@ add_unthemed_icon (GtkIconTheme *self,
|
||||
return;
|
||||
|
||||
abs_file = g_build_filename (dir, file, NULL);
|
||||
base_name = strip_suffix (file);
|
||||
base_name = strip_suffix (file, new_suffix);
|
||||
|
||||
unthemed_icon = g_hash_table_lookup (self->unthemed_icons, base_name);
|
||||
|
||||
@@ -1942,6 +1956,8 @@ load_themes (GtkIconTheme *self)
|
||||
GStatBuf stat_buf;
|
||||
int j;
|
||||
|
||||
gtk_string_set_init (&self->icons);
|
||||
|
||||
if (self->current_theme)
|
||||
insert_theme (self, self->current_theme);
|
||||
|
||||
@@ -2017,6 +2033,8 @@ load_themes (GtkIconTheme *self)
|
||||
}
|
||||
gdk_debug_message ("%s", s->str);
|
||||
g_string_free (s, TRUE);
|
||||
|
||||
dump_string_set (&self->icons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2162,10 +2180,13 @@ real_choose_icon (GtkIconTheme *self,
|
||||
theme = l->data;
|
||||
for (i = 0; icon_names[i] && icon_name_is_symbolic (icon_names[i], -1); i++)
|
||||
{
|
||||
icon_name = icon_names[i];
|
||||
icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg);
|
||||
if (icon)
|
||||
goto out;
|
||||
icon_name = gtk_string_set_lookup (&self->icons, icon_names[i]);
|
||||
if (icon_name)
|
||||
{
|
||||
icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg);
|
||||
if (icon)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2175,10 +2196,13 @@ real_choose_icon (GtkIconTheme *self,
|
||||
|
||||
for (i = 0; icon_names[i]; i++)
|
||||
{
|
||||
icon_name = icon_names[i];
|
||||
icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg);
|
||||
if (icon)
|
||||
goto out;
|
||||
icon_name = gtk_string_set_lookup (&self->icons, icon_names[i]);
|
||||
if (icon_name)
|
||||
{
|
||||
icon = theme_lookup_icon (theme, icon_name, size, scale, self->pixbuf_supports_svg);
|
||||
if (icon)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2559,7 +2583,6 @@ gboolean
|
||||
gtk_icon_theme_has_icon (GtkIconTheme *self,
|
||||
const char *icon_name)
|
||||
{
|
||||
GList *l;
|
||||
gboolean res = FALSE;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME (self), FALSE);
|
||||
@@ -2569,13 +2592,10 @@ gtk_icon_theme_has_icon (GtkIconTheme *self,
|
||||
|
||||
ensure_valid_themes (self, FALSE);
|
||||
|
||||
for (l = self->themes; l; l = l->next)
|
||||
if (gtk_string_set_lookup (&self->icons, icon_name) != NULL)
|
||||
{
|
||||
if (theme_has_icon (l->data, icon_name))
|
||||
{
|
||||
res = TRUE;
|
||||
goto out;
|
||||
}
|
||||
res = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -2614,13 +2634,10 @@ gtk_icon_theme_has_gicon (GtkIconTheme *self,
|
||||
|
||||
for (int i = 0; names[i]; i++)
|
||||
{
|
||||
for (GList *l = self->themes; l; l = l->next)
|
||||
if (gtk_string_set_lookup (&self->icons, names[i]) != NULL)
|
||||
{
|
||||
if (theme_has_icon (l->data, names[i]))
|
||||
{
|
||||
res = TRUE;
|
||||
goto out;
|
||||
}
|
||||
res = TRUE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2666,6 +2683,7 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *self,
|
||||
int i;
|
||||
GHashTable *sizes;
|
||||
int *result, *r;
|
||||
const char *interned_icon_name;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME (self), NULL);
|
||||
|
||||
@@ -2675,10 +2693,11 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *self,
|
||||
|
||||
sizes = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
interned_icon_name = gtk_string_set_lookup (&self->icons, icon_name);
|
||||
|
||||
for (l = self->themes; l; l = l->next)
|
||||
{
|
||||
IconTheme *theme = l->data;
|
||||
const char *interned_icon_name = gtk_string_set_lookup (&theme->icons, icon_name);
|
||||
|
||||
for (i = 0; i < theme->dir_sizes->len; i++)
|
||||
{
|
||||
@@ -2735,25 +2754,15 @@ gtk_icon_theme_get_icon_names (GtkIconTheme *self)
|
||||
char **names;
|
||||
char *key;
|
||||
int i;
|
||||
GList *l;
|
||||
|
||||
gtk_icon_theme_lock (self);
|
||||
|
||||
ensure_valid_themes (self, FALSE);
|
||||
|
||||
icons = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
gtk_string_set_list (&self->icons, icons);
|
||||
|
||||
l = self->themes;
|
||||
while (l != NULL)
|
||||
{
|
||||
IconTheme *theme = l->data;
|
||||
gtk_string_set_list (&theme->icons, icons);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
g_hash_table_foreach (self->unthemed_icons,
|
||||
add_key_to_hash,
|
||||
icons);
|
||||
g_hash_table_foreach (self->unthemed_icons, add_key_to_hash, icons);
|
||||
|
||||
names = g_new (char *, g_hash_table_size (icons) + 1);
|
||||
|
||||
@@ -2812,7 +2821,6 @@ theme_new (const char *theme_name,
|
||||
theme->name = g_strdup (theme_name);
|
||||
theme->dir_sizes = g_array_new (FALSE, FALSE, sizeof (IconThemeDirSize));
|
||||
theme->dirs = g_array_new (FALSE, FALSE, sizeof (IconThemeDir));
|
||||
gtk_string_set_init (&theme->icons);
|
||||
|
||||
theme->display_name =
|
||||
g_key_file_get_locale_string (theme_file, "Icon Theme", "Name", NULL, NULL);
|
||||
@@ -2843,8 +2851,6 @@ theme_destroy (IconTheme *theme)
|
||||
theme_dir_destroy (&g_array_index (theme->dirs, IconThemeDir, i));
|
||||
g_array_free (theme->dirs, TRUE);
|
||||
|
||||
gtk_string_set_destroy (&theme->icons);
|
||||
|
||||
g_free (theme);
|
||||
}
|
||||
|
||||
@@ -3043,13 +3049,6 @@ theme_lookup_icon (IconTheme *theme,
|
||||
IconCacheFlag min_suffix;
|
||||
int i;
|
||||
|
||||
/* Its not uncommon with misses, so we do an early check which allows us do
|
||||
* do a lot less work.
|
||||
* We also intern the name so later hash lookups are faster. */
|
||||
icon_name = gtk_string_set_lookup (&theme->icons, icon_name);
|
||||
if (icon_name == NULL)
|
||||
return FALSE;
|
||||
|
||||
min_difference = G_MAXINT;
|
||||
min_dir_size = NULL;
|
||||
|
||||
@@ -3109,13 +3108,6 @@ theme_lookup_icon (IconTheme *theme,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
theme_has_icon (IconTheme *theme,
|
||||
const char *icon_name)
|
||||
{
|
||||
return gtk_string_set_lookup (&theme->icons, icon_name) != NULL;
|
||||
}
|
||||
|
||||
static GHashTable *
|
||||
scan_directory (GtkIconTheme *self,
|
||||
char *full_dir,
|
||||
@@ -3141,14 +3133,13 @@ scan_directory (GtkIconTheme *self,
|
||||
if (suffix == ICON_CACHE_FLAG_NONE)
|
||||
continue;
|
||||
|
||||
strip_suffix_inline ((char *)name);
|
||||
strip_suffix_inline ((char *)name, suffix);
|
||||
interned = gtk_string_set_add (set, name);
|
||||
|
||||
if (!icons)
|
||||
icons = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
|
||||
|
||||
hash_suffix = GPOINTER_TO_INT (g_hash_table_lookup (icons, interned));
|
||||
/* takes ownership of base_name */
|
||||
g_hash_table_replace (icons, (char *)interned, GUINT_TO_POINTER (hash_suffix|suffix));
|
||||
}
|
||||
|
||||
@@ -3185,11 +3176,10 @@ scan_resource_directory (GtkIconTheme *self,
|
||||
if (!icons)
|
||||
icons = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
|
||||
|
||||
strip_suffix_inline (name);
|
||||
strip_suffix_inline (name, suffix);
|
||||
interned = gtk_string_set_add (set, name);
|
||||
|
||||
hash_suffix = GPOINTER_TO_INT (g_hash_table_lookup (icons, interned));
|
||||
/* takes ownership of base_name */
|
||||
g_hash_table_replace (icons, (char *)interned, GUINT_TO_POINTER (hash_suffix|suffix));
|
||||
}
|
||||
|
||||
@@ -3329,6 +3319,7 @@ theme_subdir_load (GtkIconTheme *self,
|
||||
IconThemeDirSize *dir_size;
|
||||
int scale;
|
||||
guint i;
|
||||
GString *str;
|
||||
|
||||
size = g_key_file_get_integer (theme_file, subdir, "Size", &error);
|
||||
if (error)
|
||||
@@ -3376,18 +3367,22 @@ theme_subdir_load (GtkIconTheme *self,
|
||||
dir_size_index = theme_ensure_dir_size (theme, type, size, min_size, max_size, threshold, scale);
|
||||
dir_size = &g_array_index (theme->dir_sizes, IconThemeDirSize, dir_size_index);
|
||||
|
||||
str = g_string_sized_new (256);
|
||||
|
||||
for (i = 0; i < self->dir_mtimes->len; i++)
|
||||
{
|
||||
IconThemeDirMtime *dir_mtime = &g_array_index (self->dir_mtimes, IconThemeDirMtime, i);
|
||||
char *full_dir;
|
||||
|
||||
if (!dir_mtime->exists)
|
||||
continue; /* directory doesn't exist */
|
||||
|
||||
full_dir = g_build_filename (dir_mtime->dir, subdir, NULL);
|
||||
g_string_assign (str, dir_mtime->dir);
|
||||
if (str->str[str->len - 1] != '/')
|
||||
g_string_append_c (str, '/');
|
||||
g_string_append (str, subdir);
|
||||
|
||||
/* First, see if we have a cache for the directory */
|
||||
if (dir_mtime->cache != NULL || g_file_test (full_dir, G_FILE_TEST_IS_DIR))
|
||||
if (dir_mtime->cache != NULL || g_file_test (str->str, G_FILE_TEST_IS_DIR))
|
||||
{
|
||||
GHashTable *icons = NULL;
|
||||
|
||||
@@ -3398,50 +3393,52 @@ theme_subdir_load (GtkIconTheme *self,
|
||||
}
|
||||
|
||||
if (dir_mtime->cache != NULL)
|
||||
icons = gtk_icon_cache_list_icons_in_directory (dir_mtime->cache, subdir, &theme->icons);
|
||||
icons = gtk_icon_cache_list_icons_in_directory (dir_mtime->cache, subdir, &self->icons);
|
||||
else
|
||||
icons = scan_directory (self, full_dir, &theme->icons);
|
||||
icons = scan_directory (self, str->str, &self->icons);
|
||||
|
||||
if (icons)
|
||||
{
|
||||
theme_add_dir_with_icons (theme,
|
||||
dir_size,
|
||||
FALSE,
|
||||
g_steal_pointer (&full_dir),
|
||||
g_strdup (str->str),
|
||||
icons);
|
||||
g_hash_table_destroy (icons);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (full_dir);
|
||||
}
|
||||
|
||||
if (strcmp (theme->name, FALLBACK_ICON_THEME) == 0)
|
||||
{
|
||||
int r;
|
||||
|
||||
for (r = 0; self->resource_path[r]; r++)
|
||||
{
|
||||
GHashTable *icons;
|
||||
char *full_dir;
|
||||
|
||||
g_string_assign (str, self->resource_path[r]);
|
||||
if (str->str[str->len - 1] != '/')
|
||||
g_string_append_c (str, '/');
|
||||
g_string_append (str, subdir);
|
||||
/* Force a trailing / here, to avoid extra copies in GResource */
|
||||
full_dir = g_build_filename (self->resource_path[r], subdir, " ", NULL);
|
||||
full_dir[strlen (full_dir) - 1] = '\0';
|
||||
if (str->str[str->len - 1] != '/')
|
||||
g_string_append_c (str, '/');
|
||||
|
||||
icons = scan_resource_directory (self, full_dir, &theme->icons);
|
||||
icons = scan_resource_directory (self, str->str, &self->icons);
|
||||
if (icons)
|
||||
{
|
||||
theme_add_dir_with_icons (theme,
|
||||
dir_size,
|
||||
TRUE,
|
||||
g_steal_pointer (&full_dir),
|
||||
g_strdup (str->str),
|
||||
icons);
|
||||
g_hash_table_destroy (icons);
|
||||
}
|
||||
|
||||
g_free (full_dir);
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3843,7 +3840,7 @@ icon_ensure_texture__locked (GtkIconPaintable *icon,
|
||||
|
||||
if (!icon->texture)
|
||||
{
|
||||
g_warning ("Failed to load icon %s: %s", icon->filename, load_error->message);
|
||||
g_warning ("Failed to load icon %s: %s", icon->filename, load_error ? load_error->message : "");
|
||||
g_clear_error (&load_error);
|
||||
icon->texture = gdk_texture_new_from_resource (IMAGE_MISSING_RESOURCE_PATH);
|
||||
icon->icon_name = g_strdup ("image-missing");
|
||||
|
||||
@@ -133,7 +133,7 @@ istring_prepend (IString *str,
|
||||
if (!istring_is_inline (str))
|
||||
old = str->u.str;
|
||||
|
||||
str->u.str = g_strconcat (istring_str (str), istring_str (other), NULL);
|
||||
str->u.str = g_strconcat (istring_str (other), istring_str (str), NULL);
|
||||
str->n_bytes += other->n_bytes;
|
||||
str->n_chars += other->n_chars;
|
||||
|
||||
|
||||
+5
-8
@@ -40,7 +40,6 @@
|
||||
#include "gtkshortcut.h"
|
||||
#include "gtkshortcutcontroller.h"
|
||||
#include "gtkshortcuttrigger.h"
|
||||
#include "gtkfilelauncher.h"
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
@@ -48,6 +47,7 @@
|
||||
#include "gtktextutilprivate.h"
|
||||
#include "gtktooltip.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkurilauncher.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkpopovermenu.h"
|
||||
#include "gtknative.h"
|
||||
@@ -94,7 +94,7 @@
|
||||
* # GtkLabel as GtkBuildable
|
||||
*
|
||||
* The GtkLabel implementation of the GtkBuildable interface supports a
|
||||
* custom <attributes> element, which supports any number of <attribute>
|
||||
* custom `<attributes>` element, which supports any number of `<attribute>`
|
||||
* elements. The <attribute> element has attributes named “name“, “value“,
|
||||
* “start“ and “end“ and allows you to specify [struct@Pango.Attribute]
|
||||
* values for this label.
|
||||
@@ -2102,17 +2102,14 @@ gtk_label_activate_link (GtkLabel *self,
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
|
||||
GFile *file;
|
||||
GtkFileLauncher *launcher;
|
||||
GtkUriLauncher *launcher;
|
||||
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
return FALSE;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
launcher = gtk_file_launcher_new (file);
|
||||
gtk_file_launcher_launch (launcher, GTK_WINDOW (toplevel), NULL, NULL, NULL);
|
||||
launcher = gtk_uri_launcher_new (uri);
|
||||
gtk_uri_launcher_launch (launcher, GTK_WINDOW (toplevel), NULL, NULL, NULL);
|
||||
g_object_unref (launcher);
|
||||
g_object_unref (file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+3
-3
@@ -64,7 +64,7 @@
|
||||
* // background-color: magenta;
|
||||
* // border-style: solid;
|
||||
* // border-color: black;
|
||||
* // border-style: 1px;
|
||||
* // border-width: 1px;
|
||||
* // }
|
||||
*
|
||||
* gtk_level_bar_add_offset_value (bar, "my-offset", 0.60);
|
||||
@@ -90,8 +90,8 @@
|
||||
* # GtkLevelBar as GtkBuildable
|
||||
*
|
||||
* The `GtkLevelBar` implementation of the `GtkBuildable` interface supports a
|
||||
* custom <offsets> element, which can contain any number of <offset> elements,
|
||||
* each of which must have name and value attributes.
|
||||
* custom `<offsets>` element, which can contain any number of `<offset>` elements,
|
||||
* each of which must have "name" and "value" attributes.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
|
||||
+4
-7
@@ -65,9 +65,9 @@
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkpopovermenu.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkfilelauncher.h"
|
||||
#include "gtksizerequest.h"
|
||||
#include "gtktooltip.h"
|
||||
#include "gtkurilauncher.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
#include <string.h>
|
||||
@@ -479,16 +479,13 @@ static gboolean
|
||||
gtk_link_button_activate_link (GtkLinkButton *link_button)
|
||||
{
|
||||
GtkWidget *toplevel;
|
||||
GFile *file;
|
||||
GtkFileLauncher *launcher;
|
||||
GtkUriLauncher *launcher;
|
||||
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (link_button)));
|
||||
|
||||
file = g_file_new_for_uri (link_button->uri);
|
||||
launcher = gtk_file_launcher_new (file);
|
||||
gtk_file_launcher_launch (launcher, GTK_WINDOW (toplevel), NULL, NULL, NULL);
|
||||
launcher = gtk_uri_launcher_new (link_button->uri);
|
||||
gtk_uri_launcher_launch (launcher, GTK_WINDOW (toplevel), NULL, NULL, NULL);
|
||||
g_object_unref (launcher);
|
||||
g_object_unref (file);
|
||||
|
||||
gtk_link_button_set_visited (link_button, TRUE);
|
||||
|
||||
|
||||
+2
-2
@@ -378,10 +378,10 @@ gtk_list_base_get_allocation_across (GtkListBase *self,
|
||||
* @pos: item to select
|
||||
* @modify: %TRUE if the selection should be modified, %FALSE
|
||||
* if a new selection should be done. This is usually set
|
||||
* to %TRUE if the user keeps the <Shift> key pressed.
|
||||
* to %TRUE if the user keeps the `<Shift>` key pressed.
|
||||
* @extend_pos: %TRUE if the selection should be extended.
|
||||
* Selections are usually extended from the last selected
|
||||
* position if the user presses the <Ctrl> key.
|
||||
* position if the user presses the `<Ctrl>` key.
|
||||
*
|
||||
* Selects the item at @pos according to how GTK list widgets modify
|
||||
* selections, both when clicking rows with the mouse or when using
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@
|
||||
*
|
||||
* The `GtkListBox` implementation of the `GtkBuildable` interface supports
|
||||
* setting a child as the placeholder by specifying “placeholder” as the “type”
|
||||
* attribute of a <child> element. See [method@Gtk.ListBox.set_placeholder]
|
||||
* attribute of a `<child>` element. See [method@Gtk.ListBox.set_placeholder]
|
||||
* for info.
|
||||
*
|
||||
* # CSS nodes
|
||||
|
||||
+31
-12
@@ -48,6 +48,8 @@
|
||||
#undef STRICT
|
||||
#endif
|
||||
|
||||
#include <hb-glib.h>
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "gtkbox.h"
|
||||
@@ -781,20 +783,37 @@ gtk_is_initialized (void)
|
||||
GtkTextDirection
|
||||
gtk_get_locale_direction (void)
|
||||
{
|
||||
/* Translate to default:RTL if you want your widgets
|
||||
* to be RTL, otherwise translate to default:LTR.
|
||||
* Do *not* translate it to "predefinito:LTR", if it
|
||||
* it isn't default:LTR or default:RTL it will not work
|
||||
*/
|
||||
char *e = _("default:LTR");
|
||||
GtkTextDirection dir = GTK_TEXT_DIR_LTR;
|
||||
PangoLanguage *language;
|
||||
const PangoScript *scripts;
|
||||
int n_scripts;
|
||||
|
||||
if (g_strcmp0 (e, "default:RTL") == 0)
|
||||
dir = GTK_TEXT_DIR_RTL;
|
||||
else if (g_strcmp0 (e, "default:LTR") != 0)
|
||||
g_warning ("Whoever translated default:LTR did so wrongly. Defaulting to LTR.");
|
||||
language = gtk_get_default_language ();
|
||||
scripts = pango_language_get_scripts (language, &n_scripts);
|
||||
|
||||
return dir;
|
||||
if (n_scripts > 0)
|
||||
{
|
||||
for (int i = 0; i < n_scripts; i++)
|
||||
{
|
||||
hb_script_t script;
|
||||
|
||||
script = hb_glib_script_to_script ((GUnicodeScript) scripts[i]);
|
||||
|
||||
switch (hb_script_get_horizontal_direction (script))
|
||||
{
|
||||
case HB_DIRECTION_LTR:
|
||||
return GTK_TEXT_DIR_LTR;
|
||||
case HB_DIRECTION_RTL:
|
||||
return GTK_TEXT_DIR_RTL;
|
||||
case HB_DIRECTION_TTB:
|
||||
case HB_DIRECTION_BTT:
|
||||
case HB_DIRECTION_INVALID:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GTK_TEXT_DIR_LTR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -832,6 +832,8 @@ update_accel (GtkModelButton *self,
|
||||
"css-name", "accelerator",
|
||||
NULL);
|
||||
gtk_widget_insert_before (self->accel_label, GTK_WIDGET (self), NULL);
|
||||
gtk_widget_set_hexpand (self->accel_label, TRUE),
|
||||
gtk_widget_set_halign (self->accel_label, GTK_ALIGN_END);
|
||||
}
|
||||
|
||||
gtk_accelerator_parse (accel, &key, &mods);
|
||||
|
||||
+3
-5
@@ -146,18 +146,16 @@ get_module_path (void)
|
||||
char **
|
||||
_gtk_get_module_path (const char *type)
|
||||
{
|
||||
char **paths = get_module_path();
|
||||
char **paths = get_module_path ();
|
||||
char **path;
|
||||
char **result;
|
||||
int count = 0;
|
||||
|
||||
for (path = paths; *path; path++)
|
||||
count++;
|
||||
|
||||
count = g_strv_length (paths);
|
||||
result = g_new (char *, count * 4 + 1);
|
||||
|
||||
count = 0;
|
||||
for (path = get_module_path (); *path; path++)
|
||||
for (path = paths; *path; path++)
|
||||
{
|
||||
result[count++] = g_build_filename (*path, GTK_BINARY_VERSION, GTK_HOST, type, NULL);
|
||||
result[count++] = g_build_filename (*path, GTK_BINARY_VERSION, type, NULL);
|
||||
|
||||
+3
-3
@@ -77,14 +77,14 @@
|
||||
*
|
||||
* The `GtkNotebook` implementation of the `GtkBuildable` interface
|
||||
* supports placing children into tabs by specifying “tab” as the
|
||||
* “type” attribute of a <child> element. Note that the content
|
||||
* “type” attribute of a `<child>` element. Note that the content
|
||||
* of the tab must be created before the tab can be filled.
|
||||
* A tab child can be specified without specifying a <child>
|
||||
* A tab child can be specified without specifying a `<child>`
|
||||
* type attribute.
|
||||
*
|
||||
* To add a child widget in the notebooks action area, specify
|
||||
* "action-start" or “action-end” as the “type” attribute of the
|
||||
* <child> element.
|
||||
* `<child>` element.
|
||||
*
|
||||
* An example of a UI definition fragment with `GtkNotebook`:
|
||||
*
|
||||
|
||||
+2
-2
@@ -64,8 +64,8 @@
|
||||
*
|
||||
* # GtkScale as GtkBuildable
|
||||
*
|
||||
* `GtkScale` supports a custom <marks> element, which can contain multiple
|
||||
* <mark\> elements. The “value” and “position” attributes have the same
|
||||
* `GtkScale` supports a custom `<marks>` element, which can contain multiple
|
||||
* `<mark\>` elements. The “value” and “position” attributes have the same
|
||||
* meaning as [method@Gtk.Scale.add_mark] parameters of the same name. If
|
||||
* the element is not empty, its content is taken as the markup to show at
|
||||
* the mark. It can be translated with the usual ”translatable” and
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define __GTK_SEARCH_ENGINE_MODEL_H__
|
||||
|
||||
#include "gtksearchengineprivate.h"
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkfilesystemmodelprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user