diff --git a/bin/rice-switch b/bin/rice-switch index f96f542..88d72e5 100755 --- a/bin/rice-switch +++ b/bin/rice-switch @@ -93,6 +93,9 @@ gui_menu() { current="$(current_rice)" local rice_names=() plain_rows="" rofi_rows="" active="" + local gutter_on='● ' + # alpha 1%: Pango's alpha range starts at 1, so 0% is not a valid value + local gutter_off='● ' for d in "$DOTFILES_DIR"/rices/*/; do [[ -d "$d" ]] || continue local rname title subtitle @@ -103,8 +106,13 @@ gui_menu() { [[ "$rname" == "$current" ]] && active="${#rice_names[@]}" rice_names+=("$rname") plain_rows+="$title${subtitle:+ — $subtitle}"$'\n' - rofi_rows+="$(markup_escape "$title")" - [[ -n "$subtitle" ]] && rofi_rows+=$'\n'"$(markup_escape "$subtitle")" + # A leading column holds a dot for the current rice. Both lines start + # with the same monospace glyph (invisible where unused), so the name + # and the subtitle stay aligned whatever the proportional font does. + local dot="$gutter_off" + [[ "$rname" == "$current" ]] && dot="$gutter_on" + rofi_rows+="$dot$(markup_escape "$title")" + [[ -n "$subtitle" ]] && rofi_rows+=$'\n'"$gutter_off$(markup_escape "$subtitle")" rofi_rows+=$'\x1f' done @@ -121,7 +129,7 @@ gui_menu() { # separated by \x1f instead of newlines local args=(-dmenu -i -no-custom -format i -markup-rows -sep $'\x1f' -eh 2 -l "${#rice_names[@]}" -p "󰍉" -theme "$theme" - -mesg "Current: $(markup_escape "$current") · ↵ switch and log out · esc cancel") + -mesg "Switching logs you out · ↵ switch · esc cancel") [[ -n "$active" ]] && args+=(-a "$active" -selected-row "$active") choice=$(printf '%s' "$rofi_rows" | rofi "${args[@]}") || return 0 elif command -v fuzzel >/dev/null 2>&1; then diff --git a/common/rofi/rice-switch.rasi b/common/rofi/rice-switch.rasi index eff7133..f464175 100644 --- a/common/rofi/rice-switch.rasi +++ b/common/rofi/rice-switch.rasi @@ -1,7 +1,6 @@ -/* Rice switcher (bin/rice-switch): frosted panel in the style of macOS Spotlight. - * Translucent enough for the compositor's blur, opaque enough to read without it. - * Only the accent comes from the palette (colors.rasi). */ -@import "colors.rasi" +/* Rice switcher (bin/rice-switch): a frosted row list in the style of macOS. + * Neutral glass on purpose; translucent enough for the compositor's blur and + * opaque enough to read without it. */ configuration { show-icons: false; @@ -11,15 +10,15 @@ configuration { } * { - font: "Inter 11"; + font: "Inter 10.5"; - glass: rgba(28, 28, 32, 70%); - stroke: rgba(255, 255, 255, 13%); + glass: rgba(30, 30, 34, 66%); + stroke: rgba(255, 255, 255, 14%); hairline: rgba(255, 255, 255, 7%); + field: rgba(255, 255, 255, 8%); text: rgba(255, 255, 255, 92%); - text-dim: rgba(235, 235, 245, 50%); + text-dim: rgba(235, 235, 245, 52%); hover: rgba(255, 255, 255, 10%); - accent: @selected-fg; background-color: transparent; text-color: @text; @@ -29,36 +28,54 @@ window { transparency: "real"; location: center; anchor: center; - width: 520px; - padding: 8px; + width: 540px; + padding: 20px 14px 14px 14px; border: 1px; border-color: @stroke; - border-radius: 18px; + border-radius: 24px; background-color: @glass; } mainbox { - spacing: 6px; - children: [ "inputbar", "listview", "message" ]; + spacing: 12px; + children: [ "header", "listview", "message" ]; +} + +header { + orientation: horizontal; + expand: false; + spacing: 16px; + padding: 0 6px; + children: [ "textbox-title", "inputbar" ]; +} + +textbox-title { + expand: true; + str: "Switch Desktop"; + font: "Inter Display Semi-Bold 16"; + vertical-align: 0.5; + horizontal-align: 0.0; + text-color: @text; } inputbar { - padding: 10px 12px 12px 12px; - spacing: 12px; - border: 0 0 1px 0; - border-color: @hairline; + expand: false; + width: 200px; + padding: 7px 12px; + spacing: 8px; + border-radius: 10px; + background-color: @field; children: [ "prompt", "entry" ]; } prompt { - font: "JetBrainsMono Nerd Font 15"; + font: "JetBrainsMono Nerd Font 11"; text-color: @text-dim; vertical-align: 0.5; } entry { - font: "Inter Display 15"; - placeholder: "Switch rice"; + placeholder: "Search"; placeholder-color: @text-dim; cursor: text; vertical-align: 0.5; @@ -71,12 +88,14 @@ listview { cycle: true; scrollbar: false; spacing: 2px; - padding: 2px 0; + padding: 8px 0 0 0; + border: 1px 0 0 0; + border-color: @hairline; } element { - padding: 8px 12px; - border-radius: 11px; + padding: 9px 14px; + border-radius: 12px; cursor: pointer; } @@ -88,22 +107,19 @@ element selected.active { element-text { text-color: inherit; vertical-align: 0.5; + highlight: bold; cursor: pointer; } -element normal.active, -element selected.active, -element alternate.active { - text-color: @accent; -} - message { - padding: 8px 12px 4px 12px; + padding: 10px 0 2px 0; border: 1px 0 0 0; border-color: @hairline; } +/* the footer; textbox-title above sets its own colour and alignment */ textbox { - font: "Inter 9.5"; + font: "Inter 9"; text-color: @text-dim; + horizontal-align: 0.5; } diff --git a/tests/rice-switch.sh b/tests/rice-switch.sh index c5f5282..cec025a 100755 --- a/tests/rice-switch.sh +++ b/tests/rice-switch.sh @@ -5,8 +5,8 @@ # 3. A chosen row still reaches the switch. # 4. Empty or path-like rice names are rejected. # 5. Menu content: one two-line row per rice (DISPLAY_NAME, then COMPOSITOR · -# SHELL_NAME), the current rice marked active, an out-of-range index -# ignored, theme fallback. +# SHELL_NAME), a dot and the active mark on the current rice, an +# out-of-range index ignored, theme fallback. set -euo pipefail REPO="$(cd "$(dirname "$0")/.." && pwd)" @@ -83,6 +83,8 @@ rices="$(find "$REPO/rices" -mindepth 1 -maxdepth 1 -type d | wc -l)" [[ "$rows" -eq "$rices" ]] || fail "expected $rices rows, got $rows" grep -qF 'end4' "$TMP/rofi.stdin" || fail "end4 row has no plain title: $(cat "$TMP/rofi.stdin")" grep -qF '>Hyprland · end4-pC Material 3' "$TMP/rofi.stdin" || fail "end4 row has no subtitle" +[[ "$(grep -o 'alpha="80%">●' "$TMP/rofi.stdin" | wc -l)" -eq 1 ]] || fail "expected one visible dot, for the current rice" +grep -qF 'alpha="80%">● end4' "$TMP/rofi.stdin" || fail "the dot is not on the end4 row" end4_index="$(find "$REPO/rices" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | LC_ALL=C sort | grep -nx end4 | cut -d: -f1)" grep -A1 -x -- '-a' "$TMP/rofi.args" | tail -n1 | grep -qx "$((end4_index - 1))" || fail "current rice not marked active: $(cat "$TMP/rofi.args")" grep -A1 -x -- '-theme' "$TMP/rofi.args" | tail -n1 | grep -q 'rice-switch.rasi$' || fail "rice-switch.rasi not used"