Fix X11 clients getting stuck minimized

Usually it should be enough to simply not grant a client's
minimize request, however some applications (Steam, fullscreen
games in Wine) don't wait for the compositor and minimize anyway,
getting them stuck in an unrecoverable state.
Restoring them immediately lead to heavy flickering when unfocused
on my test application (Earth Defense Force 5 via Steam), so it's
preferable to grant their request without actually minimizing and
then restoring them once they are in focus again.
This commit is contained in:
Tobias Langendorf 2020-07-18 21:26:15 +02:00 committed by Brian Ashworth
parent 66b7ac6a82
commit 4f718e6c75
2 changed files with 26 additions and 0 deletions

View file

@ -147,6 +147,7 @@ struct sway_xwayland_view {
struct wl_listener request_move; struct wl_listener request_move;
struct wl_listener request_resize; struct wl_listener request_resize;
struct wl_listener request_maximize; struct wl_listener request_maximize;
struct wl_listener request_minimize;
struct wl_listener request_configure; struct wl_listener request_configure;
struct wl_listener request_fullscreen; struct wl_listener request_fullscreen;
struct wl_listener request_activate; struct wl_listener request_activate;

View file

@ -222,6 +222,11 @@ static void set_activated(struct sway_view *view, bool activated) {
return; return;
} }
struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
if (activated && surface->minimized) {
wlr_xwayland_surface_set_minimized(surface, false);
}
wlr_xwayland_surface_activate(surface, activated); wlr_xwayland_surface_activate(surface, activated);
} }
@ -406,6 +411,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
wl_list_remove(&xwayland_view->destroy.link); wl_list_remove(&xwayland_view->destroy.link);
wl_list_remove(&xwayland_view->request_configure.link); wl_list_remove(&xwayland_view->request_configure.link);
wl_list_remove(&xwayland_view->request_fullscreen.link); wl_list_remove(&xwayland_view->request_fullscreen.link);
wl_list_remove(&xwayland_view->request_minimize.link);
wl_list_remove(&xwayland_view->request_move.link); wl_list_remove(&xwayland_view->request_move.link);
wl_list_remove(&xwayland_view->request_resize.link); wl_list_remove(&xwayland_view->request_resize.link);
wl_list_remove(&xwayland_view->request_activate.link); wl_list_remove(&xwayland_view->request_activate.link);
@ -508,6 +514,21 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
transaction_commit_dirty(); transaction_commit_dirty();
} }
static void handle_request_minimize(struct wl_listener *listener, void *data) {
struct sway_xwayland_view *xwayland_view =
wl_container_of(listener, xwayland_view, request_minimize);
struct sway_view *view = &xwayland_view->view;
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
if (!xsurface->mapped) {
return;
}
struct wlr_xwayland_minimize_event *e = data;
struct sway_seat *seat = input_manager_current_seat();
bool focused = seat_get_focus(seat) == &view->container->node;
wlr_xwayland_surface_set_minimized(xsurface, !focused && e->minimize);
}
static void handle_request_move(struct wl_listener *listener, void *data) { static void handle_request_move(struct wl_listener *listener, void *data) {
struct sway_xwayland_view *xwayland_view = struct sway_xwayland_view *xwayland_view =
wl_container_of(listener, xwayland_view, request_move); wl_container_of(listener, xwayland_view, request_move);
@ -653,6 +674,10 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
&xwayland_view->request_fullscreen); &xwayland_view->request_fullscreen);
xwayland_view->request_fullscreen.notify = handle_request_fullscreen; xwayland_view->request_fullscreen.notify = handle_request_fullscreen;
wl_signal_add(&xsurface->events.request_minimize,
&xwayland_view->request_minimize);
xwayland_view->request_minimize.notify = handle_request_minimize;
wl_signal_add(&xsurface->events.request_activate, wl_signal_add(&xsurface->events.request_activate,
&xwayland_view->request_activate); &xwayland_view->request_activate);
xwayland_view->request_activate.notify = handle_request_activate; xwayland_view->request_activate.notify = handle_request_activate;