summaryrefslogtreecommitdiff
path: root/gtk/gtkdnd.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2006-02-17 16:47:29 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2006-02-17 16:47:29 +0000
commit94cb364cf6b1bb7ab2210c18676ba04cb3148634 (patch)
tree7cd44eea6e33f3e9375c061feecfd89121a420c7 /gtk/gtkdnd.c
parentba6a8de6649e034d25e7a2dba5f16a2164ef26b1 (diff)
downloadgtk+-94cb364cf6b1bb7ab2210c18676ba04cb3148634.tar.gz
DND keynav support:
2006-02-17 Matthias Clasen <mclasen@redhat.com> DND keynav support: * gtk/gtkdnd.c (gtk_drag_update_idle): Protect against info->last_event being NULL. (gtk_drag_key_cb): Handle arrow keys to move the drag icon and space or enter to drop.
Diffstat (limited to 'gtk/gtkdnd.c')
-rw-r--r--gtk/gtkdnd.c104
1 files changed, 76 insertions, 28 deletions
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index 287a6f32f5..a4f2af81c0 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -3199,8 +3199,7 @@ _gtk_drag_source_handle_event (GtkWidget *widget,
info->cursor = cursor;
}
- if (info->last_event)
- gtk_drag_add_update_idle (info);
+ gtk_drag_add_update_idle (info);
}
}
break;
@@ -3681,32 +3680,36 @@ gtk_drag_update_idle (gpointer data)
info->update_idle = 0;
- time = gtk_drag_get_event_time (info->last_event);
- gtk_drag_get_event_actions (info->last_event,
- info->button,
- info->possible_actions,
- &action, &possible_actions);
- gtk_drag_update_icon (info);
- gdk_drag_find_window_for_screen (info->context,
- info->icon_window ? info->icon_window->window : NULL,
- info->cur_screen, info->cur_x, info->cur_y,
- &dest_window, &protocol);
-
- if (!gdk_drag_motion (info->context, dest_window, protocol,
- info->cur_x, info->cur_y, action,
- possible_actions,
- time))
+ if (info->last_event)
{
- gdk_event_free ((GdkEvent *)info->last_event);
- info->last_event = NULL;
- }
+ time = gtk_drag_get_event_time (info->last_event);
+ gtk_drag_get_event_actions (info->last_event,
+ info->button,
+ info->possible_actions,
+ &action, &possible_actions);
+ gtk_drag_update_icon (info);
+ gdk_drag_find_window_for_screen (info->context,
+ info->icon_window ? info->icon_window->window : NULL,
+ info->cur_screen, info->cur_x, info->cur_y,
+ &dest_window, &protocol);
+
+ if (!gdk_drag_motion (info->context, dest_window, protocol,
+ info->cur_x, info->cur_y, action,
+ possible_actions,
+ time))
+ {
+ gdk_event_free ((GdkEvent *)info->last_event);
+ info->last_event = NULL;
+ }
- if (dest_window)
- g_object_unref (dest_window);
+ if (dest_window)
+ g_object_unref (dest_window);
+
+ selection = gdk_drag_get_selection (info->context);
+ if (selection)
+ gtk_drag_source_check_selection (info, selection, time);
- selection = gdk_drag_get_selection (info->context);
- if (selection)
- gtk_drag_source_check_selection (info, selection, time);
+ }
GDK_THREADS_LEAVE ();
@@ -3886,6 +3889,9 @@ gtk_drag_motion_cb (GtkWidget *widget,
* results:
*************************************************************/
+#define BIG_STEP 20
+#define SMALL_STEP 1
+
static gint
gtk_drag_key_cb (GtkWidget *widget,
GdkEventKey *event,
@@ -3894,15 +3900,48 @@ gtk_drag_key_cb (GtkWidget *widget,
GtkDragSourceInfo *info = (GtkDragSourceInfo *)data;
GdkModifierType state;
GdkWindow *root_window;
-
+ gint dx, dy;
+
+ dx = dy = 0;
+ state = event->state & gtk_accelerator_get_default_mod_mask ();
+
if (event->type == GDK_KEY_PRESS)
{
- if (event->keyval == GDK_Escape)
+ switch (event->keyval)
{
+ case GDK_Escape:
gtk_drag_cancel (info, event->time);
+ return TRUE;
+ case GDK_space:
+ case GDK_Return:
+ case GDK_KP_Enter:
+ case GDK_KP_Space:
+ gtk_drag_end (info, event->time);
+ gtk_drag_drop (info, event->time);
return TRUE;
+
+ case GDK_Up:
+ case GDK_KP_Up:
+ dy = (state & GDK_MOD1_MASK) ? -BIG_STEP : -SMALL_STEP;
+ break;
+
+ case GDK_Down:
+ case GDK_KP_Down:
+ dy = (state & GDK_MOD1_MASK) ? BIG_STEP : SMALL_STEP;
+ break;
+
+ case GDK_Left:
+ case GDK_KP_Left:
+ dx = (state & GDK_MOD1_MASK) ? -BIG_STEP : -SMALL_STEP;
+ break;
+
+ case GDK_Right:
+ case GDK_KP_Right:
+ dx = (state & GDK_MOD1_MASK) ? BIG_STEP : SMALL_STEP;
+ break;
}
+
}
/* Now send a "motion" so that the modifier state is updated */
@@ -3913,8 +3952,17 @@ gtk_drag_key_cb (GtkWidget *widget,
*/
root_window = gtk_widget_get_root_window (widget);
gdk_window_get_pointer (root_window, 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);
+ }
+
gtk_drag_update (info, info->cur_screen, info->cur_x, info->cur_y, (GdkEvent *)event);
return TRUE;