Revert "Provide better scaling"

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