]> git.mdlowis.com Git - proto/labwc.git/commitdiff
src/ssd: refactor button hover and maximize toggle
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Wed, 6 Dec 2023 21:07:06 +0000 (22:07 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Fri, 8 Dec 2023 20:55:50 +0000 (20:55 +0000)
include/ssd-internal.h
src/ssd/ssd.c
src/ssd/ssd_part.c
src/ssd/ssd_titlebar.c

index bfc11018155ff54594821a6a323267561a25dc04..82652f2ca5754930a600fbf0b1ee0952bcf67ab9 100644 (file)
@@ -23,6 +23,8 @@ struct ssd_button {
        struct wlr_scene_node *toggled;
        struct wlr_scene_node *toggled_hover;
        struct wlr_scene_node *background;
+       struct wlr_scene_tree *icon_tree;
+       struct wlr_scene_tree *hover_tree;
 
        struct wl_listener destroy;
 };
@@ -47,7 +49,7 @@ struct ssd {
         * don't update things we don't have to.
         */
        struct {
-               bool squared_corners;   /* To un-round corner buttons on maximize */
+               bool was_maximized;   /* To un-round corner buttons and toggle icon on maximize */
                struct wlr_box geometry;
                struct ssd_state_title {
                        char *text;
@@ -99,9 +101,7 @@ struct ssd_part {
 
 struct ssd_hover_state {
        struct view *view;
-       struct wlr_scene_node *node;
-       struct wlr_scene_node *old_node;
-       int maximized;
+       struct ssd_button *button;
 };
 
 struct wlr_buffer;
index 0f1eafca45b44e3488c53ac796ce114a73431dd4..df18f1e5f9b4dbce7c87dc3f45fa5eba84bf51c2 100644 (file)
@@ -227,9 +227,15 @@ ssd_update_geometry(struct ssd *ssd)
                        ssd->state.geometry = current;
                }
                bool maximized = (ssd->view->maximized == VIEW_AXIS_BOTH);
-               if (ssd->state.squared_corners != maximized) {
+               if (ssd->state.was_maximized != maximized) {
                        ssd_border_update(ssd);
                        ssd_titlebar_update(ssd);
+                       /*
+                        * Not strictly necessary as ssd_titlebar_update()
+                        * already sets state.was_maximized but to future
+                        * proof this a bit we also set it here again.
+                        */
+                       ssd->state.was_maximized = maximized;
                }
                return;
        }
@@ -265,7 +271,7 @@ ssd_destroy(struct ssd *ssd)
        hover_state = view->server->ssd_hover_state;
        if (hover_state->view == view) {
                hover_state->view = NULL;
-               hover_state->node = NULL;
+               hover_state->button = NULL;
        }
 
        /* Destroy subcomponents */
index ea53c10410578ac1bc4e2645f99238d76667ef8f..20a9ad3aa8682d69fff6dcd9641094ada3702ffc 100644 (file)
@@ -154,10 +154,11 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
                SSD_BUTTON_WIDTH, rc.theme->title_height, 0, 0, bg_color);
 
        /* Icon */
+       struct wlr_scene_tree *icon_tree = wlr_scene_tree_create(parent);
        struct wlr_box icon_geo = get_scale_box(icon_buffer,
                SSD_BUTTON_WIDTH, rc.theme->title_height);
        struct ssd_part *icon_part = add_scene_buffer(part_list, type,
-               parent, icon_buffer, icon_geo.x, icon_geo.y);
+               icon_tree, icon_buffer, icon_geo.x, icon_geo.y);
 
        /* Make sure big icons are scaled down if necessary */
        wlr_scene_buffer_set_dest_size(
@@ -165,18 +166,18 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
                icon_geo.width, icon_geo.height);
 
        /* Hover icon */
+       struct wlr_scene_tree *hover_tree = wlr_scene_tree_create(parent);
+       wlr_scene_node_set_enabled(&hover_tree->node, false);
        struct wlr_box hover_geo = get_scale_box(hover_buffer,
                SSD_BUTTON_WIDTH, rc.theme->title_height);
        struct ssd_part *hover_part = add_scene_buffer(part_list, type,
-               parent, hover_buffer, hover_geo.x, hover_geo.y);
+               hover_tree, hover_buffer, hover_geo.x, hover_geo.y);
 
        /* Make sure big icons are scaled down if necessary */
        wlr_scene_buffer_set_dest_size(
                wlr_scene_buffer_from_node(hover_part->node),
                hover_geo.width, hover_geo.height);
 
-       wlr_scene_node_set_enabled(hover_part->node, false);
-
        struct ssd_button *button = ssd_button_descriptor_create(button_root->node);
        button->type = type;
        button->view = view;
@@ -185,6 +186,8 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type,
        button->background = bg_rect->node;
        button->toggled = NULL;
        button->toggled_hover = NULL;
+       button->icon_tree = icon_tree;
+       button->hover_tree = hover_tree;
        return button_root;
 }
 
@@ -194,14 +197,13 @@ add_toggled_icon(struct wl_list *part_list, enum ssd_part_type type,
 {
        struct ssd_part *part = ssd_get_part(part_list, type);
        struct ssd_button *button = node_ssd_button_from_node(part->node);
-       struct wlr_scene_tree *parent = wlr_scene_tree_from_node(part->node);
 
        /* Alternate icon */
        struct wlr_box icon_geo = get_scale_box(icon_buffer,
                SSD_BUTTON_WIDTH, rc.theme->title_height);
 
        struct ssd_part *alticon_part = add_scene_buffer(part_list, type,
-               parent, icon_buffer, icon_geo.x, icon_geo.y);
+               button->icon_tree, icon_buffer, icon_geo.x, icon_geo.y);
 
        wlr_scene_buffer_set_dest_size(
                wlr_scene_buffer_from_node(alticon_part->node),
@@ -212,7 +214,7 @@ add_toggled_icon(struct wl_list *part_list, enum ssd_part_type type,
        struct wlr_box hover_geo = get_scale_box(hover_buffer,
                SSD_BUTTON_WIDTH, rc.theme->title_height);
        struct ssd_part *althover_part = add_scene_buffer(part_list, type,
-               parent, hover_buffer, hover_geo.x, hover_geo.y);
+               button->hover_tree, hover_buffer, hover_geo.x, hover_geo.y);
 
        wlr_scene_buffer_set_dest_size(
                wlr_scene_buffer_from_node(althover_part->node),
index fc28e64afd35099fadd942d6663579f0b164348d..f31671626a1788690adad85bc5f854c06c77acd0 100644 (file)
@@ -18,6 +18,7 @@
        &(ssd)->titlebar.inactive)
 
 static void set_squared_corners(struct ssd *ssd, bool enable);
+static void set_maximize_alt_icon(struct ssd *ssd, bool enable);
 
 void
 ssd_titlebar_create(struct ssd *ssd)
@@ -109,6 +110,8 @@ ssd_titlebar_create(struct ssd *ssd)
 
        if (view->maximized == VIEW_AXIS_BOTH) {
                set_squared_corners(ssd, true);
+               set_maximize_alt_icon(ssd, true);
+               ssd->state.was_maximized = true;
        }
 }
 
@@ -143,8 +146,29 @@ set_squared_corners(struct ssd *ssd, bool enable)
                        wlr_scene_node_set_enabled(rounded_corner, !enable);
                }
        } FOR_EACH_END
+}
+
+static void
+set_maximize_alt_icon(struct ssd *ssd, bool enable)
+{
+       struct ssd_part *part;
+       struct ssd_button *button;
+       struct ssd_sub_tree *subtree;
+
+       FOR_EACH_STATE(ssd, subtree) {
+               part = ssd_get_part(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE);
+               button = node_ssd_button_from_node(part->node);
+
+               if (button->toggled) {
+                       wlr_scene_node_set_enabled(button->toggled, enable);
+                       wlr_scene_node_set_enabled(button->normal, !enable);
+               }
 
-       ssd->state.squared_corners = enable;
+               if (button->toggled_hover) {
+                       wlr_scene_node_set_enabled(button->toggled_hover, enable);
+                       wlr_scene_node_set_enabled(button->hover, !enable);
+               }
+       } FOR_EACH_END
 }
 
 void
@@ -155,8 +179,10 @@ ssd_titlebar_update(struct ssd *ssd)
        struct theme *theme = view->server->theme;
 
        bool maximized = (view->maximized == VIEW_AXIS_BOTH);
-       if (ssd->state.squared_corners != maximized) {
+       if (ssd->state.was_maximized != maximized) {
                set_squared_corners(ssd, maximized);
+               set_maximize_alt_icon(ssd, maximized);
+               ssd->state.was_maximized = maximized;
        }
 
        if (width == ssd->state.geometry.width) {
@@ -184,18 +210,6 @@ ssd_titlebar_update(struct ssd *ssd)
                                if (is_direct_child(part->node, subtree)) {
                                        wlr_scene_node_set_position(part->node,
                                                width - SSD_BUTTON_WIDTH * 2, 0);
-                                       struct ssd_button *button =
-                                               node_ssd_button_from_node(part->node);
-                                       if (button->toggled) {
-                                               wlr_scene_node_set_enabled(button->normal,
-                                                       !maximized);
-                                               wlr_scene_node_set_enabled(button->toggled,
-                                                       maximized);
-                                               wlr_scene_node_set_enabled(button->hover,
-                                                       false);
-                                               wlr_scene_node_set_enabled(button->toggled_hover,
-                                                       false);
-                                       }
                                }
                                continue;
                        case LAB_SSD_PART_CORNER_TOP_RIGHT:
@@ -379,6 +393,14 @@ ssd_update_title(struct ssd *ssd)
        ssd_update_title_positions(ssd);
 }
 
+static void
+ssd_button_set_hover(struct ssd_button *button, bool enabled)
+{
+       assert(button);
+       wlr_scene_node_set_enabled(&button->hover_tree->node, enabled);
+       wlr_scene_node_set_enabled(&button->icon_tree->node, !enabled);
+}
+
 void
 ssd_update_button_hover(struct wlr_scene_node *node,
                struct ssd_hover_state *hover_state)
@@ -391,33 +413,22 @@ ssd_update_button_hover(struct wlr_scene_node *node,
        struct node_descriptor *desc = node->data;
        if (desc->type == LAB_NODE_DESC_SSD_BUTTON) {
                button = node_ssd_button_from_node(node);
-               if (button->hover == hover_state->node) {
+               if (button == hover_state->button) {
                        /* Cursor is still on the same button */
                        return;
                }
        }
 
 disable_old_hover:
-       if (hover_state->node) {
-               wlr_scene_node_set_enabled(hover_state->node, false);
-               if (hover_state->maximized == (int)hover_state->view->maximized
-                       || hover_state->maximized == -1) {
-                       wlr_scene_node_set_enabled(hover_state->old_node, true);
-               }
+       if (hover_state->button) {
+               ssd_button_set_hover(hover_state->button, false);
                hover_state->view = NULL;
-               hover_state->node = NULL;
+               hover_state->button = NULL;
        }
        if (button) {
-               bool maximized = button->view->maximized;
-               if (maximized && !button->toggled) {
-                       maximized = false;
-               }
-               wlr_scene_node_set_enabled(maximized ? button->toggled_hover : button->hover, true);
+               ssd_button_set_hover(button, true);
                hover_state->view = button->view;
-               hover_state->node = maximized ? button->toggled_hover : button->hover;
-               hover_state->old_node = maximized ? button->toggled : button->normal;
-               hover_state->maximized = button->toggled ? (int)button->view->maximized : -1;
-               wlr_scene_node_set_enabled(maximized ? button->toggled : button->normal, false);
+               hover_state->button = button;
        }
 }