]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Add keepBorder `<theme>` option and enable it by default
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Fri, 14 Apr 2023 07:01:13 +0000 (09:01 +0200)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Thu, 10 Aug 2023 14:09:20 +0000 (16:09 +0200)
With the new keepBorder option enabled, the
ToggleDecorations action now has 3 states:

- the first time only disables the titlebar
- the second time disables the whole SSD
- the third time enables the whole SSD again

When the keepBorder action is disabled, the old 2-state
behavior is restored, e.g. the ToggleDecorations action
only toggles between on and off.

Fixes #813

13 files changed:
docs/labwc-actions.5.scd
docs/labwc-config.5.scd
docs/rc.xml.all
include/config/rcxml.h
include/ssd-internal.h
include/ssd.h
include/view.h
src/config/rcxml.c
src/ssd/ssd.c
src/ssd/ssd_border.c
src/ssd/ssd_extents.c
src/ssd/ssd_titlebar.c
src/view.c

index 418cff55cf0ef8ae26ee7cc5330421df85cb4d06..b5daf093231bf6b9faaaaf7fa17809ff1eb6bcd0 100644 (file)
@@ -80,6 +80,14 @@ Actions are used in menus and keyboard/mouse bindings.
 *<action name="ToggleDecorations" />*
        Toggle decorations of focused window.
 
+       This is a 3-state action which can be executed multiple times:
+       - Only the titlebar will be hidden, borders and resize area are kept
+       - Remaining decorations will be disabled
+       - Decorations will be shown normally
+
+       By disabling the theme configuration 'keepBorder' the first step
+       will be removed and the action only toggles between on and off.
+
 *<action name="ToggleFullscreen" />*
        Toggle fullscreen state of focused window.
 
index 7a9e5181400609d5fd17315f64a68f0fefe5afb2..10b228428e416e026d87b1c1c8c3325b01870b9b 100644 (file)
@@ -218,6 +218,10 @@ Therefore, where multiple objects of the same kind are required (for example
 *<theme><cornerRadius>*
        The radius of server side decoration top corners. Default is 8.
 
+*<theme><keepBorder>* [yes|no]
+       Even when disabling server side decorations via ToggleDecorations,
+       keep a small border (and resize area) around the window. Default is yes.
+
 *<theme><font place="">*
        The font to use for a specific element of a window, menu or OSD.
        Places can be any of:
index 23457f3567da96430a7b84ad0a996118926d9319..445b61dc8637fb54b26168e2f2fa464b1578575b 100644 (file)
@@ -18,6 +18,7 @@
   <theme>
     <name></name>
     <cornerRadius>8</cornerRadius>
+    <keepBorder>yes</keepBorder>
     <font place="ActiveWindow">
       <name>sans</name>
       <size>10</size>
index 88a2ee0f94446b694a183350227fab3161fd656f..62a06ab671258f082f0bff8dda9a5fa35574b3e3 100644 (file)
@@ -48,6 +48,7 @@ struct rcxml {
        /* theme */
        char *theme_name;
        int corner_radius;
+       bool ssd_keep_border;
        struct font font_activewindow;
        struct font font_menuitem;
        struct font font_osd;
index d6459122f82244b9fe366500f7da1d09ac34cb2a..755e5db402931ec136c3b5683c1b3818324d8551 100644 (file)
@@ -54,7 +54,8 @@ struct ssd {
 
        /* The top of the view, containing buttons, title, .. */
        struct {
-               /* struct wlr_scene_tree *tree;      unused for now */
+               int height;
+               struct wlr_scene_tree *tree;
                struct ssd_sub_tree active;
                struct ssd_sub_tree inactive;
        } titlebar;
index 5e82be2cae7c800d15e4ae66e48f792b8706ebad..814c6ca2be2215832f39669087590fadcd1b40dc 100644 (file)
@@ -63,6 +63,8 @@ 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);
+bool ssd_titlebar_is_hidden(struct ssd *ssd);
+void ssd_titlebar_hide(struct ssd *ssd);
 
 void ssd_enable_keybind_inhibit_indicator(struct ssd *ssd, bool enable);
 
index 79963b4b8b484a67d5d5762399719d57933fa18f..5ba62a5b7bd4903391d662ae16d7b1d56351b468 100644 (file)
@@ -89,6 +89,7 @@ struct view {
        bool mapped;
        bool been_mapped;
        bool ssd_enabled;
+       bool ssd_titlebar_hidden;
        enum ssd_preference ssd_preference;
        bool minimized;
        bool maximized;
index 42f89442ab7412c9555737fdbb692a8dd641e69e..735afeb3c34b4c9906708a6ec3bba10e3f267fa1 100644 (file)
@@ -575,6 +575,8 @@ entry(xmlNode *node, char *nodename, char *content)
                rc.theme_name = xstrdup(content);
        } else if (!strcmp(nodename, "cornerradius.theme")) {
                rc.corner_radius = atoi(content);
+       } else if (!strcasecmp(nodename, "keepBorder.theme")) {
+               set_bool(content, &rc.ssd_keep_border);
        } else if (!strcmp(nodename, "name.font.theme")) {
                fill_font(nodename, content, font_place);
        } else if (!strcmp(nodename, "size.font.theme")) {
@@ -780,6 +782,7 @@ rcxml_init(void)
        has_run = true;
 
        rc.xdg_shell_server_side_deco = true;
+       rc.ssd_keep_border = true;
        rc.corner_radius = 8;
 
        init_font_defaults(&rc.font_activewindow);
index 3cd9b875612ca6e96a3f2aa310d1ea11cbfe7e0a..f2d3f267c9b4f60d1d5d0a5b63b738bf5a177b37 100644 (file)
@@ -25,13 +25,19 @@ ssd_thickness(struct view *view)
        if (!view->ssd_enabled || view->fullscreen) {
                return (struct border){ 0 };
        }
+
        struct theme *theme = view->server->theme;
-       return (struct border){
+       struct border thickness = {
                .top = theme->title_height + theme->border_width,
                .bottom = theme->border_width,
                .left = theme->border_width,
                .right = theme->border_width,
        };
+
+       if (ssd_titlebar_is_hidden(view->ssd)) {
+               thickness.top -= theme->title_height;
+       }
+       return thickness;
 }
 
 struct wlr_box
@@ -158,9 +164,14 @@ ssd_create(struct view *view, bool active)
        ssd->view = view;
        ssd->tree = wlr_scene_tree_create(view->scene_tree);
        wlr_scene_node_lower_to_bottom(&ssd->tree->node);
+       ssd->titlebar.height = view->server->theme->title_height;
        ssd_extents_create(ssd);
        ssd_border_create(ssd);
        ssd_titlebar_create(ssd);
+       if (rc.ssd_keep_border && view->ssd_titlebar_hidden) {
+               /* Ensure we keep the old state when exiting fullscreen */
+               ssd_titlebar_hide(ssd);
+       }
        ssd->margin = ssd_thickness(view);
        ssd_set_active(ssd, active);
        ssd_enable_keybind_inhibit_indicator(ssd, view->inhibits_keybinds);
@@ -198,6 +209,25 @@ ssd_update_geometry(struct ssd *ssd)
        ssd->state.geometry = current;
 }
 
+bool
+ssd_titlebar_is_hidden(struct ssd *ssd)
+{
+       return ssd && !ssd->titlebar.tree->node.enabled;
+}
+
+void
+ssd_titlebar_hide(struct ssd *ssd)
+{
+       if (!ssd || !ssd->titlebar.tree->node.enabled) {
+               return;
+       }
+       wlr_scene_node_set_enabled(&ssd->titlebar.tree->node, false);
+       ssd->titlebar.height = 0;
+       ssd_border_update(ssd);
+       ssd_extents_update(ssd);
+       ssd->margin = ssd_thickness(ssd->view);
+}
+
 void
 ssd_destroy(struct ssd *ssd)
 {
index 1c9eb538d4fc04b104b1448c181bd2c06369ca23..d7cc0e34806317d0403030c6a3f5ea5c04f802c2 100644 (file)
@@ -44,7 +44,7 @@ ssd_border_create(struct ssd *ssd)
                add_scene_rect(&subtree->parts, LAB_SSD_PART_TOP, parent,
                        width - 2 * SSD_BUTTON_WIDTH, theme->border_width,
                        theme->border_width + SSD_BUTTON_WIDTH,
-                       -(theme->title_height + theme->border_width), color);
+                       -(ssd->titlebar.height + theme->border_width), color);
        } FOR_EACH_END
 }
 
@@ -82,9 +82,19 @@ ssd_border_update(struct ssd *ssd)
                                        0, height);
                                continue;
                        case LAB_SSD_PART_TOP:
-                               wlr_scene_rect_set_size(rect,
-                                       width - 2 * SSD_BUTTON_WIDTH,
-                                       theme->border_width);
+                               if (ssd->titlebar.height > 0) {
+                                       wlr_scene_rect_set_size(rect,
+                                               width - 2 * SSD_BUTTON_WIDTH,
+                                               theme->border_width);
+                                       wlr_scene_node_set_position(part->node,
+                                               theme->border_width + SSD_BUTTON_WIDTH,
+                                               -(ssd->titlebar.height + theme->border_width));
+                               } else {
+                                       wlr_scene_rect_set_size(rect,
+                                               full_width, theme->border_width);
+                                       wlr_scene_node_set_position(part->node,
+                                               0, -theme->border_width);
+                               }
                                continue;
                        default:
                                continue;
index aa3e271061e3ec6de470ffd80d3ca7f1e2f76d6d..1b6f465dcf72f9f2a4f4b134529618e535688f61 100644 (file)
@@ -41,7 +41,7 @@ ssd_extents_create(struct ssd *ssd)
        wl_list_init(&ssd->extents.parts);
        wlr_scene_node_set_position(&parent->node,
                -(theme->border_width + extended_area),
-               -(theme->title_height + theme->border_width + extended_area));
+               -(ssd->titlebar.height + theme->border_width + extended_area));
 
        /* Initialize parts and set constant values for targeted geometry */
        struct ssd_part *p;
@@ -110,7 +110,7 @@ ssd_extents_update(struct ssd *ssd)
 
        int width = view->current.width;
        int height = view->current.height;
-       int full_height = height + theme->border_width * 2 + theme->title_height;
+       int full_height = height + theme->border_width * 2 + ssd->titlebar.height;
        int full_width = width + 2 * theme->border_width;
        int extended_area = SSD_EXTENDED_AREA;
        int corner_size = extended_area + theme->border_width + SSD_BUTTON_WIDTH / 2;
@@ -122,6 +122,11 @@ ssd_extents_update(struct ssd *ssd)
        struct ssd_part *part;
        struct wlr_scene_rect *rect;
 
+       /* Make sure we update the y offset based on titlebar shown / hidden */
+       wlr_scene_node_set_position(&ssd->extents.tree->node,
+               -(theme->border_width + extended_area),
+               -(ssd->titlebar.height + theme->border_width + extended_area));
+
        /* Convert usable area into layout coordinates */
        struct wlr_box usable_area = view->output->usable_area;
        usable_area.x += l_output->x;
index 11db050037e14b62a4a770a7452f86e1cba9cc3f..cadb7de68be1a672a31f60669f3bfb5b233abb61 100644 (file)
@@ -34,9 +34,11 @@ ssd_titlebar_create(struct ssd *ssd)
        struct wlr_buffer *maximize_button_unpressed;
        struct wlr_buffer *close_button_unpressed;
 
+       ssd->titlebar.tree = wlr_scene_tree_create(ssd->tree);
+
        struct ssd_sub_tree *subtree;
        FOR_EACH_STATE(ssd, subtree) {
-               subtree->tree = wlr_scene_tree_create(ssd->tree);
+               subtree->tree = wlr_scene_tree_create(ssd->titlebar.tree);
                parent = subtree->tree;
                wlr_scene_node_set_position(&parent->node, 0, -theme->title_height);
                if (subtree == &ssd->titlebar.active) {
@@ -138,7 +140,7 @@ ssd_titlebar_update(struct ssd *ssd)
 void
 ssd_titlebar_destroy(struct ssd *ssd)
 {
-       if (!ssd->titlebar.active.tree) {
+       if (!ssd->titlebar.tree) {
                return;
        }
 
@@ -153,6 +155,9 @@ ssd_titlebar_destroy(struct ssd *ssd)
                free(ssd->state.title.text);
                ssd->state.title.text = NULL;
        }
+
+       wlr_scene_node_destroy(&ssd->titlebar.tree->node);
+       ssd->titlebar.tree = NULL;
 }
 
 /*
index 4c72e13f5f02907b6c06a91775a7ada67977cf15..729cedb26f172deef6f37ed71bae774247f95648 100644 (file)
@@ -658,6 +658,15 @@ void
 view_toggle_decorations(struct view *view)
 {
        assert(view);
+       if (rc.ssd_keep_border && view->ssd_enabled && view->ssd
+                       && !ssd_titlebar_is_hidden(view->ssd)) {
+               ssd_titlebar_hide(view->ssd);
+               view->ssd_titlebar_hidden = true;
+               if (!view_is_floating(view)) {
+                       view_apply_special_geometry(view);
+               }
+               return;
+       }
        view_set_decorations(view, !view->ssd_enabled);
 }
 
@@ -748,6 +757,7 @@ view_set_decorations(struct view *view, bool decorations)
                        decorate(view);
                } else {
                        undecorate(view);
+                       view->ssd_titlebar_hidden = false;
                }
                if (!view_is_floating(view)) {
                        view_apply_special_geometry(view);