From bc63001debcbecec9566b686c69e7e3c21746949 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 15 Jun 2018 08:35:14 +0200 Subject: [PATCH] x11: Store the XID instead of a GdkSurface This might be foreign Windows and we don't want to create surfaces for those. Also, stop using GdkDragContext.dest_surface, that variable is meant to go away. --- gdk/x11/gdkdnd-x11.c | 127 +++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 70 deletions(-) diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index a321cb55d3..b21c814a57 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -121,6 +121,7 @@ struct _GdkX11DragContext gint hot_y; Window dest_xid; /* The last window we looked up */ + Window proxy_xid; /* The proxy window for dest_xid (or dest_xid if no proxying happens) */ Window drop_xid; /* The (non-proxied) window that is receiving drops */ guint xdnd_targets_set : 1; /* Whether we've already set XdndTypeList */ guint xdnd_have_actions : 1; /* Whether an XdndActionList was provided */ @@ -184,13 +185,13 @@ gdk_x11_drag_context_init (GdkX11DragContext *context) } static void gdk_x11_drag_context_finalize (GObject *object); -static GdkSurface * gdk_x11_drag_context_find_surface (GdkDragContext *context, +static Window gdk_x11_drag_context_find_surface (GdkDragContext *context, GdkSurface *drag_surface, gint x_root, gint y_root, GdkDragProtocol *protocol); static gboolean gdk_x11_drag_context_drag_motion (GdkDragContext *context, - GdkSurface *dest_surface, + Window proxy_xid, GdkDragProtocol protocol, gint x_root, gint y_root, @@ -277,10 +278,10 @@ gdk_x11_drag_context_find (GdkDisplay *display, if (gdk_drag_context_get_display (context) != display) continue; - context_dest_xid = context->dest_surface + context_dest_xid = context_x11->proxy_xid ? (context_x11->drop_xid ? context_x11->drop_xid - : GDK_SURFACE_XID (context->dest_surface)) + : context_x11->proxy_xid) : None; if ((context->is_source) && @@ -996,7 +997,9 @@ send_client_message_async_cb (Window window, gboolean success, gpointer data) { + GdkX11DragContext *context_x11 = data; GdkDragContext *context = data; + GDK_DISPLAY_NOTE (gdk_drag_context_get_display (context), DND, g_message ("Got async callback for #%lx, success = %d", window, success)); @@ -1005,13 +1008,9 @@ send_client_message_async_cb (Window window, * so we don't end up blocking for a timeout */ if (!success && - context->dest_surface && - window == GDK_SURFACE_XID (context->dest_surface)) + window == context_x11->proxy_xid) { - GdkX11DragContext *context_x11 = data; - - g_object_unref (context->dest_surface); - context->dest_surface = NULL; + context_x11->proxy_xid = None; context->action = 0; if (context->action != context_x11->current_action) { @@ -1041,31 +1040,29 @@ send_client_message_async (GdkDragContext *context, static void xdnd_send_xevent (GdkX11DragContext *context_x11, - GdkSurface *surface, XEvent *event_send) { GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11); GdkDisplay *display = gdk_drag_context_get_display (context); - Window xwindow; + GdkSurface *surface; glong event_mask; g_assert (event_send->xany.type == ClientMessage); /* We short-circuit messages to ourselves */ - if (gdk_surface_get_surface_type (surface) != GDK_SURFACE_FOREIGN) + surface = gdk_x11_surface_lookup_for_display (display, context_x11->proxy_xid); + if (surface) { if (gdk_x11_drop_filter (surface, event_send)) return; } - xwindow = GDK_SURFACE_XID (surface); - - if (_gdk_x11_display_is_root_window (display, xwindow)) + if (_gdk_x11_display_is_root_window (display, context_x11->proxy_xid)) event_mask = ButtonPressMask; else event_mask = 0; - send_client_message_async (context, xwindow, event_mask, + send_client_message_async (context, context_x11->proxy_xid, event_mask, &event_send->xclient); } @@ -1083,7 +1080,7 @@ xdnd_send_enter (GdkX11DragContext *context_x11) xev.xclient.format = 32; xev.xclient.window = context_x11->drop_xid ? context_x11->drop_xid - : GDK_SURFACE_XID (context->dest_surface); + : context_x11->proxy_xid; xev.xclient.data.l[0] = GDK_SURFACE_XID (context_x11->ipc_surface); xev.xclient.data.l[1] = (context_x11->version << 24); /* version */ xev.xclient.data.l[2] = 0; @@ -1109,7 +1106,7 @@ xdnd_send_enter (GdkX11DragContext *context_x11) } } - xdnd_send_xevent (context_x11, context->dest_surface, &xev); + xdnd_send_xevent (context_x11, &xev); } static void @@ -1124,14 +1121,14 @@ xdnd_send_leave (GdkX11DragContext *context_x11) xev.xclient.format = 32; xev.xclient.window = context_x11->drop_xid ? context_x11->drop_xid - : GDK_SURFACE_XID (context->dest_surface); + : context_x11->proxy_xid; xev.xclient.data.l[0] = GDK_SURFACE_XID (context_x11->ipc_surface); xev.xclient.data.l[1] = 0; xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - xdnd_send_xevent (context_x11, context->dest_surface, &xev); + xdnd_send_xevent (context_x11, &xev); } static void @@ -1147,14 +1144,14 @@ xdnd_send_drop (GdkX11DragContext *context_x11, xev.xclient.format = 32; xev.xclient.window = context_x11->drop_xid ? context_x11->drop_xid - : GDK_SURFACE_XID (context->dest_surface); + : context_x11->proxy_xid; xev.xclient.data.l[0] = GDK_SURFACE_XID (context_x11->ipc_surface); xev.xclient.data.l[1] = 0; xev.xclient.data.l[2] = time; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - xdnd_send_xevent (context_x11, context->dest_surface, &xev); + xdnd_send_xevent (context_x11, &xev); } static void @@ -1173,14 +1170,14 @@ xdnd_send_motion (GdkX11DragContext *context_x11, xev.xclient.format = 32; xev.xclient.window = context_x11->drop_xid ? context_x11->drop_xid - : GDK_SURFACE_XID (context->dest_surface); + : context_x11->proxy_xid; xev.xclient.data.l[0] = GDK_SURFACE_XID (context_x11->ipc_surface); xev.xclient.data.l[1] = 0; xev.xclient.data.l[2] = (x_root << 16) | y_root; xev.xclient.data.l[3] = time; xev.xclient.data.l[4] = xdnd_action_to_atom (display, action); - xdnd_send_xevent (context_x11, context->dest_surface, &xev); + xdnd_send_xevent (context_x11, &xev); context_x11->drag_status = GDK_DRAG_STATUS_MOTION_WAIT; } @@ -1316,9 +1313,7 @@ static void gdk_drag_do_leave (GdkX11DragContext *context_x11, guint32 time) { - GdkDragContext *context = GDK_DRAG_CONTEXT (context_x11); - - if (context->dest_surface) + if (context_x11->proxy_xid) { switch (context_x11->protocol) { @@ -1331,8 +1326,7 @@ gdk_drag_do_leave (GdkX11DragContext *context_x11, break; } - g_object_unref (context->dest_surface); - context->dest_surface = NULL; + context_x11->proxy_xid = None; } } @@ -1417,7 +1411,7 @@ drag_context_find_window_cache (GdkX11DragContext *context_x11, return context_x11->cache; } -static GdkSurface * +static Window gdk_x11_drag_context_find_surface (GdkDragContext *context, GdkSurface *drag_surface, gint x_root, @@ -1429,7 +1423,7 @@ gdk_x11_drag_context_find_surface (GdkDragContext *context, GdkSurfaceCache *window_cache; GdkDisplay *display; Window dest; - GdkSurface *dest_surface; + Window proxy; display = gdk_drag_context_get_display (context); screen_x11 = GDK_X11_SCREEN(GDK_X11_DISPLAY (display)->screen); @@ -1444,7 +1438,6 @@ gdk_x11_drag_context_find_surface (GdkDragContext *context, if (context_x11->dest_xid != dest) { - Window recipient; context_x11->dest_xid = dest; /* Check if new destination accepts drags, and which protocol */ @@ -1455,25 +1448,18 @@ gdk_x11_drag_context_find_surface (GdkDragContext *context, * two are passed explicitly, the third implicitly through * protocol->dest_xid. */ - recipient = _gdk_x11_display_get_drag_protocol (display, - dest, - protocol, - &context_x11->version); - - if (recipient != None) - dest_surface = gdk_x11_surface_foreign_new_for_display (display, recipient); - else - dest_surface = NULL; + proxy = _gdk_x11_display_get_drag_protocol (display, + dest, + protocol, + &context_x11->version); } else { - dest_surface = context->dest_surface; - if (dest_surface) - g_object_ref (dest_surface); + proxy = dest; *protocol = context_x11->protocol; } - return dest_surface; + return proxy; } static void @@ -1491,7 +1477,7 @@ move_drag_surface (GdkDragContext *context, static gboolean gdk_x11_drag_context_drag_motion (GdkDragContext *context, - GdkSurface *dest_surface, + Window proxy_xid, GdkDragProtocol protocol, gint x_root, gint y_root, @@ -1500,7 +1486,6 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, guint32 time) { GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context); - GdkSurfaceImplX11 *impl; if (context_x11->drag_surface) move_drag_surface (context, x_root, y_root); @@ -1517,12 +1502,12 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, * gdk_drag_find_window(). This happens, e.g. * when GTK+ is proxying DND events to embedded windows. */ - if (dest_surface) + if (proxy_xid) { - GdkDisplay *display = GDK_SURFACE_DISPLAY (dest_surface); + GdkDisplay *display = gdk_drag_context_get_display (context); xdnd_check_dest (display, - GDK_SURFACE_XID (dest_surface), + proxy_xid, &context_x11->version); } } @@ -1532,19 +1517,19 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, */ if (protocol == GDK_DRAG_PROTO_XDND && context_x11->xdnd_actions != gdk_drag_context_get_actions (context)) { - if (dest_surface) + if (proxy_xid) { - GdkDisplay *display = GDK_SURFACE_DISPLAY (dest_surface); + GdkDisplay *display = gdk_drag_context_get_display (context); GdkDrop *drop = GDK_X11_DISPLAY (display)->current_drop; - if (drop && gdk_drop_get_surface (drop) == dest_surface) + if (drop && GDK_SURFACE_XID (gdk_drop_get_surface (drop)) == proxy_xid) gdk_x11_drop_read_actions (drop); else xdnd_set_actions (context_x11); } } - if (context->dest_surface != dest_surface) + if (context_x11->proxy_xid != proxy_xid) { /* Send a leave to the last destination */ gdk_drag_do_leave (context_x11, time); @@ -1552,11 +1537,10 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, /* Check if new destination accepts drags, and which protocol */ - if (dest_surface) + if (proxy_xid) { - context->dest_surface = dest_surface; + context_x11->proxy_xid = proxy_xid; context_x11->drop_xid = context_x11->dest_xid; - g_object_ref (context->dest_surface); context_x11->protocol = protocol; switch (protocol) @@ -1573,7 +1557,7 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, } else { - context->dest_surface = NULL; + context_x11->proxy_xid = None; context_x11->drop_xid = None; context->action = 0; } @@ -1593,16 +1577,17 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, context_x11->last_x = x_root; context_x11->last_y = y_root; - if (context->dest_surface) + if (context_x11->proxy_xid) { - impl = GDK_SURFACE_IMPL_X11 (context->dest_surface->impl); + GdkDisplay *display = gdk_drag_context_get_display (context); + GdkX11Screen *screen_x11 = GDK_X11_SCREEN(GDK_X11_DISPLAY (display)->screen); if (context_x11->drag_status == GDK_DRAG_STATUS_DRAG) { switch (context_x11->protocol) { case GDK_DRAG_PROTO_XDND: - xdnd_send_motion (context_x11, x_root * impl->surface_scale, y_root * impl->surface_scale, suggested_action, time); + xdnd_send_motion (context_x11, x_root * screen_x11->surface_scale, y_root * screen_x11->surface_scale, suggested_action, time); break; case GDK_DRAG_PROTO_ROOTWIN: @@ -1651,7 +1636,7 @@ gdk_x11_drag_context_drag_drop (GdkDragContext *context, { GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context); - if (context->dest_surface) + if (context_x11->proxy_xid) { switch (context_x11->protocol) { @@ -2286,17 +2271,17 @@ gdk_drag_update (GdkDragContext *context, { GdkX11DragContext *x11_context = GDK_X11_DRAG_CONTEXT (context); GdkDragAction action, possible_actions; - GdkSurface *dest_surface; GdkDragProtocol protocol; + Window proxy; gdk_drag_get_current_actions (mods, GDK_BUTTON_PRIMARY, x11_context->actions, &action, &possible_actions); - dest_surface = gdk_x11_drag_context_find_surface (context, - x11_context->drag_surface, - x_root, y_root, &protocol); + proxy = gdk_x11_drag_context_find_surface (context, + x11_context->drag_surface, + x_root, y_root, &protocol); - gdk_x11_drag_context_drag_motion (context, dest_surface, protocol, x_root, y_root, + gdk_x11_drag_context_drag_motion (context, proxy, protocol, x_root, y_root, action, possible_actions, evtime); } @@ -2341,7 +2326,7 @@ gdk_dnd_handle_key_event (GdkDragContext *context, case GDK_KEY_KP_Enter: case GDK_KEY_KP_Space: if ((gdk_drag_context_get_selected_action (context) != 0) && - (context->dest_surface != NULL)) + (x11_context->proxy_xid != None)) { g_signal_emit_by_name (context, "drop-performed", gdk_event_get_time ((GdkEvent *) event)); @@ -2422,6 +2407,8 @@ static gboolean gdk_dnd_handle_button_event (GdkDragContext *context, const GdkEventButton *event) { + GdkX11DragContext *x11_context = GDK_X11_DRAG_CONTEXT (context); + #if 0 /* FIXME: Check the button matches */ if (event->button != x11_context->button) @@ -2429,7 +2416,7 @@ gdk_dnd_handle_button_event (GdkDragContext *context, #endif if ((gdk_drag_context_get_selected_action (context) != 0) && - (context->dest_surface != NULL)) + (x11_context->proxy_xid != None)) { g_signal_emit_by_name (context, "drop-performed", gdk_event_get_time ((GdkEvent *) event));