This commit is contained in:
chocolatemintychip 2026-05-17 13:17:57 -04:00 committed by GitHub
commit ea29369672
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 68 additions and 5 deletions

View file

@ -621,6 +621,7 @@ extending outward from the snapped edge.
- 'close': close - 'close': close
- 'shade': shade toggle - 'shade': shade toggle
- 'desk': all-desktops toggle - 'desk': all-desktops toggle
- 'ontop': always-on-top toggle
A colon deliminator is used to separate buttons on the left and right, A colon deliminator is used to separate buttons on the left and right,
whereas commas are used to separate items within a section. It is whereas commas are used to separate items within a section. It is
@ -900,6 +901,8 @@ input-devices by the Wayland protocol.
- Shade: A button that, by default, toggles window shading. - Shade: A button that, by default, toggles window shading.
- AllDesktops: A button that, by default, toggles omnipresence of a - AllDesktops: A button that, by default, toggles omnipresence of a
window. window.
- OnTop: A button that, by default, toggles always-on-top state of a
window.
- Close: A button that, by default, closses a window. - Close: A button that, by default, closses a window.
- Border: The window's border including Top...BRCorner below. - Border: The window's border including Top...BRCorner below.
- Top: The top edge of the window's border. - Top: The top edge of the window's border.

View file

@ -494,6 +494,8 @@ file within a particular theme. The following xbm buttons are supported:
- max_toggled.xbm - max_toggled.xbm
- desk.xbm - desk.xbm
- desk_toggled.xbm - desk_toggled.xbm
- ontop.xbm
- ontop_toggled.xbm
- shade.xbm - shade.xbm
- shade_toggled.xbm - shade_toggled.xbm
@ -506,9 +508,11 @@ over the button in question:
- menu_hover.xbm - menu_hover.xbm
- max_toggled_hover.xbm - max_toggled_hover.xbm
- desk_hover.xbm - desk_hover.xbm
- desk_toggle_hover.xbm - desk_toggled_hover.xbm
- ontop_hover.xbm
- ontop_toggled_hover.xbm
- shade_hover.xbm - shade_hover.xbm
- shade_toggle_hover.xbm - shade_toggled_hover.xbm
One advantage of xbm buttons over other formats is that they change color based One advantage of xbm buttons over other formats is that they change color based
on the theme. Other formats use the suffices "-active" and "-inactive" to align on the theme. Other formats use the suffices "-active" and "-inactive" to align
@ -558,7 +562,14 @@ following icons should be added:
- desk_toggled-inactive.[png|svg] - desk_toggled-inactive.[png|svg]
- desk_toggled_hover-active.[png|svg] - desk_toggled_hover-active.[png|svg]
- desk_toggled_hover-inactive.[png|svg] - desk_toggled_hover-inactive.[png|svg]
- ontop-active.[png|svg]
- ontop_hover-active.[png|svg]
- ontop_hover-inactive.[png|svg]
- ontop-inactive.[png|svg]
- ontop_toggled-active.[png|svg]
- ontop_toggled-inactive.[png|svg]
- ontop_toggled_hover-active.[png|svg]
- ontop_toggled_hover-inactive.[png|svg]
# DEFINITIONS # DEFINITIONS
The handle is the window edge decoration at the bottom of the window. The handle is the window edge decoration at the bottom of the window.

View file

@ -26,8 +26,9 @@ enum lab_node_type {
LAB_NODE_BUTTON_WINDOW_MENU, LAB_NODE_BUTTON_WINDOW_MENU,
LAB_NODE_BUTTON_SHADE, LAB_NODE_BUTTON_SHADE,
LAB_NODE_BUTTON_OMNIPRESENT, LAB_NODE_BUTTON_OMNIPRESENT,
LAB_NODE_BUTTON_ONTOP,
LAB_NODE_BUTTON_FIRST = LAB_NODE_BUTTON_CLOSE, LAB_NODE_BUTTON_FIRST = LAB_NODE_BUTTON_CLOSE,
LAB_NODE_BUTTON_LAST = LAB_NODE_BUTTON_OMNIPRESENT, LAB_NODE_BUTTON_LAST = LAB_NODE_BUTTON_ONTOP,
LAB_NODE_BUTTON, LAB_NODE_BUTTON,
LAB_NODE_TITLEBAR, LAB_NODE_TITLEBAR,

View file

@ -291,6 +291,11 @@ static struct mouse_combos {
.button = "Left", .button = "Left",
.event = "Click", .event = "Click",
.action = "ToggleOmnipresent", .action = "ToggleOmnipresent",
}, {
.context = "OnTop",
.button = "Left",
.event = "Click",
.action = "ToggleAlwaysOnTop",
}, { }, {
.context = "Maximize", .context = "Maximize",
.button = "Right", .button = "Right",

View file

@ -79,6 +79,7 @@ struct ssd {
* such a small titlebar. * such a small titlebar.
*/ */
bool was_squared; bool was_squared;
bool was_ontop;
struct wlr_box geometry; struct wlr_box geometry;
struct ssd_state_title { struct ssd_state_title {

View file

@ -20,6 +20,8 @@ node_type_parse(const char *context)
return LAB_NODE_BUTTON_SHADE; return LAB_NODE_BUTTON_SHADE;
} else if (!strcasecmp(context, "AllDesktops")) { } else if (!strcasecmp(context, "AllDesktops")) {
return LAB_NODE_BUTTON_OMNIPRESENT; return LAB_NODE_BUTTON_OMNIPRESENT;
} else if (!strcasecmp(context, "OnTop")) {
return LAB_NODE_BUTTON_ONTOP;
} else if (!strcasecmp(context, "Titlebar")) { } else if (!strcasecmp(context, "Titlebar")) {
return LAB_NODE_TITLEBAR; return LAB_NODE_TITLEBAR;
} else if (!strcasecmp(context, "Title")) { } else if (!strcasecmp(context, "Title")) {

View file

@ -184,6 +184,8 @@ fill_section(const char *content, enum lab_node_type *buttons, int *count,
type = LAB_NODE_BUTTON_SHADE; type = LAB_NODE_BUTTON_SHADE;
} else if (!strcmp(identifier, "desk")) { } else if (!strcmp(identifier, "desk")) {
type = LAB_NODE_BUTTON_OMNIPRESENT; type = LAB_NODE_BUTTON_OMNIPRESENT;
} else if (!strcmp(identifier, "ontop")) {
type = LAB_NODE_BUTTON_ONTOP;
} else { } else {
wlr_log(WLR_ERROR, "invalid titleLayout identifier '%s'", wlr_log(WLR_ERROR, "invalid titleLayout identifier '%s'",
identifier); identifier);

View file

@ -299,6 +299,12 @@ ssd_titlebar_update(struct ssd *ssd)
ssd->state.was_omnipresent = view->visible_on_all_workspaces; ssd->state.was_omnipresent = view->visible_on_all_workspaces;
} }
if (ssd->state.was_ontop != view->layer) {
set_alt_button_icon(ssd, LAB_NODE_BUTTON_ONTOP,
view->layer);
ssd->state.was_ontop = view->layer;
}
if (width == ssd->state.geometry.width) { if (width == ssd->state.geometry.width) {
return; return;
} }

View file

@ -227,7 +227,8 @@ ssd_update_geometry(struct ssd *ssd)
bool state_changed = ssd->state.was_maximized != maximized bool state_changed = ssd->state.was_maximized != maximized
|| ssd->state.was_shaded != view->shaded || ssd->state.was_shaded != view->shaded
|| ssd->state.was_squared != squared || ssd->state.was_squared != squared
|| ssd->state.was_omnipresent != view->visible_on_all_workspaces; || ssd->state.was_omnipresent != view->visible_on_all_workspaces
|| ssd->state.was_ontop != (view->layer == VIEW_LAYER_ALWAYS_ON_TOP);
/* /*
* (Un)maximization updates titlebar visibility with * (Un)maximization updates titlebar visibility with

View file

@ -315,6 +315,16 @@ load_buttons(struct theme *theme)
.fallback_button = (const char[]){ 0x00, 0x1e, 0x1a, 0x16, 0x1e, 0x00 }, .fallback_button = (const char[]){ 0x00, 0x1e, 0x1a, 0x16, 0x1e, 0x00 },
.type = LAB_NODE_BUTTON_OMNIPRESENT, .type = LAB_NODE_BUTTON_OMNIPRESENT,
.state_set = LAB_BS_TOGGLED, .state_set = LAB_BS_TOGGLED,
}, {
.name = "ontop",
.fallback_button = (const char[]){ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
.type = LAB_NODE_BUTTON_ONTOP,
.state_set = 0,
}, {
.name = "ontop_toggled",
.fallback_button = (const char[]){ 0x00, 0x0c, 0x1e, 0x33, 0x21, 0x00 },
.type = LAB_NODE_BUTTON_ONTOP,
.state_set = LAB_BS_TOGGLED,
}, { }, {
.name = "close", .name = "close",
.fallback_button = (const char[]){ 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 }, .fallback_button = (const char[]){ 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 },
@ -363,6 +373,17 @@ load_buttons(struct theme *theme)
.type = LAB_NODE_BUTTON_OMNIPRESENT, .type = LAB_NODE_BUTTON_OMNIPRESENT,
.state_set = LAB_BS_TOGGLED | LAB_BS_HOVERED, .state_set = LAB_BS_TOGGLED | LAB_BS_HOVERED,
/* no fallback (non-hover variant is used instead) */ /* no fallback (non-hover variant is used instead) */
}, {
.name = "ontop_hover",
/* no fallback (non-hover variant is used instead) */
.type = LAB_NODE_BUTTON_ONTOP,
.state_set = LAB_BS_HOVERED,
}, {
.name = "ontop_toggled_hover",
.alt_name = "ontop_hover_toggled",
.type = LAB_NODE_BUTTON_ONTOP,
.state_set = LAB_BS_TOGGLED | LAB_BS_HOVERED,
/* no fallback (non-hover variant is used instead) */
}, { }, {
.name = "close_hover", .name = "close_hover",
.type = LAB_NODE_BUTTON_CLOSE, .type = LAB_NODE_BUTTON_CLOSE,
@ -836,6 +857,10 @@ entry(struct theme *theme, const char *key, const char *value)
parse_color(value, theme->window[SSD_ACTIVE] parse_color(value, theme->window[SSD_ACTIVE]
.button_colors[LAB_NODE_BUTTON_OMNIPRESENT]); .button_colors[LAB_NODE_BUTTON_OMNIPRESENT]);
} }
if (match_glob(key, "window.active.button.ontop.unpressed.image.color")) {
parse_color(value, theme->window[SSD_ACTIVE]
.button_colors[LAB_NODE_BUTTON_ONTOP]);
}
if (match_glob(key, "window.active.button.close.unpressed.image.color")) { if (match_glob(key, "window.active.button.close.unpressed.image.color")) {
parse_color(value, theme->window[SSD_ACTIVE] parse_color(value, theme->window[SSD_ACTIVE]
.button_colors[LAB_NODE_BUTTON_CLOSE]); .button_colors[LAB_NODE_BUTTON_CLOSE]);
@ -862,6 +887,10 @@ entry(struct theme *theme, const char *key, const char *value)
parse_color(value, theme->window[SSD_INACTIVE] parse_color(value, theme->window[SSD_INACTIVE]
.button_colors[LAB_NODE_BUTTON_OMNIPRESENT]); .button_colors[LAB_NODE_BUTTON_OMNIPRESENT]);
} }
if (match_glob(key, "window.inactive.button.ontop.unpressed.image.color")) {
parse_color(value, theme->window[SSD_INACTIVE]
.button_colors[LAB_NODE_BUTTON_ONTOP]);
}
if (match_glob(key, "window.inactive.button.close.unpressed.image.color")) { if (match_glob(key, "window.inactive.button.close.unpressed.image.color")) {
parse_color(value, theme->window[SSD_INACTIVE] parse_color(value, theme->window[SSD_INACTIVE]
.button_colors[LAB_NODE_BUTTON_CLOSE]); .button_colors[LAB_NODE_BUTTON_CLOSE]);

View file

@ -1562,6 +1562,8 @@ view_toggle_always_on_top(struct view *view)
} else { } else {
view_set_layer(view, VIEW_LAYER_ALWAYS_ON_TOP); view_set_layer(view, VIEW_LAYER_ALWAYS_ON_TOP);
} }
// Hack to update always-on-top ssd button state. May be wasteful, idk.
ssd_update_geometry(view->ssd);
} }
void void