diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2017-05-25 01:45:18 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2017-05-25 16:25:59 +0200 |
commit | e892e20841dcb94d85a3d006f8898a29ab9a1105 (patch) | |
tree | dcdf1e9efd871e520b2085fd7ebf23dfceb0ca6a | |
parent | ace686dba90ba734daf11d07c25612a8656953b7 (diff) | |
download | gtk+-e892e20841dcb94d85a3d006f8898a29ab9a1105.tar.gz |
gtk: Rework pointer cursor selection
Check the grab widget (both explicit and implicit) and check for a cursor
from the target widget up to this grab widget. If the target widget is
outside the grab widget, only the grab wigdet's cursor will be checked.
This also means that we have to ensure the cursor is updated on button
releases, as an implicit grab being deactivated must trigger a cursor
lookup from the target widget.
-rw-r--r-- | gtk/gtkmain.c | 5 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 51 |
2 files changed, 48 insertions, 8 deletions
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 209bb5f228..5ca3729471 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1498,7 +1498,7 @@ handle_pointing_event (GdkEvent *event) target = _gtk_toplevel_pick (toplevel, x, y, NULL, NULL); old_target = update_pointer_focus_state (toplevel, event, target); if (event->type == GDK_MOTION_NOTIFY || event->type == GDK_ENTER_NOTIFY) - gtk_window_maybe_update_cursor (toplevel, target, device); + gtk_window_maybe_update_cursor (toplevel, NULL, device); if (event->type == GDK_TOUCH_BEGIN) gtk_window_set_pointer_focus_grab (toplevel, device, sequence, target); @@ -1516,6 +1516,9 @@ handle_pointing_event (GdkEvent *event) gtk_window_set_pointer_focus_grab (toplevel, device, sequence, event->type == GDK_BUTTON_PRESS ? target : NULL); + + if (event->type == GDK_BUTTON_RELEASE) + gtk_window_maybe_update_cursor (toplevel, NULL, device); break; case GDK_SCROLL: case GDK_TOUCHPAD_PINCH: diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 0a01ac8a14..1f7e3d84d3 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -11432,15 +11432,31 @@ gtk_window_set_pointer_focus_grab (GtkWindow *window, static void update_cursor (GtkWindow *toplevel, GdkDevice *device, + GtkWidget *grab_widget, GtkWidget *target) { GdkCursor *cursor = NULL; GList *widgets = NULL, *l; - while (target) + if (grab_widget && !gtk_widget_is_ancestor (target, grab_widget)) { - widgets = g_list_prepend (widgets, target); - target = _gtk_widget_get_parent (target); + /* Outside the grab widget, cursor stays to whatever the grab + * widget says. + */ + widgets = g_list_prepend (widgets, grab_widget); + } + else + { + /* Inside the grab widget or in absence of grabs, allow walking + * up the hierarchy to find out the cursor. + */ + while (target) + { + widgets = g_list_prepend (widgets, target); + if (grab_widget && target == grab_widget) + break; + target = _gtk_widget_get_parent (target); + } } for (l = widgets; l; l = l->next) @@ -11465,17 +11481,38 @@ gtk_window_maybe_update_cursor (GtkWindow *window, for (l = window->priv->foci; l; l = l->next) { GtkPointerFocus *focus = l->data; + GtkWidget *grab_widget, *target; + GtkWindowGroup *group; if (focus->sequence) continue; if (device && device != focus->device) continue; - if (widget != focus->target && - !gtk_widget_is_ancestor (focus->target, widget)) - continue; + group = gtk_window_get_group (window); + grab_widget = gtk_window_group_get_current_device_grab (group, + focus->device); + if (!grab_widget) + grab_widget = gtk_window_group_get_current_grab (group); + if (!grab_widget) + grab_widget = gtk_pointer_focus_get_implicit_grab (focus); + + target = gtk_pointer_focus_get_target (focus); + + if (widget) + { + /* Check whether the changed widget affects the current cursor + * lookups. + */ + if (grab_widget && grab_widget != widget && + !gtk_widget_is_ancestor (widget, grab_widget)) + continue; + if (grab_widget != widget && + !gtk_widget_is_ancestor (target, widget)) + continue; + } - update_cursor (focus->toplevel, focus->device, focus->target); + update_cursor (focus->toplevel, focus->device, grab_widget, target); if (device) break; |