]> git.mdlowis.com Git - proto/labwc.git/commitdiff
output: Add output_update_usable_area/all_usable_areas()
authorJohn Lindgren <john@jlindgren.net>
Wed, 16 Nov 2022 17:43:59 +0000 (12:43 -0500)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Fri, 6 Jan 2023 13:51:46 +0000 (14:51 +0100)
Move the desktop_arrange_all_views() call outside layers_arrange() into
a new function, output_update_usable_area().  The new function currently
does exactly what layers_arrange() used to, but will be expanded in a
later commit.

Add output_update_all_usable_areas(), which is the same as calling
output_update_usable_area() for each output, but only calls
desktop_arrange_all_views() once.

Rebased and slightly modified by @Consolatis

include/labwc.h
src/layers.c
src/output.c
src/server.c

index f12d225d9e86e558a60876c8666c9e4565d2b153..bb212a6ed3c0d453026e2959d06708fae6dbf979 100644 (file)
@@ -423,6 +423,8 @@ void output_init(struct server *server);
 void output_manager_init(struct server *server);
 struct output *output_from_wlr_output(struct server *server,
        struct wlr_output *wlr_output);
+void output_update_usable_area(struct output *output);
+void output_update_all_usable_areas(struct server *server, bool enforce_view_arrange);
 struct wlr_box output_usable_area_in_layout_coords(struct output *output);
 struct wlr_box output_usable_area_from_cursor_coords(struct server *server);
 void handle_output_power_manager_set_mode(struct wl_listener *listener,
index 220914d16fa39b0d82d04913053d0ee78d6f981c..4859c402b640a59a4d91b14faa84fdecc50ea2ae 100644 (file)
@@ -35,6 +35,11 @@ arrange_one_layer(struct output *output, const struct wlr_box *full_area,
        }
 }
 
+/*
+ * To ensure outputs/views are left in a consistent state, this
+ * function should be called ONLY from output_update_usable_area()
+ * or output_update_all_usable_areas().
+ */
 void
 layers_arrange(struct output *output)
 {
@@ -43,7 +48,6 @@ layers_arrange(struct output *output)
        wlr_output_effective_resolution(output->wlr_output,
                &full_area.width, &full_area.height);
        struct wlr_box usable_area = full_area;
-       struct wlr_box old_usable_area = output->usable_area;
 
        struct server *server = output->server;
        struct wlr_scene_output *scene_output =
@@ -103,12 +107,6 @@ layers_arrange(struct output *output)
                        !seat->focused_layer->current.keyboard_interactive) {
                seat_set_focus_layer(seat, NULL);
        }
-
-       /* Finally re-arrange all views based on usable_area */
-       if (!wlr_box_equal(&old_usable_area, &usable_area)) {
-               desktop_arrange_all_views(server);
-       }
-       cursor_update_focus(output->server);
 }
 
 static void
@@ -145,7 +143,12 @@ handle_surface_commit(struct wl_listener *listener, void *data)
 
        if (committed || layer->mapped != layer_surface->mapped) {
                layer->mapped = layer_surface->mapped;
-               layers_arrange(output);
+               output_update_usable_area(output);
+               /*
+                * Update cursor focus here to ensure we
+                * enter a new/moved/resized layer surface.
+                */
+               cursor_update_focus(layer->server);
        }
 }
 
@@ -171,7 +174,7 @@ handle_unmap(struct wl_listener *listener, void *data)
        struct wlr_layer_surface_v1 *layer_surface =
                layer->scene_layer_surface->layer_surface;
        if (layer_surface->output) {
-               layers_arrange(layer_surface->output->data);
+               output_update_usable_area(layer_surface->output->data);
        }
        struct seat *seat = &layer->server->seat;
        if (seat->focused_layer == layer_surface) {
@@ -183,7 +186,11 @@ static void
 handle_map(struct wl_listener *listener, void *data)
 {
        struct lab_layer_surface *layer = wl_container_of(listener, layer, map);
-       layers_arrange(layer->scene_layer_surface->layer_surface->output->data);
+       struct wlr_output *wlr_output =
+               layer->scene_layer_surface->layer_surface->output;
+       if (wlr_output) {
+               output_update_usable_area(wlr_output->data);
+       }
        /*
         * Since moving to the wlroots scene-graph API, there is no need to
         * call wlr_surface_send_enter() from here since that will be done
@@ -374,7 +381,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
         */
        struct wlr_layer_surface_v1_state old_state = layer_surface->current;
        layer_surface->current = layer_surface->pending;
-       layers_arrange(output);
+       output_update_usable_area(output);
        layer_surface->current = old_state;
 }
 
index e80307185f3b292338828a2f2285b36bc0f38542..0726c405469b271b8b7aa9c4c8cbc45653b1fffb 100644 (file)
@@ -240,8 +240,7 @@ output_init(struct server *server)
 static void
 output_update_for_layout_change(struct server *server)
 {
-       /* Adjust window positions/sizes */
-       desktop_arrange_all_views(server);
+       output_update_all_usable_areas(server, /*enforce_view_arrange*/ true);
 
        /*
         * "Move" each wlr_output_cursor (in per-output coordinates) to
@@ -395,11 +394,6 @@ do_output_layout_change(struct server *server)
                        wlr_log(WLR_ERROR,
                                "wlr_output_manager_v1_set_configuration()");
                }
-               struct output *output;
-
-               wl_list_for_each(output, &server->outputs, link) {
-                       layers_arrange(output);
-               }
                output_update_for_layout_change(server);
        }
 }
@@ -438,6 +432,38 @@ output_from_wlr_output(struct server *server, struct wlr_output *wlr_output)
        return NULL;
 }
 
+/* returns true if usable area changed */
+static bool
+update_usable_area(struct output *output)
+{
+       struct wlr_box old = output->usable_area;
+       layers_arrange(output);
+
+       return !wlr_box_equal(&old, &output->usable_area);
+}
+
+void
+output_update_usable_area(struct output *output)
+{
+       if (update_usable_area(output)) {
+               desktop_arrange_all_views(output->server);
+       }
+}
+
+void
+output_update_all_usable_areas(struct server *server, bool enforce_view_arrange)
+{
+       bool usable_area_changed = false;
+       struct output *output;
+
+       wl_list_for_each(output, &server->outputs, link) {
+               usable_area_changed |= update_usable_area(output);
+       }
+       if (usable_area_changed || enforce_view_arrange) {
+               desktop_arrange_all_views(server);
+       }
+}
+
 struct wlr_box
 output_usable_area_in_layout_coords(struct output *output)
 {
index 5a0b19e55de06ae70a7386128c9c1dead9769286..ac6665ca4d2ca6a5758952bbf41bfc68ace00a99 100644 (file)
@@ -97,10 +97,7 @@ seat_disinhibit_input(struct seat *seat)
         * Triggers a refocus of the topmost surface layer if necessary
         * TODO: Make layer surface focus per-output based on cursor position
         */
-       struct output *output;
-       wl_list_for_each(output, &seat->server->outputs, link) {
-               layers_arrange(output);
-       }
+       output_update_all_usable_areas(seat->server, /*enforce_view_arrange*/ false);
 }
 
 static void