]> git.mdlowis.com Git - proto/labwc.git/commitdiff
SnapToRegion: Evacuate tiled views from destroying outputs
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 7 Jul 2022 17:05:54 +0000 (19:05 +0200)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Wed, 11 Jan 2023 17:52:24 +0000 (18:52 +0100)
include/regions.h
include/view.h
src/output.c
src/regions.c
src/view.c

index 180d83aa4fdddd5b243fc098a2801098c581eb69..f583a31072437e5fbbf61031474a698268b041db 100644 (file)
@@ -28,6 +28,7 @@ bool regions_available(void);
 
 void regions_init(struct server *server, struct seat *seat);
 void regions_update(struct output *output);
+void regions_evacuate_output(struct output *output);
 void regions_destroy(struct wl_list *regions);
 
 struct region *regions_from_cursor(struct server *server);
index b9c09793f380f05370c2ffdf3f8eafd9867d7fdb..c04885cc92d8d7b8b78371ecb49052ecde6d6a14 100644 (file)
@@ -50,7 +50,12 @@ struct view {
        bool minimized;
        bool maximized;
        uint32_t tiled;  /* private, enum view_edge in src/view.c */
+
+       /* Pointer to an output owned struct region, may be NULL or already free'd */
        struct region *tiled_region;
+       /* Set to region->name when tiled_region is free'd by a destroying output */
+       char *tiled_region_evacuate;
+
        struct wlr_output *fullscreen;
 
        /* geometry of the wlr_surface contained within the view */
index b30ba643cb7e829fc53f6d59bd5940132fd7ee14..c28186aca69c67690f8c14957a502340b82b4527 100644 (file)
@@ -41,6 +41,7 @@ static void
 output_destroy_notify(struct wl_listener *listener, void *data)
 {
        struct output *output = wl_container_of(listener, output, destroy);
+       regions_evacuate_output(output);
        regions_destroy(&output->regions);
        wl_list_remove(&output->link);
        wl_list_remove(&output->frame.link);
@@ -307,6 +308,7 @@ output_config_apply(struct server *server,
                }
 
                if (need_to_remove) {
+                       regions_evacuate_output(output);
                        wlr_output_layout_remove(server->output_layout, o);
                        output->scene_output = NULL;
                }
index 283334667c8771d31e0bec7f93b18e7dd9647fe6..35937a2e5ebfeb80eac1213218bf65e6aef9d946 100644 (file)
@@ -156,6 +156,26 @@ regions_update(struct output *output)
        }
 }
 
+void
+regions_evacuate_output(struct output *output)
+{
+       assert(output);
+       struct view *view;
+       struct region *region;
+
+       wl_list_for_each(view, &output->server->views, link) {
+               wl_list_for_each(region, &output->regions, link) {
+                       if (view->tiled_region == region) {
+                               if (!view->tiled_region_evacuate) {
+                                       view->tiled_region_evacuate =
+                                               xstrdup(region->name);
+                               }
+                               break;
+                       }
+               }
+       }
+}
+
 void
 regions_destroy(struct wl_list *regions)
 {
index 7e14756a92de366d5e73dd659ddbb3b332b34f5a..4e572b3a4c736c83097e8a5d2f41445267bde4a3 100644 (file)
@@ -2,6 +2,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <strings.h>
+#include "common/mem.h"
 #include "common/scene-helpers.h"
 #include "labwc.h"
 #include "menu/menu.h"
@@ -348,6 +349,29 @@ view_apply_region_geometry(struct view *view)
        assert(view);
        assert(view->tiled_region);
 
+       if (view->tiled_region_evacuate) {
+               /* View was evacuated from a destroying output */
+               struct output *output = view_output(view);
+               if (!output) {
+                       wlr_log(WLR_INFO, "apply region geometry failed: no more ouputs");
+                       return;
+               }
+
+               /* Get new output local region */
+               view->tiled_region = regions_from_name(
+                       view->tiled_region_evacuate, output);
+
+               /* Get rid of the evacuate instruction */
+               zfree(view->tiled_region_evacuate);
+
+               if (!view->tiled_region) {
+                       /* Existing region name doesn't exist in rc.xml anymore */
+                       view_set_untiled(view);
+                       view_apply_natural_geometry(view);
+                       return;
+               }
+       }
+
        /* Create a copy of the original region geometry */
        struct wlr_box geo = view->tiled_region->geo;
 
@@ -980,6 +1004,10 @@ view_destroy(struct view *view)
                seat_reset_pressed(&server->seat);
        }
 
+       if (view->tiled_region_evacuate) {
+               zfree(view->tiled_region_evacuate);
+       }
+
        osd_on_view_destroy(view);
        undecorate(view);