Compare commits
161 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d4dfbc1def | |||
| fb73acc885 | |||
| acad0e8893 | |||
| d869aec29f | |||
| aae99a8704 | |||
| 19ba03d0a6 | |||
| ac59d553ce | |||
| 9991d6834d | |||
| ddf8c4dd1a | |||
| 970072ef65 | |||
| f8321029fc | |||
| f83cab01ec | |||
| 8a74770ec1 | |||
| 39c503c108 | |||
| fc32b8242b | |||
| 7c2b4eb0e7 | |||
| d8b0aea6b7 | |||
| 190d8ef8ff | |||
| 15e9194b59 | |||
| 0257da6cc0 | |||
| 907f878c9f | |||
| b2071cdeb5 | |||
| 1a292bf8ab | |||
| 7e07d63a6c | |||
| 824e983372 | |||
| 9e5417c6c7 | |||
| e94dae8536 | |||
| 0dd163254d | |||
| 341ecab41a | |||
| 9eac7ed8b9 | |||
| 4005eb8fe8 | |||
| 1d4ceac2c5 | |||
| a5246a6856 | |||
| 11d235d165 | |||
| af00beb772 | |||
| e5cd9354d5 | |||
| 6426ab7466 | |||
| b710df6f45 | |||
| 50998b0ee9 | |||
| 92c2c68c7b | |||
| c2f5b64b5d | |||
| 460bf6d8b9 | |||
| a0dff87c86 | |||
| 3015b9f120 | |||
| 01549e3c91 | |||
| bc48bfc2b6 | |||
| 6100258ba2 | |||
| e083bd7920 | |||
| e915546b44 | |||
| b6cfe35940 | |||
| 4cd9fd9b15 | |||
| 6f8cab0e9d | |||
| 6eb9161906 | |||
| d13695f586 | |||
| 749919c551 | |||
| 58980e0b4a | |||
| 5813a5cace | |||
| f88b777fe5 | |||
| a80af681b8 | |||
| 94695bb276 | |||
| be36113826 | |||
| 5dfbaa53fc | |||
| a13ddcb67b | |||
| d228bae365 | |||
| 463f12a3bb | |||
| 3f87b130ba | |||
| c17049c6d1 | |||
| f000baf0d6 | |||
| aef4c50155 | |||
| 2a1e4b8621 | |||
| cabd18fba0 | |||
| 1da4782262 | |||
| 8911ed5d9b | |||
| 294b659dc1 | |||
| 7ad74ad6c3 | |||
| bb777507ce | |||
| 1e1d79d4f7 | |||
| a254a4529f | |||
| e7bd691532 | |||
| 4e62350232 | |||
| 2c883a70e2 | |||
| 3dfeb2fd37 | |||
| 3ba3e8286f | |||
| fbf4817ef5 | |||
| db43e0669f | |||
| 386c77b13d | |||
| e6998dffe8 | |||
| 12057c8a30 | |||
| b7c422cb98 | |||
| 1c76f6586b | |||
| d43968f7b6 | |||
| 26650787e1 | |||
| b4ef072188 | |||
| 3858c5282c | |||
| 1ff8dad8ec | |||
| d8cb11ec4a | |||
| 8796950651 | |||
| c6cef6db52 | |||
| fdea27c04d | |||
| a52f9d6def | |||
| ee272646c9 | |||
| 6655177a0b | |||
| cb78f0d10a | |||
| 1cb621633c | |||
| ce25efeee7 | |||
| 375b554924 | |||
| 69eed999bb | |||
| cab5f2bd8d | |||
| 35e3c22832 | |||
| 92612c2265 | |||
| 4e1b46a7ec | |||
| 55f7f7d0ee | |||
| 442cd4a369 | |||
| 53af41e2fa | |||
| c43e1f3d0a | |||
| 32e855ad61 | |||
| 034a8a5501 | |||
| 1e9dbf2df0 | |||
| dce21f06dd | |||
| 56c1c4152f | |||
| a9d2fa296e | |||
| 5bccb106c2 | |||
| 45086487f1 | |||
| 65f03121a4 | |||
| 09769193d7 | |||
| 7f8acf960b | |||
| ee0e026237 | |||
| 6bfd581a72 | |||
| 7b6f254e64 | |||
| 47955cfe62 | |||
| e62ca17f88 | |||
| c24ba58acb | |||
| 30987168fb | |||
| 93a875bf20 | |||
| aac3bf581a | |||
| 869f07521c | |||
| 7e392a1186 | |||
| 53d87e42a5 | |||
| 6757a1b409 | |||
| 115738dd2f | |||
| 5caa66ffb7 | |||
| 7df73c4fd2 | |||
| 1ea5a08c8f | |||
| 9c669cbe90 | |||
| 1a5184bc85 | |||
| d6ef39b9a2 | |||
| 52f6acd398 | |||
| 136c1ccd2c | |||
| 16e23b3f9e | |||
| 628aeda7ee | |||
| 2669dc269b | |||
| 1bc63eeadb | |||
| 1d8a23e97b | |||
| 422b4b6561 | |||
| 27ee8b23fd | |||
| b9847795a7 | |||
| 757d1916ae | |||
| 420be8fb0f | |||
| 9c3629653f | |||
| eb5cf831b1 | |||
| 2290c2bb23 |
@@ -364,6 +364,7 @@ asan-build:
|
||||
tags: [ asan ]
|
||||
stage: analysis
|
||||
needs: []
|
||||
when: manual
|
||||
variables:
|
||||
script:
|
||||
- export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
+2
-1
@@ -21,7 +21,7 @@ many things that we value:
|
||||
Please, do not use the issue tracker for support questions. If you have
|
||||
questions on how to use GTK effectively, you can use:
|
||||
|
||||
- the `#gtk` IRC channel on irc.gnome.org
|
||||
- the `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org)
|
||||
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
||||
|
||||
You can also look at the GTK tag on [Stack
|
||||
@@ -44,6 +44,7 @@ If you're reporting a bug make sure to list:
|
||||
|
||||
0. which version of GTK are you using?
|
||||
0. which operating system are you using?
|
||||
0. what display and graphics driver are you using?
|
||||
0. the necessary steps to reproduce the issue
|
||||
0. the expected outcome
|
||||
0. a description of the behavior; screenshots are also welcome
|
||||
|
||||
@@ -1,6 +1,76 @@
|
||||
Overview of Changes in 4.9.3, xx-xx-xxxx
|
||||
Overview of Changes in 4.9.4, xx-xx-xxxx
|
||||
========================================
|
||||
|
||||
Overview of Changes in 4.9.3, 04-02-2023
|
||||
========================================
|
||||
|
||||
* Add GtkUriLauncher, as replacement for gtk_show_uri
|
||||
|
||||
* Add GdkMonitor::description
|
||||
|
||||
* Fix problems with tooltip sizing
|
||||
|
||||
* Deprecations:
|
||||
- GtkStatusbar
|
||||
- GtkAssistant
|
||||
- GtkLockButton
|
||||
- gtk_gesture_set_sequence_state
|
||||
|
||||
* GtkColumnView:
|
||||
- Only create widgets for visible columns
|
||||
|
||||
* GtkFileDialog:
|
||||
- Drop shortcut folders API
|
||||
|
||||
* GtkCalendar:
|
||||
- Make marked days work again
|
||||
|
||||
* GtkSwitch:
|
||||
- Make state and active independently settable
|
||||
|
||||
* GtkFileChooser:
|
||||
- Fix a crash with DND
|
||||
- Fix excessively wide sidebar
|
||||
- Make context menus work again
|
||||
|
||||
* Accessibility:
|
||||
- Make GtkAccessible public, so it can be implemented outside GTK
|
||||
- Support accessible implementation for editables
|
||||
|
||||
* CSS:
|
||||
- Fix randomly stopping CSS animations
|
||||
|
||||
* GL:
|
||||
- Fix synchronization with GStreamer
|
||||
- Fix problems with 3rd party GL in the same thread
|
||||
|
||||
* Wayland:
|
||||
- Fix startup notification with xdg_activation
|
||||
|
||||
* Broadway:
|
||||
- Implement modal windows
|
||||
|
||||
* macOS:
|
||||
- Make DND work
|
||||
|
||||
* Build:
|
||||
- Require graphene 1.10
|
||||
- Require gobject-introspection 1.72
|
||||
|
||||
* Translation updates
|
||||
Catalan
|
||||
Galician
|
||||
German
|
||||
Hebrew
|
||||
Indonesian
|
||||
Portuguese
|
||||
Russian
|
||||
Spanish
|
||||
Swedish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in 4.9.2, 26-12-2022
|
||||
========================================
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef GtkApplication DemoApplication;
|
||||
typedef GtkApplicationClass DemoApplicationClass;
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *progress_bar = NULL;
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -37,6 +37,8 @@ remove_timeout (gpointer data)
|
||||
g_source_remove (id);
|
||||
}
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static gboolean
|
||||
pop_status (gpointer data)
|
||||
{
|
||||
@@ -57,6 +59,8 @@ status_message (GtkStatusbar *status,
|
||||
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
static void
|
||||
help_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_PAINTABLE = 1,
|
||||
PROP_TEXTURE = 1,
|
||||
PROP_MIN_FILTER,
|
||||
PROP_MAG_FILTER,
|
||||
PROP_SCALE
|
||||
};
|
||||
|
||||
@@ -11,8 +13,10 @@ struct _Demo3Widget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GdkPaintable *paintable;
|
||||
GdkTexture *texture;
|
||||
float scale;
|
||||
GskScalingFilter min_filter;
|
||||
GskScalingFilter mag_filter;
|
||||
|
||||
GtkWidget *menu;
|
||||
};
|
||||
@@ -28,6 +32,8 @@ static void
|
||||
demo3_widget_init (Demo3Widget *self)
|
||||
{
|
||||
self->scale = 1.f;
|
||||
self->min_filter = GSK_SCALING_FILTER_NEAREST;
|
||||
self->mag_filter = GSK_SCALING_FILTER_NEAREST;
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
@@ -36,7 +42,7 @@ demo3_widget_dispose (GObject *object)
|
||||
{
|
||||
Demo3Widget *self = DEMO3_WIDGET (object);
|
||||
|
||||
g_clear_object (&self->paintable);
|
||||
g_clear_object (&self->texture);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
|
||||
|
||||
@@ -50,12 +56,13 @@ demo3_widget_snapshot (GtkWidget *widget,
|
||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||
int x, y, width, height;
|
||||
double w, h;
|
||||
GskRenderNode *node;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
w = self->scale * gdk_paintable_get_intrinsic_width (self->paintable);
|
||||
h = self->scale * gdk_paintable_get_intrinsic_height (self->paintable);
|
||||
w = self->scale * gdk_texture_get_width (self->texture);
|
||||
h = self->scale * gdk_texture_get_height (self->texture);
|
||||
|
||||
x = MAX (0, (width - ceil (w)) / 2);
|
||||
y = MAX (0, (height - ceil (h)) / 2);
|
||||
@@ -63,7 +70,12 @@ demo3_widget_snapshot (GtkWidget *widget,
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
||||
gdk_paintable_snapshot (self->paintable, snapshot, w, h);
|
||||
node = gsk_texture_node_new_with_filters (self->texture,
|
||||
&GRAPHENE_RECT_INIT (0, 0, w, h),
|
||||
self->min_filter,
|
||||
self->mag_filter);
|
||||
gtk_snapshot_append_node (snapshot, node);
|
||||
gsk_render_node_unref (node);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
@@ -81,9 +93,9 @@ demo3_widget_measure (GtkWidget *widget,
|
||||
int size;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
size = gdk_paintable_get_intrinsic_width (self->paintable);
|
||||
size = gdk_texture_get_width (self->texture);
|
||||
else
|
||||
size = gdk_paintable_get_intrinsic_height (self->paintable);
|
||||
size = gdk_texture_get_height (self->texture);
|
||||
|
||||
*minimum = *natural = self->scale * size;
|
||||
}
|
||||
@@ -113,9 +125,9 @@ demo3_widget_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PAINTABLE:
|
||||
g_clear_object (&self->paintable);
|
||||
self->paintable = g_value_dup_object (value);
|
||||
case PROP_TEXTURE:
|
||||
g_clear_object (&self->texture);
|
||||
self->texture = g_value_dup_object (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
@@ -124,6 +136,16 @@ demo3_widget_set_property (GObject *object,
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
case PROP_MIN_FILTER:
|
||||
self->min_filter = g_value_get_enum (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
case PROP_MAG_FILTER:
|
||||
self->mag_filter = g_value_get_enum (value);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -140,14 +162,22 @@ demo3_widget_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PAINTABLE:
|
||||
g_value_set_object (value, self->paintable);
|
||||
case PROP_TEXTURE:
|
||||
g_value_set_object (value, self->texture);
|
||||
break;
|
||||
|
||||
case PROP_SCALE:
|
||||
g_value_set_float (value, self->scale);
|
||||
break;
|
||||
|
||||
case PROP_MIN_FILTER:
|
||||
g_value_set_enum (value, self->min_filter);
|
||||
break;
|
||||
|
||||
case PROP_MAG_FILTER:
|
||||
g_value_set_enum (value, self->mag_filter);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -205,16 +235,26 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
||||
widget_class->measure = demo3_widget_measure;
|
||||
widget_class->size_allocate = demo3_widget_size_allocate;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PAINTABLE,
|
||||
g_param_spec_object ("paintable", "Paintable", "Paintable",
|
||||
GDK_TYPE_PAINTABLE,
|
||||
g_object_class_install_property (object_class, PROP_TEXTURE,
|
||||
g_param_spec_object ("texture", NULL, NULL,
|
||||
GDK_TYPE_TEXTURE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCALE,
|
||||
g_param_spec_float ("scale", "Scale", "Scale",
|
||||
g_param_spec_float ("scale", NULL, NULL,
|
||||
0.0, 10.0, 1.0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_MIN_FILTER,
|
||||
g_param_spec_enum ("min-filter", NULL, NULL,
|
||||
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_MAG_FILTER,
|
||||
g_param_spec_enum ("mag-filter", NULL, NULL,
|
||||
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
/* These are the actions that we are using in the menu */
|
||||
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
|
||||
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
|
||||
@@ -229,16 +269,13 @@ GtkWidget *
|
||||
demo3_widget_new (const char *resource)
|
||||
{
|
||||
Demo3Widget *self;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPaintable *paintable;
|
||||
GdkTexture *texture;
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_resource (resource, NULL);
|
||||
paintable = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
|
||||
texture = gdk_texture_new_from_resource (resource);
|
||||
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "paintable", paintable, NULL);
|
||||
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (paintable);
|
||||
g_object_unref (texture);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
G_CALLBACK (scribble_resize), NULL);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), 0);
|
||||
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
||||
|
||||
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
|
||||
|
||||
+13
-1
@@ -22,9 +22,11 @@ do_menu (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *box2;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scale;
|
||||
GtkWidget *dropdown;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Menu");
|
||||
@@ -43,10 +45,20 @@ do_menu (GtkWidget *do_widget)
|
||||
widget = demo3_widget_new ("/transparent/portland-rose.jpg");
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), widget);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_box_append (GTK_BOX (box), box2);
|
||||
|
||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
|
||||
gtk_range_set_value (GTK_RANGE (scale), 1.0);
|
||||
gtk_box_append (GTK_BOX (box), scale);
|
||||
gtk_widget_set_hexpand (scale, TRUE);
|
||||
gtk_box_append (GTK_BOX (box2), scale);
|
||||
|
||||
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
|
||||
gtk_box_append (GTK_BOX (box2), dropdown);
|
||||
|
||||
g_object_bind_property (dropdown, "selected", widget, "min-filter", G_BINDING_DEFAULT);
|
||||
g_object_bind_property (dropdown, "selected", widget, "mag-filter", G_BINDING_DEFAULT);
|
||||
|
||||
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
|
||||
widget, "scale",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include "demo_conf.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
static GtkWidget *main_window;
|
||||
static GFile *filename = NULL;
|
||||
static GtkPageSetup *page_setup = NULL;
|
||||
|
||||
@@ -2252,11 +2252,13 @@ activate (GApplication *app)
|
||||
for (i = 0; i < G_N_ELEMENTS (accels); i++)
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), accels[i].action_and_target, accels[i].accelerators);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "statusbar");
|
||||
gtk_statusbar_push (GTK_STATUSBAR (widget), 0, "All systems are operating normally.");
|
||||
action = G_ACTION (g_property_action_new ("statusbar", widget, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (window), action);
|
||||
g_object_unref (G_OBJECT (action));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "toolbar");
|
||||
action = G_ACTION (g_property_action_new ("toolbar", widget, "visible"));
|
||||
@@ -2430,6 +2432,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "record_button");
|
||||
g_object_set_data (G_OBJECT (window), "record_button", widget);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "lockbox");
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "lockbutton");
|
||||
g_object_set_data (G_OBJECT (window), "lockbutton", widget2);
|
||||
@@ -2447,6 +2450,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
G_BINDING_SYNC_CREATE);
|
||||
gtk_lock_button_set_permission (GTK_LOCK_BUTTON (widget2), permission);
|
||||
g_object_unref (permission);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "iconview1");
|
||||
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "increase_button");
|
||||
|
||||
@@ -109,3 +109,13 @@ 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.
|
||||
|
||||
## GtkStatusbar is going away
|
||||
|
||||
This is an oldfashioned widget that does not do all that much anymore, since
|
||||
it no longer has a resize handle for the window.
|
||||
|
||||
## GtkLockButton is going away
|
||||
|
||||
This is an very specialized widget that should better live with the application
|
||||
where it is used.
|
||||
|
||||
@@ -37,7 +37,7 @@ main (int argc,
|
||||
GtkApplication *app;
|
||||
int status;
|
||||
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
|
||||
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
g_object_unref (app);
|
||||
|
||||
@@ -213,6 +213,7 @@ typedef enum {
|
||||
BROADWAY_REQUEST_RELEASE_TEXTURE,
|
||||
BROADWAY_REQUEST_SET_NODES,
|
||||
BROADWAY_REQUEST_ROUNDTRIP,
|
||||
BROADWAY_REQUEST_SET_MODAL_HINT,
|
||||
} BroadwayRequestType;
|
||||
|
||||
typedef struct {
|
||||
@@ -293,6 +294,12 @@ typedef struct {
|
||||
guint32 show_keyboard;
|
||||
} BroadwayRequestSetShowKeyboard;
|
||||
|
||||
typedef struct {
|
||||
BroadwayRequestBase base;
|
||||
guint32 id;
|
||||
gboolean modal_hint;
|
||||
} BroadwayRequestSetModalHint;
|
||||
|
||||
typedef union {
|
||||
BroadwayRequestBase base;
|
||||
BroadwayRequestNewSurface new_surface;
|
||||
@@ -312,6 +319,7 @@ typedef union {
|
||||
BroadwayRequestUploadTexture upload_texture;
|
||||
BroadwayRequestReleaseTexture release_texture;
|
||||
BroadwayRequestSetNodes set_nodes;
|
||||
BroadwayRequestSetModalHint set_modal_hint;
|
||||
} BroadwayRequest;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -124,6 +124,7 @@ struct BroadwaySurface {
|
||||
gboolean visible;
|
||||
gint32 transient_for;
|
||||
guint32 texture;
|
||||
gboolean modal_hint;
|
||||
BroadwayNode *nodes;
|
||||
GHashTable *node_lookup;
|
||||
};
|
||||
@@ -421,6 +422,14 @@ update_event_state (BroadwayServer *server,
|
||||
{
|
||||
surface->x = message->configure_notify.x;
|
||||
surface->y = message->configure_notify.y;
|
||||
|
||||
if (server->focused_surface_id != message->configure_notify.id &&
|
||||
server->pointer_grab_surface_id == -1 && surface->modal_hint)
|
||||
{
|
||||
broadway_server_surface_raise (server, message->configure_notify.id);
|
||||
broadway_server_focus_surface (server, message->configure_notify.id);
|
||||
broadway_server_flush (server);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
|
||||
@@ -1568,6 +1577,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
int id)
|
||||
{
|
||||
BroadwaySurface *surface;
|
||||
gint32 transient_for = -1;
|
||||
|
||||
if (server->mouse_in_surface_id == id)
|
||||
{
|
||||
@@ -1585,11 +1595,24 @@ broadway_server_destroy_surface (BroadwayServer *server,
|
||||
surface = broadway_server_lookup_surface (server, id);
|
||||
if (surface != NULL)
|
||||
{
|
||||
if (server->focused_surface_id == id)
|
||||
transient_for = surface->transient_for;
|
||||
|
||||
server->surfaces = g_list_remove (server->surfaces, surface);
|
||||
g_hash_table_remove (server->surface_id_hash,
|
||||
GINT_TO_POINTER (id));
|
||||
broadway_surface_free (server, surface);
|
||||
}
|
||||
|
||||
if (transient_for != -1)
|
||||
{
|
||||
surface = broadway_server_lookup_surface (server, transient_for);
|
||||
if (surface != NULL)
|
||||
{
|
||||
broadway_server_focus_surface (server, transient_for);
|
||||
broadway_server_flush (server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1710,6 +1733,19 @@ broadway_server_surface_set_transient_for (BroadwayServer *server,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
broadway_server_surface_set_modal_hint (BroadwayServer *server,
|
||||
int id, gboolean modal_hint)
|
||||
{
|
||||
BroadwaySurface *surface;
|
||||
|
||||
surface = broadway_server_lookup_surface (server, id);
|
||||
if (surface == NULL)
|
||||
return;
|
||||
|
||||
surface->modal_hint = modal_hint;
|
||||
}
|
||||
|
||||
gboolean
|
||||
broadway_server_has_client (BroadwayServer *server)
|
||||
{
|
||||
|
||||
@@ -130,6 +130,9 @@ gboolean broadway_server_surface_move_resize (BroadwayServer *
|
||||
int height);
|
||||
void broadway_server_focus_surface (BroadwayServer *server,
|
||||
int new_focused_surface);
|
||||
void broadway_server_surface_set_modal_hint (BroadwayServer *server,
|
||||
int id,
|
||||
gboolean modal_hint);
|
||||
|
||||
|
||||
#endif /* __BROADWAY_SERVER__ */
|
||||
|
||||
@@ -380,6 +380,11 @@ client_handle_request (BroadwayClient *client,
|
||||
case BROADWAY_REQUEST_SET_SHOW_KEYBOARD:
|
||||
broadway_server_set_show_keyboard (server, request->set_show_keyboard.show_keyboard);
|
||||
break;
|
||||
case BROADWAY_REQUEST_SET_MODAL_HINT:
|
||||
broadway_server_surface_set_modal_hint (server,
|
||||
request->set_modal_hint.id,
|
||||
request->set_modal_hint.modal_hint);
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unknown request of type %d", request->base.type);
|
||||
}
|
||||
|
||||
@@ -561,6 +561,18 @@ _gdk_broadway_server_surface_set_transient_for (GdkBroadwayServer *server,
|
||||
BROADWAY_REQUEST_SET_TRANSIENT_FOR);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
|
||||
int id, gboolean modal_hint)
|
||||
{
|
||||
BroadwayRequestSetModalHint msg;
|
||||
|
||||
msg.id = id;
|
||||
msg.modal_hint = modal_hint;
|
||||
gdk_broadway_server_send_message (server, msg,
|
||||
BROADWAY_REQUEST_SET_MODAL_HINT);
|
||||
}
|
||||
|
||||
static int
|
||||
open_shared_memory (void)
|
||||
{
|
||||
|
||||
@@ -78,5 +78,8 @@ gboolean _gdk_broadway_server_surface_move_resize (GdkBroadwaySe
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void _gdk_broadway_server_surface_set_modal_hint (GdkBroadwayServer *server,
|
||||
int id,
|
||||
gboolean modal_hint);
|
||||
|
||||
#endif /* __GDK_BROADWAY_SERVER__ */
|
||||
|
||||
@@ -82,6 +82,27 @@ gdk_event_source_check (GSource *source)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_focus_change (GdkEvent *event)
|
||||
{
|
||||
GdkEvent *focus_event;
|
||||
gboolean focus_in = (gdk_event_get_event_type (event) == GDK_ENTER_NOTIFY);
|
||||
|
||||
if (gdk_crossing_event_get_detail (event) == GDK_NOTIFY_INFERIOR)
|
||||
return;
|
||||
|
||||
if (!gdk_crossing_event_get_focus (event) )
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
BroadwayInputMsg *message)
|
||||
@@ -110,6 +131,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
|
||||
handle_focus_change (event);
|
||||
}
|
||||
break;
|
||||
case BROADWAY_EVENT_LEAVE:
|
||||
@@ -126,6 +149,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
|
||||
message->crossing.mode,
|
||||
GDK_NOTIFY_ANCESTOR);
|
||||
|
||||
handle_focus_change (event);
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, message->base.serial);
|
||||
}
|
||||
|
||||
@@ -709,6 +709,21 @@ gdk_broadway_surface_set_transient_for (GdkSurface *surface,
|
||||
_gdk_broadway_server_surface_set_transient_for (display->server, impl->id, impl->transient_for);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_set_modal_hint (GdkSurface *surface,
|
||||
gboolean modal)
|
||||
{
|
||||
GdkBroadwayDisplay *display;
|
||||
GdkBroadwaySurface *impl;
|
||||
|
||||
impl = GDK_BROADWAY_SURFACE (surface);
|
||||
|
||||
impl->modal_hint = modal;
|
||||
|
||||
display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
|
||||
_gdk_broadway_server_surface_set_modal_hint (display->server, impl->id, impl->modal_hint);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_broadway_surface_get_geometry (GdkSurface *surface,
|
||||
int *x,
|
||||
@@ -1433,6 +1448,8 @@ gdk_broadway_toplevel_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
|
||||
gdk_broadway_surface_set_modal_hint (surface, g_value_get_boolean (value));
|
||||
g_object_notify_by_pspec (G_OBJECT (surface), pspec);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
|
||||
@@ -1479,6 +1496,10 @@ gdk_broadway_toplevel_get_property (GObject *object,
|
||||
g_value_set_object (value, surface->transient_for);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_MODAL:
|
||||
g_value_set_boolean (value, surface->modal_hint);
|
||||
break;
|
||||
|
||||
case LAST_PROP + GDK_TOPLEVEL_PROP_ICON_LIST:
|
||||
g_value_set_pointer (value, NULL);
|
||||
break;
|
||||
|
||||
@@ -54,6 +54,7 @@ struct _GdkBroadwaySurface
|
||||
|
||||
gboolean dirty;
|
||||
gboolean last_synced;
|
||||
gboolean modal_hint;
|
||||
|
||||
GdkGeometry geometry_hints;
|
||||
GdkSurfaceHints geometry_hints_mask;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "gdkcontentformats.h"
|
||||
#include "gdkcontentserializer.h"
|
||||
#include "gdkcontentdeserializer.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
@@ -213,6 +214,8 @@ file_transfer_portal_register_files (const char **files,
|
||||
afd->len = g_strv_length ((char **)files);
|
||||
afd->start = 0;
|
||||
|
||||
GDK_DEBUG (DND, "file transfer portal: registering %d files", afd->len);
|
||||
|
||||
g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&options, "{sv}", "writable", g_variant_new_boolean (writable));
|
||||
g_variant_builder_add (&options, "{sv}", "autostop", g_variant_new_boolean (TRUE));
|
||||
@@ -348,9 +351,8 @@ portal_ready (GObject *object,
|
||||
static void
|
||||
portal_file_serializer (GdkContentSerializer *serializer)
|
||||
{
|
||||
GFile *file;
|
||||
const GValue *value;
|
||||
GPtrArray *files;
|
||||
const GValue *value;
|
||||
|
||||
files = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
@@ -358,9 +360,24 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_value_get_object (gdk_content_serializer_get_value (serializer));
|
||||
if (file)
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
|
||||
if (file && g_file_peek_path (file))
|
||||
{
|
||||
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
else if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_debug_message ("file transfer portal: %s has no path, dropping\n", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
|
||||
@@ -368,7 +385,21 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
GSList *l;
|
||||
|
||||
for (l = g_value_get_boxed (value); l; l = l->next)
|
||||
g_ptr_array_add (files, g_file_get_path (l->data));
|
||||
{
|
||||
GFile *file = l->data;
|
||||
|
||||
if (file && g_file_peek_path (file))
|
||||
{
|
||||
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_debug_message ("file transfer portal: %s has no path, dropping", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
}
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
@@ -395,6 +426,15 @@ portal_finish (GObject *object,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *s = g_strjoinv (", ", files);
|
||||
gdk_debug_message ("file transfer portal: Receiving files: %s", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
{
|
||||
|
||||
+3
-1
@@ -1149,7 +1149,7 @@ _gdk_display_get_next_serial (GdkDisplay *display)
|
||||
* [method@Gtk.Window.set_auto_startup_notification]
|
||||
* is called to disable that feature.
|
||||
*
|
||||
* Deprecated: 4.10. Using gdk_toplevel_set_startup_id() is sufficient.
|
||||
* Deprecated: 4.10: Using [method@Gdk.Toplevel.set_startup_id] is sufficient
|
||||
*/
|
||||
void
|
||||
gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
@@ -1168,6 +1168,8 @@ gdk_display_notify_startup_complete (GdkDisplay *display,
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: (nullable): the startup notification ID for @display
|
||||
*
|
||||
* Deprecated: 4.10
|
||||
*/
|
||||
const char *
|
||||
gdk_display_get_startup_notification_id (GdkDisplay *display)
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ GdkClipboard * gdk_display_get_primary_clipboard (GdkDisplay
|
||||
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
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
const char * gdk_display_get_startup_notification_id (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
+29
-2
@@ -501,6 +501,18 @@ gdk_gl_context_real_is_shared (GdkGLContext *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_is_current (GdkGLContext *self)
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
return priv->egl_context == eglGetCurrentContext ();
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_clear_current (GdkGLContext *context)
|
||||
{
|
||||
@@ -670,6 +682,7 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
klass->is_shared = gdk_gl_context_real_is_shared;
|
||||
klass->make_current = gdk_gl_context_real_make_current;
|
||||
klass->clear_current = gdk_gl_context_real_clear_current;
|
||||
klass->is_current = gdk_gl_context_real_is_current;
|
||||
klass->get_default_framebuffer = gdk_gl_context_real_get_default_framebuffer;
|
||||
|
||||
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
|
||||
@@ -1551,6 +1564,12 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_check_is_current (GdkGLContext *context)
|
||||
{
|
||||
return GDK_GL_CONTEXT_GET_CLASS (context)->is_current (context);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_make_current:
|
||||
* @context: a `GdkGLContext`
|
||||
@@ -1569,7 +1588,7 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
masked_context = mask_context (context, surfaceless);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == masked_context)
|
||||
if (current == masked_context && gdk_gl_context_check_is_current (context))
|
||||
return;
|
||||
|
||||
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
|
||||
@@ -1740,10 +1759,18 @@ GdkGLContext *
|
||||
gdk_gl_context_get_current (void)
|
||||
{
|
||||
MaskedContext *current;
|
||||
GdkGLContext *context;
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
context = unmask_context (current);
|
||||
|
||||
return unmask_context (current);
|
||||
if (context && !gdk_gl_context_check_is_current (context))
|
||||
{
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
context = NULL;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
@@ -83,6 +83,7 @@ struct _GdkGLContextClass
|
||||
gboolean (* make_current) (GdkGLContext *context,
|
||||
gboolean surfaceless);
|
||||
gboolean (* clear_current) (GdkGLContext *context);
|
||||
gboolean (* is_current) (GdkGLContext *context);
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
|
||||
gboolean (* is_shared) (GdkGLContext *self,
|
||||
|
||||
+26
-24
@@ -53,10 +53,8 @@ struct _GdkGLTextureClass {
|
||||
G_DEFINE_TYPE (GdkGLTexture, gdk_gl_texture, GDK_TYPE_TEXTURE)
|
||||
|
||||
static void
|
||||
gdk_gl_texture_dispose (GObject *object)
|
||||
drop_gl_resources (GdkGLTexture *self)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (object);
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
self->destroy (self->data);
|
||||
@@ -66,17 +64,29 @@ gdk_gl_texture_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_texture_dispose (GObject *object)
|
||||
{
|
||||
GdkGLTexture *self = GDK_GL_TEXTURE (object);
|
||||
|
||||
drop_gl_resources (self);
|
||||
|
||||
g_clear_object (&self->saved);
|
||||
|
||||
G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
typedef void (* GLFunc) (GdkGLTexture *self,
|
||||
GdkGLContext *context,
|
||||
gpointer data);
|
||||
|
||||
typedef struct _InvokeData
|
||||
{
|
||||
GdkGLTexture *self;
|
||||
volatile int spinlock;
|
||||
GFunc func;
|
||||
GLFunc func;
|
||||
gpointer data;
|
||||
} InvokeData;
|
||||
|
||||
@@ -91,7 +101,7 @@ gdk_gl_texture_invoke_callback (gpointer data)
|
||||
gdk_gl_context_make_current (context);
|
||||
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
|
||||
|
||||
invoke->func (invoke->self, invoke->data);
|
||||
invoke->func (invoke->self, context, invoke->data);
|
||||
|
||||
g_atomic_int_set (&invoke->spinlock, 1);
|
||||
|
||||
@@ -100,7 +110,7 @@ gdk_gl_texture_invoke_callback (gpointer data)
|
||||
|
||||
static void
|
||||
gdk_gl_texture_run (GdkGLTexture *self,
|
||||
GFunc func,
|
||||
GLFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
InvokeData invoke = { self, 0, func, data };
|
||||
@@ -145,19 +155,19 @@ gdk_gl_texture_find_format (gboolean use_es,
|
||||
}
|
||||
|
||||
static inline void
|
||||
gdk_gl_texture_do_download (gpointer texture_,
|
||||
gpointer download_)
|
||||
gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
GdkGLContext *context,
|
||||
gpointer download_)
|
||||
{
|
||||
GdkTexture *texture = GDK_TEXTURE (self);
|
||||
gsize expected_stride;
|
||||
GdkGLTexture *self = texture_;
|
||||
GdkTexture *texture = texture_;
|
||||
Download *download = download_;
|
||||
GLenum gl_internal_format, gl_format, gl_type;
|
||||
|
||||
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
|
||||
|
||||
if (download->stride == expected_stride &&
|
||||
!gdk_gl_context_get_use_es (self->context) &&
|
||||
!gdk_gl_context_get_use_es (context) &&
|
||||
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
|
||||
{
|
||||
glGetTexImage (GL_TEXTURE_2D,
|
||||
@@ -175,11 +185,11 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
glGenFramebuffers (1, &fbo);
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (self->context, 4, 3, 3, 1))
|
||||
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
|
||||
{
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (self->context), gl_read_format, gl_read_type, &actual_format))
|
||||
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), gl_read_format, gl_read_type, &actual_format))
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
}
|
||||
else
|
||||
@@ -193,7 +203,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
(download->stride == expected_stride))
|
||||
{
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
download->data);
|
||||
@@ -204,7 +214,7 @@ gdk_gl_texture_do_download (gpointer texture_,
|
||||
guchar *pixels = g_malloc_n (texture->width * actual_bpp, texture->height);
|
||||
|
||||
glReadPixels (0, 0,
|
||||
texture->width, texture->height,
|
||||
texture->width, texture->height,
|
||||
gl_read_format,
|
||||
gl_read_type,
|
||||
pixels);
|
||||
@@ -297,15 +307,7 @@ gdk_gl_texture_release (GdkGLTexture *self)
|
||||
self->saved = GDK_TEXTURE (gdk_memory_texture_from_texture (texture,
|
||||
gdk_texture_get_format (texture)));
|
||||
|
||||
if (self->destroy)
|
||||
{
|
||||
self->destroy (self->data);
|
||||
self->destroy = NULL;
|
||||
self->data = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&self->context);
|
||||
self->id = 0;
|
||||
drop_gl_resources (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_DISPLAY,
|
||||
PROP_MANUFACTURER,
|
||||
PROP_MODEL,
|
||||
@@ -81,6 +82,10 @@ gdk_monitor_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DESCRIPTION:
|
||||
g_value_set_string (value, monitor->description);
|
||||
break;
|
||||
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, monitor->display);
|
||||
break;
|
||||
@@ -154,6 +159,7 @@ gdk_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkMonitor *monitor = GDK_MONITOR (object);
|
||||
|
||||
g_free (monitor->description);
|
||||
g_free (monitor->connector);
|
||||
g_free (monitor->manufacturer);
|
||||
g_free (monitor->model);
|
||||
@@ -170,6 +176,18 @@ gdk_monitor_class_init (GdkMonitorClass *class)
|
||||
object_class->get_property = gdk_monitor_get_property;
|
||||
object_class->set_property = gdk_monitor_set_property;
|
||||
|
||||
/**
|
||||
* GdkMonitor:description: (attributes org.gtk.Property.get=gdk_monitor_get_description)
|
||||
*
|
||||
* A short description of the monitor, meant for display to the user.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
props[PROP_DESCRIPTION] =
|
||||
g_param_spec_string ("description", NULL, NULL,
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkMonitor:display: (attributes org.gtk.Property.get=gdk_monitor_get_display)
|
||||
*
|
||||
@@ -377,6 +395,10 @@ gdk_monitor_get_height_mm (GdkMonitor *monitor)
|
||||
*
|
||||
* Gets the name of the monitor's connector, if available.
|
||||
*
|
||||
* These are strings such as "eDP-1", or "HDMI-2". They depend
|
||||
* on software and hardware configuration, and should not be
|
||||
* relied on as stable identifiers of a specific monitor.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the connector
|
||||
*/
|
||||
const char *
|
||||
@@ -619,3 +641,33 @@ gdk_monitor_is_valid (GdkMonitor *monitor)
|
||||
|
||||
return monitor->valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_description: (attributes org.gtk.Method.get_property=description)
|
||||
* @monitor: a `GdkMonitor`
|
||||
*
|
||||
* Gets a string describing the monitor, if available.
|
||||
*
|
||||
* This can be used to identify a monitor in the UI.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the monitor description
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
const char *
|
||||
gdk_monitor_get_description (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
|
||||
|
||||
return monitor->description;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_description (GdkMonitor *monitor,
|
||||
const char *description)
|
||||
{
|
||||
g_free (monitor->description);
|
||||
monitor->description = g_strdup (description);
|
||||
g_object_notify_by_pspec (G_OBJECT (monitor), props[PROP_DESCRIPTION]);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkSubpixelLayout gdk_monitor_get_subpixel_layout (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_monitor_is_valid (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
const char * gdk_monitor_get_description (GdkMonitor *monitor);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkMonitor, g_object_unref)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ struct _GdkMonitor {
|
||||
char *manufacturer;
|
||||
char *model;
|
||||
char *connector;
|
||||
char *description;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
@@ -70,6 +71,8 @@ void gdk_monitor_set_refresh_rate (GdkMonitor *monitor,
|
||||
void gdk_monitor_set_subpixel_layout (GdkMonitor *monitor,
|
||||
GdkSubpixelLayout subpixel);
|
||||
void gdk_monitor_invalidate (GdkMonitor *monitor);
|
||||
void gdk_monitor_set_description (GdkMonitor *monitor,
|
||||
const char *description);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
#import "GdkMacosView.h"
|
||||
#import "GdkMacosWindow.h"
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdrag-private.h"
|
||||
#include "gdkmacosdrop-private.h"
|
||||
#include "gdkmacoseventsource-private.h"
|
||||
#include "gdkmacosmonitor-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
#include "gdkmacossurface-private.h"
|
||||
#include "gdkmacospopupsurface-private.h"
|
||||
#include "gdkmacostoplevelsurface-private.h"
|
||||
@@ -144,7 +146,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
*
|
||||
* TODO: Can we improve grab breaking to fix this?
|
||||
*/
|
||||
_gdk_macos_display_send_button_event ([self gdkDisplay], event);
|
||||
_gdk_macos_display_send_event ([self gdkDisplay], event);
|
||||
|
||||
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
|
||||
|
||||
@@ -246,7 +248,7 @@ typedef NSString *CALayerContentsGravity;
|
||||
[view release];
|
||||
|
||||
/* TODO: We might want to make this more extensible at some point */
|
||||
_gdk_macos_clipboard_register_drag_types (self);
|
||||
_gdk_macos_pasteboard_register_drag_types (self);
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -668,7 +670,61 @@ typedef NSString *CALayerContentsGravity;
|
||||
}
|
||||
|
||||
// NSDraggingSource protocol
|
||||
// ...
|
||||
|
||||
- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
GdkModifierType state = _gdk_macos_display_get_current_keyboard_modifiers (GDK_MACOS_DISPLAY (display));
|
||||
|
||||
_gdk_macos_drag_set_actions (GDK_MACOS_DRAG (drag), state);
|
||||
|
||||
return _gdk_macos_drag_operation (GDK_MACOS_DRAG (drag));
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (gdk_surface));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
int x, y;
|
||||
|
||||
_gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display), screenPoint.x, screenPoint.y, &x, &y);
|
||||
_gdk_macos_drag_set_start_position (GDK_MACOS_DRAG (drag), x, y);
|
||||
_gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y);
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession *)session movedToPoint:(NSPoint)screenPoint
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface)));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (GDK_MACOS_DISPLAY (display), sequence_number);
|
||||
int x, y;
|
||||
|
||||
_gdk_macos_display_send_event (display, [NSApp currentEvent]);
|
||||
|
||||
_gdk_macos_display_from_display_coords (display, screenPoint.x, screenPoint.y, &x, &y);
|
||||
_gdk_macos_drag_surface_move (GDK_MACOS_DRAG (drag), x, y);
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
NSInteger sequence_number = [session draggingSequenceNumber];
|
||||
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (gdk_surface)));
|
||||
GdkDrag *drag = _gdk_macos_display_find_drag (display, sequence_number);
|
||||
|
||||
_gdk_macos_display_send_event (display, [NSApp currentEvent]);
|
||||
gdk_drag_set_selected_action (drag, _gdk_macos_drag_ns_operation_to_action (operation));
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
_gdk_macos_display_set_drag (display, [session draggingSequenceNumber], NULL);
|
||||
}
|
||||
|
||||
// end
|
||||
|
||||
-(void)setStyleMask:(NSWindowStyleMask)styleMask
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#define GDK_IS_MACOS_WINDOW(obj) ([obj isKindOfClass:[GdkMacosWindow class]])
|
||||
|
||||
@interface GdkMacosWindow : NSWindow {
|
||||
@interface GdkMacosWindow : NSWindow <NSDraggingSource, NSDraggingDestination> {
|
||||
GdkMacosSurface *gdk_surface;
|
||||
|
||||
BOOL inMove;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -41,30 +42,6 @@ NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
|
||||
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
|
||||
void _gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error);
|
||||
|
||||
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
GCancellable *cancellable;
|
||||
GdkClipboard *clipboard;
|
||||
char **mimeTypes;
|
||||
}
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
-(NSArray<NSPasteboardType> *)types;
|
||||
|
||||
@end
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+15
-488
@@ -22,6 +22,7 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gdkmacosclipboard-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
#include "gdkprivate.h"
|
||||
|
||||
@@ -32,163 +33,8 @@ struct _GdkMacosClipboard
|
||||
NSInteger last_change_count;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMemoryOutputStream *stream;
|
||||
NSPasteboardItem *item;
|
||||
NSPasteboardType type;
|
||||
GMainContext *main_context;
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
enum {
|
||||
TYPE_STRING,
|
||||
TYPE_PBOARD,
|
||||
TYPE_URL,
|
||||
TYPE_FILE_URL,
|
||||
TYPE_COLOR,
|
||||
TYPE_TIFF,
|
||||
TYPE_PNG,
|
||||
TYPE_LAST
|
||||
};
|
||||
|
||||
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
|
||||
|
||||
static NSPasteboardType pasteboard_types[TYPE_LAST];
|
||||
|
||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||
|
||||
static NSPasteboardType
|
||||
get_pasteboard_type (int type)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
g_assert (type >= 0);
|
||||
g_assert (type < TYPE_LAST);
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
|
||||
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
|
||||
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
|
||||
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
|
||||
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
|
||||
#else
|
||||
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
|
||||
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
|
||||
#endif
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
return pasteboard_types[type];
|
||||
}
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
const char *
|
||||
_gdk_macos_clipboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSPasteboardType
|
||||
_gdk_macos_clipboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NULL;
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return PTYPE(STRING);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return PTYPE(COLOR);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return PTYPE(TIFF);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return PTYPE(PNG);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
NSPasteboardType type)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
g_return_if_fail (builder != NULL);
|
||||
g_return_if_fail (type != NULL);
|
||||
|
||||
mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
|
||||
if (mime_type != NULL)
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&formats);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
{
|
||||
@@ -199,22 +45,13 @@ _gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||
|
||||
change_count = [self->pasteboard changeCount];
|
||||
|
||||
formats = load_offer_formats (self->pasteboard);
|
||||
formats = _gdk_macos_pasteboard_load_formats (self->pasteboard);
|
||||
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
|
||||
gdk_content_formats_unref (formats);
|
||||
|
||||
self->last_change_count = change_count;
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
create_stream_from_nsdata (NSData *data)
|
||||
{
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
|
||||
GdkContentFormats *formats,
|
||||
@@ -245,34 +82,26 @@ static void
|
||||
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
|
||||
GdkContentProvider *content)
|
||||
{
|
||||
GdkMacosPasteboardItem *item;
|
||||
NSArray<NSPasteboardItem *> *items;
|
||||
|
||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_assert (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
if (self->pasteboard == NULL)
|
||||
return;
|
||||
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkMacosClipboardDataProvider *dataProvider;
|
||||
GdkContentFormats *serializable;
|
||||
NSPasteboardItem *item;
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
|
||||
g_return_if_fail (GDK_IS_MACOS_CLIPBOARD (self));
|
||||
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (content));
|
||||
|
||||
serializable = gdk_content_provider_ref_storable_formats (content);
|
||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||
|
||||
dataProvider = [[GdkMacosClipboardDataProvider alloc] initClipboard:GDK_CLIPBOARD (self)
|
||||
mimetypes:mime_types];
|
||||
item = [[NSPasteboardItem alloc] init];
|
||||
[item setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
item = [[GdkMacosPasteboardItem alloc] initForClipboard:GDK_CLIPBOARD (self) withContentProvider:content];
|
||||
items = [NSArray arrayWithObject:item];
|
||||
|
||||
[self->pasteboard clearContents];
|
||||
if ([self->pasteboard writeObjects:[NSArray arrayWithObject:item]] == NO)
|
||||
g_warning ("Failed to write object to pasteboard");
|
||||
if ([self->pasteboard writeObjects:items] == NO)
|
||||
g_warning ("Failed to send clipboard to pasteboard");
|
||||
|
||||
self->last_change_count = [self->pasteboard changeCount];
|
||||
|
||||
g_clear_pointer (&serializable, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
@@ -365,305 +194,3 @@ _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self)
|
||||
if ([self->pasteboard changeCount] != self->last_change_count)
|
||||
_gdk_macos_clipboard_load_contents (self);
|
||||
}
|
||||
|
||||
@implementation GdkMacosClipboardDataProvider
|
||||
|
||||
-(id)initClipboard:(GdkClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
||||
{
|
||||
[super init];
|
||||
|
||||
self->mimeTypes = g_strdupv ((char **)mime_types);
|
||||
self->clipboard = g_object_ref (gdkClipboard);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
|
||||
g_clear_pointer (&self->mimeTypes, g_strfreev);
|
||||
g_clear_object (&self->clipboard);
|
||||
g_clear_object (&self->cancellable);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||
{
|
||||
g_clear_object (&self->clipboard);
|
||||
}
|
||||
|
||||
-(NSArray<NSPasteboardType> *)types
|
||||
{
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
|
||||
for (guint i = 0; self->mimeTypes[i]; i++)
|
||||
{
|
||||
const char *mime_type = self->mimeTypes[i];
|
||||
NSPasteboardType type;
|
||||
NSPasteboardType alternate = nil;
|
||||
|
||||
if ((type = _gdk_macos_clipboard_to_ns_type (mime_type, &alternate)))
|
||||
{
|
||||
[ret addObject:type];
|
||||
if (alternate)
|
||||
[ret addObject:alternate];
|
||||
}
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_ready_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkClipboard *clipboard = (GdkClipboard *)object;
|
||||
WriteRequest *wr = user_data;
|
||||
GError *error = NULL;
|
||||
NSData *data = nil;
|
||||
|
||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (wr != NULL);
|
||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||
|
||||
if (gdk_clipboard_write_finish (clipboard, result, &error))
|
||||
{
|
||||
gsize size;
|
||||
gpointer bytes;
|
||||
|
||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||
|
||||
size = g_memory_output_stream_get_data_size (wr->stream);
|
||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||
length:size
|
||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to serialize clipboard contents: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
[wr->item setData:data forType:wr->type];
|
||||
|
||||
wr->done = TRUE;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
-(void) pasteboard:(NSPasteboard *)pasteboard
|
||||
item:(NSPasteboardItem *)item
|
||||
provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
const char *mime_type = _gdk_macos_clipboard_from_ns_type (type);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
WriteRequest *wr;
|
||||
|
||||
if (self->clipboard == NULL || mime_type == NULL)
|
||||
{
|
||||
[item setData:[NSData data] forType:type];
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
wr->main_context = g_main_context_ref (main_context);
|
||||
wr->done = FALSE;
|
||||
|
||||
gdk_clipboard_write_async (self->clipboard,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
self->cancellable,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
|
||||
/* We're forced to provide data synchronously via this API
|
||||
* so we must block on the main loop. Using another main loop
|
||||
* than the default tends to get us locked up here, so that is
|
||||
* what we'll do for now.
|
||||
*/
|
||||
while (!wr->done)
|
||||
g_main_context_iteration (wr->main_context, TRUE);
|
||||
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_clipboard_register_drag_types (NSWindow *window)
|
||||
{
|
||||
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
|
||||
PTYPE(PBOARD),
|
||||
PTYPE(URL),
|
||||
PTYPE(FILE_URL),
|
||||
PTYPE(COLOR),
|
||||
PTYPE(TIFF),
|
||||
PTYPE(PNG),
|
||||
nil]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
GdkContentFormats *
|
||||
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
return load_offer_formats (pasteboard);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (pasteboard != NULL);
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (object, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (pasteboard);
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
@@ -155,12 +155,13 @@ void _gdk_macos_display_surface_became_key (GdkMacosDisp
|
||||
GdkMacosSurface *surface);
|
||||
void _gdk_macos_display_clear_sorting (GdkMacosDisplay *self);
|
||||
const GList *_gdk_macos_display_get_surfaces (GdkMacosDisplay *self);
|
||||
void _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
void _gdk_macos_display_send_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent);
|
||||
void _gdk_macos_display_warp_pointer (GdkMacosDisplay *self,
|
||||
int x,
|
||||
int y);
|
||||
NSEvent *_gdk_macos_display_get_nsevent (GdkEvent *event);
|
||||
NSEvent *_gdk_macos_display_get_last_nsevent (void);
|
||||
GdkDrag *_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number);
|
||||
GdkDrop *_gdk_macos_display_find_drop (GdkMacosDisplay *self,
|
||||
|
||||
@@ -723,6 +723,85 @@ fill_scroll_event (GdkMacosDisplay *self,
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
|
||||
static GdkEvent *
|
||||
fill_event (GdkMacosDisplay *self,
|
||||
GdkMacosWindow *window,
|
||||
NSEvent *nsevent,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
GdkMacosSurface *surface = [window gdkSurface];
|
||||
NSEventType event_type = [nsevent type];
|
||||
GdkEvent *ret = NULL;
|
||||
|
||||
switch ((int)event_type)
|
||||
{
|
||||
case NSEventTypeLeftMouseDown:
|
||||
case NSEventTypeRightMouseDown:
|
||||
case NSEventTypeOtherMouseDown:
|
||||
case NSEventTypeLeftMouseUp:
|
||||
case NSEventTypeRightMouseUp:
|
||||
case NSEventTypeOtherMouseUp:
|
||||
ret = fill_button_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeLeftMouseDragged:
|
||||
case NSEventTypeRightMouseDragged:
|
||||
case NSEventTypeOtherMouseDragged:
|
||||
case NSEventTypeMouseMoved:
|
||||
ret = fill_motion_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMagnify:
|
||||
case NSEventTypeRotate:
|
||||
ret = fill_pinch_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMouseExited:
|
||||
case NSEventTypeMouseEntered:
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
GdkDevice *pointer = gdk_seat_get_pointer (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
|
||||
|
||||
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
|
||||
{
|
||||
ret = GDK_MACOS_EVENT_DROP;
|
||||
}
|
||||
else if (grab == NULL || grab->owner_events)
|
||||
{
|
||||
if (event_type == NSEventTypeMouseExited)
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
ret = synthesize_crossing_event (self, surface, nsevent, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NSEventTypeKeyDown:
|
||||
case NSEventTypeKeyUp:
|
||||
case NSEventTypeFlagsChanged: {
|
||||
GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent);
|
||||
|
||||
if (type)
|
||||
ret = fill_key_event (self, surface, nsevent, type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NSEventTypeScrollWheel:
|
||||
ret = fill_scroll_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_mouse_button_press_event (NSEventType type)
|
||||
{
|
||||
@@ -1025,16 +1104,12 @@ find_surface_for_ns_event (GdkMacosDisplay *self,
|
||||
GdkMacosBaseView *view;
|
||||
GdkSurface *surface;
|
||||
NSPoint point;
|
||||
int x_tmp;
|
||||
int y_tmp;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (self));
|
||||
g_assert (nsevent != NULL);
|
||||
g_assert (x != NULL);
|
||||
g_assert (y != NULL);
|
||||
|
||||
_gdk_macos_display_from_display_coords (self, point.x, point.y, &x_tmp, &y_tmp);
|
||||
|
||||
switch ((int)[nsevent type])
|
||||
{
|
||||
case NSEventTypeLeftMouseDown:
|
||||
@@ -1083,7 +1158,6 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
GdkMacosWindow *window;
|
||||
NSEventType event_type;
|
||||
NSWindow *event_window;
|
||||
GdkEvent *ret = NULL;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
@@ -1191,79 +1265,15 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
}
|
||||
|
||||
switch ((int)event_type)
|
||||
{
|
||||
case NSEventTypeLeftMouseDown:
|
||||
case NSEventTypeRightMouseDown:
|
||||
case NSEventTypeOtherMouseDown:
|
||||
case NSEventTypeLeftMouseUp:
|
||||
case NSEventTypeRightMouseUp:
|
||||
case NSEventTypeOtherMouseUp:
|
||||
ret = fill_button_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeLeftMouseDragged:
|
||||
case NSEventTypeRightMouseDragged:
|
||||
case NSEventTypeOtherMouseDragged:
|
||||
case NSEventTypeMouseMoved:
|
||||
ret = fill_motion_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMagnify:
|
||||
case NSEventTypeRotate:
|
||||
ret = fill_pinch_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
case NSEventTypeMouseExited:
|
||||
case NSEventTypeMouseEntered:
|
||||
{
|
||||
GdkSeat *seat = gdk_display_get_default_seat (GDK_DISPLAY (self));
|
||||
GdkDevice *pointer = gdk_seat_get_pointer (seat);
|
||||
GdkDeviceGrabInfo *grab = _gdk_display_get_last_device_grab (GDK_DISPLAY (self), pointer);
|
||||
|
||||
if ([(GdkMacosWindow *)window isInManualResizeOrMove])
|
||||
{
|
||||
ret = GDK_MACOS_EVENT_DROP;
|
||||
}
|
||||
else if (grab == NULL)
|
||||
{
|
||||
if (event_type == NSEventTypeMouseExited)
|
||||
[[NSCursor arrowCursor] set];
|
||||
|
||||
ret = synthesize_crossing_event (self, surface, nsevent, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NSEventTypeKeyDown:
|
||||
case NSEventTypeKeyUp:
|
||||
case NSEventTypeFlagsChanged: {
|
||||
GdkEventType type = _gdk_macos_keymap_get_event_type (nsevent);
|
||||
|
||||
if (type)
|
||||
ret = fill_key_event (self, surface, nsevent, type);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NSEventTypeScrollWheel:
|
||||
ret = fill_scroll_event (self, surface, nsevent, x, y);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return fill_event (self, window, nsevent, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent)
|
||||
_gdk_macos_display_send_event (GdkMacosDisplay *self,
|
||||
NSEvent *nsevent)
|
||||
{
|
||||
GdkMacosSurface *surface;
|
||||
GdkMacosWindow *window;
|
||||
GdkEvent *event;
|
||||
int x;
|
||||
int y;
|
||||
@@ -1272,7 +1282,8 @@ _gdk_macos_display_send_button_event (GdkMacosDisplay *self,
|
||||
g_return_if_fail (nsevent != NULL);
|
||||
|
||||
if ((surface = find_surface_for_ns_event (self, nsevent, &x, &y)) &&
|
||||
(event = fill_button_event (self, surface, nsevent, x, y)))
|
||||
(window = (GdkMacosWindow *)_gdk_macos_surface_get_native (surface)) &&
|
||||
(event = fill_event (self, window, nsevent, x, y)))
|
||||
_gdk_windowing_got_event (GDK_DISPLAY (self),
|
||||
_gdk_event_queue_append (GDK_DISPLAY (self), event),
|
||||
event,
|
||||
|
||||
@@ -1024,6 +1024,16 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSEvent *
|
||||
_gdk_macos_display_get_last_nsevent ()
|
||||
{
|
||||
const GdkToNSEventMap *map = g_queue_peek_tail (&event_map);
|
||||
if (map)
|
||||
return map->nsevent;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkDrag *
|
||||
_gdk_macos_display_find_drag (GdkMacosDisplay *self,
|
||||
NSInteger sequence_number)
|
||||
|
||||
@@ -41,7 +41,6 @@ struct _GdkMacosDrag
|
||||
GdkDrag parent_instance;
|
||||
|
||||
GdkMacosDragSurface *drag_surface;
|
||||
GdkSeat *drag_seat;
|
||||
GdkCursor *cursor;
|
||||
|
||||
int hot_x;
|
||||
@@ -62,8 +61,22 @@ struct _GdkMacosDragClass
|
||||
GdkDragClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self);
|
||||
GType gdk_macos_drag_get_type (void) G_GNUC_CONST;
|
||||
gboolean _gdk_macos_drag_begin (GdkMacosDrag *self,
|
||||
GdkContentProvider *content,
|
||||
GdkMacosWindow *window);
|
||||
NSDragOperation _gdk_macos_drag_operation (GdkMacosDrag *self);
|
||||
GdkDragAction _gdk_macos_drag_ns_operation_to_action
|
||||
(NSDragOperation operation);
|
||||
void _gdk_macos_drag_surface_move (GdkMacosDrag *self,
|
||||
int x_root,
|
||||
int y_root);
|
||||
void _gdk_macos_drag_set_start_position (GdkMacosDrag *self,
|
||||
int start_x,
|
||||
int start_y);
|
||||
void _gdk_macos_drag_set_actions (GdkMacosDrag *self,
|
||||
GdkModifierType mods);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+106
-271
@@ -25,6 +25,7 @@
|
||||
#include "gdkmacoscursor-private.h"
|
||||
#include "gdkmacosdisplay-private.h"
|
||||
#include "gdkmacosdragsurface-private.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
|
||||
#include "gdk/gdkdeviceprivate.h"
|
||||
#include "gdk/gdkeventsprivate.h"
|
||||
@@ -187,47 +188,6 @@ gdk_macos_drag_set_cursor (GdkDrag *drag,
|
||||
[nscursor set];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_grab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkSeat *seat;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
seat = gdk_device_get_seat (gdk_drag_get_device (GDK_DRAG (self)));
|
||||
|
||||
if (gdk_seat_grab (seat,
|
||||
GDK_SURFACE (self->drag_surface),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE,
|
||||
self->cursor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL) != GDK_GRAB_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
g_set_object (&self->drag_seat, seat);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_ungrab (GdkMacosDrag *self)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_cancel (GdkDrag *drag,
|
||||
GdkDragCancelReason reason)
|
||||
@@ -240,7 +200,6 @@ gdk_macos_drag_cancel (GdkDrag *drag,
|
||||
return;
|
||||
|
||||
self->cancelled = TRUE;
|
||||
drag_ungrab (self);
|
||||
gdk_drag_drop_done (drag, FALSE);
|
||||
}
|
||||
|
||||
@@ -253,7 +212,6 @@ gdk_macos_drag_drop_performed (GdkDrag *drag,
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
g_object_ref (self);
|
||||
drag_ungrab (self);
|
||||
g_signal_emit_by_name (drag, "dnd-finished");
|
||||
gdk_drag_drop_done (drag, TRUE);
|
||||
g_object_unref (self);
|
||||
@@ -316,225 +274,6 @@ gdk_drag_get_current_actions (GdkModifierType state,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_update (GdkDrag *drag,
|
||||
double x_root,
|
||||
double y_root,
|
||||
GdkModifierType mods,
|
||||
guint32 evtime)
|
||||
{
|
||||
GdkMacosDrag *self = (GdkMacosDrag *)drag;
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction possible_actions;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->last_x = x_root;
|
||||
self->last_y = y_root;
|
||||
|
||||
gdk_drag_get_current_actions (mods,
|
||||
GDK_BUTTON_PRIMARY,
|
||||
gdk_drag_get_actions (drag),
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y);
|
||||
|
||||
if (!self->did_update)
|
||||
{
|
||||
self->start_x = self->last_x;
|
||||
self->start_y = self->last_y;
|
||||
self->did_update = TRUE;
|
||||
}
|
||||
|
||||
gdk_drag_set_actions (drag, possible_actions);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_motion_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
double x, y;
|
||||
int x_root, y_root;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
/* Ignore motion while doing zoomback */
|
||||
if (GDK_MACOS_DRAG (drag)->cancelled)
|
||||
return FALSE;
|
||||
|
||||
gdk_event_get_position (event, &x, &y);
|
||||
x_root = event->surface->x + x;
|
||||
y_root = event->surface->y + y;
|
||||
gdk_drag_update (drag, x_root, y_root,
|
||||
gdk_event_get_modifier_state (event),
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_grab_broken_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
gboolean is_implicit = gdk_grab_broken_event_get_implicit (event);
|
||||
GdkSurface *grab_surface = gdk_grab_broken_event_get_grab_surface (event);
|
||||
|
||||
/* Don't cancel if we break the implicit grab from the initial button_press. */
|
||||
if (is_implicit || grab_surface == (GdkSurface *)self->drag_surface)
|
||||
return FALSE;
|
||||
|
||||
if (gdk_event_get_device (event) != gdk_drag_get_device (drag))
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_ERROR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_button_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
g_assert (event != NULL);
|
||||
|
||||
#if 0
|
||||
/* FIXME: Check the button matches */
|
||||
if (event->button != self->button)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dnd_handle_key_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkMacosDrag *self = GDK_MACOS_DRAG (drag);
|
||||
GdkModifierType state;
|
||||
GdkDevice *pointer;
|
||||
GdkSeat *seat;
|
||||
int dx, dy;
|
||||
|
||||
dx = dy = 0;
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
seat = gdk_event_get_seat (event);
|
||||
pointer = gdk_seat_get_pointer (seat);
|
||||
|
||||
if (event->event_type == GDK_KEY_PRESS)
|
||||
{
|
||||
guint keyval = gdk_key_event_get_keyval (event);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_Escape:
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_USER_CANCELLED);
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_space:
|
||||
case GDK_KEY_Return:
|
||||
case GDK_KEY_ISO_Enter:
|
||||
case GDK_KEY_KP_Enter:
|
||||
case GDK_KEY_KP_Space:
|
||||
if (gdk_drag_get_selected_action (drag) != 0)
|
||||
g_signal_emit_by_name (drag, "drop-performed");
|
||||
else
|
||||
gdk_drag_cancel (drag, GDK_DRAG_CANCEL_NO_TARGET);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case GDK_KEY_Up:
|
||||
case GDK_KEY_KP_Up:
|
||||
dy = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Down:
|
||||
case GDK_KEY_KP_Down:
|
||||
dy = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Left:
|
||||
case GDK_KEY_KP_Left:
|
||||
dx = (state & GDK_ALT_MASK) ? -BIG_STEP : -SMALL_STEP;
|
||||
break;
|
||||
|
||||
case GDK_KEY_Right:
|
||||
case GDK_KEY_KP_Right:
|
||||
dx = (state & GDK_ALT_MASK) ? BIG_STEP : SMALL_STEP;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The state is not yet updated in the event, so we need
|
||||
* to query it here. We could use XGetModifierMapping, but
|
||||
* that would be overkill.
|
||||
*/
|
||||
gdk_macos_device_query_state (pointer, NULL, NULL, NULL, NULL, &state);
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
{
|
||||
GdkDisplay *display = gdk_event_get_display ((GdkEvent *)event);
|
||||
|
||||
self->last_x += dx;
|
||||
self->last_y += dy;
|
||||
|
||||
_gdk_macos_display_warp_pointer (GDK_MACOS_DISPLAY (display),
|
||||
self->last_x,
|
||||
self->last_y);
|
||||
}
|
||||
|
||||
gdk_drag_update (drag,
|
||||
self->last_x, self->last_y,
|
||||
state,
|
||||
gdk_event_get_time (event));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_drag_handle_event (GdkDrag *drag,
|
||||
GdkEvent *event)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DRAG (drag));
|
||||
g_assert (event != NULL);
|
||||
|
||||
switch ((guint) event->event_type)
|
||||
{
|
||||
case GDK_MOTION_NOTIFY:
|
||||
return gdk_dnd_handle_motion_event (drag, event);
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
return gdk_dnd_handle_button_event (drag, event);
|
||||
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
return gdk_dnd_handle_key_event (drag, event);
|
||||
|
||||
case GDK_GRAB_BROKEN:
|
||||
return gdk_dnd_handle_grab_broken_event (drag, event);
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_drag_finalize (GObject *object)
|
||||
{
|
||||
@@ -542,11 +281,6 @@ gdk_macos_drag_finalize (GObject *object)
|
||||
GdkMacosDragSurface *drag_surface = g_steal_pointer (&self->drag_surface);
|
||||
|
||||
g_clear_object (&self->cursor);
|
||||
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);
|
||||
|
||||
@@ -608,7 +342,6 @@ gdk_macos_drag_class_init (GdkMacosDragClass *klass)
|
||||
drag_class->set_cursor = gdk_macos_drag_set_cursor;
|
||||
drag_class->cancel = gdk_macos_drag_cancel;
|
||||
drag_class->drop_performed = gdk_macos_drag_drop_performed;
|
||||
drag_class->handle_event = gdk_macos_drag_handle_event;
|
||||
|
||||
properties [PROP_DRAG_SURFACE] =
|
||||
g_param_spec_object ("drag-surface", NULL, NULL,
|
||||
@@ -624,11 +357,113 @@ gdk_macos_drag_init (GdkMacosDrag *self)
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_drag_begin (GdkMacosDrag *self)
|
||||
_gdk_macos_drag_begin (GdkMacosDrag *self,
|
||||
GdkContentProvider *content,
|
||||
GdkMacosWindow *window)
|
||||
{
|
||||
NSArray<NSDraggingItem *> *items;
|
||||
NSDraggingSession *session;
|
||||
NSPasteboardItem *item;
|
||||
NSEvent *nsevent;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_MACOS_WINDOW (window), FALSE);
|
||||
|
||||
_gdk_macos_surface_show (GDK_MACOS_SURFACE (self->drag_surface));
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
return drag_grab (self);
|
||||
item = [[GdkMacosPasteboardItem alloc] initForDrag:GDK_DRAG (self) withContentProvider:content];
|
||||
items = [NSArray arrayWithObject:item];
|
||||
nsevent = _gdk_macos_display_get_last_nsevent ();
|
||||
|
||||
session = [[window contentView] beginDraggingSessionWithItems:items
|
||||
event:nsevent
|
||||
source:window];
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
_gdk_macos_display_set_drag (GDK_MACOS_DISPLAY (gdk_drag_get_display (GDK_DRAG (self))),
|
||||
[session draggingSequenceNumber],
|
||||
GDK_DRAG (self));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NSDragOperation
|
||||
_gdk_macos_drag_operation (GdkMacosDrag *self)
|
||||
{
|
||||
NSDragOperation operation = NSDragOperationNone;
|
||||
GdkDragAction actions;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_DRAG (self), NSDragOperationNone);
|
||||
|
||||
actions = gdk_drag_get_actions (GDK_DRAG (self));
|
||||
|
||||
if (actions & GDK_ACTION_LINK)
|
||||
operation |= NSDragOperationLink;
|
||||
|
||||
if (actions & GDK_ACTION_MOVE)
|
||||
operation |= NSDragOperationMove;
|
||||
|
||||
if (actions & GDK_ACTION_COPY)
|
||||
operation |= NSDragOperationCopy;
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
GdkDragAction
|
||||
_gdk_macos_drag_ns_operation_to_action (NSDragOperation operation)
|
||||
{
|
||||
if (operation & NSDragOperationCopy)
|
||||
return GDK_ACTION_COPY;
|
||||
if (operation & NSDragOperationMove)
|
||||
return GDK_ACTION_MOVE;
|
||||
if (operation & NSDragOperationLink)
|
||||
return GDK_ACTION_LINK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_surface_move (GdkMacosDrag *self,
|
||||
int x_root,
|
||||
int y_root)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->last_x = x_root;
|
||||
self->last_y = y_root;
|
||||
|
||||
if (GDK_IS_MACOS_SURFACE (self->drag_surface))
|
||||
_gdk_macos_surface_move (GDK_MACOS_SURFACE (self->drag_surface),
|
||||
x_root - self->hot_x,
|
||||
y_root - self->hot_y);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_set_start_position (GdkMacosDrag *self,
|
||||
int start_x,
|
||||
int start_y)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
self->start_x = start_x;
|
||||
self->start_y = start_y;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_drag_set_actions (GdkMacosDrag *self,
|
||||
GdkModifierType mods)
|
||||
{
|
||||
GdkDragAction suggested_action;
|
||||
GdkDragAction possible_actions;
|
||||
|
||||
g_assert (GDK_IS_MACOS_DRAG (self));
|
||||
|
||||
gdk_drag_get_current_actions (mods,
|
||||
GDK_BUTTON_PRIMARY,
|
||||
gdk_drag_get_actions (GDK_DRAG (self)),
|
||||
&suggested_action,
|
||||
&possible_actions);
|
||||
|
||||
gdk_drag_set_selected_action (GDK_DRAG (self), suggested_action);
|
||||
gdk_drag_set_actions (GDK_DRAG (self), possible_actions);
|
||||
}
|
||||
|
||||
@@ -37,11 +37,15 @@
|
||||
/*
|
||||
* This file implementations integration between the GLib main loop and
|
||||
* the native system of the Core Foundation run loop and Cocoa event
|
||||
* handling. There are basically two different cases that we need to
|
||||
* handle: either the GLib main loop is in control (the application
|
||||
* has called gtk_main(), or is otherwise iterating the main loop), or
|
||||
* CFRunLoop is in control (we are in a modal operation such as window
|
||||
* resizing or drag-and-drop.)
|
||||
* handling. There are basically three different cases that we need to
|
||||
* handle:
|
||||
*
|
||||
* - the GLib main loop is in control. The application has called
|
||||
* gtk_main(), or is otherwise iterating the main loop.
|
||||
* - CFRunLoop is in control. We are in a modal operation such as window
|
||||
* resizing.
|
||||
* - CFRunLoop is running a nested loop. This happens when a drag-and-drop
|
||||
* operation has been initiated.
|
||||
*
|
||||
* When the GLib main loop is in control we integrate in native event
|
||||
* handling in two ways: first we add a GSource that handles checking
|
||||
@@ -57,14 +61,23 @@
|
||||
* stages of the GLib main loop (prepare, check, dispatch), and make the
|
||||
* appropriate calls into GLib.
|
||||
*
|
||||
* Both cases share a single problem: the OS X API’s don’t allow us to
|
||||
* When initiating a drag operation, a nested CFRunLoop is executed.
|
||||
* The nested run loop is started when fetching a native event in our GLib
|
||||
* main loop. The application does not receive any events until the nested loop
|
||||
* is finished. We work around this by forwarding the
|
||||
* events that trigger the callbacks of the NSDraggingSource protocol.
|
||||
* The "run loop observer" is executing the GLib main loop stages as long as we're
|
||||
* in the nested run loop, as if CFRunLoop were in control.
|
||||
* See also GdkMacosWindow.
|
||||
*
|
||||
* All cases share a single problem: the macOS API’s don’t allow us to
|
||||
* wait simultaneously for file descriptors and for events. So when we
|
||||
* need to do a blocking wait that includes file descriptor activity, we
|
||||
* push the actual work of calling select() to a helper thread (the
|
||||
* "select thread") and wait for native events in the main thread.
|
||||
*
|
||||
* The main known limitation of this code is that if a callback is triggered
|
||||
* via the OS X run loop while we are "polling" (in either case described
|
||||
* via the macOS run loop while we are "polling" (in either case described
|
||||
* above), iteration of the GLib main loop is not possible from within
|
||||
* that callback. If the programmer tries to do so explicitly, then they
|
||||
* will get a warning from GLib "main loop already active in another thread".
|
||||
@@ -640,6 +653,23 @@ _gdk_macos_event_source_get_pending (void)
|
||||
return event;
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_macos_event_source_queue_event (NSEvent *event)
|
||||
{
|
||||
/* Just used to wake us up; if an event and a FD arrived at the same
|
||||
* time; could have come from a previous iteration in some cases,
|
||||
* but the spurious wake up is harmless if a little inefficient.
|
||||
*/
|
||||
if (!event ||
|
||||
([event type] == NSEventTypeApplicationDefined &&
|
||||
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP))
|
||||
return;
|
||||
|
||||
if (!current_events)
|
||||
current_events = g_queue_new ();
|
||||
g_queue_push_head (current_events, [event retain]);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_event_source_prepare (GSource *source,
|
||||
int *timeout)
|
||||
@@ -782,23 +812,7 @@ poll_func (GPollFD *ufds,
|
||||
if (last_ufds == ufds && n_ready < 0)
|
||||
n_ready = select_thread_collect_poll (ufds, nfds);
|
||||
|
||||
if (event &&
|
||||
[event type] == NSEventTypeApplicationDefined &&
|
||||
[event subtype] == GDK_MACOS_EVENT_SUBTYPE_EVENTLOOP)
|
||||
{
|
||||
/* Just used to wake us up; if an event and a FD arrived at the same
|
||||
* time; could have come from a previous iteration in some cases,
|
||||
* but the spurious wake up is harmless if a little inefficient.
|
||||
*/
|
||||
event = NULL;
|
||||
}
|
||||
|
||||
if (event)
|
||||
{
|
||||
if (!current_events)
|
||||
current_events = g_queue_new ();
|
||||
g_queue_push_head (current_events, [event retain]);
|
||||
}
|
||||
_gdk_macos_event_source_queue_event (event);
|
||||
|
||||
return n_ready;
|
||||
}
|
||||
@@ -1018,7 +1032,10 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
break;
|
||||
}
|
||||
|
||||
if (getting_events > 0) /* Activity we triggered */
|
||||
/* DnD starts a nested runloop, or so it seems.
|
||||
If we have such a loop, we still want to run
|
||||
our idle handlers. */
|
||||
if (getting_events > 0 && current_loop_level < 2)
|
||||
return;
|
||||
|
||||
switch (activity)
|
||||
@@ -1042,7 +1059,6 @@ run_loop_observer_callback (CFRunLoopObserverRef observer,
|
||||
run_loop_exit ();
|
||||
break;
|
||||
case kCFRunLoopAllActivities:
|
||||
/* TODO: Do most of the above? */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -548,6 +548,14 @@ gdk_macos_gl_context_clear_current (GdkGLContext *context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_is_current (GdkGLContext *context)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
|
||||
return self->cgl_context == CGLGetCurrentContext ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
@@ -639,6 +647,7 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
|
||||
|
||||
gl_class->get_damage = gdk_macos_gl_context_get_damage;
|
||||
gl_class->clear_current = gdk_macos_gl_context_clear_current;
|
||||
gl_class->is_current = gdk_macos_gl_context_is_current;
|
||||
gl_class->make_current = gdk_macos_gl_context_make_current;
|
||||
gl_class->realize = gdk_macos_gl_context_real_realize;
|
||||
gl_class->get_default_framebuffer = gdk_macos_gl_context_get_default_framebuffer;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#ifndef __GDK_MACOS_PASTEBOARD_PRIVATE_H__
|
||||
#define __GDK_MACOS_PASTEBOARD_PRIVATE_H__
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "gdkclipboardprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@interface GdkMacosPasteboardItemDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||
{
|
||||
GdkContentProvider *_contentProvider;
|
||||
GdkClipboard *_clipboard;
|
||||
GdkDrag *_drag;
|
||||
}
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
|
||||
@end
|
||||
|
||||
@interface GdkMacosPasteboardItem : NSPasteboardItem
|
||||
{
|
||||
GdkContentProvider *_contentProvider;
|
||||
GdkClipboard *_clipboard;
|
||||
GdkDrag *_drag;
|
||||
NSRect _draggingFrame;
|
||||
}
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
|
||||
|
||||
@end
|
||||
|
||||
NSPasteboardType _gdk_macos_pasteboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate);
|
||||
const char *_gdk_macos_pasteboard_from_ns_type (NSPasteboardType type);
|
||||
GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
|
||||
void _gdk_macos_pasteboard_register_drag_types (NSWindow *window);
|
||||
void _gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_MACOS_PASTEBOARD_PRIVATE_H__ */
|
||||
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "gdkdragprivate.h"
|
||||
#include "gdkmacospasteboard-private.h"
|
||||
#include "gdkmacosutils-private.h"
|
||||
|
||||
enum {
|
||||
TYPE_STRING,
|
||||
TYPE_PBOARD,
|
||||
TYPE_URL,
|
||||
TYPE_FILE_URL,
|
||||
TYPE_COLOR,
|
||||
TYPE_TIFF,
|
||||
TYPE_PNG,
|
||||
TYPE_LAST
|
||||
};
|
||||
|
||||
#define PTYPE(k) (get_pasteboard_type(TYPE_##k))
|
||||
|
||||
static NSPasteboardType pasteboard_types[TYPE_LAST];
|
||||
|
||||
static NSPasteboardType
|
||||
get_pasteboard_type (int type)
|
||||
{
|
||||
static gsize initialized = FALSE;
|
||||
|
||||
g_assert (type >= 0);
|
||||
g_assert (type < TYPE_LAST);
|
||||
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
pasteboard_types[TYPE_PNG] = NSPasteboardTypePNG;
|
||||
pasteboard_types[TYPE_STRING] = NSPasteboardTypeString;
|
||||
pasteboard_types[TYPE_TIFF] = NSPasteboardTypeTIFF;
|
||||
pasteboard_types[TYPE_COLOR] = NSPasteboardTypeColor;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
pasteboard_types[TYPE_PBOARD] = NSStringPboardType;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_13_AND_LATER
|
||||
pasteboard_types[TYPE_URL] = NSPasteboardTypeURL;
|
||||
pasteboard_types[TYPE_FILE_URL] = NSPasteboardTypeFileURL;
|
||||
#else
|
||||
pasteboard_types[TYPE_URL] = [[NSString alloc] initWithUTF8String:"public.url"];
|
||||
pasteboard_types[TYPE_FILE_URL] = [[NSString alloc] initWithUTF8String:"public.file-url"];
|
||||
#endif
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
}
|
||||
|
||||
return pasteboard_types[type];
|
||||
}
|
||||
|
||||
const char *
|
||||
_gdk_macos_pasteboard_from_ns_type (NSPasteboardType type)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([type isEqualToString:PTYPE(STRING)] ||
|
||||
[type isEqualToString:PTYPE(PBOARD)])
|
||||
return g_intern_string ("text/plain;charset=utf-8");
|
||||
else if ([type isEqualToString:PTYPE(URL)] ||
|
||||
[type isEqualToString:PTYPE(FILE_URL)])
|
||||
return g_intern_string ("text/uri-list");
|
||||
else if ([type isEqualToString:PTYPE(COLOR)])
|
||||
return g_intern_string ("application/x-color");
|
||||
else if ([type isEqualToString:PTYPE(TIFF)])
|
||||
return g_intern_string ("image/tiff");
|
||||
else if ([type isEqualToString:PTYPE(PNG)])
|
||||
return g_intern_string ("image/png");
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSPasteboardType
|
||||
_gdk_macos_pasteboard_to_ns_type (const char *mime_type,
|
||||
NSPasteboardType *alternate)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = NULL;
|
||||
|
||||
if (g_strcmp0 (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
return PTYPE(STRING);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
if (alternate)
|
||||
*alternate = PTYPE(URL);
|
||||
return PTYPE(FILE_URL);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
return PTYPE(COLOR);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
return PTYPE(TIFF);
|
||||
}
|
||||
else if (g_strcmp0 (mime_type, "image/png") == 0)
|
||||
{
|
||||
return PTYPE(PNG);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_content_formats (GdkContentFormatsBuilder *builder,
|
||||
NSPasteboardType type)
|
||||
{
|
||||
const char *mime_type;
|
||||
|
||||
g_assert (builder != NULL);
|
||||
g_assert (type != NULL);
|
||||
|
||||
if ((mime_type = _gdk_macos_pasteboard_from_ns_type (type)))
|
||||
gdk_content_formats_builder_add_mime_type (builder, mime_type);
|
||||
}
|
||||
|
||||
static GdkContentFormats *
|
||||
load_offer_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormatsBuilder *builder;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
builder = gdk_content_formats_builder_new ();
|
||||
for (NSPasteboardType type in [pasteboard types])
|
||||
populate_content_formats (builder, type);
|
||||
formats = gdk_content_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
|
||||
return g_steal_pointer (&formats);
|
||||
}
|
||||
|
||||
GdkContentFormats *
|
||||
_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
||||
{
|
||||
return load_offer_formats (pasteboard);
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
create_stream_from_nsdata (NSData *data)
|
||||
{
|
||||
const guint8 *bytes = [data bytes];
|
||||
gsize len = [data length];
|
||||
|
||||
return g_memory_input_stream_new_from_data (g_memdup2 (bytes, len), len, g_free);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_read_async (GObject *object,
|
||||
NSPasteboard *pasteboard,
|
||||
GdkContentFormats *formats,
|
||||
int io_priority,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
GdkContentFormats *offer_formats = NULL;
|
||||
const char *mime_type;
|
||||
GInputStream *stream = NULL;
|
||||
GTask *task = NULL;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (pasteboard != NULL);
|
||||
g_assert (formats != NULL);
|
||||
|
||||
task = g_task_new (object, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
|
||||
g_task_set_priority (task, io_priority);
|
||||
|
||||
offer_formats = load_offer_formats (pasteboard);
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
|
||||
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"%s",
|
||||
_("No compatible transfer format found"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
|
||||
{
|
||||
NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
|
||||
|
||||
if (nsstr != NULL)
|
||||
{
|
||||
const char *str = [nsstr UTF8String];
|
||||
stream = g_memory_input_stream_new_from_data (g_strdup (str),
|
||||
strlen (str) + 1,
|
||||
g_free);
|
||||
}
|
||||
}
|
||||
else if (strcmp (mime_type, "text/uri-list") == 0)
|
||||
{
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
|
||||
if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
|
||||
{
|
||||
GString *str = g_string_new (NULL);
|
||||
NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
gsize n_files = [files count];
|
||||
char *data;
|
||||
guint len;
|
||||
|
||||
for (gsize i = 0; i < n_files; ++i)
|
||||
{
|
||||
NSString* uriString = [files objectAtIndex:i];
|
||||
uriString = [@"file://" stringByAppendingString:uriString];
|
||||
uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
g_string_append_printf (str,
|
||||
"%s\r\n",
|
||||
[uriString cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
len = str->len;
|
||||
data = g_string_free (str, FALSE);
|
||||
stream = g_memory_input_stream_new_from_data (data, len, g_free);
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
}
|
||||
else if (strcmp (mime_type, "application/x-color") == 0)
|
||||
{
|
||||
NSColorSpace *colorspace;
|
||||
NSColor *nscolor;
|
||||
guint16 color[4];
|
||||
|
||||
colorspace = [NSColorSpace genericRGBColorSpace];
|
||||
nscolor = [[NSColor colorFromPasteboard:pasteboard]
|
||||
colorUsingColorSpace:colorspace];
|
||||
|
||||
color[0] = 0xffff * [nscolor redComponent];
|
||||
color[1] = 0xffff * [nscolor greenComponent];
|
||||
color[2] = 0xffff * [nscolor blueComponent];
|
||||
color[3] = 0xffff * [nscolor alphaComponent];
|
||||
|
||||
stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
|
||||
sizeof color,
|
||||
g_free);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/tiff") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
else if (strcmp (mime_type, "image/png") == 0)
|
||||
{
|
||||
NSData *data = [pasteboard dataForType:PTYPE(PNG)];
|
||||
stream = create_stream_from_nsdata (data);
|
||||
}
|
||||
|
||||
if (stream != NULL)
|
||||
{
|
||||
g_task_set_task_data (task, g_strdup (mime_type), g_free);
|
||||
g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
_("Failed to decode contents with mime-type of '%s'"),
|
||||
mime_type);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_clear_object (&task);
|
||||
g_clear_pointer (&offer_formats, gdk_content_formats_unref);
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
_gdk_macos_pasteboard_read_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
const char **out_mime_type,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = (GTask *)result;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
if (out_mime_type != NULL)
|
||||
*out_mime_type = g_strdup (g_task_get_task_data (task));
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_macos_pasteboard_register_drag_types (NSWindow *window)
|
||||
{
|
||||
[window registerForDraggedTypes:[NSArray arrayWithObjects:PTYPE(STRING),
|
||||
PTYPE(PBOARD),
|
||||
PTYPE(URL),
|
||||
PTYPE(FILE_URL),
|
||||
PTYPE(COLOR),
|
||||
PTYPE(TIFF),
|
||||
PTYPE(PNG),
|
||||
nil]];
|
||||
}
|
||||
|
||||
@implementation GdkMacosPasteboardItemDataProvider
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
[super init];
|
||||
g_set_object (&self->_clipboard, clipboard);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
[super init];
|
||||
g_set_object (&self->_drag, drag);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_object (&self->_contentProvider);
|
||||
g_clear_object (&self->_clipboard);
|
||||
g_clear_object (&self->_drag);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(NSArray<NSPasteboardType> *)types
|
||||
{
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
GdkContentFormats *serializable;
|
||||
const char * const *mime_types;
|
||||
gsize n_mime_types;
|
||||
|
||||
serializable = gdk_content_provider_ref_storable_formats (self->_contentProvider);
|
||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||
|
||||
for (gsize i = 0; i < n_mime_types; i++)
|
||||
{
|
||||
const char *mime_type = mime_types[i];
|
||||
NSPasteboardType type;
|
||||
NSPasteboardType alternate = nil;
|
||||
|
||||
if ((type = _gdk_macos_pasteboard_to_ns_type (mime_type, &alternate)))
|
||||
{
|
||||
[ret addObject:type];
|
||||
if (alternate)
|
||||
[ret addObject:alternate];
|
||||
}
|
||||
}
|
||||
|
||||
gdk_content_formats_unref (serializable);
|
||||
|
||||
/* Default to an url type (think gobject://internal)
|
||||
* to support internal, GType-based DnD.
|
||||
*/
|
||||
if (n_mime_types == 0)
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
gsize n_gtypes;
|
||||
|
||||
formats = gdk_content_provider_ref_formats (self->_contentProvider);
|
||||
gdk_content_formats_get_gtypes (formats, &n_gtypes);
|
||||
|
||||
if (n_gtypes)
|
||||
[ret addObject:NSPasteboardTypeURL];
|
||||
|
||||
gdk_content_formats_unref (formats);
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMemoryOutputStream *stream;
|
||||
NSPasteboardItem *item;
|
||||
NSPasteboardType type;
|
||||
GMainContext *main_context;
|
||||
guint done : 1;
|
||||
} WriteRequest;
|
||||
|
||||
static void
|
||||
write_request_free (WriteRequest *wr)
|
||||
{
|
||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||
g_clear_object (&wr->stream);
|
||||
[wr->item release];
|
||||
g_slice_free (WriteRequest, wr);
|
||||
}
|
||||
|
||||
static void
|
||||
on_data_ready_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||
|
||||
WriteRequest *wr = user_data;
|
||||
GError *error = NULL;
|
||||
NSData *data = nil;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (G_IS_OBJECT (object));
|
||||
g_assert (GDK_IS_CLIPBOARD (object) || GDK_IS_DRAG (object));
|
||||
g_assert (G_IS_ASYNC_RESULT (result));
|
||||
g_assert (wr != NULL);
|
||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||
|
||||
if (GDK_IS_CLIPBOARD (object))
|
||||
ret = gdk_clipboard_write_finish (GDK_CLIPBOARD (object), result, &error);
|
||||
else if (GDK_IS_DRAG (object))
|
||||
ret = gdk_drag_write_finish (GDK_DRAG (object), result, &error);
|
||||
else
|
||||
g_return_if_reached ();
|
||||
|
||||
if (ret)
|
||||
{
|
||||
gsize size;
|
||||
gpointer bytes;
|
||||
|
||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||
|
||||
size = g_memory_output_stream_get_data_size (wr->stream);
|
||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||
length:size
|
||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Failed to serialize pasteboard contents: %s",
|
||||
error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
[wr->item setData:data forType:wr->type];
|
||||
|
||||
wr->done = TRUE;
|
||||
|
||||
GDK_END_MACOS_ALLOC_POOL;
|
||||
}
|
||||
|
||||
-(void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
const char *mime_type = _gdk_macos_pasteboard_from_ns_type (type);
|
||||
GMainContext *main_context = g_main_context_default ();
|
||||
WriteRequest *wr;
|
||||
|
||||
if (self->_contentProvider == NULL || mime_type == NULL)
|
||||
{
|
||||
[item setData:[NSData data] forType:type];
|
||||
return;
|
||||
}
|
||||
|
||||
wr = g_slice_new0 (WriteRequest);
|
||||
wr->item = [item retain];
|
||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||
wr->type = type;
|
||||
wr->main_context = g_main_context_ref (main_context);
|
||||
wr->done = FALSE;
|
||||
|
||||
if (GDK_IS_CLIPBOARD (self->_clipboard))
|
||||
gdk_clipboard_write_async (self->_clipboard,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
else if (GDK_IS_DRAG (self->_drag))
|
||||
gdk_drag_write_async (self->_drag,
|
||||
mime_type,
|
||||
G_OUTPUT_STREAM (wr->stream),
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
on_data_ready_cb,
|
||||
wr);
|
||||
else
|
||||
g_return_if_reached ();
|
||||
|
||||
/* We're forced to provide data synchronously via this API
|
||||
* so we must block on the main loop. Using another main loop
|
||||
* than the default tends to get us locked up here, so that is
|
||||
* what we'll do for now.
|
||||
*/
|
||||
while (!wr->done)
|
||||
g_main_context_iteration (wr->main_context, TRUE);
|
||||
|
||||
write_request_free (wr);
|
||||
}
|
||||
|
||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||
{
|
||||
g_clear_object (&self->_clipboard);
|
||||
g_clear_object (&self->_drag);
|
||||
g_clear_object (&self->_contentProvider);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GdkMacosPasteboardItem
|
||||
|
||||
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
GdkMacosPasteboardItemDataProvider *dataProvider;
|
||||
|
||||
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForClipboard:clipboard withContentProvider:contentProvider];
|
||||
|
||||
[super init];
|
||||
g_set_object (&self->_clipboard, clipboard);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
|
||||
[dataProvider release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
|
||||
{
|
||||
GdkMacosPasteboardItemDataProvider *dataProvider;
|
||||
|
||||
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForDrag:drag withContentProvider:contentProvider];
|
||||
|
||||
[super init];
|
||||
g_set_object (&self->_drag, drag);
|
||||
g_set_object (&self->_contentProvider, contentProvider);
|
||||
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||
|
||||
[dataProvider release];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
g_clear_object (&self->_contentProvider);
|
||||
g_clear_object (&self->_clipboard);
|
||||
g_clear_object (&self->_drag);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
-(NSRect)draggingFrame
|
||||
{
|
||||
return self->_draggingFrame;
|
||||
}
|
||||
|
||||
-(void)setDraggingFrame:(NSRect)draggingFrame;
|
||||
{
|
||||
self->_draggingFrame = draggingFrame;
|
||||
}
|
||||
|
||||
-(id)item
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSArray* (^) (void))imageComponentsProvider
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -446,7 +446,7 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
|
||||
gdk_drag_get_selected_action (GDK_DRAG (drag)));
|
||||
gdk_drag_set_cursor (GDK_DRAG (drag), cursor);
|
||||
|
||||
if (!_gdk_macos_drag_begin (drag))
|
||||
if (!_gdk_macos_drag_begin (drag, content, self->window))
|
||||
{
|
||||
g_object_unref (drag);
|
||||
return NULL;
|
||||
|
||||
@@ -19,6 +19,7 @@ gdk_macos_sources = files([
|
||||
'gdkmacoseventsource.c',
|
||||
'gdkmacoskeymap.c',
|
||||
'gdkmacosmonitor.c',
|
||||
'gdkmacospasteboard.c',
|
||||
'gdkmacospopupsurface.c',
|
||||
'gdkmacosseat.c',
|
||||
'gdkmacossurface.c',
|
||||
|
||||
@@ -2,6 +2,236 @@
|
||||
#define __GDK_DEVICE_WAYLAND_PRIVATE_H__
|
||||
|
||||
#include "gdkwaylanddevice.h"
|
||||
#include "gdkwaylandseat.h"
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
#include <gdk/gdkkeysprivate.h>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct _GdkWaylandDevice
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDeviceClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
typedef struct _GdkWaylandTouchData GdkWaylandTouchData;
|
||||
typedef struct _GdkWaylandPointerFrameData GdkWaylandPointerFrameData;
|
||||
typedef struct _GdkWaylandPointerData GdkWaylandPointerData;
|
||||
typedef struct _GdkWaylandTabletPadGroupData GdkWaylandTabletPadGroupData;
|
||||
typedef struct _GdkWaylandTabletPadData GdkWaylandTabletPadData;
|
||||
typedef struct _GdkWaylandTabletData GdkWaylandTabletData;
|
||||
typedef struct _GdkWaylandTabletToolData GdkWaylandTabletToolData;
|
||||
|
||||
struct _GdkWaylandTouchData
|
||||
{
|
||||
uint32_t id;
|
||||
double x;
|
||||
double y;
|
||||
GdkSurface *surface;
|
||||
uint32_t touch_down_serial;
|
||||
guint initial_touch : 1;
|
||||
};
|
||||
|
||||
struct _GdkWaylandPointerFrameData
|
||||
{
|
||||
GdkEvent *event;
|
||||
|
||||
/* Specific to the scroll event */
|
||||
double delta_x, delta_y;
|
||||
int32_t value120_x, value120_y;
|
||||
gint8 is_scroll_stop;
|
||||
enum wl_pointer_axis_source source;
|
||||
};
|
||||
|
||||
struct _GdkWaylandPointerData {
|
||||
GdkSurface *focus;
|
||||
|
||||
double surface_x, surface_y;
|
||||
|
||||
GdkModifierType button_modifiers;
|
||||
|
||||
uint32_t time;
|
||||
uint32_t enter_serial;
|
||||
uint32_t press_serial;
|
||||
|
||||
GdkSurface *grab_surface;
|
||||
uint32_t grab_time;
|
||||
|
||||
struct wl_surface *pointer_surface;
|
||||
guint cursor_is_default: 1;
|
||||
GdkCursor *cursor;
|
||||
guint cursor_timeout_id;
|
||||
guint cursor_image_index;
|
||||
guint cursor_image_delay;
|
||||
guint touchpad_event_sequence;
|
||||
|
||||
guint current_output_scale;
|
||||
GSList *pointer_surface_outputs;
|
||||
|
||||
/* Accumulated event data for a pointer frame */
|
||||
GdkWaylandPointerFrameData frame;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletPadGroupData
|
||||
{
|
||||
GdkWaylandTabletPadData *pad;
|
||||
struct zwp_tablet_pad_group_v2 *wp_tablet_pad_group;
|
||||
GList *rings;
|
||||
GList *strips;
|
||||
GList *buttons;
|
||||
|
||||
guint mode_switch_serial;
|
||||
guint n_modes;
|
||||
guint current_mode;
|
||||
|
||||
struct {
|
||||
guint source;
|
||||
gboolean is_stop;
|
||||
double value;
|
||||
} axis_tmp_info;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletPadData
|
||||
{
|
||||
GdkSeat *seat;
|
||||
struct zwp_tablet_pad_v2 *wp_tablet_pad;
|
||||
GdkDevice *device;
|
||||
|
||||
GdkWaylandTabletData *current_tablet;
|
||||
|
||||
guint enter_serial;
|
||||
uint32_t n_buttons;
|
||||
char *path;
|
||||
|
||||
GList *rings;
|
||||
GList *strips;
|
||||
GList *mode_groups;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletToolData
|
||||
{
|
||||
GdkSeat *seat;
|
||||
struct zwp_tablet_tool_v2 *wp_tablet_tool;
|
||||
GdkAxisFlags axes;
|
||||
GdkDeviceToolType type;
|
||||
guint64 hardware_serial;
|
||||
guint64 hardware_id_wacom;
|
||||
|
||||
GdkDeviceTool *tool;
|
||||
GdkWaylandTabletData *current_tablet;
|
||||
};
|
||||
|
||||
struct _GdkWaylandTabletData
|
||||
{
|
||||
struct zwp_tablet_v2 *wp_tablet;
|
||||
char *name;
|
||||
char *path;
|
||||
uint32_t vid;
|
||||
uint32_t pid;
|
||||
|
||||
GdkDevice *logical_device;
|
||||
GdkDevice *stylus_device;
|
||||
GdkSeat *seat;
|
||||
GdkWaylandPointerData pointer_info;
|
||||
|
||||
GList *pads;
|
||||
|
||||
GdkWaylandTabletToolData *current_tool;
|
||||
|
||||
int axis_indices[GDK_AXIS_LAST];
|
||||
double axes[GDK_AXIS_LAST];
|
||||
};
|
||||
|
||||
struct _GdkWaylandSeat
|
||||
{
|
||||
GdkSeat parent_instance;
|
||||
|
||||
guint32 id;
|
||||
struct wl_seat *wl_seat;
|
||||
struct wl_pointer *wl_pointer;
|
||||
struct wl_keyboard *wl_keyboard;
|
||||
struct wl_touch *wl_touch;
|
||||
struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe;
|
||||
struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch;
|
||||
struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold;
|
||||
struct zwp_tablet_seat_v2 *wp_tablet_seat;
|
||||
|
||||
GdkDisplay *display;
|
||||
|
||||
GdkDevice *logical_pointer;
|
||||
GdkDevice *logical_keyboard;
|
||||
GdkDevice *pointer;
|
||||
GdkDevice *wheel_scrolling;
|
||||
GdkDevice *finger_scrolling;
|
||||
GdkDevice *continuous_scrolling;
|
||||
GdkDevice *keyboard;
|
||||
GdkDevice *logical_touch;
|
||||
GdkDevice *touch;
|
||||
GdkCursor *cursor;
|
||||
GdkKeymap *keymap;
|
||||
|
||||
GHashTable *touches;
|
||||
GList *tablets;
|
||||
GList *tablet_tools;
|
||||
GList *tablet_pads;
|
||||
|
||||
GdkWaylandPointerData pointer_info;
|
||||
GdkWaylandPointerData touch_info;
|
||||
|
||||
GdkModifierType key_modifiers;
|
||||
GdkSurface *keyboard_focus;
|
||||
GdkSurface *grab_surface;
|
||||
uint32_t grab_time;
|
||||
gboolean have_server_repeat;
|
||||
uint32_t server_repeat_rate;
|
||||
uint32_t server_repeat_delay;
|
||||
|
||||
struct wl_data_offer *pending_offer;
|
||||
GdkContentFormatsBuilder *pending_builder;
|
||||
GdkDragAction pending_source_actions;
|
||||
GdkDragAction pending_action;
|
||||
|
||||
struct wl_callback *repeat_callback;
|
||||
guint32 repeat_timer;
|
||||
guint32 repeat_key;
|
||||
guint32 repeat_count;
|
||||
gint64 repeat_deadline;
|
||||
uint32_t keyboard_time;
|
||||
uint32_t keyboard_key_serial;
|
||||
|
||||
GdkClipboard *clipboard;
|
||||
GdkClipboard *primary_clipboard;
|
||||
struct wl_data_device *data_device;
|
||||
GdkDrag *drag;
|
||||
GdkDrop *drop;
|
||||
|
||||
/* Some tracking on gesture events */
|
||||
guint gesture_n_fingers;
|
||||
double gesture_scale;
|
||||
|
||||
GdkCursor *grab_cursor;
|
||||
};
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DEVICE_PAD (gdk_wayland_device_pad_get_type ())
|
||||
GType gdk_wayland_device_pad_get_type (void);
|
||||
|
||||
void gdk_wayland_seat_stop_cursor_animation (GdkWaylandSeat *seat,
|
||||
GdkWaylandPointerData *pointer);
|
||||
|
||||
GdkWaylandPointerData * gdk_wayland_device_get_pointer (GdkWaylandDevice *wayland_device);
|
||||
|
||||
void gdk_wayland_device_set_pointer (GdkWaylandDevice *wayland_device,
|
||||
GdkWaylandPointerData *pointer);
|
||||
|
||||
GdkWaylandTouchData * gdk_wayland_device_get_emulating_touch (GdkWaylandDevice *wayland_device);
|
||||
|
||||
void gdk_wayland_device_set_emulating_touch (GdkWaylandDevice *wayland_device,
|
||||
GdkWaylandTouchData *touch);
|
||||
|
||||
void gdk_wayland_device_query_state (GdkDevice *device,
|
||||
GdkSurface *surface,
|
||||
@@ -14,4 +244,24 @@ void gdk_wayland_device_pad_set_feedback (GdkDevice *device,
|
||||
guint feature_idx,
|
||||
const char *label);
|
||||
|
||||
GdkWaylandTabletPadData * gdk_wayland_seat_find_pad (GdkWaylandSeat *seat,
|
||||
GdkDevice *device);
|
||||
|
||||
GdkWaylandTabletData * gdk_wayland_seat_find_tablet (GdkWaylandSeat *seat,
|
||||
GdkDevice *device);
|
||||
|
||||
GdkWaylandTouchData * gdk_wayland_seat_get_touch (GdkWaylandSeat *seat,
|
||||
uint32_t id);
|
||||
|
||||
void gdk_wayland_device_maybe_emit_grab_crossing (GdkDevice *device,
|
||||
GdkSurface *window,
|
||||
guint32 time);
|
||||
|
||||
GdkSurface * gdk_wayland_device_maybe_emit_ungrab_crossing (GdkDevice *device,
|
||||
guint32 time_);
|
||||
|
||||
gboolean gdk_wayland_device_update_surface_cursor (GdkDevice *device);
|
||||
|
||||
GdkModifierType gdk_wayland_device_get_modifiers (GdkDevice *device);
|
||||
|
||||
#endif
|
||||
|
||||
+354
-5059
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,266 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@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 "gdkwaylanddevice.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
|
||||
#include <gdk/gdkdevicepadprivate.h>
|
||||
|
||||
typedef struct _GdkWaylandDevicePad GdkWaylandDevicePad;
|
||||
typedef struct _GdkWaylandDevicePadClass GdkWaylandDevicePadClass;
|
||||
|
||||
struct _GdkWaylandDevicePad
|
||||
{
|
||||
GdkWaylandDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkWaylandDevicePadClass
|
||||
{
|
||||
GdkWaylandDeviceClass parent_class;
|
||||
};
|
||||
|
||||
static void gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkWaylandDevicePad, gdk_wayland_device_pad,
|
||||
GDK_TYPE_WAYLAND_DEVICE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_DEVICE_PAD,
|
||||
gdk_wayland_device_pad_iface_init))
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_n_groups (GdkDevicePad *pad)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadData *data;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
#else
|
||||
g_assert (data != NULL);
|
||||
#endif
|
||||
|
||||
return g_list_length (data->mode_groups);
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_group_n_modes (GdkDevicePad *pad,
|
||||
int n_group)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkWaylandTabletPadData *data;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
#else
|
||||
g_assert (data != NULL);
|
||||
#endif
|
||||
|
||||
group = g_list_nth_data (data->mode_groups, n_group);
|
||||
if (!group)
|
||||
return -1;
|
||||
|
||||
return group->n_modes;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_n_features (GdkDevicePad *pad,
|
||||
GdkDevicePadFeature feature)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadData *data;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
g_assert (data != NULL);
|
||||
|
||||
switch (feature)
|
||||
{
|
||||
case GDK_DEVICE_PAD_FEATURE_BUTTON:
|
||||
return data->n_buttons;
|
||||
case GDK_DEVICE_PAD_FEATURE_RING:
|
||||
return g_list_length (data->rings);
|
||||
case GDK_DEVICE_PAD_FEATURE_STRIP:
|
||||
return g_list_length (data->strips);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_wayland_device_pad_get_feature_group (GdkDevicePad *pad,
|
||||
GdkDevicePadFeature feature,
|
||||
int idx)
|
||||
{
|
||||
GdkSeat *seat = gdk_device_get_seat (GDK_DEVICE (pad));
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkWaylandTabletPadData *data;
|
||||
GList *l;
|
||||
int i;
|
||||
|
||||
data = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat),
|
||||
GDK_DEVICE (pad));
|
||||
#ifdef G_DISABLE_ASSERT
|
||||
if (data == NULL)
|
||||
return -1;
|
||||
#else
|
||||
g_assert (data != NULL);
|
||||
#endif
|
||||
|
||||
for (l = data->mode_groups, i = 0; l; l = l->next, i++)
|
||||
{
|
||||
group = l->data;
|
||||
|
||||
switch (feature)
|
||||
{
|
||||
case GDK_DEVICE_PAD_FEATURE_BUTTON:
|
||||
if (g_list_find (group->buttons, GINT_TO_POINTER (idx)))
|
||||
return i;
|
||||
break;
|
||||
case GDK_DEVICE_PAD_FEATURE_RING:
|
||||
{
|
||||
gpointer ring;
|
||||
|
||||
ring = g_list_nth_data (data->rings, idx);
|
||||
if (ring && g_list_find (group->rings, ring))
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
case GDK_DEVICE_PAD_FEATURE_STRIP:
|
||||
{
|
||||
gpointer strip;
|
||||
strip = g_list_nth_data (data->strips, idx);
|
||||
if (strip && g_list_find (group->strips, strip))
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface)
|
||||
{
|
||||
iface->get_n_groups = gdk_wayland_device_pad_get_n_groups;
|
||||
iface->get_group_n_modes = gdk_wayland_device_pad_get_group_n_modes;
|
||||
iface->get_n_features = gdk_wayland_device_pad_get_n_features;
|
||||
iface->get_feature_group = gdk_wayland_device_pad_get_feature_group;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_pad_class_init (GdkWaylandDevicePadClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_device_pad_init (GdkWaylandDevicePad *pad)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkWaylandTabletPadGroupData *
|
||||
tablet_pad_lookup_button_group (GdkWaylandTabletPadData *pad,
|
||||
uint32_t button)
|
||||
{
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GList *l;
|
||||
|
||||
for (l = pad->mode_groups; l; l = l->next)
|
||||
{
|
||||
group = l->data;
|
||||
|
||||
if (g_list_find (group->buttons, GUINT_TO_POINTER (button)))
|
||||
return group;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_wayland_device_pad_set_feedback:
|
||||
* @device: (type GdkWaylandDevice): a %GDK_SOURCE_TABLET_PAD device
|
||||
* @feature: Feature to set the feedback label for
|
||||
* @feature_idx: 0-indexed index of the feature to set the feedback label for
|
||||
* @label: Feedback label
|
||||
*
|
||||
* Sets the feedback label for the given feature/index.
|
||||
*
|
||||
* This may be used by the compositor to provide user feedback
|
||||
* of the actions available/performed.
|
||||
*/
|
||||
void
|
||||
gdk_wayland_device_pad_set_feedback (GdkDevice *device,
|
||||
GdkDevicePadFeature feature,
|
||||
guint feature_idx,
|
||||
const char *label)
|
||||
{
|
||||
GdkWaylandTabletPadData *pad;
|
||||
GdkWaylandTabletPadGroupData *group;
|
||||
GdkSeat *seat;
|
||||
|
||||
seat = gdk_device_get_seat (device);
|
||||
pad = gdk_wayland_seat_find_pad (GDK_WAYLAND_SEAT (seat), device);
|
||||
if (!pad)
|
||||
return;
|
||||
|
||||
if (feature == GDK_DEVICE_PAD_FEATURE_BUTTON)
|
||||
{
|
||||
group = tablet_pad_lookup_button_group (pad, feature_idx);
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
zwp_tablet_pad_v2_set_feedback (pad->wp_tablet_pad, feature_idx, label,
|
||||
group->mode_switch_serial);
|
||||
}
|
||||
else if (feature == GDK_DEVICE_PAD_FEATURE_RING)
|
||||
{
|
||||
struct zwp_tablet_pad_ring_v2 *wp_pad_ring;
|
||||
|
||||
wp_pad_ring = g_list_nth_data (pad->rings, feature_idx);
|
||||
if (!wp_pad_ring)
|
||||
return;
|
||||
|
||||
group = zwp_tablet_pad_ring_v2_get_user_data (wp_pad_ring);
|
||||
zwp_tablet_pad_ring_v2_set_feedback (wp_pad_ring, label,
|
||||
group->mode_switch_serial);
|
||||
|
||||
}
|
||||
else if (feature == GDK_DEVICE_PAD_FEATURE_STRIP)
|
||||
{
|
||||
struct zwp_tablet_pad_strip_v2 *wp_pad_strip;
|
||||
|
||||
wp_pad_strip = g_list_nth_data (pad->strips, feature_idx);
|
||||
if (!wp_pad_strip)
|
||||
return;
|
||||
|
||||
group = zwp_tablet_pad_strip_v2_get_user_data (wp_pad_strip);
|
||||
zwp_tablet_pad_strip_v2_set_feedback (wp_pad_strip, label,
|
||||
group->mode_switch_serial);
|
||||
}
|
||||
}
|
||||
@@ -832,6 +832,8 @@ gdk_wayland_display_get_next_serial (GdkDisplay *display)
|
||||
* if no ID has been defined.
|
||||
*
|
||||
* Returns: (nullable): the startup notification ID for @display
|
||||
*
|
||||
* Deprecated: 4.10.
|
||||
*/
|
||||
const char *
|
||||
gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
|
||||
@@ -853,6 +855,8 @@ gdk_wayland_display_get_startup_notification_id (GdkDisplay *display)
|
||||
* The startup ID is also what is used to signal that the startup is
|
||||
* complete (for example, when opening a window or when calling
|
||||
* [method@Gdk.Display.notify_startup_complete]).
|
||||
*
|
||||
* Deprecated: 4.10. Use [method@Gdk.Toplevel.set_startup_id]
|
||||
*/
|
||||
void
|
||||
gdk_wayland_display_set_startup_notification_id (GdkDisplay *display,
|
||||
@@ -981,7 +985,9 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
display_class->queue_events = _gdk_wayland_display_queue_events;
|
||||
display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
|
||||
display_class->get_next_serial = gdk_wayland_display_get_next_serial;
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
|
||||
display_class->create_surface = _gdk_wayland_display_create_surface;
|
||||
display_class->get_keymap = _gdk_wayland_display_get_keymap;
|
||||
@@ -2326,6 +2332,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
monitor->x, monitor->y,
|
||||
monitor->width, monitor->height });
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
|
||||
gdk_monitor_set_description (GDK_MONITOR (monitor), monitor->description);
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
@@ -2382,7 +2389,7 @@ xdg_output_handle_name (void *data,
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_DEBUG (MISC, "handle name xdg-output %d", monitor->id);
|
||||
GDK_DEBUG (MISC, "handle name xdg-output %d: %s", monitor->id, name);
|
||||
|
||||
monitor->name = g_strdup (name);
|
||||
}
|
||||
@@ -2392,8 +2399,11 @@ xdg_output_handle_description (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
{
|
||||
GDK_DEBUG (MISC, "handle description xdg-output %d",
|
||||
((GdkWaylandMonitor *)data)->id);
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_DEBUG (MISC, "handle description xdg-output %d: %s", monitor->id, description);
|
||||
|
||||
monitor->description = g_strdup (description);
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
|
||||
@@ -46,6 +46,7 @@ gdk_wayland_monitor_finalize (GObject *object)
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)object;
|
||||
|
||||
g_free (monitor->name);
|
||||
g_free (monitor->description);
|
||||
|
||||
g_clear_pointer (&monitor->xdg_output, zxdg_output_v1_destroy);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ struct _GdkWaylandMonitor {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
char *name;
|
||||
char *description;
|
||||
gboolean wl_output_done;
|
||||
gboolean xdg_output_done;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,9 +53,9 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
|
||||
const char *name,
|
||||
int size);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
const char * gdk_wayland_display_get_startup_notification_id (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10_FOR(gdk_toplevel_set_startup_id)
|
||||
void gdk_wayland_display_set_startup_notification_id (GdkDisplay *display,
|
||||
const char *startup_id);
|
||||
|
||||
|
||||
@@ -6,15 +6,17 @@ gdk_wayland_sources = files([
|
||||
'gdkclipboard-wayland.c',
|
||||
'gdkcursor-wayland.c',
|
||||
'gdkdevice-wayland.c',
|
||||
'gdkdevicepad-wayland.c',
|
||||
'gdkdisplay-wayland.c',
|
||||
'gdkdrag-wayland.c',
|
||||
'gdkdragsurface-wayland.c',
|
||||
'gdkdrop-wayland.c',
|
||||
'gdkeventsource.c',
|
||||
'gdkglcontext-wayland.c',
|
||||
'gdkkeys-wayland.c',
|
||||
'gdkkeymap-wayland.c',
|
||||
'gdkmonitor-wayland.c',
|
||||
'gdkprimary-wayland.c',
|
||||
'gdkseat-wayland.c',
|
||||
'gdksurface-wayland.c',
|
||||
'gdktoplevel-wayland.c',
|
||||
'gdkpopup-wayland.c',
|
||||
|
||||
@@ -631,6 +631,14 @@ gdk_win32_gl_context_wgl_clear_current (GdkGLContext *context)
|
||||
return wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_wgl_is_current (GdkGLContext *context)
|
||||
{
|
||||
GdkWin32GLContextWGL *self = GDK_WIN32_GL_CONTEXT_WGL (context);
|
||||
|
||||
return self->wgl_context == wglGetCurrentContext ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_wgl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
@@ -682,6 +690,7 @@ gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
|
||||
context_class->realize = gdk_win32_gl_context_wgl_realize;
|
||||
context_class->make_current = gdk_win32_gl_context_wgl_make_current;
|
||||
context_class->clear_current = gdk_win32_gl_context_wgl_clear_current;
|
||||
context_class->is_current = gdk_win32_gl_context_wgl_is_current;
|
||||
|
||||
draw_context_class->begin_frame = gdk_win32_gl_context_wgl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_win32_gl_context_wgl_end_frame;
|
||||
|
||||
@@ -740,7 +740,6 @@ GPtrArray *
|
||||
_gdk_win32_display_get_monitor_list (GdkWin32Display *win32_display)
|
||||
{
|
||||
EnumMonitorData data;
|
||||
int i;
|
||||
|
||||
data.display = win32_display;
|
||||
data.monitors = get_monitor_devices (win32_display);
|
||||
|
||||
@@ -2066,19 +2066,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
|
||||
GDK_IS_TOPLEVEL (surface))
|
||||
{
|
||||
if (gdk_x11_device_xi2_get_device_type ((GdkX11DeviceXI2 *) device) != GDK_X11_DEVICE_TYPE_LOGICAL)
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (source_device));
|
||||
else
|
||||
{
|
||||
GList *physical_devices, *l;
|
||||
GList *l;
|
||||
|
||||
physical_devices = gdk_device_list_physical_devices (source_device);
|
||||
|
||||
for (l = physical_devices; l; l = l->next)
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
|
||||
|
||||
g_list_free (physical_devices);
|
||||
}
|
||||
for (l = device_manager->devices; l; l = l->next)
|
||||
_gdk_device_xi2_reset_scroll_valuators (GDK_X11_DEVICE_XI2 (l->data));
|
||||
}
|
||||
|
||||
event = gdk_crossing_event_new (ev->evtype == XI_Enter
|
||||
|
||||
@@ -2074,8 +2074,10 @@ gdk_x11_display_make_default (GdkDisplay *display)
|
||||
display_x11->startup_notification_id = NULL;
|
||||
|
||||
startup_id = gdk_get_startup_notification_id ();
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
if (startup_id)
|
||||
gdk_x11_display_set_startup_notification_id (display, startup_id);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2303,6 +2305,8 @@ gdk_x11_display_get_user_time (GdkDisplay *display)
|
||||
* Gets the startup notification ID for a display.
|
||||
*
|
||||
* Returns: the startup notification ID for @display
|
||||
*
|
||||
* Deprecated: 4.10
|
||||
*/
|
||||
const char *
|
||||
gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
|
||||
@@ -2329,7 +2333,9 @@ gdk_x11_display_get_startup_notification_id (GdkDisplay *display)
|
||||
* The startup ID is also what is used to signal that the startup is
|
||||
* complete (for example, when opening a window or when calling
|
||||
* gdk_display_notify_startup_complete()).
|
||||
**/
|
||||
*
|
||||
* Deprecated: 4.10: Using [method@Gdk.Toplevel.set_startup_id] is sufficient
|
||||
*/
|
||||
void
|
||||
gdk_x11_display_set_startup_notification_id (GdkDisplay *display,
|
||||
const char *startup_id)
|
||||
@@ -3042,7 +3048,9 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
display_class->get_app_launch_context = _gdk_x11_display_get_app_launch_context;
|
||||
|
||||
display_class->get_next_serial = gdk_x11_display_get_next_serial;
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
display_class->get_startup_notification_id = gdk_x11_display_get_startup_notification_id;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
display_class->notify_startup_complete = gdk_x11_display_notify_startup_complete;
|
||||
display_class->create_surface = _gdk_x11_display_create_surface;
|
||||
display_class->get_keymap = gdk_x11_display_get_keymap;
|
||||
|
||||
@@ -210,6 +210,14 @@ gdk_x11_gl_context_glx_clear_current (GdkGLContext *context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_glx_is_current (GdkGLContext *context)
|
||||
{
|
||||
GdkX11GLContextGLX *self = GDK_X11_GL_CONTEXT_GLX (context);
|
||||
|
||||
return self->glx_context == glXGetCurrentContext ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_glx_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
@@ -685,6 +693,7 @@ gdk_x11_gl_context_glx_class_init (GdkX11GLContextGLXClass *klass)
|
||||
context_class->realize = gdk_x11_gl_context_glx_realize;
|
||||
context_class->make_current = gdk_x11_gl_context_glx_make_current;
|
||||
context_class->clear_current = gdk_x11_gl_context_glx_clear_current;
|
||||
context_class->is_current = gdk_x11_gl_context_glx_is_current;
|
||||
context_class->get_damage = gdk_x11_gl_context_glx_get_damage;
|
||||
|
||||
draw_context_class->end_frame = gdk_x11_gl_context_glx_end_frame;
|
||||
|
||||
@@ -80,9 +80,9 @@ Cursor gdk_x11_display_get_xcursor (GdkDisplay *display,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint32 gdk_x11_display_get_user_time (GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
const char * gdk_x11_display_get_startup_notification_id (GdkDisplay *display);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gdk_x11_display_set_startup_notification_id (GdkDisplay *display,
|
||||
const char *startup_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -956,7 +956,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
guint default_framebuffer)
|
||||
{
|
||||
G_GNUC_UNUSED guint count = 0;
|
||||
graphene_rect_t scissor_test;
|
||||
graphene_rect_t scissor_test = GRAPHENE_RECT_INIT (0, 0, 0, 0);
|
||||
gboolean has_scissor = scissor != NULL;
|
||||
gboolean scissor_state = -1;
|
||||
guint program = 0;
|
||||
@@ -1439,8 +1439,7 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
|
||||
g_assert (!GDK_IS_GL_TEXTURE (texture));
|
||||
g_assert (min_filter == GL_LINEAR || min_filter == GL_NEAREST);
|
||||
g_assert (mag_filter == GL_LINEAR || min_filter == GL_NEAREST);
|
||||
g_assert (mag_filter == GL_LINEAR || mag_filter == GL_NEAREST);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
@@ -1464,6 +1463,9 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
|
||||
|
||||
gsk_gl_command_queue_do_upload_texture (self, texture);
|
||||
|
||||
if (min_filter == GL_LINEAR_MIPMAP_LINEAR)
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
|
||||
/* Restore previous texture state if any */
|
||||
if (self->attachments->textures[0].id > 0)
|
||||
glBindTexture (self->attachments->textures[0].target,
|
||||
|
||||
+12
-4
@@ -3443,9 +3443,13 @@ gsk_gl_render_job_visit_gl_shader_node (GskGLRenderJob *job,
|
||||
static void
|
||||
gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
GdkTexture *texture,
|
||||
int min_filter,
|
||||
int mag_filter,
|
||||
GskGLRenderOffscreen *offscreen)
|
||||
{
|
||||
if (gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
|
||||
if (min_filter == GL_LINEAR &&
|
||||
mag_filter == GL_LINEAR &&
|
||||
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
|
||||
texture->width,
|
||||
texture->height) &&
|
||||
!GDK_IS_GL_TEXTURE (texture))
|
||||
@@ -3458,7 +3462,7 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
}
|
||||
else
|
||||
{
|
||||
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, GL_LINEAR, GL_LINEAR);
|
||||
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, min_filter, mag_filter);
|
||||
init_full_texture_region (offscreen);
|
||||
}
|
||||
}
|
||||
@@ -3468,6 +3472,10 @@ gsk_gl_render_job_visit_texture_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
int min_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
|
||||
int mag_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR };
|
||||
int min_filter = min_filters[gsk_texture_node_get_min_filter (node)];
|
||||
int mag_filter = mag_filters[gsk_texture_node_get_mag_filter (node)];
|
||||
int max_texture_size = job->command_queue->max_texture_size;
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
@@ -3475,7 +3483,7 @@ gsk_gl_render_job_visit_texture_node (GskGLRenderJob *job,
|
||||
{
|
||||
GskGLRenderOffscreen offscreen = {0};
|
||||
|
||||
gsk_gl_render_job_upload_texture (job, texture, &offscreen);
|
||||
gsk_gl_render_job_upload_texture (job, texture, min_filter, mag_filter, &offscreen);
|
||||
|
||||
g_assert (offscreen.texture_id);
|
||||
g_assert (offscreen.was_offscreen == FALSE);
|
||||
@@ -3808,7 +3816,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
offscreen->force_offscreen == FALSE)
|
||||
{
|
||||
GdkTexture *texture = gsk_texture_node_get_texture (node);
|
||||
gsk_gl_render_job_upload_texture (job, texture, offscreen);
|
||||
gsk_gl_render_job_upload_texture (job, texture, GL_LINEAR, GL_LINEAR, offscreen);
|
||||
g_assert (offscreen->was_offscreen == FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -214,8 +214,18 @@ GType gsk_texture_node_get_type (void) G_GNUC_CO
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GskRenderNode * gsk_texture_node_new (GdkTexture *texture,
|
||||
const graphene_rect_t *bounds);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskRenderNode * gsk_texture_node_new_with_filters (GdkTexture *texture,
|
||||
const graphene_rect_t *bounds,
|
||||
GskScalingFilter min_filter,
|
||||
GskScalingFilter mag_filter);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkTexture * gsk_texture_node_get_texture (const GskRenderNode *node) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskScalingFilter gsk_texture_node_get_min_filter (const GskRenderNode *node);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GskScalingFilter gsk_texture_node_get_mag_filter (const GskRenderNode *node);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gsk_linear_gradient_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
+90
-1
@@ -1471,6 +1471,9 @@ struct _GskTextureNode
|
||||
GskRenderNode render_node;
|
||||
|
||||
GdkTexture *texture;
|
||||
|
||||
GskScalingFilter min_filter;
|
||||
GskScalingFilter mag_filter;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1492,6 +1495,11 @@ gsk_texture_node_draw (GskRenderNode *node,
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_matrix_t matrix;
|
||||
cairo_filter_t filters[] = {
|
||||
CAIRO_FILTER_BILINEAR,
|
||||
CAIRO_FILTER_NEAREST,
|
||||
CAIRO_FILTER_GOOD,
|
||||
};
|
||||
|
||||
surface = gdk_texture_download_surface (self->texture);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
@@ -1504,6 +1512,10 @@ gsk_texture_node_draw (GskRenderNode *node,
|
||||
-node->bounds.origin.x,
|
||||
-node->bounds.origin.y);
|
||||
cairo_pattern_set_matrix (pattern, &matrix);
|
||||
if (gdk_texture_get_width (self->texture) > node->bounds.size.width)
|
||||
cairo_pattern_set_filter (pattern, filters[self->min_filter]);
|
||||
else
|
||||
cairo_pattern_set_filter (pattern, filters[self->mag_filter]);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
@@ -1522,7 +1534,9 @@ gsk_texture_node_diff (GskRenderNode *node1,
|
||||
GskTextureNode *self2 = (GskTextureNode *) node2;
|
||||
|
||||
if (graphene_rect_equal (&node1->bounds, &node2->bounds) &&
|
||||
self1->texture == self2->texture)
|
||||
self1->texture == self2->texture &&
|
||||
self1->min_filter ==self2->min_filter &&
|
||||
self1->mag_filter ==self2->mag_filter)
|
||||
return;
|
||||
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
@@ -1544,6 +1558,38 @@ gsk_texture_node_get_texture (const GskRenderNode *node)
|
||||
return self->texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_texture_node_get_min_filter:
|
||||
* @node: (type GskTextureNode): a `GskRenderNode` of type %GSK_TEXTURE_NODE
|
||||
*
|
||||
* Retrieves the filter to apply when scaling the texture down.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GskScalingFilter
|
||||
gsk_texture_node_get_min_filter (const GskRenderNode *node)
|
||||
{
|
||||
const GskTextureNode *self = (const GskTextureNode *) node;
|
||||
|
||||
return self->min_filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_texture_node_get_mag_filter:
|
||||
* @node: (type GskTextureNode): a `GskRenderNode` of type %GSK_TEXTURE_NODE
|
||||
*
|
||||
* Retrieves the filter to apply when scaling the texture up.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GskScalingFilter
|
||||
gsk_texture_node_get_mag_filter (const GskRenderNode *node)
|
||||
{
|
||||
const GskTextureNode *self = (const GskTextureNode *) node;
|
||||
|
||||
return self->mag_filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_texture_node_new:
|
||||
* @texture: the `GdkTexture`
|
||||
@@ -1569,6 +1615,49 @@ gsk_texture_node_new (GdkTexture *texture,
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
self->texture = g_object_ref (texture);
|
||||
self->min_filter = GSK_SCALING_FILTER_LINEAR;
|
||||
self->mag_filter = GSK_SCALING_FILTER_LINEAR;
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
|
||||
node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_texture_node_new_with_filters:
|
||||
* @texture: the `GdkTexture`
|
||||
* @bounds: the rectangle to render the texture into
|
||||
* @min_filter: filter to apply when scaling down
|
||||
* @mag_filter: filter to apply when scaling up
|
||||
*
|
||||
* Creates a `GskRenderNode` that will render the given
|
||||
* @texture into the area given by @bounds, using the
|
||||
* given filters when required.
|
||||
*
|
||||
* Returns: (transfer full) (type GskTextureNode): A new `GskRenderNode`
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_texture_node_new_with_filters (GdkTexture *texture,
|
||||
const graphene_rect_t *bounds,
|
||||
GskScalingFilter min_filter,
|
||||
GskScalingFilter mag_filter)
|
||||
{
|
||||
GskTextureNode *self;
|
||||
GskRenderNode *node;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
|
||||
g_return_val_if_fail (bounds != NULL, NULL);
|
||||
|
||||
self = gsk_render_node_alloc (GSK_TEXTURE_NODE);
|
||||
node = (GskRenderNode *) self;
|
||||
node->offscreen_for_opacity = FALSE;
|
||||
|
||||
self->texture = g_object_ref (texture);
|
||||
self->min_filter = min_filter;
|
||||
self->mag_filter = mag_filter;
|
||||
graphene_rect_init_from_rect (&node->bounds, bounds);
|
||||
|
||||
node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
|
||||
|
||||
+88
-272
@@ -82,6 +82,10 @@
|
||||
* hold the TAB_PANEL role and be the target of the CONTROLS
|
||||
* relation with their corresponding tabs (in the stack
|
||||
* switcher or notebook).
|
||||
*
|
||||
* These are the exceptions implemented by GTK itself, but note that application
|
||||
* developers can customize the accessibility tree by implementing the
|
||||
* [iface@Gtk.Accessible] interface in any way they choose.
|
||||
*/
|
||||
|
||||
struct _GtkAtSpiContext
|
||||
@@ -329,32 +333,43 @@ collect_relations (GtkAtSpiContext *self,
|
||||
/* }}} */
|
||||
/* {{{ Accessible implementation */
|
||||
static int
|
||||
get_index_in_parent (GtkWidget *widget)
|
||||
get_index_in (GtkAccessible *parent,
|
||||
GtkAccessible *child)
|
||||
{
|
||||
GtkWidget *parent = gtk_widget_get_parent (widget);
|
||||
GtkWidget *child;
|
||||
int idx;
|
||||
GtkAccessible *candidate;
|
||||
guint res;
|
||||
|
||||
if (parent == NULL)
|
||||
return -1;
|
||||
|
||||
idx = 0;
|
||||
for (child = gtk_widget_get_first_child (parent);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
res = 0;
|
||||
for (candidate = gtk_accessible_get_first_accessible_child (parent);
|
||||
candidate != NULL;
|
||||
candidate = gtk_accessible_get_next_accessible_sibling (candidate))
|
||||
{
|
||||
if (child == widget)
|
||||
return idx;
|
||||
if (candidate == child)
|
||||
return res;
|
||||
|
||||
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
|
||||
if (!gtk_accessible_should_present (candidate))
|
||||
continue;
|
||||
|
||||
idx++;
|
||||
res++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_index_in_parent (GtkAccessible *accessible)
|
||||
{
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
if (parent != NULL)
|
||||
return get_index_in (parent, accessible);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_index_in_toplevels (GtkWidget *widget)
|
||||
{
|
||||
@@ -387,61 +402,21 @@ get_parent_context_ref (GtkAccessible *accessible)
|
||||
{
|
||||
GVariant *res = NULL;
|
||||
|
||||
if (GTK_IS_WIDGET (accessible))
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (accessible);
|
||||
GtkWidget *parent = gtk_widget_get_parent (widget);
|
||||
GtkATContext *context = gtk_accessible_get_at_context (accessible);
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
|
||||
|
||||
if (parent == NULL)
|
||||
{
|
||||
GtkATContext *context = gtk_accessible_get_at_context (accessible);
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
|
||||
|
||||
res = gtk_at_spi_root_to_ref (self->root);
|
||||
}
|
||||
else if (GTK_IS_STACK (parent))
|
||||
{
|
||||
GtkStackPage *page =
|
||||
gtk_stack_get_page (GTK_STACK (parent), widget);
|
||||
GtkATContext *parent_context =
|
||||
gtk_accessible_get_at_context (GTK_ACCESSIBLE (page));
|
||||
|
||||
if (parent_context != NULL)
|
||||
{
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkATContext *parent_context =
|
||||
gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
|
||||
|
||||
if (parent_context != NULL)
|
||||
{
|
||||
/* XXX: This realize() is needed otherwise opening a GtkPopover will
|
||||
* emit a warning when getting the context's reference
|
||||
*/
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
}
|
||||
}
|
||||
res = gtk_at_spi_root_to_ref (self->root);
|
||||
}
|
||||
else if (GTK_IS_STACK_PAGE (accessible))
|
||||
else
|
||||
{
|
||||
GtkWidget *parent =
|
||||
gtk_widget_get_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)));
|
||||
GtkATContext *parent_context =
|
||||
gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
|
||||
GtkATContext *parent_context = gtk_accessible_get_at_context (parent);
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
if (parent_context != NULL)
|
||||
{
|
||||
gtk_at_context_realize (parent_context);
|
||||
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
}
|
||||
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
|
||||
}
|
||||
|
||||
if (res == NULL)
|
||||
@@ -522,49 +497,30 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
{
|
||||
GtkATContext *context = NULL;
|
||||
GtkAccessible *accessible;
|
||||
int idx, real_idx = 0;
|
||||
int idx, presentable_idx;
|
||||
|
||||
g_variant_get (parameters, "(i)", &idx);
|
||||
|
||||
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
|
||||
if (GTK_IS_STACK_PAGE (accessible))
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkAccessible *child;
|
||||
|
||||
presentable_idx = 0;
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
if (presentable_idx == idx)
|
||||
break;
|
||||
presentable_idx++;
|
||||
|
||||
child = gtk_stack_page_get_child (GTK_STACK_PAGE (accessible));
|
||||
if (gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_WIDGET (accessible))
|
||||
if (child)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (accessible);
|
||||
GtkWidget *child;
|
||||
|
||||
real_idx = 0;
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
|
||||
continue;
|
||||
|
||||
if (real_idx == idx)
|
||||
break;
|
||||
|
||||
real_idx += 1;
|
||||
}
|
||||
|
||||
if (child)
|
||||
{
|
||||
if (GTK_IS_STACK (accessible))
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_stack_get_page (GTK_STACK (accessible), child)));
|
||||
else
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
}
|
||||
context = gtk_accessible_get_at_context (child);
|
||||
}
|
||||
|
||||
if (context == NULL)
|
||||
@@ -588,45 +544,24 @@ handle_accessible_method (GDBusConnection *connection,
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)"));
|
||||
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
if (GTK_IS_WIDGET (accessible))
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (accessible);
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
|
||||
continue;
|
||||
GtkAccessible *child;
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
GtkATContext *context = gtk_accessible_get_at_context (child);
|
||||
|
||||
/* Realize the child ATContext in order to get its ref */
|
||||
gtk_at_context_realize (context);
|
||||
/* Realize the child ATContext in order to get its ref */
|
||||
gtk_at_context_realize (context);
|
||||
|
||||
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
|
||||
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
|
||||
|
||||
if (ref != NULL)
|
||||
g_variant_builder_add (&builder, "@(so)", ref);
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_STACK_PAGE (accessible))
|
||||
{
|
||||
GtkWidget *child = gtk_stack_page_get_child (GTK_STACK_PAGE (accessible));
|
||||
|
||||
if (gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
|
||||
{
|
||||
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
|
||||
|
||||
/* Realize the child ATContext in order to get its ref */
|
||||
gtk_at_context_realize (context);
|
||||
|
||||
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
|
||||
|
||||
if (ref != NULL)
|
||||
g_variant_builder_add (&builder, "@(so)", ref);
|
||||
}
|
||||
if (ref != NULL)
|
||||
g_variant_builder_add (&builder, "@(so)", ref);
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
|
||||
@@ -915,7 +850,7 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
|
||||
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkAccessible *parent;
|
||||
GtkATContext *context;
|
||||
GtkAccessibleChildChange change;
|
||||
|
||||
@@ -932,14 +867,9 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GTK_IS_WIDGET (accessible))
|
||||
parent = gtk_widget_get_parent (GTK_WIDGET (accessible));
|
||||
else if (GTK_IS_STACK_PAGE (accessible))
|
||||
parent = gtk_widget_get_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)));
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
parent = gtk_accessible_get_accessible_parent (accessible);
|
||||
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent));
|
||||
context = gtk_accessible_get_at_context (parent);
|
||||
gtk_at_context_child_changed (context, change, accessible);
|
||||
}
|
||||
}
|
||||
@@ -1168,29 +1098,9 @@ gtk_at_spi_context_bounds_change (GtkATContext *ctx)
|
||||
{
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (ctx);
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (ctx);
|
||||
GtkWidget *widget;
|
||||
GtkWidget *parent;
|
||||
double x, y;
|
||||
int width, height;
|
||||
|
||||
if (!GTK_IS_WIDGET (accessible))
|
||||
return;
|
||||
|
||||
widget = GTK_WIDGET (accessible);
|
||||
if (!gtk_widget_get_realized (widget))
|
||||
return;
|
||||
|
||||
parent = gtk_widget_get_parent (widget);
|
||||
|
||||
if (parent)
|
||||
gtk_widget_translate_coordinates (widget, parent, 0., 0., &x, &y);
|
||||
else
|
||||
x = y = 0.;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
emit_bounds_changed (self, (int)x, (int)y, width, height);
|
||||
int x, y, width, height;
|
||||
if (gtk_accessible_get_bounds (accessible, &x, &y, &width, &height))
|
||||
emit_bounds_changed (self, x, y, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1201,99 +1111,17 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
|
||||
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (ctx);
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (ctx);
|
||||
GtkATContext *child_context = gtk_accessible_get_at_context (child);
|
||||
GtkWidget *parent_widget;
|
||||
GtkWidget *child_widget;
|
||||
int idx = 0;
|
||||
|
||||
if (!GTK_IS_WIDGET (accessible))
|
||||
return;
|
||||
|
||||
if (child_context == NULL)
|
||||
return;
|
||||
|
||||
/* handle the stack page special case */
|
||||
if (GTK_IS_WIDGET (child) &&
|
||||
GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (child))))
|
||||
{
|
||||
GtkWidget *stack;
|
||||
GtkStackPage *page;
|
||||
GListModel *pages;
|
||||
GtkAccessible *parent = gtk_accessible_get_accessible_parent (child);
|
||||
int idx = 0;
|
||||
|
||||
stack = gtk_widget_get_parent (GTK_WIDGET (child));
|
||||
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (child));
|
||||
pages = G_LIST_MODEL (gtk_stack_get_pages (GTK_STACK (stack)));
|
||||
idx = 0;
|
||||
for (guint i = 0; i < g_list_model_get_n_items (pages); i++)
|
||||
{
|
||||
GtkStackPage *item = g_list_model_get_item (pages, i);
|
||||
|
||||
g_object_unref (item);
|
||||
|
||||
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (item)))
|
||||
continue;
|
||||
|
||||
if (item == page)
|
||||
break;
|
||||
|
||||
idx++;
|
||||
}
|
||||
g_object_unref (pages);
|
||||
|
||||
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
|
||||
{
|
||||
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (stack))),
|
||||
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
|
||||
idx,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_ADDED);
|
||||
|
||||
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
|
||||
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (child)),
|
||||
0,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_ADDED);
|
||||
}
|
||||
|
||||
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED)
|
||||
{
|
||||
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
|
||||
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (child)),
|
||||
0,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
|
||||
emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (stack))),
|
||||
GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))),
|
||||
idx,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parent_widget = GTK_WIDGET (accessible);
|
||||
|
||||
if (GTK_IS_STACK_PAGE (child))
|
||||
child_widget = gtk_stack_page_get_child (GTK_STACK_PAGE (child));
|
||||
else
|
||||
child_widget = GTK_WIDGET (child);
|
||||
|
||||
if (gtk_widget_get_parent (child_widget) != parent_widget)
|
||||
{
|
||||
idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (GtkWidget *iter = gtk_widget_get_first_child (parent_widget);
|
||||
iter != NULL;
|
||||
iter = gtk_widget_get_next_sibling (iter))
|
||||
{
|
||||
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (iter)))
|
||||
continue;
|
||||
|
||||
if (iter == child_widget)
|
||||
break;
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
if (parent == NULL)
|
||||
idx = -1;
|
||||
else if (parent == accessible)
|
||||
idx = get_index_in (accessible, child);
|
||||
|
||||
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
|
||||
emit_children_changed (self,
|
||||
@@ -1858,12 +1686,8 @@ gtk_at_spi_context_get_index_in_parent (GtkAtSpiContext *self)
|
||||
|
||||
if (GTK_IS_ROOT (accessible))
|
||||
idx = get_index_in_toplevels (GTK_WIDGET (accessible));
|
||||
else if (GTK_IS_STACK_PAGE (accessible))
|
||||
idx = get_index_in_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)));
|
||||
else if (GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (accessible))))
|
||||
idx = 1;
|
||||
else
|
||||
idx = get_index_in_parent (GTK_WIDGET (accessible));
|
||||
idx = get_index_in_parent (accessible);
|
||||
|
||||
return idx;
|
||||
}
|
||||
@@ -1874,26 +1698,18 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
|
||||
g_return_val_if_fail (GTK_IS_AT_SPI_CONTEXT (self), -1);
|
||||
|
||||
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
|
||||
int n_children = -1;
|
||||
int n_children = 0;
|
||||
|
||||
if (GTK_IS_WIDGET (accessible))
|
||||
GtkAccessible *child = NULL;
|
||||
|
||||
for (child = gtk_accessible_get_first_accessible_child (accessible);
|
||||
child != NULL;
|
||||
child = gtk_accessible_get_next_accessible_sibling (child))
|
||||
{
|
||||
GtkWidget *child;
|
||||
if (!gtk_accessible_should_present (child))
|
||||
continue;
|
||||
|
||||
n_children = 0;
|
||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (accessible));
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child)))
|
||||
continue;
|
||||
|
||||
n_children++;
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_STACK_PAGE (accessible))
|
||||
{
|
||||
n_children = 1;
|
||||
n_children++;
|
||||
}
|
||||
|
||||
return n_children;
|
||||
|
||||
@@ -88,6 +88,8 @@
|
||||
#include "gtkstack.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
typedef struct _GtkAssistantPageClass GtkAssistantPageClass;
|
||||
|
||||
struct _GtkAssistantPage
|
||||
@@ -103,81 +103,81 @@ GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_assistant_page_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_assistant_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkWidget *gtk_assistant_new (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_next_page (GtkAssistant *assistant);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_previous_page (GtkAssistant *assistant);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
int gtk_assistant_get_current_page (GtkAssistant *assistant);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_set_current_page (GtkAssistant *assistant,
|
||||
int page_num);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
int gtk_assistant_get_n_pages (GtkAssistant *assistant);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkWidget *gtk_assistant_get_nth_page (GtkAssistant *assistant,
|
||||
int page_num);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
int gtk_assistant_prepend_page (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
int gtk_assistant_append_page (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
int gtk_assistant_insert_page (GtkAssistant *assistant,
|
||||
GtkWidget *page,
|
||||
int position);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_remove_page (GtkAssistant *assistant,
|
||||
int page_num);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_set_forward_page_func (GtkAssistant *assistant,
|
||||
GtkAssistantPageFunc page_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_set_page_type (GtkAssistant *assistant,
|
||||
GtkWidget *page,
|
||||
GtkAssistantPageType type);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkAssistantPageType gtk_assistant_get_page_type (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_set_page_title (GtkAssistant *assistant,
|
||||
GtkWidget *page,
|
||||
const char *title);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
const char * gtk_assistant_get_page_title (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_set_page_complete (GtkAssistant *assistant,
|
||||
GtkWidget *page,
|
||||
gboolean complete);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
gboolean gtk_assistant_get_page_complete (GtkAssistant *assistant,
|
||||
GtkWidget *page);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_add_action_widget (GtkAssistant *assistant,
|
||||
GtkWidget *child);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_remove_action_widget (GtkAssistant *assistant,
|
||||
GtkWidget *child);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_update_buttons_state (GtkAssistant *assistant);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_assistant_commit (GtkAssistant *assistant);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkAssistantPage * gtk_assistant_get_page (GtkAssistant *assistant,
|
||||
GtkWidget *child);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkWidget * gtk_assistant_page_get_child (GtkAssistantPage *page);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GListModel * gtk_assistant_get_pages (GtkAssistant *assistant);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkAssistant, g_object_unref)
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "gtkstack.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
/**
|
||||
* GtkLockButton:
|
||||
*
|
||||
@@ -32,11 +32,11 @@ typedef struct _GtkLockButton GtkLockButton;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_lock_button_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkWidget *gtk_lock_button_new (GPermission *permission);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GPermission *gtk_lock_button_get_permission (GtkLockButton *button);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_lock_button_set_permission (GtkLockButton *button,
|
||||
GPermission *permission);
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
|
||||
/**
|
||||
* GtkStatusbar:
|
||||
*
|
||||
@@ -42,23 +42,23 @@ typedef struct _GtkStatusbar GtkStatusbar;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_statusbar_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
GtkWidget* gtk_statusbar_new (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
guint gtk_statusbar_get_context_id (GtkStatusbar *statusbar,
|
||||
const char *context_description);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
guint gtk_statusbar_push (GtkStatusbar *statusbar,
|
||||
guint context_id,
|
||||
const char *text);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_statusbar_pop (GtkStatusbar *statusbar,
|
||||
guint context_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_statusbar_remove (GtkStatusbar *statusbar,
|
||||
guint context_id,
|
||||
guint message_id);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
void gtk_statusbar_remove_all (GtkStatusbar *statusbar,
|
||||
guint context_id);
|
||||
|
||||
@@ -3,6 +3,7 @@ gtk_deprecated_sources = [
|
||||
'deprecated/gtkappchooserbutton.c',
|
||||
'deprecated/gtkappchooserdialog.c',
|
||||
'deprecated/gtkappchooserwidget.c',
|
||||
'deprecated/gtkassistant.c',
|
||||
'deprecated/gtkcellarea.c',
|
||||
'deprecated/gtkcellareabox.c',
|
||||
'deprecated/gtkcellareacontext.c',
|
||||
@@ -31,8 +32,10 @@ gtk_deprecated_sources = [
|
||||
'deprecated/gtkiconview.c',
|
||||
'deprecated/gtkinfobar.c',
|
||||
'deprecated/gtkliststore.c',
|
||||
'deprecated/gtklockbutton.c',
|
||||
'deprecated/gtkrender.c',
|
||||
'deprecated/gtkshow.c',
|
||||
'deprecated/gtkstatusbar.c',
|
||||
'deprecated/gtkstylecontext.c',
|
||||
'deprecated/gtktreedatalist.c',
|
||||
'deprecated/gtktreednd.c',
|
||||
@@ -53,6 +56,7 @@ gtk_deprecated_headers = [
|
||||
'deprecated/gtkappchooserbutton.h',
|
||||
'deprecated/gtkappchooserdialog.h',
|
||||
'deprecated/gtkappchooserwidget.h',
|
||||
'deprecated/gtkassistant.h',
|
||||
'deprecated/gtkcellarea.h',
|
||||
'deprecated/gtkcellareabox.h',
|
||||
'deprecated/gtkcellareacontext.h',
|
||||
@@ -87,9 +91,11 @@ gtk_deprecated_headers = [
|
||||
'deprecated/gtkiconview.h',
|
||||
'deprecated/gtkinfobar.h',
|
||||
'deprecated/gtkliststore.h',
|
||||
'deprecated/gtklockbutton.h',
|
||||
'deprecated/gtkmessagedialog.h',
|
||||
'deprecated/gtkrender.h',
|
||||
'deprecated/gtkshow.h',
|
||||
'deprecated/gtkstatusbar.h',
|
||||
'deprecated/gtkstylecontext.h',
|
||||
'deprecated/gtktreednd.h',
|
||||
'deprecated/gtktreemodel.h',
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright 2017 Red Hat, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __G_OPEN_URI_PORTAL_H__
|
||||
|
||||
#include "gtkwindow.h"
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean g_openuri_portal_is_available (void);
|
||||
|
||||
void g_openuri_portal_open_async (GFile *file,
|
||||
gboolean open_folder,
|
||||
GtkWindow *window,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
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
|
||||
@@ -46,7 +46,7 @@
|
||||
#include <gtk/gtkapplication.h>
|
||||
#include <gtk/gtkapplicationwindow.h>
|
||||
#include <gtk/gtkaspectframe.h>
|
||||
#include <gtk/gtkassistant.h>
|
||||
#include <gtk/deprecated/gtkassistant.h>
|
||||
#include <gtk/gtkatcontext.h>
|
||||
#include <gtk/gtkbinlayout.h>
|
||||
#include <gtk/gtkbitset.h>
|
||||
@@ -177,7 +177,7 @@
|
||||
#include <gtk/gtklistitemfactory.h>
|
||||
#include <gtk/deprecated/gtkliststore.h>
|
||||
#include <gtk/gtklistview.h>
|
||||
#include <gtk/gtklockbutton.h>
|
||||
#include <gtk/deprecated/gtklockbutton.h>
|
||||
#include <gtk/gtkmain.h>
|
||||
#include <gtk/gtkmaplistmodel.h>
|
||||
#include <gtk/gtkmediacontrols.h>
|
||||
@@ -252,7 +252,7 @@
|
||||
#include <gtk/gtkspinner.h>
|
||||
#include <gtk/gtkstack.h>
|
||||
#include <gtk/gtkstackswitcher.h>
|
||||
#include <gtk/gtkstatusbar.h>
|
||||
#include <gtk/deprecated/gtkstatusbar.h>
|
||||
#include <gtk/gtkstringfilter.h>
|
||||
#include <gtk/gtkstringlist.h>
|
||||
#include <gtk/gtkstringsorter.h>
|
||||
|
||||
+114
-13
@@ -37,6 +37,14 @@
|
||||
* a way that should be reflected by assistive technologies. For instance,
|
||||
* if a `GtkWidget` visibility changes, the %GTK_ACCESSIBLE_STATE_HIDDEN
|
||||
* state will also change to reflect the [property@Gtk.Widget:visible] property.
|
||||
*
|
||||
* Every accessible implementation is part of a tree of accessible objects.
|
||||
* Normally, this tree corresponds to the widget tree, but can be customized
|
||||
* by reimplementing the [vfunc@Gtk.Accessible.get_accessible_parent],
|
||||
* [vfunc@Gtk.Accessible.get_first_accessible_child] and
|
||||
* [vfunc@Gtk.Accessible.get_next_accessible_sibling] virtual functions.
|
||||
* Note that you can not create a top-level accessible object as of now,
|
||||
* which means that you must always have a parent accessible object.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -74,7 +82,7 @@ gtk_accessible_default_init (GtkAccessibleInterface *iface)
|
||||
g_object_interface_install_property (iface, pspec);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
/**
|
||||
* gtk_accessible_get_at_context:
|
||||
* @self: a `GtkAccessible`
|
||||
*
|
||||
@@ -91,12 +99,68 @@ gtk_accessible_get_at_context (GtkAccessible *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_get_accessible_role: (attributes org.gtk.Method.get_property=accessible-role)
|
||||
* gtk_accessible_get_accessible_parent:
|
||||
* @self: a `GtkAccessible`
|
||||
*
|
||||
* Retrieves the `GtkAccessibleRole` for the given `GtkAccessible`.
|
||||
* Retrieves the accessible accessible for an accessible object
|
||||
*
|
||||
* Returns: a `GtkAccessibleRole`
|
||||
* This function returns `NULL` for top level widgets
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the accessible parent
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GtkAccessible *
|
||||
gtk_accessible_get_accessible_parent (GtkAccessible *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), NULL);
|
||||
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_accessible_parent (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_get_first_accessible_child:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the first accessible child of an accessible object.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the first accessible child
|
||||
*
|
||||
* since: 4.10
|
||||
*/
|
||||
GtkAccessible *
|
||||
gtk_accessible_get_first_accessible_child (GtkAccessible *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), NULL);
|
||||
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_first_accessible_child (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_get_next_accessible_sibling:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the next accessible sibling of an accessible object
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the next accessible sibling
|
||||
*
|
||||
* since: 4.10
|
||||
*/
|
||||
GtkAccessible *
|
||||
gtk_accessible_get_next_accessible_sibling (GtkAccessible *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), NULL);
|
||||
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_next_accessible_sibling (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_get_accessible_role:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the accessible role of an accessible object.
|
||||
*
|
||||
* Returns: the accessible role
|
||||
*/
|
||||
GtkAccessibleRole
|
||||
gtk_accessible_get_accessible_role (GtkAccessible *self)
|
||||
@@ -127,6 +191,7 @@ gtk_accessible_get_accessible_role (GtkAccessible *self)
|
||||
* state change must be communicated to assistive technologies.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```c
|
||||
* value = GTK_ACCESSIBLE_TRISTATE_MIXED;
|
||||
* gtk_accessible_update_state (GTK_ACCESSIBLE (check_button),
|
||||
@@ -659,10 +724,10 @@ gtk_accessible_role_to_name (GtkAccessibleRole role,
|
||||
/*< private >
|
||||
* gtk_accessible_role_is_range_subclass:
|
||||
* @role: a `GtkAccessibleRole`
|
||||
*
|
||||
*
|
||||
* Checks if @role is considered to be a subclass of %GTK_ACCESSIBLE_ROLE_RANGE
|
||||
* according to the WAI-ARIA specification.
|
||||
*
|
||||
*
|
||||
* Returns: whether the @role is range-like
|
||||
*/
|
||||
gboolean
|
||||
@@ -683,7 +748,7 @@ gtk_accessible_role_is_range_subclass (GtkAccessibleRole role)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*<private>
|
||||
/*< private >
|
||||
* gtk_accessible_platform_changed:
|
||||
* @self: a `GtkAccessible`
|
||||
* @change: the platform state change to report
|
||||
@@ -712,7 +777,7 @@ gtk_accessible_platform_changed (GtkAccessible *self,
|
||||
|
||||
/* propagate changes up from ignored widgets */
|
||||
if (gtk_accessible_get_accessible_role (self) == GTK_ACCESSIBLE_ROLE_NONE)
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_widget_get_parent (GTK_WIDGET (self))));
|
||||
context = gtk_accessible_get_at_context (gtk_accessible_get_accessible_parent (self));
|
||||
|
||||
if (context == NULL)
|
||||
return;
|
||||
@@ -721,7 +786,7 @@ gtk_accessible_platform_changed (GtkAccessible *self,
|
||||
gtk_at_context_update (context);
|
||||
}
|
||||
|
||||
/*<private>
|
||||
/**
|
||||
* gtk_accessible_get_platform_state:
|
||||
* @self: a `GtkAccessible`
|
||||
* @state: platform state to query
|
||||
@@ -735,15 +800,19 @@ gtk_accessible_platform_changed (GtkAccessible *self,
|
||||
* child widget, as is the case for `GtkText` wrappers.
|
||||
*
|
||||
* Returns: the value of @state for the accessible
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_accessible_get_platform_state (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), FALSE);
|
||||
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_platform_state (self, state);
|
||||
}
|
||||
|
||||
/*<private>
|
||||
/*< private >
|
||||
* gtk_accessible_bounds_changed:
|
||||
* @self: a `GtkAccessible`
|
||||
*
|
||||
@@ -752,7 +821,7 @@ gtk_accessible_get_platform_state (GtkAccessible *self,
|
||||
* changed.
|
||||
*
|
||||
* Note that the bounds are not included in this API.
|
||||
* AT backends should use widget API to obtain them.
|
||||
* AT backends should use [method@Gtk.Accessible.get_bounds] to get them.
|
||||
*/
|
||||
void
|
||||
gtk_accessible_bounds_changed (GtkAccessible *self)
|
||||
@@ -770,7 +839,39 @@ gtk_accessible_bounds_changed (GtkAccessible *self)
|
||||
gtk_at_context_bounds_changed (context);
|
||||
}
|
||||
|
||||
/*<private>
|
||||
/**
|
||||
* gtk_accessible_get_bounds:
|
||||
* @self: a `GtkAccessible`
|
||||
* @x: (out): the x coordinate of the top left corner of the accessible
|
||||
* @y: (out): the y coordinate of the top left corner of the widget
|
||||
* @width: (out): the width of the accessible object
|
||||
* @height: (out): the height of the accessible object
|
||||
*
|
||||
* Queries the coordinates and dimensions of this accessible
|
||||
*
|
||||
* This functionality can be overridden by `GtkAccessible`
|
||||
* implementations, e.g. to get the bounds from an ignored
|
||||
* child widget.
|
||||
*
|
||||
* Returns: true if the bounds are valid, and false otherwise
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_accessible_get_bounds (GtkAccessible *self,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), FALSE);
|
||||
g_return_val_if_fail (x != NULL && y != NULL, FALSE);
|
||||
g_return_val_if_fail (width != NULL && height != NULL, FALSE);
|
||||
|
||||
return GTK_ACCESSIBLE_GET_IFACE (self)->get_bounds (self, x, y, width, height);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_accessible_should_present:
|
||||
* @self: a `GtkAccessible`
|
||||
*
|
||||
@@ -829,7 +930,7 @@ gtk_accessible_update_children (GtkAccessible *self,
|
||||
|
||||
/* propagate changes up from ignored widgets */
|
||||
if (gtk_accessible_get_accessible_role (self) == GTK_ACCESSIBLE_ROLE_NONE)
|
||||
context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_widget_get_parent (GTK_WIDGET (self))));
|
||||
context = gtk_accessible_get_at_context (gtk_accessible_get_accessible_parent (self));
|
||||
|
||||
if (context == NULL)
|
||||
return;
|
||||
|
||||
+184
-43
@@ -32,58 +32,199 @@ G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ACCESSIBLE (gtk_accessible_get_type())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
G_DECLARE_INTERFACE (GtkAccessible, gtk_accessible, GTK, ACCESSIBLE, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self);
|
||||
/**
|
||||
* GtkAccessiblePlatformState:
|
||||
* @GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE: whether the accessible can be focused
|
||||
* @GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED: whether the accessible has focus
|
||||
* @GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE: whether the accessible is active
|
||||
*
|
||||
* The various platform states which can be queried
|
||||
* using [method@Gtk.Accessible.get_platform_state].
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
|
||||
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
|
||||
GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE
|
||||
} GtkAccessiblePlatformState;
|
||||
|
||||
/**
|
||||
* GtkAccessibleInterface:
|
||||
* @get_at_context: retrieve the platform-specific accessibility context
|
||||
* for the accessible implementation
|
||||
* @get_platform_state: retrieve the accessible state
|
||||
*
|
||||
* The common interface for accessible objects.
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
struct _GtkAccessibleInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/**
|
||||
* GtkAccessibleInterface::get_at_context:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the platform-specific accessibility context for the
|
||||
* accessible implementation.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the accessibility context
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GtkATContext * (* get_at_context) (GtkAccessible *self);
|
||||
|
||||
/**
|
||||
* GtkAccessibleInterface::get_platform_state:
|
||||
* @self: an accessible object
|
||||
* @state: the state to query
|
||||
*
|
||||
* Checks if the given @state applies to the accessible object.
|
||||
*
|
||||
* Returns: true if the @state is set, and false otherwise
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
gboolean (* get_platform_state) (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state);
|
||||
|
||||
/**
|
||||
* GtkAccessibleInterface::get_accessible_parent:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the accessible parent of an accessible object.
|
||||
*
|
||||
* This virtual function should return `NULL` for top level objects.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the accessible parent
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GtkAccessible * (* get_accessible_parent) (GtkAccessible *self);
|
||||
|
||||
/**
|
||||
* GtkaccessibleInterface::get_first_accessible_child:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the first accessible child of an accessible object.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): an accessible object
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GtkAccessible * (* get_first_accessible_child) (GtkAccessible *self);
|
||||
|
||||
/**
|
||||
* GtkaccessibleInterface::get_next_accessible_sibling:
|
||||
* @self: an accessible object
|
||||
*
|
||||
* Retrieves the next accessible sibling of an accessible object.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): an accessible object
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
GtkAccessible * (* get_next_accessible_sibling) (GtkAccessible *self);
|
||||
|
||||
/**
|
||||
* GtkAccessibleInterface::get_bounds:
|
||||
* @self: an accessible object
|
||||
* @x: (out): the horizontal coordinate of a rectangle
|
||||
* @y: (out): the vertical coordinate of a rectangle
|
||||
* @width: (out): the width of a rectangle
|
||||
* @height: (out): the height of a rectangle
|
||||
*
|
||||
* Retrieves the dimensions and position of an accessible object in its
|
||||
* parent's coordinate space, if those values can be determined.
|
||||
*
|
||||
* For top level accessible objects, the X and Y coordinates are always
|
||||
* going to be set to zero.
|
||||
*
|
||||
* Returns: true if the values are value, and false otherwise
|
||||
*/
|
||||
gboolean (* get_bounds) (GtkAccessible *self,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_state (GtkAccessible *self,
|
||||
GtkAccessibleState first_state,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_property (GtkAccessible *self,
|
||||
GtkAccessibleProperty first_property,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_relation (GtkAccessible *self,
|
||||
GtkAccessibleRelation first_relation,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_state_value (GtkAccessible *self,
|
||||
int n_states,
|
||||
GtkAccessibleState states[],
|
||||
const GValue values[]);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_property_value (GtkAccessible *self,
|
||||
int n_properties,
|
||||
GtkAccessibleProperty properties[],
|
||||
const GValue values[]);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_relation_value (GtkAccessible *self,
|
||||
int n_relations,
|
||||
GtkAccessibleRelation relations[],
|
||||
const GValue values[]);
|
||||
GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
gboolean gtk_accessible_get_platform_state (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GtkAccessible * gtk_accessible_get_accessible_parent (GtkAccessible *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GtkAccessible * gtk_accessible_get_first_accessible_child (GtkAccessible *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GtkAccessible * gtk_accessible_get_next_accessible_sibling (GtkAccessible *self);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
gboolean gtk_accessible_get_bounds (GtkAccessible *self,
|
||||
int *x,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_reset_state (GtkAccessible *self,
|
||||
GtkAccessibleState state);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_reset_property (GtkAccessible *self,
|
||||
GtkAccessibleProperty property);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_reset_relation (GtkAccessible *self,
|
||||
GtkAccessibleRelation relation);
|
||||
GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_state_init_value (GtkAccessibleState state,
|
||||
GValue *value);
|
||||
void gtk_accessible_update_state (GtkAccessible *self,
|
||||
GtkAccessibleState first_state,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_property_init_value (GtkAccessibleProperty property,
|
||||
GValue *value);
|
||||
void gtk_accessible_update_property (GtkAccessible *self,
|
||||
GtkAccessibleProperty first_property,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_relation_init_value (GtkAccessibleRelation relation,
|
||||
GValue *value);
|
||||
void gtk_accessible_update_relation (GtkAccessible *self,
|
||||
GtkAccessibleRelation first_relation,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_state_value (GtkAccessible *self,
|
||||
int n_states,
|
||||
GtkAccessibleState states[],
|
||||
const GValue values[]);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_property_value (GtkAccessible *self,
|
||||
int n_properties,
|
||||
GtkAccessibleProperty properties[],
|
||||
const GValue values[]);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_update_relation_value (GtkAccessible *self,
|
||||
int n_relations,
|
||||
GtkAccessibleRelation relations[],
|
||||
const GValue values[]);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_reset_state (GtkAccessible *self,
|
||||
GtkAccessibleState state);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_reset_property (GtkAccessible *self,
|
||||
GtkAccessibleProperty property);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_reset_relation (GtkAccessible *self,
|
||||
GtkAccessibleRelation relation);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_state_init_value (GtkAccessibleState state,
|
||||
GValue *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_property_init_value (GtkAccessibleProperty property,
|
||||
GValue *value);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_accessible_relation_init_value (GtkAccessibleRelation relation,
|
||||
GValue *value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+30
-17
@@ -21,21 +21,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "gtkaccessible.h"
|
||||
#include "gtkatcontextprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GtkAccessibleInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
/* < private >
|
||||
* GtkAccessiblePlatformChange:
|
||||
* @GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE: whether the accessible has changed
|
||||
* its focusable state
|
||||
* @GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED: whether the accessible has changed its
|
||||
* focused state
|
||||
* @GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE: whether the accessible has changed its
|
||||
* active state
|
||||
*
|
||||
* Represents the various platform changes which can occur and are communicated
|
||||
* using [method@Gtk.Accessible.platform_changed].
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
|
||||
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
|
||||
GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE,
|
||||
} GtkAccessiblePlatformChange;
|
||||
|
||||
GtkATContext * (* get_at_context) (GtkAccessible *self);
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_CHILD_STATE_ADDED,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_REMOVED
|
||||
} GtkAccessibleChildState;
|
||||
|
||||
gboolean (* get_platform_state) (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state);
|
||||
};
|
||||
|
||||
GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self);
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_CHILD_CHANGE_ADDED = 1 << GTK_ACCESSIBLE_CHILD_STATE_ADDED,
|
||||
GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED = 1 << GTK_ACCESSIBLE_CHILD_STATE_REMOVED
|
||||
} GtkAccessibleChildChange;
|
||||
|
||||
const char * gtk_accessible_role_to_name (GtkAccessibleRole role,
|
||||
const char *domain);
|
||||
@@ -44,15 +59,13 @@ gboolean gtk_accessible_role_is_range_subclass (GtkAccessibleRole role);
|
||||
|
||||
gboolean gtk_accessible_should_present (GtkAccessible *self);
|
||||
|
||||
void gtk_accessible_platform_changed (GtkAccessible *self,
|
||||
GtkAccessiblePlatformChange change);
|
||||
gboolean gtk_accessible_get_platform_state (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state);
|
||||
|
||||
void gtk_accessible_bounds_changed (GtkAccessible *self);
|
||||
|
||||
void gtk_accessible_update_children (GtkAccessible *self,
|
||||
GtkAccessible *child,
|
||||
GtkAccessibleChildState state);
|
||||
|
||||
void gtk_accessible_bounds_changed (GtkAccessible *self);
|
||||
|
||||
void gtk_accessible_platform_changed (GtkAccessible *self,
|
||||
GtkAccessiblePlatformChange change);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -104,9 +104,13 @@ gtk_application_impl_wayland_before_emit (GtkApplicationImpl *impl,
|
||||
{
|
||||
const char *startup_notification_id = NULL;
|
||||
|
||||
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
|
||||
g_variant_lookup (platform_data, "activation-token", "&s", &startup_notification_id);
|
||||
if (!startup_notification_id)
|
||||
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gdk_wayland_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
static guint
|
||||
|
||||
@@ -87,7 +87,9 @@ gtk_application_impl_x11_before_emit (GtkApplicationImpl *impl,
|
||||
|
||||
g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_notification_id);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gdk_x11_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -321,10 +321,16 @@ gtk_application_add_platform_data (GApplication *application,
|
||||
{
|
||||
const char *startup_id;
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
startup_id = gdk_display_get_startup_notification_id (display);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
if (startup_id && g_utf8_validate (startup_id, -1, NULL))
|
||||
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
|
||||
g_variant_new_string (startup_id));
|
||||
{
|
||||
g_variant_builder_add (builder, "{sv}", "activation-token",
|
||||
g_variant_new_string (startup_id));
|
||||
g_variant_builder_add (builder, "{sv}", "desktop-startup-id",
|
||||
g_variant_new_string (startup_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "gtkatcontext.h"
|
||||
|
||||
#include "gtkaccessibleprivate.h"
|
||||
#include "gtkaccessibleattributesetprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -80,28 +81,6 @@ typedef enum {
|
||||
GTK_ACCESSIBLE_STATE_CHANGE_SELECTED = 1 << GTK_ACCESSIBLE_STATE_SELECTED
|
||||
} GtkAccessibleStateChange;
|
||||
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
|
||||
GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
|
||||
GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE
|
||||
} GtkAccessiblePlatformState;
|
||||
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSABLE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE,
|
||||
GTK_ACCESSIBLE_PLATFORM_CHANGE_FOCUSED = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED,
|
||||
GTK_ACCESSIBLE_PLATFORM_CHANGE_ACTIVE = 1 << GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE,
|
||||
} GtkAccessiblePlatformChange;
|
||||
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_CHILD_STATE_ADDED,
|
||||
GTK_ACCESSIBLE_CHILD_STATE_REMOVED
|
||||
} GtkAccessibleChildState;
|
||||
|
||||
typedef enum {
|
||||
GTK_ACCESSIBLE_CHILD_CHANGE_ADDED = 1 << GTK_ACCESSIBLE_CHILD_STATE_ADDED,
|
||||
GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED = 1 << GTK_ACCESSIBLE_CHILD_STATE_REMOVED
|
||||
} GtkAccessibleChildChange;
|
||||
|
||||
struct _GtkATContext
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
@@ -1086,10 +1086,8 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
|
||||
/**
|
||||
* gtk_css_provider_load_from_data:
|
||||
* @css_provider: a `GtkCssProvider`
|
||||
* @data: (array length=length) (element-type guint8): CSS data loaded in memory
|
||||
* @length: the length of @data in bytes, or -1 for NUL terminated strings. If
|
||||
* @length is not -1, the code will assume it is not NUL terminated and will
|
||||
* potentially do a copy.
|
||||
* @data: CSS data to be parsed
|
||||
* @length: the length of @data in bytes, or -1 for NUL terminated strings
|
||||
*
|
||||
* Loads @data into @css_provider.
|
||||
*
|
||||
|
||||
@@ -555,6 +555,9 @@ gtk_drag_icon_create_widget_for_value (const GValue *value)
|
||||
GtkWidget *image;
|
||||
|
||||
info = g_file_query_info (G_FILE (g_value_get_object (value)), "standard::icon", 0, NULL, NULL);
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
image = gtk_image_new_from_gicon (g_file_info_get_icon (info));
|
||||
gtk_widget_add_css_class (image, "large-icons");
|
||||
g_object_unref (info);
|
||||
|
||||
+1
-1
@@ -569,7 +569,7 @@ gtk_drag_source_drag_begin (GtkDragSource *source)
|
||||
GtkNative *native;
|
||||
GdkSurface *surface;
|
||||
double px, py;
|
||||
int dx, dy;
|
||||
double dx, dy;
|
||||
GdkContentProvider *content = NULL;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
+53
-2
@@ -19,7 +19,7 @@
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GTK+ Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -485,7 +485,7 @@ gtk_editable_insert_text (GtkEditable *editable,
|
||||
|
||||
if (length < 0)
|
||||
length = strlen (text);
|
||||
|
||||
|
||||
GTK_EDITABLE_GET_IFACE (editable)->do_insert_text (editable, text, length, position);
|
||||
}
|
||||
|
||||
@@ -1181,3 +1181,54 @@ gtk_editable_delegate_get_property (GObject *object,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_editable_delegate_get_accessible_platform_state:
|
||||
* @editable: a `GtkEditable` implementation
|
||||
* @state: what kind of accessible state to retrieve
|
||||
*
|
||||
* Retrieves the accessible platform state from the editable delegate.
|
||||
*
|
||||
* This is an helper function to retrieve the accessible state for
|
||||
* `GtkEditable` interface implementations using a delegate pattern.
|
||||
*
|
||||
* You should call this function in your editable widget implementation
|
||||
* of the [vfunc@Gtk.Accessible.get_platform_state] virtual function, for
|
||||
* instance:
|
||||
*
|
||||
* ```c
|
||||
* static void
|
||||
* accessible_interface_init (GtkAccessibleInterface *iface)
|
||||
* {
|
||||
* iface->get_platform_state = your_editable_get_accessible_platform_state;
|
||||
* }
|
||||
*
|
||||
* static gboolean
|
||||
* your_editable_get_accessible_platform_state (GtkAccessible *accessible,
|
||||
* GtkAccessiblePlatformState state)
|
||||
* {
|
||||
* return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (accessible), state);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Since: 4.10
|
||||
*/
|
||||
gboolean
|
||||
gtk_editable_delegate_get_accessible_platform_state (GtkEditable *editable,
|
||||
GtkAccessiblePlatformState state)
|
||||
{
|
||||
GtkWidget *delegate = GTK_WIDGET (gtk_editable_get_delegate (editable));
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
|
||||
return gtk_widget_get_focusable (delegate);
|
||||
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
|
||||
return gtk_widget_has_focus (delegate);
|
||||
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
|
||||
return FALSE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -30,9 +30,9 @@
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkaccessible.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_EDITABLE (gtk_editable_get_type ())
|
||||
@@ -194,6 +194,9 @@ gboolean gtk_editable_delegate_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
gboolean gtk_editable_delegate_get_accessible_platform_state (GtkEditable *editable,
|
||||
GtkAccessiblePlatformState state);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEditable, g_object_unref)
|
||||
|
||||
|
||||
+1
-14
@@ -339,20 +339,7 @@ static gboolean
|
||||
gtk_entry_accessible_get_platform_state (GtkAccessible *self,
|
||||
GtkAccessiblePlatformState state)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (self);
|
||||
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
|
||||
return gtk_widget_get_focusable (GTK_WIDGET (priv->text));
|
||||
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
|
||||
return gtk_widget_has_focus (GTK_WIDGET (priv->text));
|
||||
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
|
||||
return FALSE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -207,7 +207,7 @@ send_close (FilechooserPortalData *data)
|
||||
|
||||
message = g_dbus_message_new_method_call (PORTAL_BUS_NAME,
|
||||
PORTAL_OBJECT_PATH,
|
||||
PORTAL_FILECHOOSER_INTERFACE,
|
||||
PORTAL_REQUEST_INTERFACE,
|
||||
"Close");
|
||||
g_dbus_message_set_body (message,
|
||||
g_variant_new ("(o)", data->portal_handle));
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
#include "gtkexpression.h"
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
#include "gopenuriportal.h"
|
||||
#include "gtkopenuriportal.h"
|
||||
#endif
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
@@ -1566,6 +1566,9 @@ file_list_drag_drop_cb (GtkDropTarget *dest,
|
||||
|
||||
files = g_value_get_boxed (value);
|
||||
|
||||
if (files == NULL)
|
||||
return TRUE;
|
||||
|
||||
data = g_new0 (FileListDragData, 1);
|
||||
data->impl = g_object_ref (impl);
|
||||
data->files = g_slist_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
|
||||
@@ -7219,16 +7222,21 @@ popup_menu (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
file_chooser_widget_clicked (GtkEventController *controller,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data)
|
||||
file_chooser_widget_clicked (GtkEventController *controller,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkWidget *widget = user_data;
|
||||
GtkWidget *widget = GTK_WIDGET (impl);
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_gesture_set_state (GTK_GESTURE (controller), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
popup_menu (widget, x, y);
|
||||
child = gtk_widget_pick (widget, x, y, 0);
|
||||
if (gtk_widget_is_ancestor (child, impl->browse_files_stack))
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (controller), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
popup_menu (widget, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+3
-3
@@ -694,7 +694,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
|
||||
GFile *folder;
|
||||
GFileInfo *info;
|
||||
|
||||
if (g_file_equal (self->initial_file, file))
|
||||
if (self->initial_file && g_file_equal (self->initial_file, file))
|
||||
return;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_FILE]);
|
||||
@@ -707,7 +707,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_FOLDER]);
|
||||
|
||||
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, 0, NULL, NULL);
|
||||
if (g_file_info_get_edit_name (info) != NULL)
|
||||
if (info && g_file_info_get_edit_name (info) != NULL)
|
||||
{
|
||||
if (g_set_str (&self->initial_name, g_file_info_get_edit_name (info)))
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INITIAL_NAME]);
|
||||
@@ -724,7 +724,7 @@ gtk_file_dialog_set_initial_file (GtkFileDialog *self,
|
||||
g_free (name);
|
||||
g_free (relative);
|
||||
}
|
||||
g_object_unref (info);
|
||||
g_clear_object (&info);
|
||||
g_object_unref (folder);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "gtkfilelauncher.h"
|
||||
|
||||
#include "gtkdialogerror.h"
|
||||
#include "gopenuriportal.h"
|
||||
#include "gtkopenuriportal.h"
|
||||
#include "deprecated/gtkshow.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
@@ -219,7 +219,7 @@ open_done (GObject *source,
|
||||
GTask *task = G_TASK (data);
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_openuri_portal_open_finish (result, &error))
|
||||
if (!gtk_openuri_portal_open_finish (result, &error))
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_boolean (task, TRUE);
|
||||
@@ -367,9 +367,9 @@ gtk_file_launcher_launch (GtkFileLauncher *self,
|
||||
}
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
if (g_openuri_portal_is_available ())
|
||||
if (gtk_openuri_portal_is_available ())
|
||||
{
|
||||
g_openuri_portal_open_async (self->file, FALSE, parent, cancellable, open_done, task);
|
||||
gtk_openuri_portal_open_async (self->file, FALSE, parent, cancellable, open_done, task);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -461,9 +461,9 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self,
|
||||
}
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
if (g_openuri_portal_is_available ())
|
||||
if (gtk_openuri_portal_is_available ())
|
||||
{
|
||||
g_openuri_portal_open_async (self->file, TRUE, parent, cancellable, open_done, task);
|
||||
gtk_openuri_portal_open_async (self->file, TRUE, parent, cancellable, open_done, task);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
+48
-4
@@ -69,7 +69,7 @@
|
||||
*
|
||||
* Within a widget, gestures can be grouped through [method@Gtk.Gesture.group].
|
||||
* Grouped gestures synchronize the state of sequences, so calling
|
||||
* [method@Gtk.Gesture.set_sequence_state] on one will effectively propagate
|
||||
* [method@Gtk.Gesture.set_state] on one will effectively propagate
|
||||
* the state throughout the group.
|
||||
*
|
||||
* By default, all sequences start out in the %GTK_EVENT_SEQUENCE_NONE state,
|
||||
@@ -99,7 +99,7 @@
|
||||
* again.
|
||||
*
|
||||
* Sequence states can't be changed freely.
|
||||
* See [method@Gtk.Gesture.set_sequence_state] to know about the possible
|
||||
* See [method@Gtk.Gesture.set_state] to know about the possible
|
||||
* lifetimes of a `GdkEventSequence`.
|
||||
*
|
||||
* ## Touchpad gestures
|
||||
@@ -519,7 +519,9 @@ _gtk_gesture_update_point (GtkGesture *gesture,
|
||||
else
|
||||
state = gtk_gesture_get_group_state (gesture, sequence);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
gtk_gesture_set_sequence_state (gesture, sequence, state);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -1017,6 +1019,8 @@ gtk_gesture_get_sequence_state (GtkGesture *gesture,
|
||||
*
|
||||
* Returns: %TRUE if @sequence is handled by @gesture,
|
||||
* and the state is changed successfully
|
||||
*
|
||||
* Deprecated: 4.10. Use [method@Gtk.Gesture.set_state]
|
||||
*/
|
||||
gboolean
|
||||
gtk_gesture_set_sequence_state (GtkGesture *gesture,
|
||||
@@ -1069,8 +1073,46 @@ gtk_gesture_set_sequence_state (GtkGesture *gesture,
|
||||
* Sets the state of all sequences that @gesture is currently
|
||||
* interacting with.
|
||||
*
|
||||
* See [method@Gtk.Gesture.set_sequence_state] for more details
|
||||
* on sequence states.
|
||||
* Sequences start in state %GTK_EVENT_SEQUENCE_NONE, and whenever
|
||||
* they change state, they can never go back to that state. Likewise,
|
||||
* sequences in state %GTK_EVENT_SEQUENCE_DENIED cannot turn back to
|
||||
* a not denied state. With these rules, the lifetime of an event
|
||||
* sequence is constrained to the next four:
|
||||
*
|
||||
* * None
|
||||
* * None → Denied
|
||||
* * None → Claimed
|
||||
* * None → Claimed → Denied
|
||||
*
|
||||
* Note: Due to event handling ordering, it may be unsafe to set the
|
||||
* state on another gesture within a [signal@Gtk.Gesture::begin] signal
|
||||
* handler, as the callback might be executed before the other gesture
|
||||
* knows about the sequence. A safe way to perform this could be:
|
||||
*
|
||||
* ```c
|
||||
* static void
|
||||
* first_gesture_begin_cb (GtkGesture *first_gesture,
|
||||
* GdkEventSequence *sequence,
|
||||
* gpointer user_data)
|
||||
* {
|
||||
* gtk_gesture_set_state (first_gesture, GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
* gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
|
||||
* }
|
||||
*
|
||||
* static void
|
||||
* second_gesture_begin_cb (GtkGesture *second_gesture,
|
||||
* GdkEventSequence *sequence,
|
||||
* gpointer user_data)
|
||||
* {
|
||||
* if (gtk_gesture_get_sequence_state (first_gesture, sequence) == GTK_EVENT_SEQUENCE_CLAIMED)
|
||||
* gtk_gesture_set_state (second_gesture, GTK_EVENT_SEQUENCE_DENIED);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If both gestures are in the same group, just set the state on
|
||||
* the gesture emitting the event, the sequence will be already
|
||||
* be initialized to the group's global state when the second
|
||||
* gesture processes the event.
|
||||
*
|
||||
* Returns: %TRUE if the state of at least one sequence
|
||||
* was changed successfully
|
||||
@@ -1090,8 +1132,10 @@ gtk_gesture_set_state (GtkGesture *gesture,
|
||||
priv = gtk_gesture_get_instance_private (gesture);
|
||||
sequences = g_hash_table_get_keys (priv->points);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
for (l = sequences; l; l = l->next)
|
||||
handled |= gtk_gesture_set_sequence_state (gesture, l->data, state);
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
g_list_free (sequences);
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkEventSequenceState
|
||||
gtk_gesture_get_sequence_state (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GDK_DEPRECATED_IN_4_10
|
||||
gboolean gtk_gesture_set_sequence_state (GtkGesture *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
GtkEventSequenceState state);
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gdk/gdkprofilerprivate.h"
|
||||
#include "gtksymbolicpaintable.h"
|
||||
|
||||
struct _GtkIconHelper
|
||||
{
|
||||
@@ -123,7 +124,7 @@ gtk_icon_helper_load_paintable (GtkIconHelper *self,
|
||||
{
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
paintable = g_object_ref (gtk_image_definition_get_paintable (self->def));
|
||||
symbolic = FALSE;
|
||||
symbolic = GTK_IS_SYMBOLIC_PAINTABLE (paintable);
|
||||
break;
|
||||
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
|
||||
+1
-1
@@ -3046,7 +3046,7 @@ theme_lookup_icon (IconTheme *theme,
|
||||
IconThemeDirSize *min_dir_size;
|
||||
IconThemeFile *min_file;
|
||||
int min_difference;
|
||||
IconCacheFlag min_suffix;
|
||||
IconCacheFlag min_suffix = ICON_CACHE_FLAG_PNG_SUFFIX;
|
||||
int i;
|
||||
|
||||
min_difference = G_MAXINT;
|
||||
|
||||
@@ -1441,13 +1441,10 @@ gesture_pressed (GtkGestureClick *gesture,
|
||||
double y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkEventSequence *sequence;
|
||||
|
||||
if (gtk_widget_get_focus_on_click (widget) && !gtk_widget_has_focus (widget))
|
||||
gtk_widget_grab_focus (widget);
|
||||
|
||||
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
gtk_gesture_set_sequence_state (GTK_GESTURE (gesture), sequence, GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "gopenuriportal.h"
|
||||
#include "gtkopenuriportal.h"
|
||||
#include "xdp-dbus.h"
|
||||
#include "gtkwindowprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
@@ -43,7 +43,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
static GXdpOpenURI *openuri;
|
||||
static GtkXdpOpenURI *openuri;
|
||||
|
||||
static gboolean
|
||||
init_openuri_portal (void)
|
||||
@@ -57,10 +57,10 @@ init_openuri_portal (void)
|
||||
|
||||
if (connection != NULL)
|
||||
{
|
||||
openuri = gxdp_open_uri_proxy_new_sync (connection, 0,
|
||||
PORTAL_BUS_NAME,
|
||||
PORTAL_OBJECT_PATH,
|
||||
NULL, &error);
|
||||
openuri = gtk_xdp_open_uri_proxy_new_sync (connection, 0,
|
||||
PORTAL_BUS_NAME,
|
||||
PORTAL_OBJECT_PATH,
|
||||
NULL, &error);
|
||||
if (openuri == NULL)
|
||||
{
|
||||
g_warning ("Cannot create OpenURI portal proxy: %s", error->message);
|
||||
@@ -83,7 +83,7 @@ init_openuri_portal (void)
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_openuri_portal_is_available (void)
|
||||
gtk_openuri_portal_is_available (void)
|
||||
{
|
||||
return init_openuri_portal ();
|
||||
}
|
||||
@@ -169,7 +169,7 @@ open_call_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GXdpOpenURI *portal = GXDP_OPEN_URI (source);
|
||||
GtkXdpOpenURI *portal = GTK_XDP_OPEN_URI (source);
|
||||
GTask *task = user_data;
|
||||
OpenUriData *data = g_task_get_task_data (task);
|
||||
GError *error = NULL;
|
||||
@@ -179,13 +179,13 @@ open_call_done (GObject *source,
|
||||
switch (data->call)
|
||||
{
|
||||
case OPEN_FILE:
|
||||
res = gxdp_open_uri_call_open_file_finish (portal, &path, NULL, result, &error);
|
||||
res = gtk_xdp_open_uri_call_open_file_finish (portal, &path, NULL, result, &error);
|
||||
break;
|
||||
case OPEN_FOLDER:
|
||||
res = gxdp_open_uri_call_open_directory_finish (portal, &path, NULL, result, &error);
|
||||
res = gtk_xdp_open_uri_call_open_directory_finish (portal, &path, NULL, result, &error);
|
||||
break;
|
||||
case OPEN_URI:
|
||||
res = gxdp_open_uri_call_open_uri_finish (portal, &path, result, &error);
|
||||
res = gtk_xdp_open_uri_call_open_uri_finish (portal, &path, result, &error);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -341,7 +341,7 @@ open_uri (OpenUriData *data,
|
||||
if (open_folder)
|
||||
{
|
||||
data->call = OPEN_FOLDER;
|
||||
gxdp_open_uri_call_open_directory (openuri,
|
||||
gtk_xdp_open_uri_call_open_directory (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
g_variant_new ("h", fd_id),
|
||||
opts,
|
||||
@@ -353,7 +353,7 @@ open_uri (OpenUriData *data,
|
||||
else
|
||||
{
|
||||
data->call = OPEN_FILE;
|
||||
gxdp_open_uri_call_open_file (openuri,
|
||||
gtk_xdp_open_uri_call_open_file (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
g_variant_new ("h", fd_id),
|
||||
opts,
|
||||
@@ -373,7 +373,7 @@ open_uri (OpenUriData *data,
|
||||
uri = g_file_get_uri (file);
|
||||
|
||||
data->call = OPEN_URI;
|
||||
gxdp_open_uri_call_open_uri (openuri,
|
||||
gtk_xdp_open_uri_call_open_uri (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
uri ? uri : data->uri,
|
||||
opts,
|
||||
@@ -441,12 +441,12 @@ window_handle_exported (GtkWindow *window,
|
||||
}
|
||||
|
||||
void
|
||||
g_openuri_portal_open_async (GFile *file,
|
||||
gboolean open_folder,
|
||||
GtkWindow *parent,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
gtk_openuri_portal_open_async (GFile *file,
|
||||
gboolean open_folder,
|
||||
GtkWindow *parent,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
OpenUriData *data;
|
||||
|
||||
@@ -465,27 +465,27 @@ g_openuri_portal_open_async (GFile *file,
|
||||
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_async);
|
||||
g_task_set_source_tag (data->task, gtk_openuri_portal_open_async);
|
||||
|
||||
if (!parent || !gtk_window_export_handle (parent, window_handle_exported, data))
|
||||
window_handle_exported (parent, NULL, data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_openuri_portal_open_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
gtk_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);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_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)
|
||||
gtk_openuri_portal_open_uri_async (const char *uri,
|
||||
GtkWindow *parent,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
OpenUriData *data;
|
||||
|
||||
@@ -503,17 +503,17 @@ g_openuri_portal_open_uri_async (const char *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);
|
||||
g_task_set_source_tag (data->task, gtk_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)
|
||||
gtk_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);
|
||||
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gtk_openuri_portal_open_uri_async, FALSE);
|
||||
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user