From d0ebdf00f877c63a09a73b208b43d107260546d2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 14 Jun 2018 03:41:57 +0200 Subject: [PATCH] x11: Store the source surface as an XID Don't create a foreign GDK surface, just store the XID. With this, we can avoid GDK APIs that we want to get rid of and just use the X counterpart. --- gdk/x11/gdkdrop-x11.c | 121 ++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 70 deletions(-) diff --git a/gdk/x11/gdkdrop-x11.c b/gdk/x11/gdkdrop-x11.c index 6aabc9ef35..ddae88e13d 100644 --- a/gdk/x11/gdkdrop-x11.c +++ b/gdk/x11/gdkdrop-x11.c @@ -58,7 +58,7 @@ struct _GdkX11Drop { GdkDrop parent_instance; - GdkSurface *source_surface; + Window source_window; guint16 last_x; /* Coordinates from last event */ guint16 last_y; @@ -79,6 +79,9 @@ struct _GdkX11DropClass /* Forward declarations */ +static gboolean xdnd_source_surface_filter (GdkDisplay *display, + const XEvent *xevent, + gpointer data); static gboolean xdnd_enter_filter (GdkSurface *surface, const XEvent *xevent); static gboolean xdnd_leave_filter (GdkSurface *surface, @@ -88,10 +91,6 @@ static gboolean xdnd_position_filter (GdkSurface *surface, static gboolean xdnd_drop_filter (GdkSurface *surface, const XEvent *xevent); -static void xdnd_manage_source_filter (GdkDrop *drop, - GdkSurface *surface, - gboolean add_filter); - static const struct { const char *atom_name; gboolean (* func) (GdkSurface *surface, const XEvent *event); @@ -238,9 +237,15 @@ gdk_x11_drop_finalize (GObject *object) { GdkX11Drop *drop_x11 = GDK_X11_DROP (object); - if (drop_x11->source_surface) + if (gdk_drop_get_drag (GDK_DROP (drop_x11)) == NULL) { - xdnd_manage_source_filter (GDK_DROP (drop_x11), drop_x11->source_surface, FALSE); + g_signal_handlers_disconnect_by_func (gdk_drop_get_display (GDK_DROP (drop_x11)), + xdnd_source_surface_filter, + drop_x11); + /* Should we remove the GDK_PROPERTY_NOTIFY mask? + * but we might want it for other reasons. (Like + * INCR selection transactions). + */ } G_OBJECT_CLASS (gdk_x11_drop_parent_class)->finalize (object); @@ -350,7 +355,7 @@ gdk_x11_drop_read_actions (GdkDrop *drop) gdk_x11_display_error_trap_push (display); if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), - GDK_SURFACE_XID (drop_x11->source_surface), + drop_x11->source_window, gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"), 0, 65536, False, XA_ATOM, &type, &format, &nitems, @@ -415,7 +420,7 @@ xdnd_source_surface_filter (GdkDisplay *display, GdkX11Drop *drop_x11 = data; if ((xevent->xany.type == PropertyNotify) && - (xevent->xany.window == GDK_SURFACE_XID (drop_x11->source_surface)) && + (xevent->xany.window == drop_x11->source_window) && (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "XdndActionList"))) { gdk_x11_drop_read_actions (GDK_DROP (drop_x11)); @@ -424,39 +429,6 @@ xdnd_source_surface_filter (GdkDisplay *display, return FALSE; } -static void -xdnd_manage_source_filter (GdkDrop *drop, - GdkSurface *surface, - gboolean add_filter) -{ - if (!GDK_SURFACE_DESTROYED (surface) && - gdk_surface_get_surface_type (surface) == GDK_SURFACE_FOREIGN) - { - GdkDisplay *display = gdk_drop_get_display (drop); - - if (add_filter) - { - gdk_x11_display_error_trap_push (display); - gdk_surface_set_events (surface, - gdk_surface_get_events (surface) | - GDK_PROPERTY_CHANGE_MASK); - gdk_x11_display_error_trap_pop_ignored (display); - - g_signal_connect (display, "xevent", G_CALLBACK (xdnd_source_surface_filter), drop); - } - else - { - g_signal_handlers_disconnect_by_func (display, - xdnd_source_surface_filter, - drop); - /* Should we remove the GDK_PROPERTY_NOTIFY mask? - * but we might want it for other reasons. (Like - * INCR selection transactions). - */ - } - } -} - static void xdnd_precache_atoms (GdkDisplay *display) { @@ -506,11 +478,11 @@ xdnd_enter_filter (GdkSurface *surface, Atom *atoms; GdkContentFormats *content_formats; GPtrArray *formats; - guint32 source_surface; + Window source_window; gboolean get_types; gint version; - source_surface = xevent->xclient.data.l[0]; + source_window = xevent->xclient.data.l[0]; get_types = ((xevent->xclient.data.l[1] & 1) != 0); version = (xevent->xclient.data.l[1] & 0xff000000) >> 24; @@ -520,8 +492,8 @@ xdnd_enter_filter (GdkSurface *surface, xdnd_precache_atoms (display); GDK_DISPLAY_NOTE (display, DND, - g_message ("XdndEnter: source_surface: %#x, version: %#x", - source_surface, version)); + g_message ("XdndEnter: source_window: %#lx, version: %#x", + source_window, version)); if (version < 3) { @@ -539,7 +511,7 @@ xdnd_enter_filter (GdkSurface *surface, { gdk_x11_display_error_trap_push (display); XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), - source_surface, + source_window, gdk_x11_get_xatom_by_name_for_display (display, "XdndTypeList"), 0, 65536, False, XA_ATOM, &type, &format, &nitems, @@ -576,7 +548,7 @@ xdnd_enter_filter (GdkSurface *surface, print_target_list (content_formats); #endif /* G_ENABLE_DEBUG */ - drag = gdk_x11_drag_context_find (display, source_surface, GDK_SURFACE_XID (surface)); + drag = gdk_x11_drag_context_find (display, source_window, GDK_SURFACE_XID (surface)); drop_x11 = g_object_new (GDK_TYPE_X11_DROP, "device", gdk_seat_get_pointer (seat), @@ -590,13 +562,22 @@ xdnd_enter_filter (GdkSurface *surface, /* FIXME: Should extend DnD protocol to have device info */ - drop_x11->source_surface = gdk_x11_surface_foreign_new_for_display (display, source_surface); - if (!drop_x11->source_surface) + drop_x11->source_window = source_window; + if (drag == NULL) { - g_object_unref (drop); - return TRUE; + Display *xdisplay = gdk_x11_display_get_xdisplay (display); + XWindowAttributes attrs; + + gdk_x11_display_error_trap_push (display); + XGetWindowAttributes (xdisplay, source_window, &attrs); + if (!(attrs.your_event_mask & PropertyChangeMask)) + { + XSelectInput (xdisplay, source_window, attrs.your_event_mask | PropertyChangeMask); + } + gdk_x11_display_error_trap_pop_ignored (display); + + g_signal_connect (display, "xevent", G_CALLBACK (xdnd_source_surface_filter), drop); } - xdnd_manage_source_filter (drop, drop_x11->source_surface, TRUE); gdk_x11_drop_read_actions (drop); display_x11->current_drop = drop; @@ -612,7 +593,7 @@ static gboolean xdnd_leave_filter (GdkSurface *surface, const XEvent *xevent) { - guint32 source_surface = xevent->xclient.data.l[0]; + Window source_window = xevent->xclient.data.l[0]; GdkDisplay *display; GdkX11Display *display_x11; @@ -620,13 +601,13 @@ xdnd_leave_filter (GdkSurface *surface, display_x11 = GDK_X11_DISPLAY (display); GDK_DISPLAY_NOTE (display, DND, - g_message ("XdndLeave: source_surface: %#x", - source_surface)); + g_message ("XdndLeave: source_window: %#lx", + source_window)); xdnd_precache_atoms (display); if ((display_x11->current_drop != NULL) && - (GDK_SURFACE_XID (GDK_X11_DROP (display_x11->current_drop)->source_surface) == source_surface)) + (GDK_X11_DROP (display_x11->current_drop)->source_window == source_window)) { gdk_drop_emit_leave_event (display_x11->current_drop, FALSE, GDK_CURRENT_TIME); @@ -641,7 +622,7 @@ xdnd_position_filter (GdkSurface *surface, const XEvent *xevent) { GdkSurfaceImplX11 *impl; - guint32 source_surface = xevent->xclient.data.l[0]; + Window source_window = xevent->xclient.data.l[0]; gint16 x_root = xevent->xclient.data.l[2] >> 16; gint16 y_root = xevent->xclient.data.l[2] & 0xffff; guint32 time = xevent->xclient.data.l[3]; @@ -655,8 +636,8 @@ xdnd_position_filter (GdkSurface *surface, display_x11 = GDK_X11_DISPLAY (display); GDK_DISPLAY_NOTE (display, DND, - g_message ("XdndPosition: source_surface: %#x position: (%d, %d) time: %d action: %ld", - source_surface, x_root, y_root, time, action)); + g_message ("XdndPosition: source_window: %#lx position: (%d, %d) time: %d action: %ld", + source_window, x_root, y_root, time, action)); xdnd_precache_atoms (display); @@ -664,7 +645,7 @@ xdnd_position_filter (GdkSurface *surface, drop_x11 = GDK_X11_DROP (drop); if ((drop != NULL) && - (GDK_SURFACE_XID (drop_x11->source_surface) == source_surface)) + (drop_x11->source_window == source_window)) { impl = GDK_SURFACE_IMPL_X11 (gdk_drop_get_surface (drop)->impl); @@ -684,7 +665,7 @@ static gboolean xdnd_drop_filter (GdkSurface *surface, const XEvent *xevent) { - guint32 source_surface = xevent->xclient.data.l[0]; + Window source_window = xevent->xclient.data.l[0]; guint32 time = xevent->xclient.data.l[2]; GdkDisplay *display; GdkX11Display *display_x11; @@ -695,8 +676,8 @@ xdnd_drop_filter (GdkSurface *surface, display_x11 = GDK_X11_DISPLAY (display); GDK_DISPLAY_NOTE (display, DND, - g_message ("XdndDrop: source_surface: %#x time: %d", - source_surface, time)); + g_message ("XdndDrop: source_window: %#lx time: %d", + source_window, time)); xdnd_precache_atoms (display); @@ -704,7 +685,7 @@ xdnd_drop_filter (GdkSurface *surface, drop_x11 = GDK_X11_DROP (drop); if ((drop != NULL) && - (GDK_SURFACE_XID (drop_x11->source_surface) == source_surface)) + (drop_x11->source_window == source_window)) { gdk_x11_surface_set_user_time (gdk_drop_get_surface (drop), time); @@ -780,7 +761,7 @@ gdk_x11_drop_status (GdkDrop *drop, xev.xclient.type = ClientMessage; xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndStatus"); xev.xclient.format = 32; - xev.xclient.window = GDK_SURFACE_XID (drop_x11->source_surface); + xev.xclient.window = drop_x11->source_window; xev.xclient.data.l[0] = GDK_SURFACE_XID (gdk_drop_get_surface (drop)); xev.xclient.data.l[1] = (possible_actions != 0) ? (2 | 1) : 0; @@ -795,7 +776,7 @@ gdk_x11_drop_status (GdkDrop *drop, else { _gdk_x11_send_client_message_async (display, - GDK_SURFACE_XID (drop_x11->source_surface), + drop_x11->source_window, FALSE, 0, &xev.xclient, gdk_x11_drop_do_nothing, @@ -817,7 +798,7 @@ gdk_x11_drop_finish (GdkDrop *drop, gdk_x11_get_xatom_by_name_for_display (display, "XdndSelection"), gdk_x11_get_xatom_by_name_for_display (display, "DELETE"), gdk_x11_get_xatom_by_name_for_display (display, "GDK_SELECTION"), - GDK_SURFACE_XID (drop_x11->source_surface), + drop_x11->source_window, GDK_X11_DROP (drop)->timestamp); /* XXX: Do we need to wait for a reply here before sending the next message? */ } @@ -825,7 +806,7 @@ gdk_x11_drop_finish (GdkDrop *drop, xev.xclient.type = ClientMessage; xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "XdndFinished"); xev.xclient.format = 32; - xev.xclient.window = GDK_SURFACE_XID (drop_x11->source_surface); + xev.xclient.window = drop_x11->source_window; xev.xclient.data.l[0] = GDK_SURFACE_XID (gdk_drop_get_surface (drop)); if (action != 0) @@ -848,7 +829,7 @@ gdk_x11_drop_finish (GdkDrop *drop, else { _gdk_x11_send_client_message_async (display, - GDK_SURFACE_XID (drop_x11->source_surface), + drop_x11->source_window, FALSE, 0, &xev.xclient, gdk_x11_drop_do_nothing, -- 2.30.2