[gtk+/xi2] Make GTK+ DND use device-aware API.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2] Make GTK+ DND use device-aware API.
- Date: Sat, 9 Jan 2010 12:46:57 +0000 (UTC)
commit 9d74acfa5753fda367990a5bd0a56ed7f9538eec
Author: Carlos Garnacho <carlos gnome org>
Date: Sat Jan 9 13:36:43 2010 +0100
Make GTK+ DND use device-aware API.
Now the device attached to the GdkDragContext is used to perform device grabs
and such. The only pending point is about keyboard navigation, the X11 code
uses passive grabs and XEvent modifications to have certain key combinations
redirected to the ipc widget, but XGE/XI2 provides allocated events, which are
later freed before GDK gets to translate the event, so modifying the XI2 event
isn't going to work... Active grabs are used at the moment.
gtk/gtkdnd.c | 144 ++++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 100 insertions(+), 44 deletions(-)
---
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index c3a95d8..ec068d3 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -398,8 +398,12 @@ gtk_drag_get_ipc_widget (GtkWidget *widget)
return result;
}
-
-#ifdef GDK_WINDOWING_X11
+/* FIXME: modifying the XEvent window as in root_key_filter() isn't
+ * going to work with XGE/XI2, since the actual event to handle would
+ * be allocated/freed before GDK gets to translate the event.
+ * Active grabs on the keyboard are used instead at the moment...
+ */
+#if defined (GDK_WINDOWING_X11) && !defined (XINPUT_2)
/*
* We want to handle a handful of keys during DND, e.g. Escape to abort.
@@ -418,7 +422,7 @@ root_key_filter (GdkXEvent *xevent,
GdkEvent *event,
gpointer data)
{
- XEvent *ev = (XEvent *)xevent;
+ XEvent *ev = (XEvent *) xevent;
if ((ev->type == KeyPress || ev->type == KeyRelease) &&
ev->xkey.root == ev->xkey.window)
@@ -458,6 +462,7 @@ static GrabKey grab_keys[] = {
static void
grab_dnd_keys (GtkWidget *widget,
+ GdkDevice *device,
guint32 time)
{
guint i;
@@ -488,6 +493,7 @@ grab_dnd_keys (GtkWidget *widget,
static void
ungrab_dnd_keys (GtkWidget *widget,
+ GdkDevice *device,
guint32 time)
{
guint i;
@@ -513,23 +519,28 @@ ungrab_dnd_keys (GtkWidget *widget,
gdk_error_trap_pop ();
}
-#else
+#else /* GDK_WINDOWING_X11 && !XINPUT_2 */
static void
grab_dnd_keys (GtkWidget *widget,
+ GdkDevice *device,
guint32 time)
{
- gdk_keyboard_grab (widget->window, FALSE, time);
+ gdk_device_grab (device, widget->window,
+ GDK_OWNERSHIP_APPLICATION, FALSE,
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
+ NULL, time);
}
static void
ungrab_dnd_keys (GtkWidget *widget,
+ GdkDevice *device,
guint32 time)
{
- gdk_display_keyboard_ungrab (gtk_widget_get_display (widget), time);
+ gdk_device_ungrab (device, time);
}
-#endif
+#endif /* GDK_WINDOWING_X11 */
/***************************************************************
@@ -545,9 +556,20 @@ gtk_drag_release_ipc_widget (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GdkScreen *screen = gtk_widget_get_screen (widget);
+ GdkDragContext *context = g_object_get_data (G_OBJECT (widget), "drag-context");
GSList *drag_widgets = g_object_get_data (G_OBJECT (screen),
"gtk-dnd-ipc-widgets");
- ungrab_dnd_keys (widget, GDK_CURRENT_TIME);
+ GdkDevice *pointer, *keyboard;
+
+ if (context)
+ {
+ pointer = gdk_drag_context_get_device (context);
+ keyboard = gdk_device_get_associated_device (pointer);
+
+ if (keyboard)
+ ungrab_dnd_keys (widget, keyboard, GDK_CURRENT_TIME);
+ }
+
if (window->group)
gtk_window_group_remove_window (window->group, window);
drag_widgets = g_slist_prepend (drag_widgets, widget);
@@ -940,11 +962,13 @@ gtk_drag_update_cursor (GtkDragSourceInfo *info)
if (cursor != info->cursor)
{
- gdk_pointer_grab (info->ipc_widget->window, FALSE,
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_RELEASE_MASK,
- NULL,
- cursor, info->grab_time);
+ GdkDevice *pointer;
+
+ pointer = gdk_drag_context_get_device (info->context);
+ gdk_device_grab (pointer, info->ipc_widget->window,
+ GDK_OWNERSHIP_APPLICATION, FALSE,
+ GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+ cursor, info->grab_time);
info->cursor = cursor;
}
}
@@ -2364,7 +2388,9 @@ gtk_drag_begin_internal (GtkWidget *widget,
GdkDragContext *context;
GtkWidget *ipc_widget;
GdkCursor *cursor;
-
+ GdkDevice *pointer, *keyboard;
+
+ pointer = keyboard = NULL;
ipc_widget = gtk_drag_get_ipc_widget (widget);
gtk_drag_get_event_actions (event, button, actions,
@@ -2375,18 +2401,39 @@ gtk_drag_begin_internal (GtkWidget *widget,
NULL);
if (event)
- time = gdk_event_get_time (event);
+ {
+ time = gdk_event_get_time (event);
+ pointer = gdk_event_get_device (event);
- if (gdk_pointer_grab (ipc_widget->window, FALSE,
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_RELEASE_MASK, NULL,
- cursor, time) != GDK_GRAB_SUCCESS)
+ if (pointer->source == GDK_SOURCE_KEYBOARD)
+ {
+ keyboard = pointer;
+ pointer = gdk_device_get_associated_device (keyboard);
+ }
+ else
+ keyboard = gdk_device_get_associated_device (pointer);
+ }
+ else
+ {
+ pointer = gdk_display_get_core_pointer (gtk_widget_get_display (widget));
+ keyboard = gdk_device_get_associated_device (pointer);
+ }
+
+ if (!pointer)
+ return NULL;
+
+ if (gdk_device_grab (pointer, ipc_widget->window,
+ GDK_OWNERSHIP_APPLICATION, FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ cursor, time) != GDK_GRAB_SUCCESS)
{
gtk_drag_release_ipc_widget (ipc_widget);
return NULL;
}
- grab_dnd_keys (ipc_widget, time);
+ if (keyboard)
+ grab_dnd_keys (ipc_widget, keyboard, time);
/* We use a GTK grab here to override any grabs that the widget
* we are dragging from might have held
@@ -2405,6 +2452,7 @@ gtk_drag_begin_internal (GtkWidget *widget,
source_widgets = g_slist_prepend (source_widgets, ipc_widget);
context = gdk_drag_begin (ipc_widget->window, targets);
+ gdk_drag_context_set_device (context, pointer);
g_list_free (targets);
info = gtk_drag_get_source_info (context, TRUE);
@@ -2436,10 +2484,10 @@ gtk_drag_begin_internal (GtkWidget *widget,
info->cur_x = event->motion.x_root;
info->cur_y = event->motion.y_root;
}
- else
+ else
{
- gdk_display_get_pointer (gtk_widget_get_display (widget),
- &info->cur_screen, &info->cur_x, &info->cur_y, NULL);
+ gdk_display_get_device_state (gtk_widget_get_display (widget), pointer,
+ &info->cur_screen, &info->cur_x, &info->cur_y, NULL);
}
g_signal_emit_by_name (widget, "drag-begin", info->context);
@@ -2495,11 +2543,11 @@ gtk_drag_begin_internal (GtkWidget *widget,
if (cursor != info->cursor)
{
- gdk_pointer_grab (widget->window, FALSE,
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_RELEASE_MASK,
- NULL,
- cursor, time);
+ gdk_device_grab (pointer, widget->window,
+ GDK_OWNERSHIP_APPLICATION, FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ cursor, time);
info->cursor = cursor;
}
}
@@ -3500,11 +3548,13 @@ _gtk_drag_source_handle_event (GtkWidget *widget,
info);
if (info->cursor != cursor)
{
- gdk_pointer_grab (widget->window, FALSE,
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_RELEASE_MASK,
- NULL,
- cursor, info->grab_time);
+ GdkDevice *pointer;
+
+ pointer = gdk_drag_context_get_device (context);
+ gdk_device_grab (pointer, widget->window,
+ GDK_OWNERSHIP_APPLICATION, FALSE,
+ GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+ cursor, info->grab_time);
info->cursor = cursor;
}
@@ -4094,7 +4144,10 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time)
{
GdkEvent *send_event;
GtkWidget *source_widget = info->widget;
- GdkDisplay *display = gtk_widget_get_display (source_widget);
+ GdkDevice *pointer, *keyboard;
+
+ pointer = gdk_drag_context_get_device (info->context);
+ keyboard = gdk_device_get_associated_device (pointer);
if (info->update_idle)
{
@@ -4126,8 +4179,8 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time)
gtk_drag_key_cb,
info);
- gdk_display_pointer_ungrab (display, time);
- ungrab_dnd_keys (info->ipc_widget, time);
+ gdk_device_ungrab (pointer, time);
+ ungrab_dnd_keys (info->ipc_widget, keyboard, time);
gtk_grab_remove (info->ipc_widget);
/* Send on a release pair to the original
@@ -4146,7 +4199,7 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time)
send_event->button.axes = NULL;
send_event->button.state = 0;
send_event->button.button = info->button;
- send_event->button.device = gdk_display_get_core_pointer (display);
+ send_event->button.device = pointer;
send_event->button.x_root = 0;
send_event->button.y_root = 0;
@@ -4192,15 +4245,16 @@ gtk_drag_motion_cb (GtkWidget *widget,
if (event->is_hint)
{
GdkDisplay *display = gtk_widget_get_display (widget);
-
- gdk_display_get_pointer (display, &screen, &x_root, &y_root, NULL);
+
+ gdk_display_get_device_state (display, event->device,
+ &screen, &x_root, &y_root, NULL);
event->x_root = x_root;
event->y_root = y_root;
}
else
screen = gdk_event_get_screen ((GdkEvent *)event);
- gtk_drag_update (info, screen, event->x_root, event->y_root, (GdkEvent *)event);
+ gtk_drag_update (info, screen, event->x_root, event->y_root, (GdkEvent *) event);
return TRUE;
}
@@ -4224,10 +4278,12 @@ gtk_drag_key_cb (GtkWidget *widget,
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
GdkModifierType state;
GdkWindow *root_window;
+ GdkDevice *pointer;
gint dx, dy;
dx = dy = 0;
state = event->state & gtk_accelerator_get_default_mod_mask ();
+ pointer = gdk_device_get_associated_device (event->device);
if (event->type == GDK_KEY_PRESS)
{
@@ -4276,16 +4332,16 @@ gtk_drag_key_cb (GtkWidget *widget,
* that would be overkill.
*/
root_window = gtk_widget_get_root_window (widget);
- gdk_window_get_pointer (root_window, NULL, NULL, &state);
+ gdk_window_get_device_position (root_window, pointer, NULL, NULL, &state);
event->state = state;
if (dx != 0 || dy != 0)
{
info->cur_x += dx;
info->cur_y += dy;
- gdk_display_warp_pointer (gtk_widget_get_display (widget),
- gtk_widget_get_screen (widget),
- info->cur_x, info->cur_y);
+ gdk_display_warp_device (gtk_widget_get_display (widget), pointer,
+ gtk_widget_get_screen (widget),
+ info->cur_x, info->cur_y);
}
gtk_drag_update (info, info->cur_screen, info->cur_x, info->cur_y, (GdkEvent *)event);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]