From a595fc7ca575de9de87f1311f3113f6fd4c6c326 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 15 Sep 2026 17:24:02 +0200 Subject: fix: give the launcher a mark for each state The pill inverts on hover, so one mark could never work: filled dark it vanished on the dark hover background, filled light it would vanish on the accent pill at rest. Both halves of that shipped, one after the other. Removing the hover rule did not help either, because the GTK theme paints its own hover shade on the button node underneath. Declining to set a background does not leave the pill alone, it leaves that shade in charge. So the mark moves out of the image module and into CSS, where a background-image can be swapped per state: dark on the accent pill at rest, light on the dark pill hovered, with the hover background set explicitly rather than left to the theme. install.sh generates both tints from one source file, so they cannot drift apart in shape. That makes the launcher a custom module, since an image module's path is read once and CSS cannot reach inside it. Its format is a single space for the usual reason: an empty one draws no widget at all. install.sh also removes the file the old image module left behind. The prune only clears dangling symlinks, and that one was written as a real file, so nothing had been removing it. Co-Authored-By: Claude Opus 5 --- README.md | 16 +++++++------- SPEC.md | 4 ++-- config.jsonc | 4 ++-- icons/slackware-light.svg | 12 +++++++++++ install.sh | 40 +++++++++++++++++------------------ modules/custom/launcher.jsonc | 22 +++++++++++++++++++ modules/image/launcher.jsonc | 19 ----------------- styles/modules.css | 49 +++++++++++++++++++++++++++---------------- styles/pills.css | 6 +++--- 9 files changed, 100 insertions(+), 72 deletions(-) create mode 100644 icons/slackware-light.svg create mode 100644 modules/custom/launcher.jsonc delete mode 100644 modules/image/launcher.jsonc diff --git a/README.md b/README.md index 6abc653..b39aee2 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ single one covers everything: | Mechanism | Used by | Why | | --- | --- | --- | | `icon-theme` config key | taskbar, tray | Native support, nothing else needed. | -| `image` module | launcher, volume, microphone, language | Takes a path: either static, or from a script that resolves the current state. | -| CSS `background-image` | workspaces, clock, mail, presentation mode | `format-icons` takes text, not paths. | +| `image` module | volume, microphone, language | Takes a path from a script that resolves the current state. | +| CSS `background-image` | workspaces, clock, mail, presentation mode, launcher | `format-icons` takes text, not paths, and CSS can swap the image per state. | The consequence worth knowing: **the workspace icons live in `styles/modules.css`, not in the module config.** Changing one means editing @@ -67,11 +67,13 @@ with nothing to say why, so it fails while someone is watching instead. gradient and are not recolourable. That is intended here: icons match the rest of the desktop rather than the bar. -The three icons this repo ships are the exception, because the icon theme has -none of them. `icons/slackware.svg` (Simple Icons, CC0) is single-path -monochrome, so `install.sh` tints it from the palette. It is filled with the -bar's background colour rather than the accent, because it sits on the accent -pill and the accent would render it invisible against itself. +The icons this repo ships are the exception, because the icon theme has none +of them. `icons/slackware.svg` (Simple Icons, CC0) is single-path monochrome, +so `install.sh` tints it from the palette, **twice**: the launcher pill +inverts on hover, so the mark has to invert with it, dark on the accent pill +at rest and light on the dark pill hovered. One mark would be invisible in one +of the two states, which is what shipped twice before this. Both tints are +generated from one source file, so they cannot drift apart in shape. `icons/flag-it.svg` and `icons/burger.svg` (Twemoji, CC-BY 4.0) keep their own colours. The hamburger stands in for the English layout, which is what the diff --git a/SPEC.md b/SPEC.md index 54e6d62..8042637 100644 --- a/SPEC.md +++ b/SPEC.md @@ -47,7 +47,7 @@ transparent gaps, so the bar reads as groups rather than a continuous strip. | Position | Module | Icon source | Notes | | --- | --- | --- | --- | -| DP-1 centre | `image#launcher` | `slackware.svg`, shipped here | Accent background, the one always-coloured pill. Opens the quickshell drawer. An `image` module: a `custom` one draws nothing when its format is empty, and the format has to be empty because the mark is an icon. | +| DP-1 centre | `custom/launcher` | `slackware.svg` + `slackware-light.svg`, shipped here | Accent background, the one always-coloured pill. Opens the quickshell drawer. A `custom` module with the mark as a CSS background, because CSS can swap the image on `:hover` and cannot reach inside an `image` module. Its format is a single space: an empty one draws no widget at all. | | left | `clock#date` | `x-office-calendar` | Icon then text. Calendar tooltip kept. | | left | `clock#time` | `clock` | Icon then text. | | left | `hyprland/workspaces` | eight themed icons, via CSS | See below. | @@ -134,7 +134,7 @@ Modular, one file per module, mirroring the current setup: workspaces.jsonc language.jsonc custom/ - launcher.jsonc + launcher.jsonc the drawer button, mark drawn in CSS vmdot.jsonc extras/ taskbar.jsonc diff --git a/config.jsonc b/config.jsonc index 58944aa..d93907c 100644 --- a/config.jsonc +++ b/config.jsonc @@ -51,7 +51,7 @@ { "include": [ "$HOME/.config/waybar-udt/modules/hyprland/workspaces.jsonc", - "$HOME/.config/waybar-udt/modules/image/launcher.jsonc", + "$HOME/.config/waybar-udt/modules/custom/launcher.jsonc", "$HOME/.config/waybar-udt/modules/extras/taskbar.jsonc", ], @@ -59,7 +59,7 @@ "hyprland/workspaces" ], "modules-center": [ - "image#launcher" + "custom/launcher" ], "modules-right": [ "wlr/taskbar" diff --git a/icons/slackware-light.svg b/icons/slackware-light.svg new file mode 100644 index 0000000..74e6911 --- /dev/null +++ b/icons/slackware-light.svg @@ -0,0 +1,12 @@ + + + + diff --git a/install.sh b/install.sh index bae549c..cf4965d 100755 --- a/install.sh +++ b/install.sh @@ -90,6 +90,7 @@ for f in modules/clock.jsonc \ modules/hyprland/workspaces.jsonc \ modules/custom/vmdot.jsonc modules/custom/privacy_dots.jsonc \ modules/custom/presentation.jsonc modules/custom/mail.jsonc \ + modules/custom/launcher.jsonc \ modules/extras/taskbar.jsonc modules/extras/tray.jsonc \ modules/image/volume.jsonc modules/image/language.jsonc; do ln -sfn "$repo/$f" "$target/$f" @@ -104,31 +105,28 @@ done sed -e "s|@ICONS@|$icons|g" -e "s|@CONFIG@|$target|g" \ "$repo/styles/modules.css" > "$target/styles/modules.css" -# The launcher module is generated for the same reason. A module's `path` is -# NOT shell-expanded the way `exec` is, so it needs the absolute path written -# in: with "$HOME/..." waybar finds no file and the module draws nothing, with -# no error to say why. -# -# The target is removed first. An earlier install symlinked this file, and a -# redirect onto a surviving link writes THROUGH it: the shell truncates the -# link's target, which is the repo's own copy, before sed reads it. That -# emptied the source file once already. -rm -f "$target/modules/image/launcher.jsonc" -sed "s|@CONFIG@|$target|g" \ - "$repo/modules/image/launcher.jsonc" > "$target/modules/image/launcher.jsonc" +# The launcher module carries no generated path any more: its mark is a CSS +# background, so modules.css owns the paths and the module file is a plain +# symlink like every other. # The flags ship as they are; the Slackware mark is monochrome, so it is -# tinted here. It sits ON the accent pill, so it takes the bar's background -# colour rather than the accent: filled with the accent it would be invisible -# against its own pill, which is exactly what the first version did. -mark="$(sed -n 's/^@define-color main-bg *\(.*\);$/\1/p' "$target/styles/theme.css" | head -1)" -mark="${mark:-#24273a}" -sed "s|@ACCENT@|$mark|" "$repo/icons/slackware.svg" > "$target/slackware.svg" +# tinted here, twice. The pill inverts on hover, so the mark has to invert +# with it: dark on the accent pill at rest, light on the dark pill hovered. +# One mark and one pill colour would always collide in one of the two states, +# which is exactly what shipped twice before this. +mark_dark="$(sed -n 's/^@define-color main-bg *\(.*\);$/\1/p' "$target/styles/theme.css" | head -1)" +mark_light="$(sed -n 's/^@define-color main-fg *\(.*\);$/\1/p' "$target/styles/theme.css" | head -1)" +mark_dark="${mark_dark:-#24273a}" +mark_light="${mark_light:-#cad3f5}" +sed "s|@ACCENT@|$mark_dark|" "$repo/icons/slackware.svg" > "$target/slackware.svg" +sed "s|@MARK_LIGHT@|$mark_light|" "$repo/icons/slackware-light.svg" > "$target/slackware-light.svg" install -Dm644 "$repo/icons/flag-it.svg" "$target/flag-it.svg" install -Dm644 "$repo/icons/burger.svg" "$target/burger.svg" -# The UK flag was replaced by the hamburger for English; drop a copy left by -# an earlier install, or wb-lang's old target lingers on disk unreferenced. -rm -f "$target/flag-gb.svg" +# Files an earlier install generated that nothing references any more. The +# prune above only clears dangling SYMLINKS, and these were written as real +# files, so nothing else removes them: the UK flag the hamburger replaced, and +# the launcher from when it was an image module. +rm -f "$target/flag-gb.svg" "$target/modules/image/launcher.jsonc" # ---------------------------------------------------------------- scripts -- # The two dot scripts used to live only in ~/bin, in no repository at all. diff --git a/modules/custom/launcher.jsonc b/modules/custom/launcher.jsonc new file mode 100644 index 0000000..9aa901c --- /dev/null +++ b/modules/custom/launcher.jsonc @@ -0,0 +1,22 @@ +// Opens the quickshell desktop drawer. A static button: no "exec", so it +// cannot show whether the drawer is open, which would need the shell to feed +// waybar. +// +// A custom module rather than an image one, because the mark has to change +// between the resting and hover states. An image module's `path` is read once +// and CSS cannot reach it, so the mark could not be swapped; a CSS +// background-image can, which is the same mechanism the workspaces, the clock +// and the mail pill already use. +// +// The format is a single space, and it has to be something. It defaults to +// "{text}", a static custom module has no text, and waybar draws no widget at +// all for a custom module whose formatted output is empty: not an empty pill, +// no pill. A space gives the label real content to be allocated for and shows +// nothing itself. +{ + "custom/launcher": { + "format": " ", + "tooltip": false, + "on-click": "qs -p $HOME/Programming/GIT/quickshell/desktop ipc call drawer toggle" + } +} diff --git a/modules/image/launcher.jsonc b/modules/image/launcher.jsonc deleted file mode 100644 index 7c7b979..0000000 --- a/modules/image/launcher.jsonc +++ /dev/null @@ -1,19 +0,0 @@ -// Opens the quickshell desktop drawer. A static button: no state, because -// waybar cannot see whether the drawer is open without the shell feeding it. -// -// An `image` module rather than a custom one: a custom module draws nothing at -// all when its format is empty, and the format has to be empty because the -// mark is an icon rather than text. `image` takes a path and needs no label. -// -// This file is GENERATED into place by install.sh, not symlinked: `path` is -// not shell-expanded the way `exec` is, so a "$HOME/..." here is taken -// literally, no file is found, and the module draws nothing without saying so. -// @CONFIG@ becomes the absolute install directory. -{ - "image#launcher": { - "path": "@CONFIG@/slackware.svg", - "size": 18, - "tooltip": false, - "on-click": "qs -p $HOME/Programming/GIT/quickshell/desktop ipc call drawer toggle" - } -} diff --git a/styles/modules.css b/styles/modules.css index cac68da..9131752 100644 --- a/styles/modules.css +++ b/styles/modules.css @@ -10,28 +10,41 @@ * Launcher: the one always-coloured pill, and the desktop's identity. * * ------------------------------------------------------------------ */ -/* The mark itself is the image module's own content, so this only draws the - * pill it sits in. The horizontal padding is wider than the vertical so the - * pill reads as a capsule like its neighbours rather than a circle: an image - * module sizes to its icon, where the others size to their text. */ -#image.launcher { - background: @accent; +/* Launcher: two marks, one per state. + * + * The mark is a CSS background rather than an image module's content, which + * is what makes this possible at all: CSS can swap a background-image on + * :hover, but it cannot reach inside an image module to recolour what that + * module drew. + * + * Two files, same path, different fill: dark on the accent pill at rest, + * light on the dark pill when hovered. install.sh generates both from one + * source, so they cannot drift apart in shape. + * + * The hover background is set explicitly rather than left out. The GTK theme + * paints its own hover shade on the button node underneath, so declining to + * set one does not leave the pill alone, it leaves the shade in charge, and + * the pill went dark with the dark mark on it. That was the second version of + * this bug; the first filled the mark with @accent and drew it on the @accent + * pill. + * + * min-height is load-bearing: the label is a single space, so without it the + * background paints into a box with almost no height. */ +#custom-launcher { + background-color: @accent; + background-image: url("@CONFIG@/slackware.svg"); + background-repeat: no-repeat; + background-position: center; + background-size: 18px 18px; padding: 2px 14px; min-width: 20px; + min-height: 18px; } -/* This pill deliberately has NO hover background. - * - * The mark is a rendered image inside the module, not a CSS background, so - * CSS cannot recolour it for a hover state. It is filled with @main-bg to - * contrast against the accent pill, which means any hover that sets the - * background to @main-bg paints the mark in its own colour and the pill goes - * blank. That shipped twice: first filled with @accent on an @accent pill, - * then hovering to @main-bg with an @main-bg mark. - * - * Changing the background here at all requires a colour that contrasts with - * BOTH @accent and @main-bg, which the palette does not owe us. So the pill - * holds its colour and the cursor alone signals it is clickable. */ +#custom-launcher:hover { + background-color: @main-bg; + background-image: url("@CONFIG@/slackware-light.svg"); +} /* ---------------------------------------------- * * Clock: the only text, each with a leading icon. * diff --git a/styles/pills.css b/styles/pills.css index 1794523..7bc9947 100644 --- a/styles/pills.css +++ b/styles/pills.css @@ -12,7 +12,7 @@ /* Every pill. Shared geometry lives here exactly once; modules.css only says * what is different about each one. */ -#image.launcher, +#custom-launcher, #clock.date, #clock.time, #workspaces, @@ -70,8 +70,8 @@ margin-right: 6px; } -/* Top bar, centre: the launcher stands alone. */ -#image.launcher { +/* DP-1 centre: the launcher stands alone. */ +#custom-launcher { margin-left: 6px; margin-right: 6px; } -- cgit v1.2.3