{
GdkDrop parent_instance;
- GdkSurface *source_surface;
+ Window source_window;
guint16 last_x; /* Coordinates from last event */
guint16 last_y;
/* 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,
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);
{
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);
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,
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));
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)
{
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;
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)
{
{
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,
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),
/* 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;
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;
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);
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];
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);
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);
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;
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);
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);
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;
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,
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? */
}
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)
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,