]> git.mdlowis.com Git - proto/labwc.git/commitdiff
view: Tidy up view->output/view->fullscreen redundancy
authorJohn Lindgren <john@jlindgren.net>
Wed, 15 Feb 2023 07:12:22 +0000 (02:12 -0500)
committerJohn Lindgren <john@jlindgren.net>
Fri, 17 Feb 2023 11:59:39 +0000 (06:59 -0500)
A fullscreen view currently has its output specified twice by:
  - struct output *output
  - struct wlr_output *fullscreen

view->fullscreen may also become a dangling pointer if the output is
disconnected, because view_on_output_destroy() clears view->output but
not view->fullscreen.

To eliminate the redundancy and the dangling pointer, let's change
view->fullscreen to a Boolean and rely on view->output to specify the
output.

Along the way, change a few related usages of struct wlr_output to
struct output as well.

No functional change intended.

v2: Don't allow entering fullscreen on disabled output (makes
    conditions for entering/leaving fullscreen symmetric)
v3: Use output_is_usable() helper

include/view.h
src/view.c
src/xdg.c

index e6501a9060b910ce83d600cd49480a01f7d35911..b790baeabf36b5521bf5ec005cc96778723d8f5e 100644 (file)
@@ -48,6 +48,7 @@ struct view {
        bool ssd_enabled;
        bool minimized;
        bool maximized;
+       bool fullscreen;
        uint32_t tiled;  /* private, enum view_edge in src/view.c */
 
        /* Pointer to an output owned struct region, may be NULL */
@@ -55,8 +56,6 @@ struct view {
        /* 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, as
         * currently displayed. Should be kept in sync with the
@@ -137,7 +136,7 @@ void view_set_untiled(struct view *view);
 void view_maximize(struct view *view, bool maximize,
        bool store_natural_geometry);
 void view_set_fullscreen(struct view *view, bool fullscreen,
-       struct wlr_output *wlr_output);
+       struct output *output);
 void view_toggle_maximize(struct view *view);
 void view_toggle_decorations(struct view *view);
 void view_toggle_always_on_top(struct view *view);
index 8c166bea3cefce3b514ca4c9e55431f8eb723dce..6e2af1e1f93600d5c8619054ce675336bb23d73e 100644 (file)
@@ -221,9 +221,9 @@ view_minimize(struct view *view, bool minimized)
        }
 }
 
-/* view_wlr_output - return the output that a view is mostly on */
-static struct wlr_output *
-view_wlr_output(struct view *view)
+/* view_output - return the output that a view is mostly on */
+static struct output *
+view_output(struct view *view)
 {
        assert(view);
        double closest_x, closest_y;
@@ -234,13 +234,6 @@ view_wlr_output(struct view *view)
                &closest_x, &closest_y);
        wlr_output = wlr_output_layout_output_at(view->server->output_layout,
                closest_x, closest_y);
-       return wlr_output;
-}
-
-static struct output *
-view_output(struct view *view)
-{
-       struct wlr_output *wlr_output = view_wlr_output(view);
        return output_from_wlr_output(view->server, wlr_output);
 }
 
@@ -442,16 +435,17 @@ view_apply_tiled_geometry(struct view *view, struct output *output)
 }
 
 static void
-view_apply_fullscreen_geometry(struct view *view, struct wlr_output *wlr_output)
+view_apply_fullscreen_geometry(struct view *view)
 {
-       assert(wlr_output);
-       struct output *output =
-               output_from_wlr_output(view->server, wlr_output);
+       assert(view->fullscreen);
+       assert(output_is_usable(view->output));
+
        struct wlr_box box = { 0 };
-       wlr_output_effective_resolution(wlr_output, &box.width, &box.height);
+       wlr_output_effective_resolution(view->output->wlr_output,
+               &box.width, &box.height);
        double ox = 0, oy = 0;
-       wlr_output_layout_output_coords(output->server->output_layout,
-               output->wlr_output, &ox, &oy);
+       wlr_output_layout_output_coords(view->server->output_layout,
+               view->output->wlr_output, &ox, &oy);
        box.x -= ox;
        box.y -= oy;
        view_move_resize(view, box);
@@ -679,16 +673,15 @@ view_toggle_fullscreen(struct view *view)
 }
 
 void
-view_set_fullscreen(struct view *view, bool fullscreen,
-               struct wlr_output *wlr_output)
+view_set_fullscreen(struct view *view, bool fullscreen, struct output *output)
 {
        assert(view);
-       if (fullscreen != !view->fullscreen) {
+       if (fullscreen == view->fullscreen) {
                return;
        }
-       if (!wlr_output) {
-               wlr_output = view_wlr_output(view);
-               if (!wlr_output && fullscreen) {
+       if (fullscreen && !output_is_usable(output)) {
+               output = view_output(view);
+               if (!output_is_usable(output)) {
                        /* Prevent fullscreen with no available outputs */
                        return;
                }
@@ -713,8 +706,9 @@ view_set_fullscreen(struct view *view, bool fullscreen,
                if (view->ssd_enabled) {
                        undecorate(view);
                }
-               view->fullscreen = wlr_output;
-               view_apply_fullscreen_geometry(view, view->fullscreen);
+               view->fullscreen = true;
+               view->output = output;
+               view_apply_fullscreen_geometry(view);
        } else {
                view->fullscreen = false;
                /* Re-show decorations when no longer fullscreen */
@@ -728,32 +722,29 @@ view_set_fullscreen(struct view *view, bool fullscreen,
        }
 
        /* Show fullscreen views above top-layer */
-       struct output *output =
-               output_from_wlr_output(view->server, wlr_output);
-       if (!output) {
-               return;
+       if (view->output) {
+               uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
+               wlr_scene_node_set_enabled(&view->output->layer_tree[top]->node,
+                       !fullscreen);
        }
-       uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
-       wlr_scene_node_set_enabled(&output->layer_tree[top]->node, !fullscreen);
 }
 
 void
 view_adjust_for_layout_change(struct view *view)
 {
        assert(view);
-       struct wlr_output_layout *layout = view->server->output_layout;
        if (view->fullscreen) {
-               if (wlr_output_layout_get(layout, view->fullscreen)) {
+               if (output_is_usable(view->output)) {
                        /* recompute fullscreen geometry */
-                       view_apply_fullscreen_geometry(view, view->fullscreen);
+                       view_apply_fullscreen_geometry(view);
                } else {
                        /* output is gone, exit fullscreen */
                        view_set_fullscreen(view, false, NULL);
                }
        } else if (!view_apply_special_geometry(view)) {
                /* reposition view if it's offscreen */
-               if (!wlr_output_layout_intersects(layout, NULL,
-                               &view->pending)) {
+               if (!wlr_output_layout_intersects(view->server->output_layout,
+                               NULL, &view->pending)) {
                        view_center(view);
                }
        }
@@ -771,7 +762,13 @@ void
 view_discover_output(struct view *view)
 {
        assert(view);
-       view->output = view_output(view);
+       /*
+        * Fullscreen views are tied to a particular output so don't
+        * auto-discover output for them.
+        */
+       if (!view->fullscreen) {
+               view->output = view_output(view);
+       }
 }
 
 void
@@ -1052,11 +1049,10 @@ view_destroy(struct view *view)
         * in fullscreen mode, so if that's the case, we have to re-enable it
         * here.
         */
-       if (view->fullscreen) {
-               struct output *output =
-                       output_from_wlr_output(server, view->fullscreen);
+       if (view->fullscreen && view->output) {
                uint32_t top = ZWLR_LAYER_SHELL_V1_LAYER_TOP;
-               wlr_scene_node_set_enabled(&output->layer_tree[top]->node, true);
+               wlr_scene_node_set_enabled(&view->output->layer_tree[top]->node,
+                       true);
        }
 
        /* If we spawned a window menu, close it */
index 0c793b942058c701d243524b451a06ccd4ba5ba0..1c185eeb77341a4144b01245c7048fb110053070 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -178,8 +178,9 @@ handle_request_fullscreen(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, request_fullscreen);
        struct wlr_xdg_toplevel *xdg_toplevel = xdg_toplevel_from_view(view);
-       view_set_fullscreen(view, xdg_toplevel->requested.fullscreen,
+       struct output *output = output_from_wlr_output(view->server,
                xdg_toplevel->requested.fullscreen_output);
+       view_set_fullscreen(view, xdg_toplevel->requested.fullscreen, output);
 }
 
 static void
@@ -345,8 +346,9 @@ xdg_toplevel_view_map(struct view *view)
                }
 
                if (!view->fullscreen && requested->fullscreen) {
-                       view_set_fullscreen(view, true,
-                               requested->fullscreen_output);
+                       struct output *output = output_from_wlr_output(
+                               view->server, requested->fullscreen_output);
+                       view_set_fullscreen(view, true, output);
                } else if (!view->maximized && requested->maximized) {
                        view_maximize(view, true,
                                /*store_natural_geometry*/ true);