mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
wayland/xdg-shell: Handle requests after toplevel was unmanaged
A window can be unmanaged without asking the client to do it, for example as a side effect of a parent window being unmanaged, if the child window was a attached dialog. This means that the client might still make requests post updates to it after that it was unmapped. Handle this gracefully by NULL-checking the surface's MetaWindow pointer. We're not loosing any state due to this, as if the client wants to map the same surface again, it needs to either reassign it the toplevel role, or reset the xdg-toplevel, both resulting in all state being lost anyway. https://gitlab.gnome.org/GNOME/mutter/issues/240
This commit is contained in:
parent
80d420ff43
commit
5fd0f62a62
@ -191,6 +191,11 @@ xdg_toplevel_set_parent (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
MetaWindow *transient_for = NULL;
|
MetaWindow *transient_for = NULL;
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (parent_resource)
|
if (parent_resource)
|
||||||
{
|
{
|
||||||
@ -200,7 +205,7 @@ xdg_toplevel_set_parent (struct wl_client *client,
|
|||||||
transient_for = parent_surface->window;
|
transient_for = parent_surface->window;
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_set_transient_for (surface->window, transient_for);
|
meta_window_set_transient_for (window, transient_for);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -209,11 +214,16 @@ xdg_toplevel_set_title (struct wl_client *client,
|
|||||||
const char *title)
|
const char *title)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!g_utf8_validate (title, -1, NULL))
|
if (!g_utf8_validate (title, -1, NULL))
|
||||||
title = "";
|
title = "";
|
||||||
|
|
||||||
meta_window_set_title (surface->window, title);
|
meta_window_set_title (window, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -222,11 +232,16 @@ xdg_toplevel_set_app_id (struct wl_client *client,
|
|||||||
const char *app_id)
|
const char *app_id)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!g_utf8_validate (app_id, -1, NULL))
|
if (!g_utf8_validate (app_id, -1, NULL))
|
||||||
app_id = "";
|
app_id = "";
|
||||||
|
|
||||||
meta_window_set_wm_class (surface->window, app_id, app_id);
|
meta_window_set_wm_class (window, app_id, app_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -239,15 +254,20 @@ xdg_toplevel_show_window_menu (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
int monitor_scale;
|
int monitor_scale;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL))
|
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, FALSE, NULL, NULL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
monitor_scale = surface->window->monitor->scale;
|
monitor_scale = window->monitor->scale;
|
||||||
meta_window_show_menu (surface->window, META_WINDOW_MENU_WM,
|
meta_window_show_menu (window, META_WINDOW_MENU_WM,
|
||||||
surface->window->buffer_rect.x + (x * monitor_scale),
|
window->buffer_rect.x + (x * monitor_scale),
|
||||||
surface->window->buffer_rect.y + (y * monitor_scale));
|
window->buffer_rect.y + (y * monitor_scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -258,8 +278,13 @@ xdg_toplevel_move (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
float x, y;
|
float x, y;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
|
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -298,9 +323,14 @@ xdg_toplevel_resize (struct wl_client *client,
|
|||||||
{
|
{
|
||||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
gfloat x, y;
|
gfloat x, y;
|
||||||
MetaGrabOp grab_op;
|
MetaGrabOp grab_op;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
|
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -357,7 +387,11 @@ xdg_toplevel_set_maximized (struct wl_client *client,
|
|||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
MetaWindow *window = surface->window;
|
MetaWindow *window;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
meta_window_force_placement (window, TRUE);
|
meta_window_force_placement (window, TRUE);
|
||||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||||
@ -368,8 +402,13 @@ xdg_toplevel_unset_maximized (struct wl_client *client,
|
|||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH);
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -378,6 +417,11 @@ xdg_toplevel_set_fullscreen (struct wl_client *client,
|
|||||||
struct wl_resource *output_resource)
|
struct wl_resource *output_resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
if (output_resource)
|
if (output_resource)
|
||||||
{
|
{
|
||||||
@ -385,12 +429,12 @@ xdg_toplevel_set_fullscreen (struct wl_client *client,
|
|||||||
|
|
||||||
if (output)
|
if (output)
|
||||||
{
|
{
|
||||||
meta_window_move_to_monitor (surface->window,
|
meta_window_move_to_monitor (window,
|
||||||
output->logical_monitor->number);
|
output->logical_monitor->number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_window_make_fullscreen (surface->window);
|
meta_window_make_fullscreen (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -398,8 +442,13 @@ xdg_toplevel_unset_fullscreen (struct wl_client *client,
|
|||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
meta_window_unmake_fullscreen (surface->window);
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_window_unmake_fullscreen (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -407,8 +456,13 @@ xdg_toplevel_set_minimized (struct wl_client *client,
|
|||||||
struct wl_resource *resource)
|
struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource);
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
meta_window_minimize (surface->window);
|
window = surface->window;
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_window_minimize (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct xdg_toplevel_interface meta_wayland_xdg_toplevel_interface = {
|
static const struct xdg_toplevel_interface meta_wayland_xdg_toplevel_interface = {
|
||||||
|
Loading…
Reference in New Issue
Block a user