diff options
author | Owen Taylor <otaylor@redhat.com> | 1998-11-18 17:00:48 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 1998-11-18 17:00:48 +0000 |
commit | 8715d1c1b38969cd887cb218ba72ae343e7bc275 (patch) | |
tree | 06aac423fa1bfbe1e96dcd2b1b9c1776d30856c9 /gdk | |
parent | fb6a7ccb92c4443108e4bc07b6cb43ab3268a94e (diff) | |
download | gtk+-8715d1c1b38969cd887cb218ba72ae343e7bc275.tar.gz |
Accept drops that are sent to a toplevel but are not within the toplevels
Wed Nov 18 11:54:57 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtkdnd.c (gtk_drag_find_widget): Accept drops
that are sent to a toplevel but are not within the
toplevels bounds.
* gdk/gdkdnd.c gdk/gdk.h: Added support for a
XdndProxy atom which proxies the drag to another window.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdk.h | 4 | ||||
-rw-r--r-- | gdk/gdkdnd.c | 96 | ||||
-rw-r--r-- | gdk/x11/gdkdnd-x11.c | 96 |
3 files changed, 140 insertions, 56 deletions
@@ -245,8 +245,8 @@ GdkAtom gdk_drag_get_selection (GdkDragContext *context); GdkDragContext * gdk_drag_begin (GdkWindow *window, GList *targets, GdkDragAction actions); -gboolean gdk_drag_get_protocol (guint32 xid, - GdkDragProtocol *protocol); +guint32 gdk_drag_get_protocol (guint32 xid, + GdkDragProtocol *protocol); void gdk_drag_find_window (GdkDragContext *context, GdkWindow *drag_window, gint x_root, diff --git a/gdk/gdkdnd.c b/gdk/gdkdnd.c index c4dc41a078..9c088cbc62 100644 --- a/gdk/gdkdnd.c +++ b/gdk/gdkdnd.c @@ -1214,7 +1214,7 @@ motif_set_targets (GdkDragContext *context) private->motif_targets_set = 1; } -gboolean +guint32 motif_check_dest (Window win) { gboolean retval = FALSE; @@ -1225,7 +1225,7 @@ motif_check_dest (Window win) if (!motif_drag_receiver_info_atom) motif_drag_receiver_info_atom = gdk_atom_intern ("_MOTIF_DRAG_RECEIVER_INFO", FALSE); - + XGetWindowProperty (gdk_display, win, motif_drag_receiver_info_atom, 0, (sizeof(*info)+3)/4, False, AnyPropertyType, @@ -1251,7 +1251,7 @@ motif_check_dest (Window win) XFree (info); } - return retval; + return retval ? win : GDK_NONE; } @@ -2098,7 +2098,7 @@ xdnd_send_motion (GdkDragContext *context, private->drag_status = GDK_DRAG_STATUS_MOTION_WAIT; } -static gboolean +static guint32 xdnd_check_dest (Window win) { gboolean retval = FALSE; @@ -2106,31 +2106,70 @@ xdnd_check_dest (Window win) int format; unsigned long nitems, after; GdkAtom *version; + Window *proxy_data; + Window proxy; + static GdkAtom xdnd_proxy_atom = GDK_NONE; + + gint old_warnings = gdk_error_warnings; + + if (!xdnd_proxy_atom) + xdnd_proxy_atom = gdk_atom_intern ("XdndProxy", FALSE); if (!xdnd_aware_atom) xdnd_aware_atom = gdk_atom_intern ("XdndAware", FALSE); + proxy = GDK_NONE; + + gdk_error_code = 0; + gdk_error_warnings = 0; + XGetWindowProperty (gdk_display, win, - xdnd_aware_atom, 0, + xdnd_proxy_atom, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, - (guchar **)&version); - - if (type != None) + (guchar **)&proxy_data); + + if (!gdk_error_code) { - if ((format == 32) && (nitems == 1)) + if (type != None) { - if (*version == 3) - retval = TRUE; + if ((format == 32) && (nitems == 1)) + { + proxy = *proxy_data; + } + else + GDK_NOTE (DND, + g_warning ("Invalid XdndOwner property on window %ld\n", win)); + + XFree (proxy_data); } - else - GDK_NOTE (DND, - g_warning ("Invalid XdndAware property on window %ld\n", win)); - - XFree (version); + + XGetWindowProperty (gdk_display, proxy ? proxy : win, + xdnd_aware_atom, 0, + 1, False, AnyPropertyType, + &type, &format, &nitems, &after, + (guchar **)&version); + + if (!gdk_error_code && type != None) + { + if ((format == 32) && (nitems == 1)) + { + if (*version == 3) + retval = TRUE; + } + else + GDK_NOTE (DND, + g_warning ("Invalid XdndAware property on window %ld\n", win)); + + XFree (version); + } + } - return retval; + gdk_error_warnings = old_warnings; + gdk_error_code = 0; + + return retval ? (proxy ? proxy : win) : GDK_NONE; } /* Target side */ @@ -2423,21 +2462,23 @@ gdk_drag_begin (GdkWindow *window, return new_context; } -gboolean +guint32 gdk_drag_get_protocol (guint32 xid, GdkDragProtocol *protocol) { - if (xdnd_check_dest (xid)) + guint32 retval; + + if ((retval = xdnd_check_dest (xid))) { *protocol = GDK_DRAG_PROTO_XDND; GDK_NOTE (DND, g_message ("Entering dnd window %#x\n", xid)); - return TRUE; + return retval; } - else if (motif_check_dest (xid)) + else if ((retval = motif_check_dest (xid))) { *protocol = GDK_DRAG_PROTO_MOTIF; GDK_NOTE (DND, g_message ("Entering motif window %#x\n", xid)); - return TRUE; + return retval; } else { @@ -2491,11 +2532,11 @@ gdk_drag_get_protocol (guint32 xid, if (rootwin) { *protocol = GDK_DRAG_PROTO_ROOTWIN; - return TRUE; + return xid; } } - return FALSE; + return GDK_NONE; } void @@ -2519,17 +2560,18 @@ gdk_drag_find_window (GdkDragContext *context, if (private->dest_xid != dest) { + Window recipient; private->dest_xid = dest; /* Check if new destination accepts drags, and which protocol */ - if (gdk_drag_get_protocol (dest, protocol)) + if ((recipient = gdk_drag_get_protocol (dest, protocol))) { - *dest_window = gdk_window_lookup (dest); + *dest_window = gdk_window_lookup (recipient); if (*dest_window) gdk_window_ref (*dest_window); else - *dest_window = gdk_window_foreign_new (dest); + *dest_window = gdk_window_foreign_new (recipient); } else *dest_window = NULL; diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index c4dc41a078..9c088cbc62 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -1214,7 +1214,7 @@ motif_set_targets (GdkDragContext *context) private->motif_targets_set = 1; } -gboolean +guint32 motif_check_dest (Window win) { gboolean retval = FALSE; @@ -1225,7 +1225,7 @@ motif_check_dest (Window win) if (!motif_drag_receiver_info_atom) motif_drag_receiver_info_atom = gdk_atom_intern ("_MOTIF_DRAG_RECEIVER_INFO", FALSE); - + XGetWindowProperty (gdk_display, win, motif_drag_receiver_info_atom, 0, (sizeof(*info)+3)/4, False, AnyPropertyType, @@ -1251,7 +1251,7 @@ motif_check_dest (Window win) XFree (info); } - return retval; + return retval ? win : GDK_NONE; } @@ -2098,7 +2098,7 @@ xdnd_send_motion (GdkDragContext *context, private->drag_status = GDK_DRAG_STATUS_MOTION_WAIT; } -static gboolean +static guint32 xdnd_check_dest (Window win) { gboolean retval = FALSE; @@ -2106,31 +2106,70 @@ xdnd_check_dest (Window win) int format; unsigned long nitems, after; GdkAtom *version; + Window *proxy_data; + Window proxy; + static GdkAtom xdnd_proxy_atom = GDK_NONE; + + gint old_warnings = gdk_error_warnings; + + if (!xdnd_proxy_atom) + xdnd_proxy_atom = gdk_atom_intern ("XdndProxy", FALSE); if (!xdnd_aware_atom) xdnd_aware_atom = gdk_atom_intern ("XdndAware", FALSE); + proxy = GDK_NONE; + + gdk_error_code = 0; + gdk_error_warnings = 0; + XGetWindowProperty (gdk_display, win, - xdnd_aware_atom, 0, + xdnd_proxy_atom, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, - (guchar **)&version); - - if (type != None) + (guchar **)&proxy_data); + + if (!gdk_error_code) { - if ((format == 32) && (nitems == 1)) + if (type != None) { - if (*version == 3) - retval = TRUE; + if ((format == 32) && (nitems == 1)) + { + proxy = *proxy_data; + } + else + GDK_NOTE (DND, + g_warning ("Invalid XdndOwner property on window %ld\n", win)); + + XFree (proxy_data); } - else - GDK_NOTE (DND, - g_warning ("Invalid XdndAware property on window %ld\n", win)); - - XFree (version); + + XGetWindowProperty (gdk_display, proxy ? proxy : win, + xdnd_aware_atom, 0, + 1, False, AnyPropertyType, + &type, &format, &nitems, &after, + (guchar **)&version); + + if (!gdk_error_code && type != None) + { + if ((format == 32) && (nitems == 1)) + { + if (*version == 3) + retval = TRUE; + } + else + GDK_NOTE (DND, + g_warning ("Invalid XdndAware property on window %ld\n", win)); + + XFree (version); + } + } - return retval; + gdk_error_warnings = old_warnings; + gdk_error_code = 0; + + return retval ? (proxy ? proxy : win) : GDK_NONE; } /* Target side */ @@ -2423,21 +2462,23 @@ gdk_drag_begin (GdkWindow *window, return new_context; } -gboolean +guint32 gdk_drag_get_protocol (guint32 xid, GdkDragProtocol *protocol) { - if (xdnd_check_dest (xid)) + guint32 retval; + + if ((retval = xdnd_check_dest (xid))) { *protocol = GDK_DRAG_PROTO_XDND; GDK_NOTE (DND, g_message ("Entering dnd window %#x\n", xid)); - return TRUE; + return retval; } - else if (motif_check_dest (xid)) + else if ((retval = motif_check_dest (xid))) { *protocol = GDK_DRAG_PROTO_MOTIF; GDK_NOTE (DND, g_message ("Entering motif window %#x\n", xid)); - return TRUE; + return retval; } else { @@ -2491,11 +2532,11 @@ gdk_drag_get_protocol (guint32 xid, if (rootwin) { *protocol = GDK_DRAG_PROTO_ROOTWIN; - return TRUE; + return xid; } } - return FALSE; + return GDK_NONE; } void @@ -2519,17 +2560,18 @@ gdk_drag_find_window (GdkDragContext *context, if (private->dest_xid != dest) { + Window recipient; private->dest_xid = dest; /* Check if new destination accepts drags, and which protocol */ - if (gdk_drag_get_protocol (dest, protocol)) + if ((recipient = gdk_drag_get_protocol (dest, protocol))) { - *dest_window = gdk_window_lookup (dest); + *dest_window = gdk_window_lookup (recipient); if (*dest_window) gdk_window_ref (*dest_window); else - *dest_window = gdk_window_foreign_new (dest); + *dest_window = gdk_window_foreign_new (recipient); } else *dest_window = NULL; |