]> git.mdlowis.com Git - proto/labwc.git/commitdiff
ssd: Allocate `struct ssd` and `struct ssd_hover_state` separately
authorJohn Lindgren <john@jlindgren.net>
Sat, 26 Nov 2022 21:46:28 +0000 (16:46 -0500)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sun, 27 Nov 2022 06:48:41 +0000 (06:48 +0000)
- Store a pointer to the `struct view` in `struct ssd`
- Pass `struct ssd *` instead of `struct view *` to ssd functions
- Add `ssd_get_margin()` convenience function

15 files changed:
include/labwc.h
include/ssd.h
include/view.h
src/action.c
src/cursor.c
src/debug.c
src/desktop.c
src/resistance.c
src/server.c
src/ssd/ssd.c
src/ssd/ssd_border.c
src/ssd/ssd_extents.c
src/ssd/ssd_titlebar.c
src/view.c
src/xdg.c

index 788bfa0ec960eb5cbf5d06b58322df2ecc74074c..0f8217d61fc1fef54ad8bb485fd265b0bd97fd20 100644 (file)
@@ -50,7 +50,6 @@
 #include "cursor.h"
 #include "config/keybind.h"
 #include "config/rcxml.h"
-#include "ssd.h"
 #if HAVE_NLS
 #include <libintl.h>
 #include <locale.h>
@@ -232,7 +231,7 @@ struct server {
 
        /* SSD state */
        struct view *focused_view;
-       struct ssd_hover_state ssd_hover_state;
+       struct ssd_hover_state *ssd_hover_state;
 
        /* Tree for all non-layer xdg/xwayland-shell surfaces */
        struct wlr_scene_tree *view_tree;
index 667803907d2a908abd68dfbfbfa33a6bccd7a844..21821ee7273af56d0bd73eb472709f4d088b985b 100644 (file)
@@ -80,6 +80,7 @@ struct ssd_state_title_width {
 };
 
 struct ssd {
+       struct view *view;
        struct wlr_scene_tree *tree;
 
        /*
@@ -144,12 +145,23 @@ struct ssd_hover_state {
        struct wlr_scene_node *node;
 };
 
-/* Public SSD API */
-void ssd_create(struct view *view, bool active);
-void ssd_set_active(struct view *view, bool active);
-void ssd_update_title(struct view *view);
-void ssd_update_geometry(struct view *view);
-void ssd_destroy(struct view *view);
+/*
+ * Public SSD API
+ *
+ * For convenience in dealing with non-SSD views, this API allows NULL
+ * ssd/button/node arguments and attempts to do something sensible in
+ * that case (e.g. no-op/return default values).
+ *
+ * NULL scene/view arguments are not allowed.
+ */
+struct ssd *ssd_create(struct view *view, bool active);
+struct border ssd_get_margin(const struct ssd *ssd);
+void ssd_set_active(struct ssd *ssd, bool active);
+void ssd_update_title(struct ssd *ssd);
+void ssd_update_geometry(struct ssd *ssd);
+void ssd_destroy(struct ssd *ssd);
+
+struct ssd_hover_state *ssd_hover_state_new(void);
 void ssd_update_button_hover(struct wlr_scene_node *node,
        struct ssd_hover_state *hover_state);
 
index a174b1b70ab2a9ddd1d4cfcc496fe00b8af3cc1d..1cbe8b22492631dc24cd1e745eaf1f9f54a203e8 100644 (file)
@@ -7,7 +7,6 @@
 #include <stdint.h>
 #include <wayland-util.h>
 #include <wlr/util/box.h>
-#include "ssd.h"
 
 /*
  * In labwc, a view is a container for surfaces which can be moved around by
@@ -21,6 +20,7 @@ enum view_type {
 #endif
 };
 
+struct view;
 struct view_impl {
        void (*configure)(struct view *view, struct wlr_box geo);
        void (*close)(struct view *view);
@@ -65,7 +65,7 @@ struct view {
                uint32_t configure_serial;
        } pending_move_resize;
 
-       struct ssd ssd;
+       struct ssd *ssd;
 
        struct wlr_foreign_toplevel_handle_v1 *toplevel_handle;
        struct wl_listener toplevel_handle_request_maximize;
index 879f3e9b71b0ede6e14ea68b9903bf9c5ef8bc8f..b6440a5a6a4ef20e6dcfe88f7823607d9073f8e1 100644 (file)
@@ -161,7 +161,7 @@ show_menu(struct server *server, struct view *view, const char *menu_name)
                if (!view) {
                        return;
                }
-               enum ssd_part_type type = ssd_at(&view->ssd, server->scene,
+               enum ssd_part_type type = ssd_at(view->ssd, server->scene,
                        server->seat.cursor->x, server->seat.cursor->y);
                if (type == LAB_SSD_BUTTON_WINDOW_MENU) {
                        force_menu_top_left = true;
index 3e1cb2c442fa61c218e85a4f4877ac8629396e80..3cfc6b1cf49a5b527054e9a50d076822c4499320 100644 (file)
@@ -330,7 +330,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx,
        struct seat *seat = &server->seat;
        struct wlr_seat *wlr_seat = seat->seat;
 
-       ssd_update_button_hover(ctx->node, &server->ssd_hover_state);
+       ssd_update_button_hover(ctx->node, server->ssd_hover_state);
 
        if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
                /*
index 8be927beb9cffca29b23e682022a75286a68637b..83754a3d913c3c974fcc9bd542ab68b01a4b7ca4 100644 (file)
@@ -61,7 +61,7 @@ get_view_part(struct view *view, struct wlr_scene_node *node)
                return "view->scene_node";
        }
        if (view) {
-               return ssd_debug_get_node_name(&view->ssd, node);
+               return ssd_debug_get_node_name(view->ssd, node);
        }
        return NULL;
 }
@@ -159,7 +159,7 @@ dump_tree(struct server *server, struct wlr_scene_node *node,
 
        if ((IGNORE_MENU && node == &server->menu_tree->node)
                        || (IGNORE_SSD && view
-                       && ssd_debug_is_root_node(&view->ssd, node))) {
+                       && ssd_debug_is_root_node(view->ssd, node))) {
                printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', "<skipping children>");
                return;
        }
index 895c9011e5b719121ca47748a062df32864a96c6..99948d94ebe02e6a2f705ae7798f2e713f78b123 100644 (file)
@@ -339,7 +339,7 @@ get_cursor_context(struct server *server)
                        case LAB_NODE_DESC_VIEW:
                        case LAB_NODE_DESC_XDG_POPUP:
                                ret.view = desc->data;
-                               ret.type = ssd_get_part_type(&ret.view->ssd, ret.node);
+                               ret.type = ssd_get_part_type(ret.view->ssd, ret.node);
                                if (ret.type == LAB_SSD_CLIENT) {
                                        ret.surface = lab_wlr_surface_from_node(ret.node);
                                }
index 9a09097421dd9ba92e1c7da94465d34a9c55123a..2f40ca15d4418be21644e3add60a308bbce2798c 100644 (file)
@@ -41,7 +41,7 @@ resistance_move_apply(struct view *view, double *x, double *y)
        struct wlr_box tgeom = {.x = *x, .y = *y, .width = view->w,
                .height = view->h};
        struct output *output;
-       struct border border = view->ssd.margin;
+       struct border border = ssd_get_margin(view->ssd);
        struct edges view_edges; /* The edges of the current view */
        struct edges target_edges; /* The desired edges */
        struct edges other_edges; /* The edges of the monitor/other view */
@@ -112,7 +112,7 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo)
                .height = view->h};
        struct wlr_box tgeom = {.x = new_view_geo->x, .y = new_view_geo->y,
                .width = new_view_geo->width, .height = new_view_geo->height};
-       struct border border = view->ssd.margin;
+       struct border border = ssd_get_margin(view->ssd);
        struct edges view_edges; /* The edges of the current view */
        struct edges target_edges; /* The desired edges */
        struct edges other_edges; /* The edges of the monitor/other view */
index a1f40f998ddb24082cf286fbb9832495b32802ba..457960c05de7af0b1ed377ed314c690d115d3c2d 100644 (file)
@@ -221,6 +221,8 @@ server_init(struct server *server)
        wl_list_init(&server->views);
        wl_list_init(&server->unmanaged_surfaces);
 
+       server->ssd_hover_state = ssd_hover_state_new();
+
        server->scene = wlr_scene_create();
        if (!server->scene) {
                wlr_log(WLR_ERROR, "unable to create scene");
index 01dd66ccf84e9b5f1768b6fba7a85bd76b956062..7f987f21f9e4b1156c3613444b9c4526a1a33aa1 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <assert.h>
+#include "common/mem.h"
 #include "common/scene-helpers.h"
 #include "labwc.h"
 #include "ssd.h"
@@ -16,6 +17,7 @@
 struct border
 ssd_thickness(struct view *view)
 {
+       assert(view);
        /*
         * Check preconditions for displaying SSD. Note that this
         * needs to work even before ssd_create() has been called.
@@ -35,6 +37,7 @@ ssd_thickness(struct view *view)
 struct wlr_box
 ssd_max_extents(struct view *view)
 {
+       assert(view);
        struct border border = ssd_thickness(view);
        return (struct wlr_box){
                .x = view->x - border.left,
@@ -61,7 +64,7 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
        } else if (node->type == WLR_SCENE_NODE_BUFFER
                        && lab_wlr_surface_from_node(node)) {
                return LAB_SSD_CLIENT;
-       } else if (!ssd->tree) {
+       } else if (!ssd) {
                return LAB_SSD_NONE;
        }
 
@@ -114,6 +117,7 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
 enum ssd_part_type
 ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly)
 {
+       assert(scene);
        double sx, sy;
        struct wlr_scene_node *node = wlr_scene_node_at(
                &scene->tree.node, lx, ly, &sx, &sy);
@@ -145,34 +149,43 @@ ssd_resize_edges(enum ssd_part_type type)
        }
 }
 
-void
+struct ssd *
 ssd_create(struct view *view, bool active)
 {
-       struct ssd *ssd = &view->ssd;
-       assert(!ssd->tree);
+       assert(view);
+       struct ssd *ssd = znew(*ssd);
 
+       ssd->view = view;
        ssd->tree = wlr_scene_tree_create(view->scene_tree);
        wlr_scene_node_lower_to_bottom(&ssd->tree->node);
        ssd_extents_create(ssd);
        ssd_border_create(ssd);
        ssd_titlebar_create(ssd);
        ssd->margin = ssd_thickness(view);
-       ssd_set_active(view, active);
+       ssd_set_active(ssd, active);
 
        ssd->state.width = view->w;
        ssd->state.height = view->h;
        ssd->state.x = view->x;
        ssd->state.y = view->y;
+
+       return ssd;
+}
+
+struct border
+ssd_get_margin(const struct ssd *ssd)
+{
+       return ssd ? ssd->margin : (struct border){ 0 };
 }
 
 void
-ssd_update_geometry(struct view *view)
+ssd_update_geometry(struct ssd *ssd)
 {
-       struct ssd *ssd = &view->ssd;
-       if (!ssd->tree) {
+       if (!ssd) {
                return;
        }
 
+       struct view *view = ssd->view;
        if (view->w == ssd->state.width && view->h == ssd->state.height) {
                if (view->x != ssd->state.x || view->y != ssd->state.y) {
                        /* Dynamically resize extents based on position and usable_area */
@@ -193,16 +206,16 @@ ssd_update_geometry(struct view *view)
 }
 
 void
-ssd_destroy(struct view *view)
+ssd_destroy(struct ssd *ssd)
 {
-       struct ssd *ssd = &view->ssd;
-       if (!ssd->tree) {
+       if (!ssd) {
                return;
        }
 
        /* Maybe reset hover view */
+       struct view *view = ssd->view;
        struct ssd_hover_state *hover_state;
-       hover_state = &view->server->ssd_hover_state;
+       hover_state = view->server->ssd_hover_state;
        if (hover_state->view == view) {
                hover_state->view = NULL;
                hover_state->node = NULL;
@@ -213,8 +226,8 @@ ssd_destroy(struct view *view)
        ssd_border_destroy(ssd);
        ssd_extents_destroy(ssd);
        wlr_scene_node_destroy(&ssd->tree->node);
-       ssd->tree = NULL;
-       ssd->margin = (struct border){ 0 };
+
+       free(ssd);
 }
 
 bool
@@ -256,10 +269,9 @@ ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate)
 }
 
 void
-ssd_set_active(struct view *view, bool active)
+ssd_set_active(struct ssd *ssd, bool active)
 {
-       struct ssd *ssd = &view->ssd;
-       if (!ssd->tree) {
+       if (!ssd) {
                return;
        }
        wlr_scene_node_set_enabled(&ssd->border.active.tree->node, active);
@@ -268,10 +280,16 @@ ssd_set_active(struct view *view, bool active)
        wlr_scene_node_set_enabled(&ssd->titlebar.inactive.tree->node, !active);
 }
 
+struct ssd_hover_state *
+ssd_hover_state_new(void)
+{
+       return znew(struct ssd_hover_state);
+}
+
 bool
 ssd_debug_is_root_node(const struct ssd *ssd, struct wlr_scene_node *node)
 {
-       if (!ssd->tree || !node) {
+       if (!ssd || !node) {
                return false;
        }
        return node == &ssd->tree->node;
@@ -280,7 +298,7 @@ ssd_debug_is_root_node(const struct ssd *ssd, struct wlr_scene_node *node)
 const char *
 ssd_debug_get_node_name(const struct ssd *ssd, struct wlr_scene_node *node)
 {
-       if (!ssd->tree || !node) {
+       if (!ssd || !node) {
                return NULL;
        }
        if (node == &ssd->tree->node) {
index b1ef3e85411318486202bdacd54bdbb019e1208f..a145c424332ffa58cd569ffa64277890b7ecb70b 100644 (file)
@@ -13,7 +13,7 @@
 void
 ssd_border_create(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        struct theme *theme = view->server->theme;
        int width = view->w;
        int height = view->h;
@@ -51,7 +51,7 @@ ssd_border_create(struct ssd *ssd)
 void
 ssd_border_update(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        struct theme *theme = view->server->theme;
 
        int width = view->w;
index 2d203609890805ce0ce7915ce8e7b7bb8855c680..25ed8af655785bc7e199de478f56a6fa6f9d92e8 100644 (file)
@@ -37,7 +37,7 @@ lab_wlr_output_layout_layout_coords(struct wlr_output_layout *layout,
 void
 ssd_extents_create(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        struct theme *theme = view->server->theme;
        struct wl_list *part_list = &ssd->extents.parts;
        int extended_area = EXTENDED_AREA;
@@ -98,7 +98,7 @@ ssd_extents_create(struct ssd *ssd)
 void
 ssd_extents_update(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        if (view->maximized || view->fullscreen) {
                wlr_scene_node_set_enabled(&ssd->extents.tree->node, false);
                return;
index 15bb2c079533c07fc9d5f16c4dce3861308ce1a0..93b300d8d06c5a7277b35abde9412f61a73b16d3 100644 (file)
@@ -20,7 +20,7 @@
 void
 ssd_titlebar_create(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        struct theme *theme = view->server->theme;
        int width = view->w;
 
@@ -78,7 +78,7 @@ ssd_titlebar_create(struct ssd *ssd)
                        corner_top_right, close_button_unpressed,
                        width - BUTTON_WIDTH * 1, view);
        } FOR_EACH_END
-       ssd_update_title(view);
+       ssd_update_title(ssd);
 }
 
 static bool
@@ -90,7 +90,7 @@ is_direct_child(struct wlr_scene_node *node, struct ssd_sub_tree *subtree)
 void
 ssd_titlebar_update(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        int width = view->w;
        if (width == ssd->state.width) {
                return;
@@ -131,7 +131,7 @@ ssd_titlebar_update(struct ssd *ssd)
                        }
                }
        } FOR_EACH_END
-       ssd_update_title(view);
+       ssd_update_title(ssd);
 }
 
 void
@@ -169,7 +169,7 @@ ssd_titlebar_destroy(struct ssd *ssd)
 static void
 ssd_update_title_positions(struct ssd *ssd)
 {
-       struct view *view = wl_container_of(ssd, view, ssd);
+       struct view *view = ssd->view;
        struct theme *theme = view->server->theme;
        int width = view->w;
        int title_bg_width = width - BUTTON_WIDTH * BUTTON_COUNT;
@@ -219,13 +219,13 @@ ssd_update_title_positions(struct ssd *ssd)
 }
 
 void
-ssd_update_title(struct view *view)
+ssd_update_title(struct ssd *ssd)
 {
-       struct ssd *ssd = &view->ssd;
-       if (!ssd->tree) {
+       if (!ssd) {
                return;
        }
 
+       struct view *view = ssd->view;
        char *title = (char *)view_get_string_prop(view, "title");
        if (!title || !*title) {
                return;
index a747c0a6234704ccad27e18f4d0fedfc111fc9fd..cd24313705cd76d1670ab2dc576907fed379f834 100644 (file)
@@ -88,7 +88,7 @@ view_get_edge_snap_box(struct view *view, struct output *output,
                break;
        }
 
-       struct border margin = view->ssd.margin;
+       struct border margin = ssd_get_margin(view->ssd);
        struct wlr_box dst = {
                .x = x_offset + usable.x + margin.left,
                .y = y_offset + usable.y + margin.top,
@@ -102,9 +102,7 @@ view_get_edge_snap_box(struct view *view, struct output *output,
 static void
 _view_set_activated(struct view *view, bool activated)
 {
-       if (view->ssd.tree) {
-               ssd_set_active(view, activated);
-       }
+       ssd_set_active(view->ssd, activated);
        if (view->impl->set_activated) {
                view->impl->set_activated(view, activated);
        }
@@ -153,7 +151,7 @@ view_moved(struct view *view)
        assert(view);
        wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y);
        view_discover_output(view);
-       ssd_update_geometry(view);
+       ssd_update_geometry(view->ssd);
        cursor_update_focus(view->server);
 }
 
@@ -278,7 +276,7 @@ view_compute_centered_position(struct view *view, int w, int h, int *x, int *y)
                return false;
        }
 
-       struct border margin = view->ssd.margin;
+       struct border margin = ssd_get_margin(view->ssd);
        struct wlr_box usable = output_usable_area_in_layout_coords(output);
        int width = w + margin.left + margin.right;
        int height = h + margin.top + margin.bottom;
@@ -554,6 +552,22 @@ view_move_to_workspace(struct view *view, struct workspace *workspace)
        }
 }
 
+static void
+decorate(struct view *view)
+{
+       if (!view->ssd) {
+               view->ssd = ssd_create(view,
+                       view == view->server->focused_view);
+       }
+}
+
+static void
+undecorate(struct view *view)
+{
+       ssd_destroy(view->ssd);
+       view->ssd = NULL;
+}
+
 void
 view_set_decorations(struct view *view, bool decorations)
 {
@@ -565,9 +579,9 @@ view_set_decorations(struct view *view, bool decorations)
                 */
                view->ssd_enabled = decorations;
                if (decorations) {
-                       ssd_create(view, view == view->server->focused_view);
+                       decorate(view);
                } else {
-                       ssd_destroy(view);
+                       undecorate(view);
                }
                if (view->maximized) {
                        view_apply_maximized_geometry(view);
@@ -614,7 +628,7 @@ view_set_fullscreen(struct view *view, bool fullscreen,
                }
                /* Hide decorations when going fullscreen */
                if (view->ssd_enabled) {
-                       ssd_destroy(view);
+                       undecorate(view);
                }
                view->fullscreen = wlr_output;
                view_apply_fullscreen_geometry(view, view->fullscreen);
@@ -630,7 +644,7 @@ view_set_fullscreen(struct view *view, bool fullscreen,
                }
                /* Re-show decorations when no longer fullscreen */
                if (view->ssd_enabled) {
-                       ssd_create(view, view == view->server->focused_view);
+                       decorate(view);
                }
        }
 
@@ -734,7 +748,7 @@ view_move_to_edge(struct view *view, const char *direction)
                return;
        }
 
-       struct border margin = view->ssd.margin;
+       struct border margin = ssd_get_margin(view->ssd);
        struct wlr_box usable = output_usable_area_in_layout_coords(output);
        if (usable.height == output->wlr_output->height
                        && output->wlr_output->scale != 1) {
@@ -872,7 +886,7 @@ view_update_title(struct view *view)
        if (!view->toplevel_handle || !title) {
                return;
        }
-       ssd_update_title(view);
+       ssd_update_title(view->ssd);
        wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, title);
 }
 
@@ -893,8 +907,8 @@ view_reload_ssd(struct view *view)
 {
        assert(view);
        if (view->ssd_enabled && !view->fullscreen) {
-               ssd_destroy(view);
-               ssd_create(view, view == view->server->focused_view);
+               undecorate(view);
+               decorate(view);
        }
 }
 
@@ -926,9 +940,9 @@ view_destroy(struct view *view)
        }
 
        osd_on_view_destroy(view);
+       undecorate(view);
 
        if (view->scene_tree) {
-               ssd_destroy(view);
                wlr_scene_node_destroy(&view->scene_tree->node);
                view->scene_tree = NULL;
        }
index 3f5bf2cd6e3e57c36a43865ea7667a05406bd9e0..edfdabbf0c12b60e9bc98b6782963b04a1fd5db5 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -303,8 +303,10 @@ position_xdg_toplevel_view(struct view *view)
                view->x = center_x - xdg_surface->current.geometry.width / 2;
                view->y = center_y - xdg_surface->current.geometry.height / 2;
        }
-       view->x += view->ssd.margin.left;
-       view->y += view->ssd.margin.top;
+
+       struct border margin = ssd_get_margin(view->ssd);
+       view->x += margin.left;
+       view->y += margin.top;
 }
 
 static const char *