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.
This commit is contained in:
Owen Taylor 1998-11-18 17:00:48 +00:00 committed by Owen Taylor
parent fb6a7ccb92
commit 8715d1c1b3
11 changed files with 222 additions and 78 deletions

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -1,3 +1,12 @@
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.
Tue Nov 17 1998 The Rasterman <raster@redhat.com>
* gdk/gdk.h, gdk/gdkwindow.c: Added gdk_window_get_deskrelative_origin
function to correctly determine gdk window position relative to
@ -81,8 +90,7 @@ Tue Nov 17 00:06:29 1998 Lars Hamann <lars@gtk.org>
Mon Nov 16 15:10:33 1998 Owen Taylor <otaylor@redhat.com>
* gtk/gtktext.c: Optimizations for moving point n
places.
* gtk/gtktext.c: Optimizations for [advance/decrement]_mark_n.
(gtk-mailund-980718-0, Thomas Mailund Jensen <mailund@daimi.aau.dk>)
* gtk/gtkfixed.c: Removed gtk_fixed_umap, which was

View File

@ -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,

View File

@ -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)
{
if ((format == 32) && (nitems == 1))
{
if (*version == 3)
retval = TRUE;
}
else
GDK_NOTE (DND,
g_warning ("Invalid XdndAware property on window %ld\n", win));
(guchar **)&proxy_data);
XFree (version);
if (!gdk_error_code)
{
if (type != None)
{
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);
}
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;

View File

@ -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)
{
if ((format == 32) && (nitems == 1))
{
if (*version == 3)
retval = TRUE;
}
else
GDK_NOTE (DND,
g_warning ("Invalid XdndAware property on window %ld\n", win));
(guchar **)&proxy_data);
XFree (version);
if (!gdk_error_code)
{
if (type != None)
{
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);
}
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;

View File

@ -121,6 +121,7 @@ struct _GtkDragFindData {
GdkDragContext *context;
GtkDragDestInfo *info;
gboolean found;
gboolean toplevel;
gboolean (*callback) (GtkWidget *widget, GdkDragContext *context,
gint x, gint y, guint32 time);
guint32 time;
@ -829,9 +830,10 @@ gtk_drag_dest_handle_event (GtkWidget *toplevel,
data.x = event->dnd.x_root - tx;
data.y = event->dnd.y_root - ty;
data.context = context;
data.context = context;
data.info = info;
data.found = FALSE;
data.toplevel = TRUE;
data.callback = (event->type == GDK_DRAG_MOTION) ?
gtk_drag_dest_motion : gtk_drag_dest_drop;
data.time = event->dnd.time;
@ -1048,9 +1050,10 @@ gtk_drag_find_widget (GtkWidget *widget,
}
}
if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
(data->x < new_allocation.x + new_allocation.width) &&
(data->y < new_allocation.y + new_allocation.height))
if (data->toplevel ||
((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
(data->x < new_allocation.x + new_allocation.width) &&
(data->y < new_allocation.y + new_allocation.height)))
{
/* First, check if the drag is in a valid drop site in
* one of our children
@ -1062,6 +1065,7 @@ gtk_drag_find_widget (GtkWidget *widget,
new_data.x -= x_offset;
new_data.y -= y_offset;
new_data.found = FALSE;
new_data.toplevel = FALSE;
gtk_container_foreach (GTK_CONTAINER (widget),
(GtkCallback)gtk_drag_find_widget,