wayland: Allow grabless xdg_popups

xdg_shell v6 allows grabless popups, whose behavior is not that
different from override redirect windows with no grab to take
keyboard input (and pointer events outside).

This means we can relax the requirement to have a grab before
creating an xdg_popup. The warning is still useful to have so
people stop relying on gdk_window_show();gdk_device_grab() being
an ok pattern to popup a window, it's been moved to wayland
implementation of gdk_device_grab() instead, so we warn if trying
to grab a GDK_WINDOW_TEMP window that's already visible.

https://bugzilla.gnome.org/show_bug.cgi?id=771694
This commit is contained in:
Carlos Garnacho 2016-10-18 19:18:14 +02:00
parent e75314ec17
commit 2dfaae6737
2 changed files with 15 additions and 25 deletions

View File

@ -740,6 +740,15 @@ gdk_wayland_device_grab (GdkDevice *device,
GdkWindow *prev_focus = gdk_wayland_device_get_focus (device);
GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP &&
gdk_window_is_visible (window))
{
g_warning ("Window %p is already mapped at the time of grabbing. "
"gdk_seat_grab() should be used to simultanously grab input "
"and show this popup. You may find oddities ahead.",
window);
}
if (prev_focus != window)
device_emit_grab_crossing (device, prev_focus, window, GDK_CROSSING_GRAB, time_);

View File

@ -2072,9 +2072,12 @@ gdk_wayland_window_create_xdg_popup (GdkWindow *window,
zxdg_positioner_v6_destroy (positioner);
gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
zxdg_popup_v6_grab (impl->display_server.xdg_popup, seat, serial);
if (seat)
{
gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
zxdg_popup_v6_grab (impl->display_server.xdg_popup, seat, serial);
}
wl_surface_commit (impl->display_server.wl_surface);
@ -2123,18 +2126,6 @@ find_grab_input_seat (GdkWindow *window, GdkWindow *transient_for)
return NULL;
}
static struct wl_seat *
find_default_input_seat (GdkWindow *window)
{
GdkDisplay *display;
GdkSeat *seat;
display = gdk_window_get_display (window);
seat = gdk_display_get_default_seat (display);
return gdk_wayland_seat_get_wl_seat (seat);
}
static gboolean
should_be_mapped (GdkWindow *window)
{
@ -2330,16 +2321,6 @@ gdk_wayland_window_map (GdkWindow *window)
else
{
grab_input_seat = find_grab_input_seat (window, transient_for);
if (!grab_input_seat)
{
g_warning ("No grabbed seat found, using the default one in "
"order to map popup window %p. You may find oddities "
"ahead, gdk_seat_grab() should be used to "
"simultaneously grab input and show this popup",
window);
grab_input_seat = find_default_input_seat (window);
}
}
if (!create_fallback)