]> git.mdlowis.com Git - proto/labwc.git/commitdiff
ssd: add optional shade button
authorAndrew J. Hesford <ajh@sideband.org>
Thu, 22 Aug 2024 20:27:24 +0000 (16:27 -0400)
committerConsolatis <35009135+Consolatis@users.noreply.github.com>
Sat, 24 Aug 2024 03:42:38 +0000 (05:42 +0200)
docs/labwc-config.5.scd
docs/rc.xml.all
include/config/default-bindings.h
include/ssd-internal.h
include/ssd.h
include/theme.h
src/config/mousebind.c
src/config/rcxml.c
src/ssd/ssd-titlebar.c
src/ssd/ssd.c
src/theme.c

index 6da0af3419f9463e066c0aa7323c3216a7a25d08..ed063aed968fb8696818a3ffc0947e51550e407d 100644 (file)
@@ -438,6 +438,7 @@ extending outward from the snapped edge.
        - L: window label (aka. title)
        - |: empty space (can be used instead of a title)
        - W: window menu
+       - S: shade
        - I: iconify
        - M: maximize
        - C: close
@@ -615,6 +616,7 @@ extending outward from the snapped edge.
        - WindowMenu: The button on the left.
        - Iconify: The button that looks like an underline.
        - Maximize: The button that looks like a box.
+       - Shade: A button that looks like an overline.
        - Close: The button that looks like an X.
        - Top: The top edge of the window's border.
        - Bottom: The bottom edge of the window's border.
index ab462a14f9445142d42cfa1bf3e73b9a793ebea1..f2de0f29327a7f3d85d4f7501603b8228c811363 100644 (file)
       </mousebind>
     </context>
 
+    <context name="Shade">
+      <mousebind button="Left" action="Click">
+        <action name="ToggleShade" />
+      </mousebind>
+    </context>
+
     <context name="Iconify">
       <mousebind button="Left" action="Click">
         <action name="Iconify" />
index 535ee25ab529b8c559045610a9d3b80187d524c8..f3de19b2fd238e481914d248c9e47d282c1c41ec 100644 (file)
@@ -322,6 +322,11 @@ static struct mouse_combos {
                .button = "Left",
                .event = "Click",
                .action = "ToggleMaximize",
+       }, {
+               .context = "Shade",
+               .button = "Left",
+               .event = "Click",
+               .action = "ToggleShade",
        }, {
                .context = "Maximize",
                .button = "Right",
index c6e3ba770d0e9c8ac303e0db39b3c6423e03873e..c8f4ab7bc99077a324ae5e354ea8a435ee75d2e1 100644 (file)
@@ -48,6 +48,7 @@ struct ssd {
         * don't update things we don't have to.
         */
        struct {
+               bool was_shaded;   /* To toggle icon on shade */
                bool was_maximized;   /* To un-round corner buttons and toggle icon on maximize */
                bool was_tiled_not_maximized;   /* To un-round corner buttons */
                struct wlr_box geometry;
index 2924253ca9ea5e23cd83a7af245669095d459225..8b8f77d3f9465f0a9dcc81a8a9d911fd6d4350fa 100644 (file)
@@ -25,6 +25,7 @@ enum ssd_part_type {
        LAB_SSD_BUTTON_MAXIMIZE,
        LAB_SSD_BUTTON_ICONIFY,
        LAB_SSD_BUTTON_WINDOW_MENU,
+       LAB_SSD_BUTTON_SHADE,
        LAB_SSD_PART_TITLEBAR,
        LAB_SSD_PART_TITLEBAR_CORNER_RIGHT,
        LAB_SSD_PART_TITLEBAR_CORNER_LEFT,
@@ -100,7 +101,6 @@ enum ssd_part_type ssd_at(const struct ssd *ssd,
 enum ssd_part_type ssd_get_part_type(const struct ssd *ssd,
        struct wlr_scene_node *node);
 uint32_t ssd_resize_edges(enum ssd_part_type type);
-bool ssd_is_button(enum ssd_part_type type);
 bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate);
 enum ssd_mode ssd_mode_parse(const char *mode);
 
index f0c3b757847b635f11a6fb587b8fa300b542e598..2a40b589c2c319c5e6368ba44af4ba0520199546 100644 (file)
@@ -54,10 +54,12 @@ struct theme {
        float window_active_button_iconify_unpressed_image_color[4];
        float window_active_button_max_unpressed_image_color[4];
        float window_active_button_close_unpressed_image_color[4];
+       float window_active_button_shade_unpressed_image_color[4];
        float window_inactive_button_menu_unpressed_image_color[4];
        float window_inactive_button_iconify_unpressed_image_color[4];
        float window_inactive_button_max_unpressed_image_color[4];
        float window_inactive_button_close_unpressed_image_color[4];
+       float window_inactive_button_shade_unpressed_image_color[4];
        /* TODO: add pressed and hover colors for buttons */
 
        int menu_item_padding_x;
@@ -114,12 +116,16 @@ struct theme {
        struct lab_data_buffer *button_restore_active_unpressed;
        struct lab_data_buffer *button_iconify_active_unpressed;
        struct lab_data_buffer *button_menu_active_unpressed;
+       struct lab_data_buffer *button_shade_active_unpressed;
+       struct lab_data_buffer *button_unshade_active_unpressed;
 
        struct lab_data_buffer *button_close_inactive_unpressed;
        struct lab_data_buffer *button_maximize_inactive_unpressed;
        struct lab_data_buffer *button_restore_inactive_unpressed;
        struct lab_data_buffer *button_iconify_inactive_unpressed;
        struct lab_data_buffer *button_menu_inactive_unpressed;
+       struct lab_data_buffer *button_shade_inactive_unpressed;
+       struct lab_data_buffer *button_unshade_inactive_unpressed;
 
        /* hover variants are optional and may be NULL */
        struct lab_data_buffer *button_close_active_hover;
@@ -127,12 +133,16 @@ struct theme {
        struct lab_data_buffer *button_restore_active_hover;
        struct lab_data_buffer *button_iconify_active_hover;
        struct lab_data_buffer *button_menu_active_hover;
+       struct lab_data_buffer *button_shade_active_hover;
+       struct lab_data_buffer *button_unshade_active_hover;
 
        struct lab_data_buffer *button_close_inactive_hover;
        struct lab_data_buffer *button_maximize_inactive_hover;
        struct lab_data_buffer *button_restore_inactive_hover;
        struct lab_data_buffer *button_iconify_inactive_hover;
        struct lab_data_buffer *button_menu_inactive_hover;
+       struct lab_data_buffer *button_shade_inactive_hover;
+       struct lab_data_buffer *button_unshade_inactive_hover;
 
        struct lab_data_buffer *corner_top_left_active_normal;
        struct lab_data_buffer *corner_top_right_active_normal;
index 857012fdda0ed9fbd24e2064e7fd0ea86ae54514..f7b0b44e4985f702a51f4c099bed43ddfd97cc84 100644 (file)
@@ -114,6 +114,8 @@ context_from_str(const char *str)
                return LAB_SSD_BUTTON_ICONIFY;
        } else if (!strcasecmp(str, "WindowMenu")) {
                return LAB_SSD_BUTTON_WINDOW_MENU;
+       } else if (!strcasecmp(str, "Shade")) {
+               return LAB_SSD_BUTTON_SHADE;
        } else if (!strcasecmp(str, "Titlebar")) {
                return LAB_SSD_PART_TITLEBAR;
        } else if (!strcasecmp(str, "Title")) {
index 30fd6afe3a50f601d97e43c223c6c17231bf0f88..71b2276804640a8539b2e0518e592cc45ca70005 100644 (file)
@@ -158,7 +158,9 @@ fill_title_layout(char *nodename, char *content)
                case 'C':
                        type = LAB_SSD_BUTTON_CLOSE;
                        break;
-               /* case 'S': shade */
+               case 'S':
+                       type = LAB_SSD_BUTTON_SHADE;
+                       break;
                /* case 'D': omnipresent */
                default:
                        continue;
index 827269aa1f0473dd26b642a6f07d7ca3c780c49a..834d8831bf0d0cde78b690b620ad6c8ac7114054 100644 (file)
@@ -19,7 +19,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);
+static void set_alt_button_icon(struct ssd *ssd, enum ssd_part_type type, bool enable);
 
 static void
 add_button(struct ssd *ssd, struct ssd_sub_tree *subtree, enum ssd_part_type type, int x)
@@ -29,8 +29,8 @@ add_button(struct ssd *ssd, struct ssd_sub_tree *subtree, enum ssd_part_type typ
        struct wlr_scene_tree *parent = subtree->tree;
        bool active = subtree == &ssd->titlebar.active;
 
-       struct ssd_part *btn_max_root;
-       struct ssd_button *btn_max;
+       struct ssd_part *btn_root;
+       struct ssd_button *btn;
 
        switch (type) {
        case LAB_SSD_BUTTON_WINDOW_MENU:
@@ -51,19 +51,34 @@ add_button(struct ssd *ssd, struct ssd_sub_tree *subtree, enum ssd_part_type typ
                break;
        case LAB_SSD_BUTTON_MAXIMIZE:
                /* Maximize button has an alternate state when maximized */
-               btn_max_root = add_scene_button(&subtree->parts, type, parent,
+               btn_root = add_scene_button(&subtree->parts, type, parent,
                        active ? &theme->button_maximize_active_unpressed->base
                                : &theme->button_maximize_inactive_unpressed->base,
                        active ? &theme->button_maximize_active_hover->base
                                : &theme->button_maximize_inactive_hover->base,
                        x, view);
-               btn_max = node_ssd_button_from_node(btn_max_root->node);
-               add_toggled_icon(btn_max, &subtree->parts, LAB_SSD_BUTTON_MAXIMIZE,
+               btn = node_ssd_button_from_node(btn_root->node);
+               add_toggled_icon(btn, &subtree->parts, LAB_SSD_BUTTON_MAXIMIZE,
                        active ? &theme->button_restore_active_unpressed->base
                                : &theme->button_restore_inactive_unpressed->base,
                        active ? &theme->button_restore_active_hover->base
                                : &theme->button_restore_inactive_hover->base);
                break;
+       case LAB_SSD_BUTTON_SHADE:
+               /* Shade button has an alternate state when shaded */
+               btn_root = add_scene_button(&subtree->parts, type, parent,
+                       active ? &theme->button_shade_active_unpressed->base
+                               : &theme->button_shade_inactive_unpressed->base,
+                       active ? &theme->button_shade_active_hover->base
+                               : &theme->button_shade_inactive_hover->base,
+                       x, view);
+               btn = node_ssd_button_from_node(btn_root->node);
+               add_toggled_icon(btn, &subtree->parts, LAB_SSD_BUTTON_SHADE,
+                       active ? &theme->button_unshade_active_unpressed->base
+                               : &theme->button_unshade_inactive_unpressed->base,
+                       active ? &theme->button_unshade_active_hover->base
+                               : &theme->button_unshade_inactive_hover->base);
+               break;
        case LAB_SSD_BUTTON_CLOSE:
                add_scene_button(&subtree->parts, type, parent,
                        active ? &theme->button_close_active_unpressed->base
@@ -141,9 +156,14 @@ ssd_titlebar_create(struct ssd *ssd)
        bool maximized = view->maximized == VIEW_AXIS_BOTH;
        if (maximized) {
                set_squared_corners(ssd, true);
-               set_maximize_alt_icon(ssd, true);
+               set_alt_button_icon(ssd, LAB_SSD_BUTTON_MAXIMIZE, true);
                ssd->state.was_maximized = true;
        }
+
+       if (view->shaded) {
+               set_alt_button_icon(ssd, LAB_SSD_BUTTON_SHADE, true);
+       }
+
        if (view_is_tiled_and_notify_tiled(view) && !maximized) {
                set_squared_corners(ssd, true);
                ssd->state.was_tiled_not_maximized = true;
@@ -176,14 +196,14 @@ set_squared_corners(struct ssd *ssd, bool enable)
 }
 
 static void
-set_maximize_alt_icon(struct ssd *ssd, bool enable)
+set_alt_button_icon(struct ssd *ssd, enum ssd_part_type type, 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);
+               part = ssd_get_part(&subtree->parts, type);
                if (!part) {
                        return;
                }
@@ -214,12 +234,17 @@ ssd_titlebar_update(struct ssd *ssd)
                && !maximized;
 
        if (ssd->state.was_maximized != maximized
+                       || ssd->state.was_shaded != view->shaded
                        || ssd->state.was_tiled_not_maximized != tiled_not_maximized) {
                set_squared_corners(ssd, maximized || tiled_not_maximized);
                if (ssd->state.was_maximized != maximized) {
-                       set_maximize_alt_icon(ssd, maximized);
+                       set_alt_button_icon(ssd, LAB_SSD_BUTTON_MAXIMIZE, maximized);
+               }
+               if (ssd->state.was_shaded != view->shaded) {
+                       set_alt_button_icon(ssd, LAB_SSD_BUTTON_SHADE, view->shaded);
                }
                ssd->state.was_maximized = maximized;
+               ssd->state.was_shaded = view->shaded;
                ssd->state.was_tiled_not_maximized = tiled_not_maximized;
        }
 
index ca82fe4a29b2da86b57ba5ceae43d842ecb58612..3d14750016301e0e033772c7d030357f7cca7a24 100644 (file)
@@ -74,15 +74,6 @@ ssd_max_extents(struct view *view)
        };
 }
 
-bool
-ssd_is_button(enum ssd_part_type type)
-{
-       return type == LAB_SSD_BUTTON_CLOSE
-               || type == LAB_SSD_BUTTON_MAXIMIZE
-               || type == LAB_SSD_BUTTON_ICONIFY
-               || type == LAB_SSD_BUTTON_WINDOW_MENU;
-}
-
 enum ssd_part_type
 ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
 {
@@ -257,16 +248,17 @@ ssd_update_geometry(struct ssd *ssd)
                        ssd->state.geometry = current;
                }
                bool maximized = ssd->view->maximized == VIEW_AXIS_BOTH;
-               if (ssd->state.was_maximized != maximized) {
+               if (ssd->state.was_maximized != maximized
+                               || ssd->state.was_shaded != ssd->view->shaded) {
                        ssd_titlebar_update(ssd);
                        ssd_border_update(ssd);
                        ssd_shadow_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.
+                        * already sets these values, but set here to be safe.
                         */
                        ssd->state.was_maximized = maximized;
+                       ssd->state.was_shaded = ssd->view->shaded;
                }
                bool tiled_and_not_maximized = view_is_tiled(ssd->view) && !maximized;
                if (ssd->state.was_tiled_not_maximized != tiled_and_not_maximized) {
@@ -403,6 +395,7 @@ ssd_enable_shade(struct ssd *ssd, bool enable)
        if (!ssd) {
                return;
        }
+       ssd_titlebar_update(ssd);
        ssd_border_update(ssd);
        wlr_scene_node_set_enabled(&ssd->extents.tree->node, !enable);
        ssd_shadow_update(ssd);
index 486773029dbb1e2fcb890b8d4014cb1983060b8b..c4f576af4e0bf4d5c0847f6be0e079e688c18f5c 100644 (file)
@@ -79,6 +79,19 @@ zdrop(struct lab_data_buffer **buffer)
        }
 }
 
+static bool
+match_button_by_name(struct title_button *b, const char *icon_name)
+{
+       assert(icon_name);
+       return (b->type == LAB_SSD_BUTTON_WINDOW_MENU && !strcmp(icon_name, "menu"))
+               || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max"))
+               || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max_toggled"))
+               || (b->type == LAB_SSD_BUTTON_ICONIFY && !strcmp(icon_name, "iconify"))
+               || (b->type == LAB_SSD_BUTTON_CLOSE && !strcmp(icon_name, "close"))
+               || (b->type == LAB_SSD_BUTTON_SHADE && !strcmp(icon_name, "shade"))
+               || (b->type == LAB_SSD_BUTTON_SHADE && !strcmp(icon_name, "shade_toggled"));
+}
+
 static enum corner
 corner_from_icon_name(const char *icon_name)
 {
@@ -86,21 +99,13 @@ corner_from_icon_name(const char *icon_name)
 
        struct title_button *b;
        wl_list_for_each(b, &rc.title_buttons_left, link) {
-               if ((b->type == LAB_SSD_BUTTON_WINDOW_MENU && !strcmp(icon_name, "menu"))
-                       || (b->type == LAB_SSD_BUTTON_ICONIFY && !strcmp(icon_name, "iconify"))
-                       || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max"))
-                       || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max_toggled"))
-                       || (b->type == LAB_SSD_BUTTON_CLOSE && !strcmp(icon_name, "close"))) {
+               if (match_button_by_name(b, icon_name)) {
                        return LAB_CORNER_TOP_LEFT;
                }
                break;
        }
        wl_list_for_each_reverse(b, &rc.title_buttons_right, link) {
-               if ((b->type == LAB_SSD_BUTTON_WINDOW_MENU && !strcmp(icon_name, "menu"))
-                       || (b->type == LAB_SSD_BUTTON_ICONIFY && !strcmp(icon_name, "iconify"))
-                       || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max"))
-                       || (b->type == LAB_SSD_BUTTON_MAXIMIZE && !strcmp(icon_name, "max_toggled"))
-                       || (b->type == LAB_SSD_BUTTON_CLOSE && !strcmp(icon_name, "close"))) {
+               if (match_button_by_name(b, icon_name)) {
                        return LAB_CORNER_TOP_RIGHT;
                }
                break;
@@ -244,6 +249,20 @@ load_buttons(struct theme *theme)
                .active.rgba = theme->window_active_button_max_unpressed_image_color,
                .inactive.buffer = &theme->button_restore_inactive_unpressed,
                .inactive.rgba = theme->window_inactive_button_max_unpressed_image_color,
+       }, {
+               .name = "shade",
+               .fallback_button = (const char[]){ 0x3f, 0x3f, 0x00, 0x0c, 0x1e, 0x3f },
+               .active.buffer = &theme->button_shade_active_unpressed,
+               .active.rgba = theme->window_active_button_shade_unpressed_image_color,
+               .inactive.buffer = &theme->button_shade_inactive_unpressed,
+               .inactive.rgba = theme->window_inactive_button_shade_unpressed_image_color,
+       }, {
+               .name = "shade_toggled",
+               .fallback_button = (const char[]){ 0x3f, 0x3f, 0x00, 0x3f, 0x1e, 0x0c },
+               .active.buffer = &theme->button_unshade_active_unpressed,
+               .active.rgba = theme->window_active_button_shade_unpressed_image_color,
+               .inactive.buffer = &theme->button_unshade_inactive_unpressed,
+               .inactive.rgba = theme->window_inactive_button_shade_unpressed_image_color,
        }, {
                .name = "close",
                .fallback_button = (const char[]){ 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 },
@@ -280,6 +299,21 @@ load_buttons(struct theme *theme)
                .active.rgba = theme->window_active_button_max_unpressed_image_color,
                .inactive.buffer = &theme->button_restore_inactive_hover,
                .inactive.rgba = theme->window_inactive_button_max_unpressed_image_color,
+       }, {
+               .name = "shade_hover",
+               /* no fallback (non-hover variant is used instead) */
+               .active.buffer = &theme->button_shade_active_hover,
+               .active.rgba = theme->window_active_button_shade_unpressed_image_color,
+               .inactive.buffer = &theme->button_shade_inactive_hover,
+               .inactive.rgba = theme->window_inactive_button_shade_unpressed_image_color,
+       }, {
+               .name = "shade_toggled_hover",
+               .alt_name = "shade_hover_toggled",
+               /* no fallback (non-hover variant is used instead) */
+               .active.buffer = &theme->button_unshade_active_hover,
+               .active.rgba = theme->window_active_button_shade_unpressed_image_color,
+               .inactive.buffer = &theme->button_unshade_inactive_hover,
+               .inactive.rgba = theme->window_inactive_button_shade_unpressed_image_color,
        }, {
                .name = "close_hover",
                /* no fallback (non-hover variant is used instead) */
@@ -509,6 +543,8 @@ theme_builtin(struct theme *theme, struct server *server)
                theme->window_active_button_iconify_unpressed_image_color);
        parse_hexstr("#000000",
                theme->window_active_button_max_unpressed_image_color);
+       parse_hexstr("#000000",
+               theme->window_active_button_shade_unpressed_image_color);
        parse_hexstr("#000000",
                theme->window_active_button_close_unpressed_image_color);
        parse_hexstr("#000000",
@@ -517,6 +553,8 @@ theme_builtin(struct theme *theme, struct server *server)
                theme->window_inactive_button_iconify_unpressed_image_color);
        parse_hexstr("#000000",
                theme->window_inactive_button_max_unpressed_image_color);
+       parse_hexstr("#000000",
+               theme->window_inactive_button_shade_unpressed_image_color);
        parse_hexstr("#000000",
                theme->window_inactive_button_close_unpressed_image_color);
 
@@ -681,6 +719,8 @@ entry(struct theme *theme, const char *key, const char *value)
                        theme->window_active_button_iconify_unpressed_image_color);
                parse_hexstr(value,
                        theme->window_active_button_max_unpressed_image_color);
+               parse_hexstr(value,
+                       theme->window_active_button_shade_unpressed_image_color);
                parse_hexstr(value,
                        theme->window_active_button_close_unpressed_image_color);
        }
@@ -691,6 +731,8 @@ entry(struct theme *theme, const char *key, const char *value)
                        theme->window_inactive_button_iconify_unpressed_image_color);
                parse_hexstr(value,
                        theme->window_inactive_button_max_unpressed_image_color);
+               parse_hexstr(value,
+                       theme->window_inactive_button_shade_unpressed_image_color);
                parse_hexstr(value,
                        theme->window_inactive_button_close_unpressed_image_color);
        }
@@ -708,6 +750,10 @@ entry(struct theme *theme, const char *key, const char *value)
                parse_hexstr(value,
                        theme->window_active_button_max_unpressed_image_color);
        }
+       if (match_glob(key, "window.active.button.shade.unpressed.image.color")) {
+               parse_hexstr(value,
+                       theme->window_active_button_shade_unpressed_image_color);
+       }
        if (match_glob(key, "window.active.button.close.unpressed.image.color")) {
                parse_hexstr(value,
                        theme->window_active_button_close_unpressed_image_color);
@@ -724,6 +770,10 @@ entry(struct theme *theme, const char *key, const char *value)
                parse_hexstr(value,
                        theme->window_inactive_button_max_unpressed_image_color);
        }
+       if (match_glob(key, "window.inactive.button.shade.unpressed.image.color")) {
+               parse_hexstr(value,
+                       theme->window_inactive_button_shade_unpressed_image_color);
+       }
        if (match_glob(key, "window.inactive.button.close.unpressed.image.color")) {
                parse_hexstr(value,
                        theme->window_inactive_button_close_unpressed_image_color);
@@ -1442,24 +1492,32 @@ theme_finish(struct theme *theme)
        zdrop(&theme->button_close_active_unpressed);
        zdrop(&theme->button_maximize_active_unpressed);
        zdrop(&theme->button_restore_active_unpressed);
+       zdrop(&theme->button_shade_active_unpressed);
+       zdrop(&theme->button_unshade_active_unpressed);
        zdrop(&theme->button_iconify_active_unpressed);
        zdrop(&theme->button_menu_active_unpressed);
 
        zdrop(&theme->button_close_inactive_unpressed);
        zdrop(&theme->button_maximize_inactive_unpressed);
        zdrop(&theme->button_restore_inactive_unpressed);
+       zdrop(&theme->button_shade_inactive_unpressed);
+       zdrop(&theme->button_unshade_inactive_unpressed);
        zdrop(&theme->button_iconify_inactive_unpressed);
        zdrop(&theme->button_menu_inactive_unpressed);
 
        zdrop(&theme->button_close_active_hover);
        zdrop(&theme->button_maximize_active_hover);
        zdrop(&theme->button_restore_active_hover);
+       zdrop(&theme->button_shade_active_hover);
+       zdrop(&theme->button_unshade_active_hover);
        zdrop(&theme->button_iconify_active_hover);
        zdrop(&theme->button_menu_active_hover);
 
        zdrop(&theme->button_close_inactive_hover);
        zdrop(&theme->button_maximize_inactive_hover);
        zdrop(&theme->button_restore_inactive_hover);
+       zdrop(&theme->button_shade_inactive_hover);
+       zdrop(&theme->button_unshade_inactive_hover);
        zdrop(&theme->button_iconify_inactive_hover);
        zdrop(&theme->button_menu_inactive_hover);