diff --git a/configure.ac b/configure.ac index 62c17b2b8472ee8552405e26f4b1a13307619009..a26b03d3c3e1ece50fa171cfc4af316315da2edd 100644 --- a/configure.ac +++ b/configure.ac @@ -61,7 +61,7 @@ m4_define([cairo_required_version], [1.14.0]) m4_define([gdk_pixbuf_required_version], [2.30.0]) m4_define([introspection_required_version], [1.39.0]) m4_define([wayland_required_version], [1.14.91]) -m4_define([wayland_protocols_required_version], [1.14]) +m4_define([wayland_protocols_required_version], [1.17]) m4_define([epoxy_required_version], [1.4]) m4_define([cloudproviders_required_version], [0.2.5]) m4_define([sysprof_required_version], [3.33.2]) diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am index 31f12251b30b175e353888c6ce4fb315fa34ce13..6595013d3f00314c42d4a530ecfeba39d1c5d477 100644 --- a/gdk/wayland/Makefile.am +++ b/gdk/wayland/Makefile.am @@ -40,7 +40,9 @@ BUILT_SOURCES = \ server-decoration-client-protocol.h \ server-decoration-protocol.c \ gtk-shell-client-protocol.h \ - gtk-shell-protocol.c + gtk-shell-protocol.c \ + primary-selection-unstable-v1-client-protocol.h \ + primary-selection-unstable-v1-protocol.c nodist_libgdk_wayland_la_SOURCES = \ $(BUILT_SOURCES) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 7d81eaff3b40e3775e1c21637773145f56acb7bc..c5b273eb908d727751dafc22d710f10a20d16a79 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -237,7 +237,8 @@ struct _GdkWaylandSeat uint32_t keyboard_time; uint32_t keyboard_key_serial; - struct gtk_primary_selection_device *primary_data_device; + struct gtk_primary_selection_device *gtk_primary_data_device; + struct zwp_primary_selection_device_v1 *zwp_primary_data_device_v1; struct wl_data_device *data_device; GdkDragContext *drop_context; @@ -1308,23 +1309,43 @@ static const struct wl_data_device_listener data_device_listener = { }; static void -primary_selection_data_offer (void *data, - struct gtk_primary_selection_device *gtk_primary_selection_device, - struct gtk_primary_selection_offer *gtk_primary_offer) +primary_selection_data_offer (void *data, + gpointer primary_selection_device, + gpointer primary_offer) { GdkWaylandSeat *seat = data; GDK_NOTE (EVENTS, g_message ("primary selection offer, device %p, data offer %p", - gtk_primary_selection_device, gtk_primary_offer)); + primary_selection_device, primary_offer)); - gdk_wayland_selection_ensure_primary_offer (seat->display, gtk_primary_offer); + gdk_wayland_selection_ensure_primary_offer (seat->display, primary_offer); } static void -primary_selection_selection (void *data, - struct gtk_primary_selection_device *gtk_primary_selection_device, - struct gtk_primary_selection_offer *gtk_primary_offer) +gtk_primary_selection_data_offer (void *data, + struct gtk_primary_selection_device *primary_selection_device, + struct gtk_primary_selection_offer *primary_offer) +{ + primary_selection_data_offer (data, + (gpointer) primary_selection_device, + (gpointer) primary_offer); +} + +static void +zwp_primary_selection_v1_data_offer (void *data, + struct zwp_primary_selection_device_v1 *primary_selection_device, + struct zwp_primary_selection_offer_v1 *primary_offer) +{ + primary_selection_data_offer (data, + (gpointer) primary_selection_device, + (gpointer) primary_offer); +} + +static void +primary_selection_selection (void *data, + gpointer primary_selection_device, + gpointer primary_offer) { GdkWaylandSeat *seat = data; GdkAtom selection; @@ -1334,16 +1355,41 @@ primary_selection_selection (void *data, GDK_NOTE (EVENTS, g_message ("primary selection selection, device %p, data offer %p", - gtk_primary_selection_device, gtk_primary_offer)); + primary_selection_device, primary_offer)); selection = gdk_atom_intern_static_string ("PRIMARY"); - gdk_wayland_selection_set_offer (seat->display, selection, gtk_primary_offer); + gdk_wayland_selection_set_offer (seat->display, selection, primary_offer); emit_selection_owner_change (seat->keyboard_focus, selection); } -static const struct gtk_primary_selection_device_listener primary_selection_device_listener = { - primary_selection_data_offer, - primary_selection_selection, +static void +gtk_primary_selection_selection (void *data, + struct gtk_primary_selection_device *primary_selection_device, + struct gtk_primary_selection_offer *primary_offer) +{ + primary_selection_selection (data, + (gpointer) primary_selection_device, + (gpointer) primary_offer); +} + +static void +zwp_primary_selection_v1_selection (void *data, + struct zwp_primary_selection_device_v1 *primary_selection_device, + struct zwp_primary_selection_offer_v1 *primary_offer) +{ + primary_selection_selection (data, + (gpointer) primary_selection_device, + (gpointer) primary_offer); +} + +static const struct gtk_primary_selection_device_listener gtk_primary_device_listener = { + gtk_primary_selection_data_offer, + gtk_primary_selection_selection, +}; + +static const struct zwp_primary_selection_device_v1_listener zwp_primary_device_v1_listener = { + zwp_primary_selection_v1_data_offer, + zwp_primary_selection_v1_selection, }; static GdkDevice * get_scroll_device (GdkWaylandSeat *seat, @@ -5078,13 +5124,23 @@ _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager, wl_seat_add_listener (seat->wl_seat, &seat_listener, seat); wl_seat_set_user_data (seat->wl_seat, seat); - if (display_wayland->primary_selection_manager) + if (display_wayland->zwp_primary_selection_manager_v1) { - seat->primary_data_device = - gtk_primary_selection_device_manager_get_device (display_wayland->primary_selection_manager, + seat->zwp_primary_data_device_v1 = + zwp_primary_selection_device_manager_v1_get_device (display_wayland->zwp_primary_selection_manager_v1, + seat->wl_seat); + zwp_primary_selection_device_v1_add_listener (seat->zwp_primary_data_device_v1, + &zwp_primary_device_v1_listener, + seat); + } + else if (display_wayland->gtk_primary_selection_manager) + { + seat->gtk_primary_data_device = + gtk_primary_selection_device_manager_get_device (display_wayland->gtk_primary_selection_manager, seat->wl_seat); - gtk_primary_selection_device_add_listener (seat->primary_data_device, - &primary_selection_device_listener, seat); + gtk_primary_selection_device_add_listener (seat->gtk_primary_data_device, + >k_primary_device_listener, + seat); } seat->data_device = @@ -5355,8 +5411,8 @@ gdk_wayland_seat_set_selection (GdkSeat *seat, } void -gdk_wayland_seat_set_primary (GdkSeat *seat, - struct gtk_primary_selection_source *source) +gdk_wayland_seat_set_primary (GdkSeat *seat, + gpointer source) { GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat); GdkWaylandDisplay *display_wayland; @@ -5366,8 +5422,16 @@ gdk_wayland_seat_set_primary (GdkSeat *seat, { display_wayland = GDK_WAYLAND_DISPLAY (gdk_seat_get_display (seat)); serial = _gdk_wayland_display_get_serial (display_wayland); - gtk_primary_selection_device_set_selection (wayland_seat->primary_data_device, - source, serial); + if (wayland_seat->zwp_primary_data_device_v1) + { + zwp_primary_selection_device_v1_set_selection (wayland_seat->zwp_primary_data_device_v1, + source, serial); + } + else if (wayland_seat->gtk_primary_data_device) + { + gtk_primary_selection_device_set_selection (wayland_seat->gtk_primary_data_device, + source, serial); + } } } diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index d4503c256236ae942bde999c964fbf1d85abdf29..dfb8d3069a36ddb72340815cd2e809596416ccaf 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -476,10 +476,16 @@ gdk_registry_handle_global (void *data, } else if (strcmp (interface, "gtk_primary_selection_device_manager") == 0) { - display_wayland->primary_selection_manager = + display_wayland->gtk_primary_selection_manager = wl_registry_bind(display_wayland->wl_registry, id, >k_primary_selection_device_manager_interface, 1); } + else if (strcmp (interface, "zwp_primary_selection_device_manager_v1") == 0) + { + display_wayland->zwp_primary_selection_manager_v1 = + wl_registry_bind(display_wayland->wl_registry, id, + &zwp_primary_selection_device_manager_v1_interface, 1); + } else if (strcmp (interface, "zwp_tablet_manager_v2") == 0) { display_wayland->tablet_manager = diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index 1e4a9860f61c71466bdb58e288abcb83129fc63d..62696300d15531d0ca212428c8eb3325fe10eb96 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -88,7 +89,8 @@ struct _GdkWaylandDisplay struct wl_data_device_manager *data_device_manager; struct wl_subcompositor *subcompositor; struct zwp_pointer_gestures_v1 *pointer_gestures; - struct gtk_primary_selection_device_manager *primary_selection_manager; + struct gtk_primary_selection_device_manager *gtk_primary_selection_manager; + struct zwp_primary_selection_device_manager_v1 *zwp_primary_selection_manager_v1; struct zwp_tablet_manager_v2 *tablet_manager; struct zxdg_exporter_v1 *xdg_exporter; struct zxdg_importer_v1 *xdg_importer; diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index fc8e9fe2800b129a9ac0432ee85511633eb407f5..4a921b3b9965085b580cbb736f280cfae60efb86 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -191,8 +191,8 @@ struct wl_data_device * gdk_wayland_device_get_data_device (GdkDevice *gdk_devic void gdk_wayland_seat_set_selection (GdkSeat *seat, struct wl_data_source *source); -void gdk_wayland_seat_set_primary (GdkSeat *seat, - struct gtk_primary_selection_source *source); +void gdk_wayland_seat_set_primary (GdkSeat *seat, + gpointer source); GdkDragContext * gdk_wayland_device_get_drop_context (GdkDevice *gdk_device); @@ -249,8 +249,8 @@ void gdk_wayland_selection_free (GdkWaylandSelection *selection); void gdk_wayland_selection_ensure_offer (GdkDisplay *display, struct wl_data_offer *wl_offer); -void gdk_wayland_selection_ensure_primary_offer (GdkDisplay *display, - struct gtk_primary_selection_offer *wp_offer); +void gdk_wayland_selection_ensure_primary_offer (GdkDisplay *display, + gpointer wp_offer); void gdk_wayland_selection_set_offer (GdkDisplay *display, GdkAtom selection, diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c index 0dd3aa9ebfd4dbd80666fcd1c122f67fb2d44569..f85f595616a51168be49b3dd92612ccd6d325fa7 100644 --- a/gdk/wayland/gdkselection-wayland.c +++ b/gdk/wayland/gdkselection-wayland.c @@ -104,7 +104,7 @@ struct _GdkWaylandSelection GArray *source_targets; GdkAtom requested_target; - struct gtk_primary_selection_source *primary_source; + gpointer primary_source; GdkWindow *primary_owner; struct wl_data_source *clipboard_source; @@ -434,6 +434,18 @@ gdk_wayland_selection_new (void) return selection; } +static void +primary_selection_source_destroy (gpointer primary_source) +{ + GdkDisplay *display = gdk_display_get_default (); + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); + + if (display_wayland->zwp_primary_selection_manager_v1) + zwp_primary_selection_source_v1_destroy (primary_source); + else if (display_wayland->gtk_primary_selection_manager) + gtk_primary_selection_source_destroy (primary_source); +} + void gdk_wayland_selection_free (GdkWaylandSelection *selection) { @@ -448,7 +460,7 @@ gdk_wayland_selection_free (GdkWaylandSelection *selection) g_ptr_array_unref (selection->stored_selections); if (selection->primary_source) - gtk_primary_selection_source_destroy (selection->primary_source); + primary_selection_source_destroy (selection->primary_source); if (selection->clipboard_source) wl_data_source_destroy (selection->clipboard_source); if (selection->dnd_source) @@ -546,27 +558,47 @@ static const struct wl_data_offer_listener data_offer_listener = { }; static void -primary_offer_offer (void *data, - struct gtk_primary_selection_offer *gtk_offer, - const char *type) +primary_offer_offer (void *data, + gpointer offer, + const char *type) { GdkWaylandSelection *selection = data; DataOfferData *info; GdkAtom atom = gdk_atom_intern (type, FALSE); - info = g_hash_table_lookup (selection->offers, gtk_offer); + info = g_hash_table_lookup (selection->offers, offer); if (!info || g_list_find (info->targets, atom)) return; GDK_NOTE (EVENTS, - g_message ("primary offer offer, offer %p, type = %s", gtk_offer, type)); + g_message ("primary offer offer, offer %p, type = %s", offer, type)); info->targets = g_list_prepend (info->targets, atom); } -static const struct gtk_primary_selection_offer_listener primary_offer_listener = { - primary_offer_offer, +static void +gtk_primary_offer_offer (void *data, + struct gtk_primary_selection_offer *offer, + const char *type) +{ + primary_offer_offer (data, (gpointer) offer, type); +} + +static void +zwp_primary_offer_v1_offer (void *data, + struct zwp_primary_selection_offer_v1 *offer, + const char *type) +{ + primary_offer_offer (data, (gpointer) offer, type); +} + +static const struct gtk_primary_selection_offer_listener gtk_primary_offer_listener = { + gtk_primary_offer_offer, +}; + +static const struct zwp_primary_selection_offer_v1_listener zwp_primary_offer_listener_v1 = { + zwp_primary_offer_v1_offer, }; SelectionData * @@ -604,9 +636,10 @@ gdk_wayland_selection_ensure_offer (GdkDisplay *display, } void -gdk_wayland_selection_ensure_primary_offer (GdkDisplay *display, - struct gtk_primary_selection_offer *gtk_offer) +gdk_wayland_selection_ensure_primary_offer (GdkDisplay *display, + gpointer gtk_offer) { + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display); DataOfferData *info; @@ -614,12 +647,24 @@ gdk_wayland_selection_ensure_primary_offer (GdkDisplay * if (!info) { - info = data_offer_data_new (gtk_offer, - (GDestroyNotify) gtk_primary_selection_offer_destroy); - g_hash_table_insert (selection->offers, gtk_offer, info); - gtk_primary_selection_offer_add_listener (gtk_offer, - &primary_offer_listener, - selection); + if (display_wayland->zwp_primary_selection_manager_v1) + { + info = data_offer_data_new (gtk_offer, + (GDestroyNotify) zwp_primary_selection_offer_v1_destroy); + g_hash_table_insert (selection->offers, gtk_offer, info); + zwp_primary_selection_offer_v1_add_listener (gtk_offer, + &zwp_primary_offer_listener_v1, + selection); + } + else if (display_wayland->gtk_primary_selection_manager) + { + info = data_offer_data_new (gtk_offer, + (GDestroyNotify) gtk_primary_selection_offer_destroy); + g_hash_table_insert (selection->offers, gtk_offer, info); + gtk_primary_selection_offer_add_listener (gtk_offer, + >k_primary_offer_listener, + selection); + } } } @@ -1138,10 +1183,10 @@ static const struct wl_data_source_listener data_source_listener = { }; static void -primary_source_send (void *data, - struct gtk_primary_selection_source *source, - const char *mime_type, - int32_t fd) +primary_source_send (void *data, + gpointer source, + const char *mime_type, + int32_t fd) { GdkWaylandSelection *wayland_selection = data; @@ -1163,8 +1208,26 @@ primary_source_send (void *data, } static void -primary_source_cancelled (void *data, - struct gtk_primary_selection_source *source) +gtk_primary_source_send (void *data, + struct gtk_primary_selection_source *source, + const char *mime_type, + int32_t fd) +{ + primary_source_send (data, (gpointer) source, mime_type, fd); +} + +static void +zwp_primary_source_v1_send (void *data, + struct zwp_primary_selection_source_v1 *source, + const char *mime_type, + int32_t fd) +{ + primary_source_send (data, (gpointer) source, mime_type, fd); +} + +static void +primary_source_cancelled (void *data, + gpointer source) { GdkDisplay *display; GdkAtom atom; @@ -1180,9 +1243,28 @@ primary_source_cancelled (void *data, gdk_wayland_selection_unset_data_source (display, atom); } -static const struct gtk_primary_selection_source_listener primary_source_listener = { - primary_source_send, - primary_source_cancelled, +static void +gtk_primary_source_cancelled (void *data, + struct gtk_primary_selection_source *source) +{ + primary_source_cancelled (data, source); +} + +static void +zwp_primary_source_v1_cancelled (void *data, + struct zwp_primary_selection_source_v1 *source) +{ + primary_source_cancelled (data, source); +} + +static const struct gtk_primary_selection_source_listener gtk_primary_source_listener = { + gtk_primary_source_send, + gtk_primary_source_cancelled, +}; + +static const struct zwp_primary_selection_source_v1_listener zwp_primary_source_v1_listener = { + zwp_primary_source_v1_send, + zwp_primary_source_v1_cancelled, }; struct wl_data_source * @@ -1204,11 +1286,11 @@ gdk_wayland_selection_get_data_source (GdkWindow *owner, { if (wayland_selection->primary_source && (!owner || owner == wayland_selection->primary_owner)) - return (gpointer) wayland_selection->primary_source; + return wayland_selection->primary_source; if (wayland_selection->primary_source) { - gtk_primary_selection_source_destroy (wayland_selection->primary_source); + primary_selection_source_destroy (wayland_selection->primary_source); wayland_selection->primary_source = NULL; } } @@ -1234,11 +1316,18 @@ gdk_wayland_selection_get_data_source (GdkWindow *owner, if (selection == atoms[ATOM_PRIMARY]) { - if (display_wayland->primary_selection_manager) + if (display_wayland->zwp_primary_selection_manager_v1) + { + source = zwp_primary_selection_device_manager_v1_create_source (display_wayland->zwp_primary_selection_manager_v1); + zwp_primary_selection_source_v1_add_listener (source, + &zwp_primary_source_v1_listener, + wayland_selection); + } + else if (display_wayland->gtk_primary_selection_manager) { - source = gtk_primary_selection_device_manager_create_source (display_wayland->primary_selection_manager); + source = gtk_primary_selection_device_manager_create_source (display_wayland->gtk_primary_selection_manager); gtk_primary_selection_source_add_listener (source, - &primary_source_listener, + >k_primary_source_listener, wayland_selection); } } @@ -1278,7 +1367,7 @@ gdk_wayland_selection_unset_data_source (GdkDisplay *display, { if (wayland_selection->primary_source) { - gtk_primary_selection_source_destroy (wayland_selection->primary_source); + primary_selection_source_destroy (wayland_selection->primary_source); wayland_selection->primary_source = NULL; } } @@ -1449,6 +1538,7 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display, GdkAtom target, guint32 time) { + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display); const SelectionData *selection_data; SelectionBuffer *buffer_data; @@ -1514,9 +1604,16 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display, g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL); if (selection == atoms[ATOM_PRIMARY]) - gtk_primary_selection_offer_receive (offer, mimetype, pipe_fd[1]); + { + if (display_wayland->zwp_primary_selection_manager_v1) + zwp_primary_selection_offer_v1_receive (offer, mimetype, pipe_fd[1]); + else if (display_wayland->gtk_primary_selection_manager) + gtk_primary_selection_offer_receive (offer, mimetype, pipe_fd[1]); + } else - wl_data_offer_receive (offer, mimetype, pipe_fd[1]); + { + wl_data_offer_receive (offer, mimetype, pipe_fd[1]); + } stream = g_unix_input_stream_new (pipe_fd[0], TRUE); close (pipe_fd[1]); diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build index 8f6b7faf31ca379cd602ae437b7864308b1bffd6..e66afd7f95bfc6e39cd200eedf55813862213664 100644 --- a/gdk/wayland/meson.build +++ b/gdk/wayland/meson.build @@ -56,6 +56,7 @@ proto_sources = [ ['keyboard-shortcuts-inhibit', 'unstable', 'v1', ], ['server-decoration', 'private' ], ['xdg-output', 'unstable', 'v1', ], + ['primary-selection', 'unstable', 'v1', ], ] gdk_wayland_gen_headers = [] diff --git a/meson.build b/meson.build index a3a7545ae103a88fc73cffe917c79848018f1a61..9c80fafc0314aed310018bc1f8851bc00e85f68a 100644 --- a/meson.build +++ b/meson.build @@ -30,7 +30,7 @@ atk_req = '>= 2.15.1' cairo_req = '>= 1.14.0' gdk_pixbuf_req = '>= 2.30.0' introspection_req = '>= 1.39.0' -wayland_proto_req = '>= 1.14' +wayland_proto_req = '>= 1.17' wayland_req = '>= 1.14.91' epoxy_req = '>= 1.4' cloudproviders_req = '>= 0.2.5'