diff --git a/app/display/gimpdisplayshell-grab.c b/app/display/gimpdisplayshell-grab.c index 09a45e21ae..84765ef900 100644 --- a/app/display/gimpdisplayshell-grab.c +++ b/app/display/gimpdisplayshell-grab.c @@ -31,6 +31,7 @@ #include "gimpdisplayshell-grab.h" +#if 0 static GdkDevice * get_associated_pointer (GdkDevice *device) { @@ -58,45 +59,56 @@ get_associated_pointer (GdkDevice *device) return device; } +#endif gboolean gimp_display_shell_pointer_grab (GimpDisplayShell *shell, const GdkEvent *event, GdkEventMask event_mask) { + GdkDisplay *display; + GdkSeat *seat; GdkDevice *device; GdkDevice *source_device; GdkGrabStatus status; g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE); g_return_val_if_fail (event != NULL, FALSE); - g_return_val_if_fail (shell->grab_pointer == NULL, FALSE); + g_return_val_if_fail (shell->grab_seat == NULL, FALSE); source_device = gimp_devices_get_from_event (shell->display->gimp, event, &device); + display = gdk_device_get_display (device); + seat = gdk_display_get_default_seat (display); if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) { - device = get_associated_pointer (device); + /* When the source grab event was a keyboard, we want to accept + * pointer events from any pointing device. This is especially + * true on Wayland where each pointing device can be really + * independant whereas on X11, they all appear as "Virtual core + * pointer". + */ + device = NULL; source_device = NULL; } - status = gdk_device_grab (device, - gtk_widget_get_window (shell->canvas), - GDK_OWNERSHIP_APPLICATION, - FALSE, event_mask, NULL, - gdk_event_get_time (event)); + status = gdk_seat_grab (seat, + gtk_widget_get_window (shell->canvas), + GDK_SEAT_CAPABILITY_ALL_POINTING, + FALSE, NULL, + event, NULL, NULL); if (status == GDK_GRAB_SUCCESS) { + shell->grab_seat = seat; shell->grab_pointer = device; shell->grab_pointer_source = source_device; - shell->grab_pointer_time = gdk_event_get_time (event); return TRUE; } - g_printerr ("%s: gdk_device_grab(%s) failed with status %d\n", + g_printerr ("%s: gdk_seat_grab(%s) failed with status %d\n", G_STRFUNC, gdk_device_get_name (device), status); return FALSE; @@ -108,11 +120,11 @@ gimp_display_shell_pointer_ungrab (GimpDisplayShell *shell, { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (event != NULL); - g_return_if_fail (shell->grab_pointer != NULL); + g_return_if_fail (shell->grab_seat != NULL); - gdk_device_ungrab (shell->grab_pointer, shell->grab_pointer_time); + gdk_seat_ungrab (shell->grab_seat); + shell->grab_seat = NULL; shell->grab_pointer = NULL; shell->grab_pointer_source = NULL; - shell->grab_pointer_time = 0; } diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c index a68816d0c2..939ba8d9a6 100644 --- a/app/display/gimpdisplayshell-tool-events.c +++ b/app/display/gimpdisplayshell-tool-events.c @@ -410,7 +410,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, return TRUE; /* ignore enter notify while we have a grab */ - if (shell->grab_pointer) + if (shell->grab_seat) return TRUE; gimp_display_shell_proximity_in (shell); @@ -431,7 +431,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, return TRUE; /* ignore leave notify while we have a grab */ - if (shell->grab_pointer) + if (shell->grab_seat) return TRUE; gimp_display_shell_proximity_out (shell); @@ -471,7 +471,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, g_warning ("%s: FOCUS_IN but canvas has no focus", G_STRFUNC); /* ignore focus changes while we have a grab */ - if (shell->grab_pointer) + if (shell->grab_seat) return TRUE; /* press modifier keys when the canvas gets the focus */ @@ -484,7 +484,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, g_warning ("%s: FOCUS_OUT but canvas has focus", G_STRFUNC); /* ignore focus changes while we have a grab */ - if (shell->grab_pointer) + if (shell->grab_seat) return TRUE; /* release modifier keys when the canvas loses the focus */ @@ -502,7 +502,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, /* ignore new mouse events */ if (gimp->busy || shell->mod_action != GIMP_MODIFIER_ACTION_NONE || - shell->grab_pointer || + shell->grab_seat || shell->button1_release_pending) return TRUE; @@ -703,7 +703,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, * a button press we intentionally ignored because we had * a grab on another device at the time of the press */ - if (! shell->grab_pointer || shell->mod_action != GIMP_MODIFIER_ACTION_NONE) + if (! shell->grab_seat || shell->mod_action != GIMP_MODIFIER_ACTION_NONE) return TRUE; if (active_tool && @@ -1215,7 +1215,7 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, /* We need to ungrab the pointer in order to catch * button release events. */ - if (shell->grab_pointer) + if (shell->grab_seat) gimp_display_shell_pointer_ungrab (shell, event); } else @@ -1630,7 +1630,8 @@ gimp_display_shell_check_device (GimpDisplayShell *shell, event->type != GDK_KEY_RELEASE && event->type != GDK_FOCUS_CHANGE) { - if ((shell->grab_pointer && (shell->grab_pointer != grab_device)) || + if (shell->grab_seat && + (shell->grab_pointer && shell->grab_pointer != grab_device) && (shell->grab_pointer_source && (shell->grab_pointer_source != device))) { GIMP_LOG (TOOL_EVENTS, @@ -1813,7 +1814,7 @@ gimp_display_shell_stop_scrolling (GimpDisplayShell *shell, /* We may have ungrabbed the pointer when space was released while * mouse was down, to be able to catch a GDK_BUTTON_RELEASE event. */ - if (shell->grab_pointer) + if (shell->grab_seat) gimp_display_shell_pointer_ungrab (shell, event); } diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index 953e227562..f58334af93 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -193,9 +193,9 @@ struct _GimpDisplayShell gboolean size_allocate_center_image; /* the state of gimp_display_shell_tool_events() */ + GdkSeat *grab_seat; GdkDevice *grab_pointer; GdkDevice *grab_pointer_source; - guint32 grab_pointer_time; /* the state of gimp_display_shell_zoom_gesture_*() */ gdouble last_zoom_scale;