diff --git a/default/themed/shell.toml.tpl b/default/themed/shell.toml.tpl index b3d219da..3c2a700b 100644 --- a/default/themed/shell.toml.tpl +++ b/default/themed/shell.toml.tpl @@ -9,10 +9,8 @@ background-alpha = 1.0 text = "{{ foreground }}" # Modules calling attention to themselves (recording, voxtype, alerts, updates) active = "{{ color1 }}" -# Cross-axis size at font base-size 12. size-horizontal is the height of -# top/bottom bars; size-vertical is the width of left/right bars. With -# scale-with-font enabled, these grow/shrink with [font] base-size. -scale-with-font = true +# Cross-axis size in px. size-horizontal is the height of top/bottom bars; +# size-vertical is the width of left/right bars. size-horizontal = 26 size-vertical = 28 @@ -51,13 +49,11 @@ pressed-fill-alpha = 0.22 selection-fill-alpha = 0.35 [spacing] -# `scale` multiplies shared margins, gaps, padding, controls, and panel -# dimensions; components keep their proportions. With scale-with-font -# enabled, those dimensions grow/shrink with [font] base-size too. Per-token -# overrides (in px) below pin individual values without affecting the rest -# of the scale. Uncomment any to tune a specific surface. +# `scale` multiplies shared margins, gaps, and padding; components keep +# their proportions. Per-token overrides (in px) below pin individual +# values without affecting the rest of the scale. Uncomment any to tune +# a specific surface. scale = 1.0 -scale-with-font = true # xxs = 2 # xs = 3 # sm = 4 @@ -87,8 +83,8 @@ scale-with-font = true [font] # base-size is the rem root for the type scale. Every Style.font. # derives from it (e.g. body = base, subtitle ≈ base * 1.083, -# heading ≈ base * 1.333). The shell only floors this at 1px; increase it -# as much as you want. +# heading ≈ base * 1.333). Clamped 11..13 by the shell because some +# row heights remain fixed, so larger type can clip. base-size = 12 # Per-token overrides, in px. Uncomment any to pin a specific size without # affecting the rest of the scale. Useful for stylistic emphasis (a diff --git a/docs/omarchy-shell.md b/docs/omarchy-shell.md index afcf2da6..c778e286 100644 --- a/docs/omarchy-shell.md +++ b/docs/omarchy-shell.md @@ -173,17 +173,13 @@ both `[controls]` and `[style]`. ### Spacing -`[spacing] scale` multiplies the shell's shared margins, gaps, padding, -control sizes, and panel dimensions. The default is `1.0`; values above -`1.0` create more breathing room while values below `1.0` make controls -dense. By default `scale-with-font = true`, so increasing `[font] -base-size` also scales buttons, popup widths, row heights, and panel -padding proportionally. +`[spacing] scale` multiplies the shell's shared margins, gaps, and +padding. The default is `1.0`; values above `1.0` create more breathing +room while values below `1.0` make controls denser. ```toml [spacing] -scale = 1.15 -scale-with-font = true # grow controls and panels with [font] base-size +scale = 1.15 # roomier panels and controls ``` QML components should prefer semantic tokens where possible: @@ -207,11 +203,10 @@ Popout placement deliberately follows Hyprland's `general:gaps_out` interior breathing room. For one-off proportional constants, use `Style.space(px)` to preserve the -old default at scale `1.0` and `base-size = 12` while still responding to -the theme scale and font scale. Use `Style.spaceReal(px)` only for -fractional geometry that should not be rounded, such as bar widget text -margins. Themes can override any semantic token directly in `[spacing]`, -e.g.: +old default at scale `1.0` while still responding to the theme scale. Use +`Style.spaceReal(px)` only for fractional geometry that should not be +rounded, such as bar widget text margins. Themes can override any semantic +token directly in `[spacing]`, e.g.: ```toml [spacing] @@ -261,27 +256,22 @@ Recognized override keys: `base-size`, `caption`, `body-small`, `body`, `subtitle`, `title`, `heading`, `display`, `display-large`, `icon-small`, `icon`, `icon-large`. -`base-size` has no upper clamp; the shell only floors it at **1px** to -avoid nonsensical zero/negative sizes. Per-token overrides aren't clamped -either. The shell font family is the fontconfig `monospace` alias — -themes don't set it, the user does via `omarchy font set `. +`base-size` is clamped to **11..13** because some row heights and the bar +cross-axis size remain fixed; per-token overrides aren't clamped. The +shell font family is the fontconfig `monospace` alias — themes don't +set it, the user does via `omarchy font set `. ### Bar size `[bar] size-horizontal` / `size-vertical` set the cross-axis dimension -of top/bottom and left/right bars respectively, measured at the default -12px font base. By default `scale-with-font = true`, so increasing -`[font] base-size` also increases the bar's cross-axis size: +of top/bottom and left/right bars respectively (in px): ```toml [bar] -scale-with-font = true -size-horizontal = 26 # top/bottom bar height at base-size 12 -size-vertical = 28 # left/right bar width at base-size 12 +size-horizontal = 26 # top/bottom bar height +size-vertical = 28 # left/right bar width ``` -Set `scale-with-font = false` to keep those bar sizes as fixed pixels. - ## Custom bar modules If a full plugin is overkill, declare a one-off module inline in diff --git a/shell/Commons/Style.qml b/shell/Commons/Style.qml index 789b070e..e0d506a1 100644 --- a/shell/Commons/Style.qml +++ b/shell/Commons/Style.qml @@ -19,12 +19,10 @@ import Quickshell.Io // Typography, spacing, and bar size come from theme/shell.toml. // `[font] base-size` is the rem root; every `Style.font.` derives // from it via the scale multipliers below unless the theme pins that -// specific token. `[spacing] scale` multiplies shared margins, gaps, -// padding, controls, and panel dimensions while preserving each component's -// proportions; by default it also tracks `base-size`. `[bar] +// specific token. `[spacing] scale` multiplies shared margins, gaps, and +// padding while preserving each component's proportions. `[bar] // size-horizontal` / `size-vertical` set the cross-axis dimension for -// top/bottom and left/right bars at the default 12px font size; by default -// those dimensions scale with `base-size` so larger fonts don't clip. +// top/bottom and left/right bars respectively. QtObject { id: root @@ -206,14 +204,12 @@ QtObject { // fractional geometry); themes can make the shell denser or roomier // with `[spacing] scale`, or pin individual tokens. property real spacingScale: 1.0 - property bool spacingScaleWithFont: true property var spacingOverrides: ({}) - readonly property real effectiveSpacingScale: spacingScale * (spacingScaleWithFont ? fontScale : 1) function spaceReal(px) { var n = Number(px) if (!isFinite(n) || n <= 0) return 0 - return n * effectiveSpacingScale + return n * spacingScale } function space(px) { @@ -229,7 +225,7 @@ QtObject { } readonly property QtObject spacing: QtObject { - readonly property real scale: root.effectiveSpacingScale + readonly property real scale: root.spacingScale readonly property int hairline: root.space(1) readonly property int xxs: root.spacingToken("xxs", 2) @@ -274,14 +270,12 @@ QtObject { // read `resolvedFontFamily` when you want to *display* what's drawing. property string resolvedFontFamily: "monospace" - // The only sanity floor is 1px. Themes and users can make this as large - // as they like; if the shell gets ridiculous, that's their call. + // Clamped 11..13 by applyShellValues — some row heights remain fixed, + // so unbounded type growth can still clip even with scalable spacing. property int fontBaseSize: 12 property var fontOverrides: ({}) property var barOverrides: ({}) - property bool barScaleWithFont: true - readonly property real fontScale: Math.max(1 / 12, fontBaseSize / 12) function fontPx(mult) { return Math.max(1, Math.round(fontBaseSize * mult)) @@ -296,17 +290,7 @@ QtObject { function barToken(key, fallback) { var v = barOverrides[key] var n = Number(v) - var base = (isFinite(n) && n > 0) ? n : fallback - if (barScaleWithFont) base *= fontScale - return Math.max(1, Math.round(base)) - } - - function boolToken(value, fallback) { - if (value === undefined || value === null) return fallback - var s = String(value).replace(/^\s+|\s+$/g, "").toLowerCase() - if (s === "true" || s === "1" || s === "yes" || s === "on") return true - if (s === "false" || s === "0" || s === "no" || s === "off") return false - return fallback + return (isFinite(n) && n > 0) ? Math.round(n) : fallback } // The launcher, menu, polkit, emojis, and clipboard surfaces honor an @@ -384,8 +368,6 @@ QtObject { var spacingOut = {} var nextBase = 12 var nextSpacingScale = 1.0 - var nextSpacingScaleWithFont = true - var nextBarScaleWithFont = true var v = values || {} for (var fullKey in v) { var dot = fullKey.indexOf(".") @@ -398,38 +380,28 @@ QtObject { if (!isFinite(ival)) continue if (key === "base-size") nextBase = ival else fontOut[key] = ival - } else if (section === "bar") { - if (key === "scale-with-font") { - nextBarScaleWithFont = boolToken(raw, nextBarScaleWithFont) - } else if (key === "size-horizontal" || key === "size-vertical") { - var b = parseInt(raw, 10) - if (isFinite(b)) barOut[key] = b - } + } else if (section === "bar" && (key === "size-horizontal" || key === "size-vertical")) { + var b = parseInt(raw, 10) + if (isFinite(b)) barOut[key] = b } else if (section === "spacing") { - if (key === "scale-with-font") { - nextSpacingScaleWithFont = boolToken(raw, nextSpacingScaleWithFont) - } else { - var fval = parseFloat(raw) - if (!isFinite(fval)) continue - if (key === "scale") nextSpacingScale = fval - else spacingOut[key] = fval - } + var fval = parseFloat(raw) + if (!isFinite(fval)) continue + if (key === "scale") nextSpacingScale = fval + else spacingOut[key] = fval } else if (section === "controls") { // Strings are passed through; styleRawNum/styleString coerce on read. styleOut[key] = raw } } - // Keep only a 1px sanity floor. Per-token overrides aren't clamped - // either — a theme that wants display-large = 64 should be allowed to - // ship it. - if (!isFinite(nextBase) || nextBase < 1) nextBase = 1 + // Clamp the rem root. Per-token overrides aren't clamped — a theme + // that wants display-large = 64 should be allowed to ship it. + if (nextBase < 11) nextBase = 11 + if (nextBase > 13) nextBase = 13 if (!isFinite(nextSpacingScale) || nextSpacingScale < 0) nextSpacingScale = 1.0 spacingScale = nextSpacingScale - spacingScaleWithFont = nextSpacingScaleWithFont fontBaseSize = nextBase fontOverrides = fontOut barOverrides = barOut - barScaleWithFont = nextBarScaleWithFont spacingOverrides = spacingOut styleOverrides = styleOut } diff --git a/shell/Ui/KeyboardPanel.qml b/shell/Ui/KeyboardPanel.qml index c23d41f3..46a460a1 100644 --- a/shell/Ui/KeyboardPanel.qml +++ b/shell/Ui/KeyboardPanel.qml @@ -40,8 +40,8 @@ PanelWindow { property var owner: null property int margin: Style.gapsOut property int padding: Style.spacing.popupPadding - property int contentWidth: Style.space(280) - property int contentHeight: Style.space(200) + property int contentWidth: 280 + property int contentHeight: 200 property bool open: false property int gap: Style.gapsOut // distance between bar edge and panel property bool popoutSwitching: false diff --git a/shell/Ui/PopupCard.qml b/shell/Ui/PopupCard.qml index 475d7df4..9a4fc9c2 100644 --- a/shell/Ui/PopupCard.qml +++ b/shell/Ui/PopupCard.qml @@ -11,8 +11,8 @@ PopupWindow { property var owner: null property int margin: Style.gapsOut property int padding: Style.spacing.popupPadding - property int contentWidth: Style.space(280) - property int contentHeight: Style.space(200) + property int contentWidth: 280 + property int contentHeight: 200 property color borderColor: Color.popups.border property bool open: false property bool centerOnBar: false diff --git a/shell/plugins/bar/widgets/Tray.qml b/shell/plugins/bar/widgets/Tray.qml index 6fb4181b..567bcf01 100644 --- a/shell/plugins/bar/widgets/Tray.qml +++ b/shell/plugins/bar/widgets/Tray.qml @@ -18,9 +18,7 @@ BarWidget { readonly property var drawerItems: bucket("drawer") readonly property var allItems: bucket("all") readonly property int drawerCount: drawerItems.length - readonly property int trayItemExtent: Style.space(16) - readonly property int trayItemGap: Style.space(6) - readonly property int drawerExtent: drawerCount > 0 ? drawerCount * trayItemExtent + (drawerCount - 1) * trayItemGap : 0 + readonly property int drawerExtent: drawerCount > 0 ? drawerCount * 16 + (drawerCount - 1) * 17 : 0 // Match Waybar's group/tray-expander drawer transition-duration. readonly property int animationDuration: 600 property real revealProgress: expanded ? 1 : 0 @@ -156,7 +154,7 @@ BarWidget { height: implicitHeight x: root.drawerExtent - root.revealExtent text: "\uf053" - horizontalMargin: 5 + horizontalMargin: 9 verticalPadding: 6 onPressed: function(button) { if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen @@ -175,7 +173,7 @@ BarWidget { id: trayIcons x: root.drawerExtent - root.revealExtent anchors.verticalCenter: parent.verticalCenter - spacing: root.trayItemGap + spacing: Style.space(17) layer.enabled: true Repeater { @@ -190,8 +188,8 @@ BarWidget { id: pinnedRow x: drawerArea.x + horizontalTrayRoot.drawerBlockWidth anchors.verticalCenter: parent.verticalCenter - spacing: root.trayItemGap - leftPadding: root.pinnedItems.length > 0 && root.allItems.length > 0 ? root.trayItemGap : 0 + spacing: Style.space(17) + leftPadding: root.pinnedItems.length > 0 && root.allItems.length > 0 ? Style.space(6) : 0 Repeater { model: root.pinnedItems TrayItem {} @@ -241,7 +239,7 @@ BarWidget { y: root.drawerExtent - root.revealExtent text: "\uf053" textRotation: 90 - horizontalMargin: 5 + horizontalMargin: 9 verticalPadding: 6 onPressed: function(button) { if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen @@ -260,7 +258,7 @@ BarWidget { id: trayIcons y: root.drawerExtent - root.revealExtent anchors.horizontalCenter: parent.horizontalCenter - spacing: root.trayItemGap + spacing: Style.space(17) layer.enabled: true Repeater { @@ -275,8 +273,8 @@ BarWidget { id: pinnedCol y: drawerArea.y + verticalTrayRoot.drawerBlockHeight anchors.horizontalCenter: parent.horizontalCenter - spacing: root.trayItemGap - topPadding: root.pinnedItems.length > 0 && root.allItems.length > 0 ? root.trayItemGap : 0 + spacing: Style.space(17) + topPadding: root.pinnedItems.length > 0 && root.allItems.length > 0 ? Style.space(6) : 0 Repeater { model: root.pinnedItems TrayItem {} @@ -409,14 +407,14 @@ BarWidget { required property var modelData visible: modelData.status !== Status.Passive - implicitWidth: visible ? root.trayItemExtent : 0 - implicitHeight: visible ? root.trayItemExtent : 0 + implicitWidth: visible ? 16 : 0 + implicitHeight: visible ? 16 : 0 IconImage { anchors.centerIn: parent - implicitSize: Style.space(12) - width: Style.space(12) - height: Style.space(12) + implicitSize: 12 + width: 12 + height: 12 source: root.trayIconSource(trayItemRoot.modelData.icon) } diff --git a/shell/plugins/bar/widgets/Workspaces.qml b/shell/plugins/bar/widgets/Workspaces.qml index a72af41f..ab134320 100644 --- a/shell/plugins/bar/widgets/Workspaces.qml +++ b/shell/plugins/bar/widgets/Workspaces.qml @@ -60,7 +60,7 @@ BarWidget { opacity: occupied || focused ? 1 : 0.5 horizontalMargin: 6 verticalPadding: 6 - fixedWidth: root.vertical ? root.barSize : Style.space(22) + fixedWidth: root.vertical ? root.barSize : 22 fixedHeight: root.barSize onPressed: function() { root.focusWorkspace(modelData) } } diff --git a/shell/plugins/dev-gallery/GalleryPanel.qml b/shell/plugins/dev-gallery/GalleryPanel.qml index 96d343da..61d4a77e 100644 --- a/shell/plugins/dev-gallery/GalleryPanel.qml +++ b/shell/plugins/dev-gallery/GalleryPanel.qml @@ -445,12 +445,11 @@ Item { } Text { text: "Style.font.* is the shell-wide type scale. Themes ship a single " - + "[font] base-size in shell.toml; every token derives from it via a " - + "fixed multiplier, so changing base-size rescales the whole shell " - + "proportionally. There is no upper clamp. Themes can also pin " - + "individual tokens (caption, heading, display, etc.) for stylistic " - + "emphasis. The family follows the fontconfig monospace alias \u2014 " - + "set it with `omarchy font set `." + + "[font] base-size in shell.toml (clamped 11..13); every token derives from " + + "it via a fixed multiplier, so changing base-size rescales the whole shell " + + "proportionally. Themes can also pin individual tokens (caption, heading, " + + "display, etc.) for stylistic emphasis. The family follows the fontconfig " + + "monospace alias \u2014 set it with `omarchy font set `." color: Qt.darker(root.foreground, 1.5) font.family: root.fontFamily font.pixelSize: Style.font.bodySmall diff --git a/shell/plugins/panels/Audio.qml b/shell/plugins/panels/Audio.qml index 16560886..0e5cce68 100644 --- a/shell/plugins/panels/Audio.qml +++ b/shell/plugins/panels/Audio.qml @@ -625,7 +625,6 @@ Panel { bar: root.bar text: root.outputIcon() fontSize: Style.font.body - horizontalMargin: 5 onPressed: function(b) { if (b === Qt.RightButton) root.toggleOutputMute() else root.toggle() diff --git a/shell/plugins/panels/Bluetooth.qml b/shell/plugins/panels/Bluetooth.qml index 82bf2037..9201ff16 100644 --- a/shell/plugins/panels/Bluetooth.qml +++ b/shell/plugins/panels/Bluetooth.qml @@ -459,7 +459,6 @@ Panel { anchors.fill: parent bar: root.bar text: root.icon - horizontalMargin: 5 onPressed: function(b) { if (b === Qt.RightButton) root.toggleBluetooth() else if (b === Qt.MiddleButton) root.bar.run("omarchy-launch-bluetooth") diff --git a/shell/plugins/panels/Monitor.qml b/shell/plugins/panels/Monitor.qml index 72d8dac2..537b51f5 100644 --- a/shell/plugins/panels/Monitor.qml +++ b/shell/plugins/panels/Monitor.qml @@ -357,7 +357,6 @@ Panel { bar: root.bar text: root.displays.length > 1 ? "󰍺" : "󰍹" fontSize: Style.font.subtitle - horizontalMargin: 5 onPressed: function(b) { root.toggle() } onWheelMoved: function(delta) { if (root.brightnessAvailable) root.setBrightness(root.brightnessPercent + (delta > 0 ? 5 : -5)) diff --git a/shell/plugins/panels/Network.qml b/shell/plugins/panels/Network.qml index 3f2e5d44..ad91fe23 100644 --- a/shell/plugins/panels/Network.qml +++ b/shell/plugins/panels/Network.qml @@ -644,7 +644,8 @@ Panel { anchors.fill: parent bar: root.bar text: root.icon - horizontalMargin: 5 + horizontalMargin: 8.5 + rightExtraMargin: 2 onPressed: function(b) { if (root.opened) root.close() diff --git a/shell/plugins/panels/Power.qml b/shell/plugins/panels/Power.qml index fa1a4ff8..d65329d6 100644 --- a/shell/plugins/panels/Power.qml +++ b/shell/plugins/panels/Power.qml @@ -259,7 +259,8 @@ Panel { anchors.fill: parent bar: root.bar text: root.batteryIcon() - horizontalMargin: 5 + horizontalMargin: 8.5 + rightExtraMargin: 2 active: UPower.displayDevice && UPower.displayDevice.percentage <= 0.2 && UPower.onBattery tooltipText: "" onPressed: function(b) { root.toggle() }