From f1ba0a89fc6af3c9a927e8a07ebfd612191b07ed Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sun, 10 Jul 2022 23:24:32 +0200 Subject: [PATCH] src/view.c: Prevent crash by killing a moving application When a view is destroyed labwc calls interactive_end(view) which may reposition the view which is partly destroyed and doesn't own any surface anymore. To prevent this scenario from happening don't call interactive_end() at all and just reset server->grabbed_view and server->input_mode directly. Before this patch, the bug could be reproduced by: - xcalc & - sleep 5; killall xcalc - move the xcalc window completely to one of the edges The change in src/xwayland.c is not required for this bug to be fixed but may prevent something similar in the future. --- src/view.c | 23 +++++++++++++++++------ src/xwayland.c | 4 ++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/view.c b/src/view.c index 6288d671..b3f5dcad 100644 --- a/src/view.c +++ b/src/view.c @@ -759,25 +759,36 @@ view_update_app_id(struct view *view) void view_destroy(struct view *view) { + struct server *server = view->server; + if (view->toplevel_handle) { wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle); } - interactive_end(view); - struct server *server = view->server; + if (server->grabbed_view == view) { + /* Application got killed while moving around */ + server->input_mode = LAB_INPUT_STATE_PASSTHROUGH; + server->grabbed_view = NULL; + } + if (server->seat.pressed.view == view) { + /* Mouse was pressed on surface and is still pressed */ server->seat.pressed.view = NULL; server->seat.pressed.surface = NULL; } if (server->cycle_view == view) { - /* If we are the current OSD selected view, cycle - * to the next because we are dying. */ + /* + * If we are the current OSD selected view, cycle + * to the next because we are dying. + */ server->cycle_view = desktop_cycle_view(server, server->cycle_view, LAB_CYCLE_DIR_BACKWARD); - /* If we cycled back to ourselves, then we have no windows. - * just remove it and close the OSD for good. */ + /* + * If we cycled back to ourselves, then we have no windows. + * just remove it and close the OSD for good. + */ if (server->cycle_view == view || !server->cycle_view) { server->cycle_view = NULL; osd_finish(server); diff --git a/src/xwayland.c b/src/xwayland.c index 9c516433..aa89ce19 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -209,6 +209,10 @@ handle_set_class(struct wl_listener *listener, void *data) static void configure(struct view *view, struct wlr_box geo) { + if (!view->xwayland_surface) { + wlr_log(WLR_ERROR, "Not configuring view without xwayland_surface"); + return; + } view->pending_move_resize.update_x = geo.x != view->x; view->pending_move_resize.update_y = geo.y != view->y; view->pending_move_resize.x = geo.x;