mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 21:51:08 +00:00
gdkdnd: Add private means to commit the drag status
The way gdk_drag_status() may be called multiple times during the processing of drag and drop events throughout the widget hierarchy brings some superfluous messaging going in, esp. when it's the last request the one we want to honor, yet we emit messaging requests on all. This is barely appreciable in the X11 backend, but due to the design of the wayland protocol, quick series of changes like this it have some self-amplificating consequences which may end up flooding the connection. We can delegate this to a late "commit" call, performed within GDK event management. This way gdk_drag_status() calls may be cached and only result in windowing messaging once per ::drag-motion or ::drag-data-received event. Emitting the final status will also avoid spurious action changes on the compositor and the other peer. https://bugzilla.gnome.org/show_bug.cgi?id=763298
This commit is contained in:
parent
160a4fe5ac
commit
2923f69d3c
50
gdk/gdkdnd.c
50
gdk/gdkdnd.c
@ -764,3 +764,53 @@ gdk_drag_get_cursor (GdkDragAction action)
|
||||
drag_cursors[i].name);
|
||||
return drag_cursors[i].cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_drag_context_commit_drag_status (GdkDragContext *context)
|
||||
{
|
||||
GdkDragContextClass *context_class;
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
|
||||
g_return_if_fail (!context->is_source);
|
||||
|
||||
context_class = GDK_DRAG_CONTEXT_GET_CLASS (context);
|
||||
|
||||
if (context_class->commit_drag_status)
|
||||
context_class->commit_drag_status (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_drag_context_handle_dest_event (GdkEvent *event)
|
||||
{
|
||||
GdkDragContext *context = NULL;
|
||||
GList *l;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_DRAG_MOTION:
|
||||
case GDK_DROP_START:
|
||||
context = event->dnd.context;
|
||||
break;
|
||||
case GDK_SELECTION_NOTIFY:
|
||||
for (l = contexts; l; l = l->next)
|
||||
{
|
||||
GdkDragContext *c = l->data;
|
||||
|
||||
if (!c->is_source &&
|
||||
event->selection.selection == gdk_drag_get_selection (c))
|
||||
{
|
||||
context = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
gdk_drag_context_commit_drag_status (context);
|
||||
return TRUE;;
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ struct _GdkDragContextClass {
|
||||
const GdkEvent *event);
|
||||
void (*action_changed) (GdkDragContext *context,
|
||||
GdkDragAction action);
|
||||
|
||||
void (*commit_drag_status) (GdkDragContext *context);
|
||||
};
|
||||
|
||||
struct _GdkDragContext {
|
||||
@ -116,6 +118,7 @@ void gdk_drag_context_set_cursor (GdkDragContext *context,
|
||||
void gdk_drag_context_cancel (GdkDragContext *context,
|
||||
GdkDragCancelReason reason);
|
||||
gboolean gdk_drag_context_handle_source_event (GdkEvent *event);
|
||||
gboolean gdk_drag_context_handle_dest_event (GdkEvent *event);
|
||||
GdkCursor * gdk_drag_get_cursor (GdkDragAction action);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -71,6 +71,9 @@ _gdk_event_emit (GdkEvent *event)
|
||||
|
||||
if (_gdk_event_func)
|
||||
(*_gdk_event_func) (event, _gdk_event_data);
|
||||
|
||||
if (gdk_drag_context_handle_dest_event (event))
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
|
@ -287,8 +287,6 @@ gdk_wayland_drag_context_drag_status (GdkDragContext *context,
|
||||
|
||||
wayland_context = GDK_WAYLAND_DRAG_CONTEXT (context);
|
||||
wayland_context->selected_action = action;
|
||||
|
||||
gdk_wayland_drag_context_commit_status (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -471,6 +469,7 @@ gdk_wayland_drag_context_class_init (GdkWaylandDragContextClass *klass)
|
||||
context_class->action_changed = gdk_wayland_drag_context_action_changed;
|
||||
context_class->drop_performed = gdk_wayland_drag_context_drop_performed;
|
||||
context_class->cancel = gdk_wayland_drag_context_cancel;
|
||||
context_class->commit_drag_status = gdk_wayland_drag_context_commit_status;
|
||||
}
|
||||
|
||||
GdkDragProtocol
|
||||
|
Loading…
Reference in New Issue
Block a user