]> git.mdlowis.com Git - proto/labwc.git/commitdiff
src/view.c: Prevent crash by killing a moving application
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Sun, 10 Jul 2022 21:24:32 +0000 (23:24 +0200)
committerJohan Malm <johanmalm@users.noreply.github.com>
Mon, 11 Jul 2022 14:58:33 +0000 (15:58 +0100)
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
src/xwayland.c

index 6288d671274d5aa5380815a7bf161438732f1720..b3f5dcadba4a1d71afb56aaf7ae0347ded4a38cf 100644 (file)
@@ -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);
index 9c5164337df894ab880dd5745b28968b2dbae06d..aa89ce19387457eb957cc3899d987c64e1fbe827 100644 (file)
@@ -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;