Commit e892e208 authored by Carlos Garnacho's avatar Carlos Garnacho

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.
parent ace686db
......@@ -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:
......
......@@ -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;
......
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