Commit 39469f8f authored by Matthias Clasen's avatar Matthias Clasen Committed by Matthias Clasen
Browse files

Really fix the initialization of the target list.

2004-08-06  Matthias Clasen  <mclasen@redhat.com>

	* gtk/gtkdnd.c (gtk_drag_dest_set, gtk_drag_source_set): Really
	fix the initialization of the target list.

	Support XDND v5. (#10220, Owen Taylor)

	* gdk/x11/gdkdnd-x11.c: Record the XDND version and whether the
	drop was successful in the GdkDragContextPrivateX11 struct.
	(xdnd_finished_filter): Store the success status of the drop
	for an XDND version 5 interaction. For other versions, always
	assume the drop was successful.
	(xdnd_check_dest): Return the protocol version.
	(_gdk_drag_get_protocol_for_display): Return the protocol version.
	(gdk_drag_find_window_for_screen): Store the used protocol version
	in the GdkDragContext.
	(xdnd_send_enter): Send the used protocol version from the context,
	instead of hardwiring 3.
	(xdnd_enter_filter): Accept protocol versions >= 3 and store the
	used protocol version in the context.

	* gdk/gdkdnd.h:
	* gdk/x11/gdkdnd-x11.c (gdk_drag_drop_succeeded): New function
	to find out whether a drop was successful.
parent b65449a7
2004-08-06 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkdnd.c (gtk_drag_dest_set, gtk_drag_source_set): Really
fix the initialization of the target list.
Support XDND v5. (#10220, Owen Taylor)
* gdk/x11/gdkdnd-x11.c: Record the XDND version and whether the
drop was successful in the GdkDragContextPrivateX11 struct.
(xdnd_finished_filter): Store the success status of the drop
for an XDND version 5 interaction. For other versions, always
assume the drop was successful.
(xdnd_check_dest): Return the protocol version.
(_gdk_drag_get_protocol_for_display): Return the protocol version.
(gdk_drag_find_window_for_screen): Store the used protocol version
in the GdkDragContext.
(xdnd_send_enter): Send the used protocol version from the context,
instead of hardwiring 3.
(xdnd_enter_filter): Accept protocol versions >= 3 and store the
used protocol version in the context.
* gdk/gdkdnd.h:
* gdk/x11/gdkdnd-x11.c (gdk_drag_drop_succeeded): New function
to find out whether a drop was successful.
2004-07-28 Robert Ögren <gtk@roboros.com> 2004-07-28 Robert Ögren <gtk@roboros.com>
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root * gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root
......
2004-08-06 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkdnd.c (gtk_drag_dest_set, gtk_drag_source_set): Really
fix the initialization of the target list.
Support XDND v5. (#10220, Owen Taylor)
* gdk/x11/gdkdnd-x11.c: Record the XDND version and whether the
drop was successful in the GdkDragContextPrivateX11 struct.
(xdnd_finished_filter): Store the success status of the drop
for an XDND version 5 interaction. For other versions, always
assume the drop was successful.
(xdnd_check_dest): Return the protocol version.
(_gdk_drag_get_protocol_for_display): Return the protocol version.
(gdk_drag_find_window_for_screen): Store the used protocol version
in the GdkDragContext.
(xdnd_send_enter): Send the used protocol version from the context,
instead of hardwiring 3.
(xdnd_enter_filter): Accept protocol versions >= 3 and store the
used protocol version in the context.
* gdk/gdkdnd.h:
* gdk/x11/gdkdnd-x11.c (gdk_drag_drop_succeeded): New function
to find out whether a drop was successful.
2004-07-28 Robert Ögren <gtk@roboros.com> 2004-07-28 Robert Ögren <gtk@roboros.com>
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root * gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root
......
2004-08-06 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkdnd.c (gtk_drag_dest_set, gtk_drag_source_set): Really
fix the initialization of the target list.
Support XDND v5. (#10220, Owen Taylor)
* gdk/x11/gdkdnd-x11.c: Record the XDND version and whether the
drop was successful in the GdkDragContextPrivateX11 struct.
(xdnd_finished_filter): Store the success status of the drop
for an XDND version 5 interaction. For other versions, always
assume the drop was successful.
(xdnd_check_dest): Return the protocol version.
(_gdk_drag_get_protocol_for_display): Return the protocol version.
(gdk_drag_find_window_for_screen): Store the used protocol version
in the GdkDragContext.
(xdnd_send_enter): Send the used protocol version from the context,
instead of hardwiring 3.
(xdnd_enter_filter): Accept protocol versions >= 3 and store the
used protocol version in the context.
* gdk/gdkdnd.h:
* gdk/x11/gdkdnd-x11.c (gdk_drag_drop_succeeded): New function
to find out whether a drop was successful.
2004-07-28 Robert Ögren <gtk@roboros.com> 2004-07-28 Robert Ögren <gtk@roboros.com>
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root * gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root
......
2004-08-06 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkdnd.c (gtk_drag_dest_set, gtk_drag_source_set): Really
fix the initialization of the target list.
Support XDND v5. (#10220, Owen Taylor)
* gdk/x11/gdkdnd-x11.c: Record the XDND version and whether the
drop was successful in the GdkDragContextPrivateX11 struct.
(xdnd_finished_filter): Store the success status of the drop
for an XDND version 5 interaction. For other versions, always
assume the drop was successful.
(xdnd_check_dest): Return the protocol version.
(_gdk_drag_get_protocol_for_display): Return the protocol version.
(gdk_drag_find_window_for_screen): Store the used protocol version
in the GdkDragContext.
(xdnd_send_enter): Send the used protocol version from the context,
instead of hardwiring 3.
(xdnd_enter_filter): Accept protocol versions >= 3 and store the
used protocol version in the context.
* gdk/gdkdnd.h:
* gdk/x11/gdkdnd-x11.c (gdk_drag_drop_succeeded): New function
to find out whether a drop was successful.
2004-07-28 Robert Ögren <gtk@roboros.com> 2004-07-28 Robert Ögren <gtk@roboros.com>
* gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root * gdk/win32/gdkinput-win32.c (_gdk_input_other_event): Set x_root
......
2004-08-06 Matthias Clasen <mclasen@redhat.com>
* gdk/gdk-sections.txt: Add gdk_drag_drop_succeeded.
2004-08-04 Matthias Clasen <mclasen@redhat.com> 2004-08-04 Matthias Clasen <mclasen@redhat.com>
* gtk/gtk-sections.txt: Add gtk_file_chooser_[sg]et_show_hidden. * gtk/gtk-sections.txt: Add gtk_file_chooser_[sg]et_show_hidden.
......
...@@ -1142,6 +1142,7 @@ gdk_drag_context_unref ...@@ -1142,6 +1142,7 @@ gdk_drag_context_unref
GdkDragContext GdkDragContext
GdkDragAction GdkDragAction
gdk_drag_status gdk_drag_status
gdk_drag_drop_succeeded
<SUBSECTION Standard> <SUBSECTION Standard>
GDK_DRAG_CONTEXT GDK_DRAG_CONTEXT
......
...@@ -136,6 +136,7 @@ void gdk_drag_drop (GdkDragContext *context, ...@@ -136,6 +136,7 @@ void gdk_drag_drop (GdkDragContext *context,
guint32 time_); guint32 time_);
void gdk_drag_abort (GdkDragContext *context, void gdk_drag_abort (GdkDragContext *context,
guint32 time_); guint32 time_);
gboolean gdk_drag_drop_succeeded (GdkDragContext *context);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -80,9 +80,12 @@ struct _GdkDragContextPrivateX11 { ...@@ -80,9 +80,12 @@ struct _GdkDragContextPrivateX11 {
Window drop_xid; /* The (non-proxied) window that is receiving drops */ Window drop_xid; /* The (non-proxied) window that is receiving drops */
guint xdnd_targets_set : 1; /* Whether we've already set XdndTypeList */ guint xdnd_targets_set : 1; /* Whether we've already set XdndTypeList */
guint xdnd_actions_set : 1; /* Whether we've already set XdndActionList */ guint xdnd_actions_set : 1; /* Whether we've already set XdndActionList */
guint xdnd_have_actions : 1; /* Whether an XdndActionList was provided */ guint xdnd_have_actions : 1; /* Whether an XdndActionList was provided */
guint motif_targets_set : 1; /* Whether we've already set motif initiator info */ guint motif_targets_set : 1; /* Whether we've already set motif initiator info */
guint drag_status : 4; /* current status of drag */ guint drag_status : 4; /* current status of drag */
guint drop_failed : 1; /* Whether the drop was unsuccessful */
guint version; /* Xdnd protocol version */
GSList *window_caches; GSList *window_caches;
}; };
...@@ -1997,6 +2000,7 @@ xdnd_finished_filter (GdkXEvent *xev, ...@@ -1997,6 +2000,7 @@ xdnd_finished_filter (GdkXEvent *xev,
XEvent *xevent = (XEvent *)xev; XEvent *xevent = (XEvent *)xev;
guint32 dest_window = xevent->xclient.data.l[0]; guint32 dest_window = xevent->xclient.data.l[0];
GdkDragContext *context; GdkDragContext *context;
GdkDragContextPrivateX11 *private;
if (!event->any.window || if (!event->any.window ||
gdk_window_get_window_type (event->any.window) == GDK_WINDOW_FOREIGN) gdk_window_get_window_type (event->any.window) == GDK_WINDOW_FOREIGN)
...@@ -2010,6 +2014,10 @@ xdnd_finished_filter (GdkXEvent *xev, ...@@ -2010,6 +2014,10 @@ xdnd_finished_filter (GdkXEvent *xev,
if (context) if (context)
{ {
private = PRIVATE_DATA (context);
if (private->version == 5)
private->drop_failed = xevent->xclient.data.l[1] == 0;
event->dnd.type = GDK_DROP_FINISHED; event->dnd.type = GDK_DROP_FINISHED;
event->dnd.context = context; event->dnd.context = context;
g_object_ref (context); g_object_ref (context);
...@@ -2230,11 +2238,14 @@ xdnd_send_enter (GdkDragContext *context) ...@@ -2230,11 +2238,14 @@ xdnd_send_enter (GdkDragContext *context)
private->drop_xid : private->drop_xid :
GDK_DRAWABLE_XID (context->dest_window); GDK_DRAWABLE_XID (context->dest_window);
xev.xclient.data.l[0] = GDK_DRAWABLE_XID (context->source_window); xev.xclient.data.l[0] = GDK_DRAWABLE_XID (context->source_window);
xev.xclient.data.l[1] = (3 << 24); /* version */ xev.xclient.data.l[1] = (private->version << 24); /* version */
xev.xclient.data.l[2] = 0; xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0; xev.xclient.data.l[4] = 0;
GDK_NOTE(DND,
g_message ("Sending enter source window %#lx XDND protocol version %d\n",
GDK_DRAWABLE_XID (context->source_window), private->version));
if (g_list_length (context->targets) > 3) if (g_list_length (context->targets) > 3)
{ {
if (!private->xdnd_targets_set) if (!private->xdnd_targets_set)
...@@ -2364,7 +2375,8 @@ xdnd_send_motion (GdkDragContext *context, ...@@ -2364,7 +2375,8 @@ xdnd_send_motion (GdkDragContext *context,
static guint32 static guint32
xdnd_check_dest (GdkDisplay *display, xdnd_check_dest (GdkDisplay *display,
Window win) Window win,
gint *xdnd_version)
{ {
gboolean retval = FALSE; gboolean retval = FALSE;
Atom type = None; Atom type = None;
...@@ -2411,10 +2423,13 @@ xdnd_check_dest (GdkDisplay *display, ...@@ -2411,10 +2423,13 @@ xdnd_check_dest (GdkDisplay *display,
{ {
if (*version >= 3) if (*version >= 3)
retval = TRUE; retval = TRUE;
if (xdnd_version)
*xdnd_version = *version;
} }
else else
GDK_NOTE (DND, GDK_NOTE (DND,
g_warning ("Invalid XdndAware property on window %ld\n", win)); g_warning ("Invalid XdndAware "
"property on window %ld\n", win));
XFree (version); XFree (version);
} }
...@@ -2651,7 +2666,7 @@ xdnd_enter_filter (GdkXEvent *xev, ...@@ -2651,7 +2666,7 @@ xdnd_enter_filter (GdkXEvent *xev,
g_message ("XdndEnter: source_window: %#x, version: %#x", g_message ("XdndEnter: source_window: %#x, version: %#x",
source_window, version)); source_window, version));
if (version != 3) if (version < 3)
{ {
/* Old source ignore */ /* Old source ignore */
GDK_NOTE (DND, g_message ("Ignored old XdndEnter message")); GDK_NOTE (DND, g_message ("Ignored old XdndEnter message"));
...@@ -2666,7 +2681,7 @@ xdnd_enter_filter (GdkXEvent *xev, ...@@ -2666,7 +2681,7 @@ xdnd_enter_filter (GdkXEvent *xev,
new_context = gdk_drag_context_new (); new_context = gdk_drag_context_new ();
new_context->protocol = GDK_DRAG_PROTO_XDND; new_context->protocol = GDK_DRAG_PROTO_XDND;
new_context->is_source = FALSE; PRIVATE_DATA(new_context)->version = version;
new_context->source_window = gdk_window_lookup_for_display (display, source_window); new_context->source_window = gdk_window_lookup_for_display (display, source_window);
if (new_context->source_window) if (new_context->source_window)
...@@ -2956,23 +2971,12 @@ gdk_drag_begin (GdkWindow *window, ...@@ -2956,23 +2971,12 @@ gdk_drag_begin (GdkWindow *window,
return new_context; return new_context;
} }
/** static guint32
* gdk_drag_get_protocol_for_display: _gdk_drag_get_protocol_for_display (GdkDisplay *display,
* @display: the #GdkDisplay where the destination window resides guint32 xid,
* @xid: the X id of the destination window. GdkDragProtocol *protocol,
* @protocol: location where the supported DND protocol is returned. gint *version)
* @returns: the X id of the window where the drop should happen. This
* may be @xid or the X id of a proxy window, or None if @xid doesn't
* support Drag and Drop.
*
* Finds out the DND protocol supported by a window.
*
* Since: 2.2
*/
guint32
gdk_drag_get_protocol_for_display (GdkDisplay *display,
guint32 xid,
GdkDragProtocol *protocol)
{ {
GdkWindow *window; GdkWindow *window;
guint32 retval; guint32 retval;
...@@ -2989,6 +2993,7 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display, ...@@ -2989,6 +2993,7 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display,
if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL) if (g_object_get_data (G_OBJECT (window), "gdk-dnd-registered") != NULL)
{ {
*protocol = GDK_DRAG_PROTO_XDND; *protocol = GDK_DRAG_PROTO_XDND;
*version = 5;
xdnd_precache_atoms (display); xdnd_precache_atoms (display);
GDK_NOTE (DND, g_message ("Entering local Xdnd window %#x\n", xid)); GDK_NOTE (DND, g_message ("Entering local Xdnd window %#x\n", xid));
return xid; return xid;
...@@ -2997,7 +3002,7 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display, ...@@ -2997,7 +3002,7 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display,
return None; return None;
} }
if ((retval = xdnd_check_dest (display, xid))) if ((retval = xdnd_check_dest (display, xid, version)))
{ {
*protocol = GDK_DRAG_PROTO_XDND; *protocol = GDK_DRAG_PROTO_XDND;
xdnd_precache_atoms (display); xdnd_precache_atoms (display);
...@@ -3067,6 +3072,27 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display, ...@@ -3067,6 +3072,27 @@ gdk_drag_get_protocol_for_display (GdkDisplay *display,
return None; return None;
} }
/**
* gdk_drag_get_protocol_for_display:
* @display: the #GdkDisplay where the destination window resides
* @xid: the X id of the destination window.
* @protocol: location where the supported DND protocol is returned.
* @returns: the X id of the window where the drop should happen. This
* may be @xid or the X id of a proxy window, or None if @xid doesn't
* support Drag and Drop.
*
* Finds out the DND protocol supported by a window.
*
* Since: 2.2
*/
guint32
gdk_drag_get_protocol_for_display (GdkDisplay *display,
guint32 xid,
GdkDragProtocol *protocol)
{
return _gdk_drag_get_protocol_for_display (display, xid, protocol, NULL);
}
static GdkWindowCache * static GdkWindowCache *
drag_context_find_window_cache (GdkDragContext *context, drag_context_find_window_cache (GdkDragContext *context,
GdkScreen *screen) GdkScreen *screen)
...@@ -3145,7 +3171,8 @@ gdk_drag_find_window_for_screen (GdkDragContext *context, ...@@ -3145,7 +3171,8 @@ gdk_drag_find_window_for_screen (GdkDragContext *context,
* two are passed explicitely, the third implicitly through * two are passed explicitely, the third implicitly through
* protocol->dest_xid. * protocol->dest_xid.
*/ */
if ((recipient = gdk_drag_get_protocol_for_display (display, dest, protocol))) if ((recipient = _gdk_drag_get_protocol_for_display (display, dest,
protocol, &private->version)))
{ {
*dest_window = gdk_window_lookup_for_display (display, recipient); *dest_window = gdk_window_lookup_for_display (display, recipient);
if (*dest_window) if (*dest_window)
...@@ -3626,8 +3653,19 @@ gdk_drop_finish (GdkDragContext *context, ...@@ -3626,8 +3653,19 @@ gdk_drop_finish (GdkDragContext *context,
xev.xclient.window = GDK_DRAWABLE_XID (context->source_window); xev.xclient.window = GDK_DRAWABLE_XID (context->source_window);
xev.xclient.data.l[0] = GDK_DRAWABLE_XID (context->dest_window); xev.xclient.data.l[0] = GDK_DRAWABLE_XID (context->dest_window);
xev.xclient.data.l[1] = 0; if (success)
xev.xclient.data.l[2] = 0; {
g_print ("sending back success status; version %d\n",
PRIVATE_DATA (context)->version);
xev.xclient.data.l[1] = 1;
xev.xclient.data.l[2] = xdnd_action_to_atom (display,
context->action);
}
else
{
xev.xclient.data.l[1] = 0;
xev.xclient.data.l[2] = None;
}
xev.xclient.data.l[3] = 0; xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0; xev.xclient.data.l[4] = 0;
...@@ -3643,7 +3681,7 @@ gdk_drop_finish (GdkDragContext *context, ...@@ -3643,7 +3681,7 @@ gdk_drop_finish (GdkDragContext *context,
void void
gdk_window_register_dnd (GdkWindow *window) gdk_window_register_dnd (GdkWindow *window)
{ {
static gulong xdnd_version = 3; static gulong xdnd_version = 5;
MotifDragReceiverInfo info; MotifDragReceiverInfo info;
Atom motif_drag_receiver_info_atom; Atom motif_drag_receiver_info_atom;
GdkDisplay *display = gdk_drawable_get_display (window); GdkDisplay *display = gdk_drawable_get_display (window);
...@@ -3707,3 +3745,25 @@ gdk_drag_get_selection (GdkDragContext *context) ...@@ -3707,3 +3745,25 @@ gdk_drag_get_selection (GdkDragContext *context)
return GDK_NONE; return GDK_NONE;
} }
/**
* gdk_drag_drop_succeeded:
* @context: a #GdkDragContext
*
* Returns wether the dropped data has been successfully
* transferred. This function is intended to be used while
* handling a %GDK_DROP_FINISHED event, its return value is
* meaningless at other times.
*
* Return value: %TRUE if the drop was successful.
*
* Since: 2.6
**/
gboolean
gdk_drag_drop_succeeded (GdkDragContext *context)
{
g_return_val_if_fail (context != NULL, FALSE);
GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);
return !private->drop_failed;
}
...@@ -901,7 +901,10 @@ gtk_drag_dest_set (GtkWidget *widget, ...@@ -901,7 +901,10 @@ gtk_drag_dest_set (GtkWidget *widget,
site->flags = flags; site->flags = flags;
site->have_drag = FALSE; site->have_drag = FALSE;
site->target_list = NULL; if (targets)
site->target_list = gtk_target_list_new (targets, n_targets);
else
site->target_list = NULL;
site->actions = actions; site->actions = actions;
site->do_proxy = FALSE; site->do_proxy = FALSE;
site->proxy_window = NULL; site->proxy_window = NULL;
...@@ -2092,7 +2095,10 @@ gtk_drag_source_set (GtkWidget *widget, ...@@ -2092,7 +2095,10 @@ gtk_drag_source_set (GtkWidget *widget,
site->start_button_mask = start_button_mask; site->start_button_mask = start_button_mask;
site->target_list = gtk_target_list_new (targets, n_targets); if (targets)
site->target_list = gtk_target_list_new (targets, n_targets);
else
site->target_list = NULL;
site->actions = actions; site->actions = actions;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment