Convert British spellings to American across the repo
colour -> color, behaviour -> behavior, centre -> center, favourite -> favorite, and about twenty other pairs, applied consistently across comments, docs, error/UI copy, and a handful of QML identifiers that used the British spelling as their actual name: SystemSettings' serialiseValue/serialiseTable/normaliseGradient, Displays' normaliseModes, Wallpaper's normalisePolicy, SettingsBackup's serialiseHomeState, DateTime's ntpSynchronised property, Clipboard's _normalise helper, and ShortcutCapture's cancelled signal (with its onCancelled handler in ShortcutsPage.qml). Every call site and the two tests that assert on the literal source text (settings-ownership and settings-backup-live contracts) were updated in lockstep. Left untouched: config/dot/espanso/match/packages/misspell-en/ is a vendored third-party autocorrect dictionary -- its entries are typo corrections, not our prose, and rewriting them would fight the package's own purpose (and any future re-sync from upstream). The already-American `favorites` property (Home page pinned accessories) was never actually misspelled -- only nearby comments and error strings said "favourites" -- so no data migration was needed there. Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
This commit is contained in:
+2
-2
@@ -14,10 +14,10 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
||||||
# Generated from the colour scheme; machine state, not configuration.
|
# Generated from the color scheme; machine state, not configuration.
|
||||||
/config/dot/kitty/current-theme.conf
|
/config/dot/kitty/current-theme.conf
|
||||||
|
|
||||||
# Generated from the colour scheme; machine state, not configuration.
|
# Generated from the color scheme; machine state, not configuration.
|
||||||
/config/dot/gtk-3.0/settings.ini
|
/config/dot/gtk-3.0/settings.ini
|
||||||
/config/dot/gtk-4.0/settings.ini
|
/config/dot/gtk-4.0/settings.ini
|
||||||
/config/dot/tmux/current-theme.conf
|
/config/dot/tmux/current-theme.conf
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# btop ships no Tokyo Night light variant at all, and the nearest stock light
|
# btop ships no Tokyo Night light variant at all, and the nearest stock light
|
||||||
# theme (flat-remix-light) is a different palette that happens to have a similar
|
# theme (flat-remix-light) is a different palette that happens to have a similar
|
||||||
# background. Same colours as kitty/themes/tokyonight-day.conf so the terminal
|
# background. Same colors as kitty/themes/tokyonight-day.conf so the terminal
|
||||||
# and what runs inside it cannot disagree.
|
# and what runs inside it cannot disagree.
|
||||||
#
|
#
|
||||||
# Gradients keep the same low -> middle -> high meaning as the dark theme, using
|
# Gradients keep the same low -> middle -> high meaning as the dark theme, using
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# GENERATED FILE -- edit settings.ini.template instead.
|
# GENERATED FILE -- edit settings.ini.template instead.
|
||||||
#
|
#
|
||||||
# The theme name and dark preference below follow Panama's colour
|
# The theme name and dark preference below follow Panama's color
|
||||||
# scheme, so this file is regenerated on every switch and is not
|
# scheme, so this file is regenerated on every switch and is not
|
||||||
# committed. Under GNOME, gnome-settings-daemon publishes these over
|
# committed. Under GNOME, gnome-settings-daemon publishes these over
|
||||||
# XSETTINGS and this file is ignored; under Hyprland there is no
|
# XSETTINGS and this file is ignored; under Hyprland there is no
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# GENERATED FILE -- edit settings.ini.template instead.
|
# GENERATED FILE -- edit settings.ini.template instead.
|
||||||
#
|
#
|
||||||
# The theme name and dark preference below follow Panama's colour
|
# The theme name and dark preference below follow Panama's color
|
||||||
# scheme, so this file is regenerated on every switch and is not
|
# scheme, so this file is regenerated on every switch and is not
|
||||||
# committed. Under GNOME, gnome-settings-daemon publishes these over
|
# committed. Under GNOME, gnome-settings-daemon publishes these over
|
||||||
# XSETTINGS and this file is ignored; under Hyprland there is no
|
# XSETTINGS and this file is ignored; under Hyprland there is no
|
||||||
|
|||||||
@@ -15,15 +15,15 @@ Last live audit: 2026-08-17, Fedora 44, Hyprland 0.56.2, Quickshell 0.3.0.
|
|||||||
| Hidden applications | GNOME App Hider list in Vicinae provider config | Live |
|
| Hidden applications | GNOME App Hider list in Vicinae provider config | Live |
|
||||||
| Tiling and dynamic workspaces | Hyprland Lua config, Forge keymap preserved | Live |
|
| Tiling and dynamic workspaces | Hyprland Lua config, Forge keymap preserved | Live |
|
||||||
| Overview | Continuum filmstrip, large workspace preview, cross-workspace search | Live |
|
| Overview | Continuum filmstrip, large workspace preview, cross-workspace search | Live |
|
||||||
| Minimise | `SUPER+SHIFT+X` sends to scratchpad; `SUPER+X` restores | Live |
|
| Minimize | `SUPER+SHIFT+X` sends to scratchpad; `SUPER+X` restores | Live |
|
||||||
| Dock | Quickshell dock with GNOME favourites and intellihide | Live |
|
| Dock | Quickshell dock with GNOME favorites and intellihide | Live |
|
||||||
| Panel | Workspaces, CPU/RAM/GPU, clock, weather, quiet event capsule, media, clipboard, tray, status | Live |
|
| Panel | Workspaces, CPU/RAM/GPU, clock, weather, quiet event capsule, media, clipboard, tray, status | Live |
|
||||||
| Clipboard history | Vicinae owns capture/storage; Quickshell provides the panel | Live |
|
| Clipboard history | Vicinae owns capture/storage; Quickshell provides the panel | Live |
|
||||||
| Notifications | Quickshell server, toasts, grouped history, DND, clear actions | Live |
|
| Notifications | Quickshell server, toasts, grouped history, DND, clear actions | Live |
|
||||||
| Date menu | Two-column Daybook with Agenda, Ongoing activity, Notifications, month calendar, weather, and media | Live |
|
| Date menu | Two-column Daybook with Agenda, Ongoing activity, Notifications, month calendar, weather, and media | Live |
|
||||||
| Ongoing activity | Focus, Caffeine, recording, screen sharing, camera, and microphone state with direct controls | Live |
|
| Ongoing activity | Focus, Caffeine, recording, screen sharing, camera, and microphone state with direct controls | Live |
|
||||||
| Calendar agenda | Existing GNOME, Google, iCloud, and Nextcloud sources through Evolution Data Server | Live |
|
| Calendar agenda | Existing GNOME, Google, iCloud, and Nextcloud sources through Evolution Data Server | Live |
|
||||||
| Control Center | Wi-Fi, Bluetooth, audio input/output, Caffeine, Night Light, Focus, Home Assistant favourites, and KDE Connect phone continuity | Live |
|
| Control Center | Wi-Fi, Bluetooth, audio input/output, Caffeine, Night Light, Focus, Home Assistant favorites, and KDE Connect phone continuity | Live |
|
||||||
| Focus sessions | Persistent workspace-bound timer, DND/caffeine coordination, Signal Glass controls | Live |
|
| Focus sessions | Persistent workspace-bound timer, DND/caffeine coordination, Signal Glass controls | Live |
|
||||||
| Brightness | Appears only when a backlight device exists | Live, not applicable on this monitor |
|
| Brightness | Appears only when a backlight device exists | Live, not applicable on this monitor |
|
||||||
| AppIndicator / tray | Native StatusNotifierItem host and themed menus | Live |
|
| AppIndicator / tray | Native StatusNotifierItem host and themed menus | Live |
|
||||||
@@ -36,7 +36,7 @@ Last live audit: 2026-08-17, Fedora 44, Hyprland 0.56.2, Quickshell 0.3.0.
|
|||||||
| Removable media | udiskie plus udisks notifications | Live |
|
| Removable media | udiskie plus udisks notifications | Live |
|
||||||
| Autostart apps | Nextcloud, Bitwarden, and RustDesk system service/tray | Live |
|
| Autostart apps | Nextcloud, Bitwarden, and RustDesk system service/tray | Live |
|
||||||
| Printer administration | CUPS with the `system-config-printer` graphical interface | Live |
|
| Printer administration | CUPS with the `system-config-printer` graphical interface | Live |
|
||||||
| System settings | The Settings app for display policy, appearance, desktop, sound, focus, shortcuts, and services; labelled GNOME hardware/account handoffs | Live |
|
| System settings | The Settings app for display policy, appearance, desktop, sound, focus, shortcuts, and services; labeled GNOME hardware/account handoffs | Live |
|
||||||
| System health and recovery | Settings → System Health, `Panama: Check System Health` in Vicinae, a degraded-only bar indicator, redacted reports, and bounded Panama-owned repairs | Live |
|
| System health and recovery | Settings → System Health, `Panama: Check System Health` in Vicinae, a degraded-only bar indicator, redacted reports, and bounded Panama-owned repairs | Live |
|
||||||
|
|
||||||
## System health and recovery
|
## System health and recovery
|
||||||
@@ -59,7 +59,7 @@ They never install packages, invoke `sudo`, delete user data, or rewrite
|
|||||||
arbitrary configuration.
|
arbitrary configuration.
|
||||||
|
|
||||||
Generic Fedora configuration remains with the system tools that own it. The
|
Generic Fedora configuration remains with the system tools that own it. The
|
||||||
final System Health card hands network settings, users, sharing, colour
|
final System Health card hands network settings, users, sharing, color
|
||||||
profiles, and digital wellbeing to their exact GNOME Settings panels rather
|
profiles, and digital wellbeing to their exact GNOME Settings panels rather
|
||||||
than presenting inert Hyprland controls.
|
than presenting inert Hyprland controls.
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ than presenting inert Hyprland controls.
|
|||||||
| Bluetooth Quick Connect | Replaced by the full Bluetooth picker |
|
| Bluetooth Quick Connect | Replaced by the full Bluetooth picker |
|
||||||
| Wi-Fi QR | Replaced by an on-demand QR-code sharing flow in Control Center's Wi-Fi panel; the code is generated only while shown and written to tmpfs, never persisted |
|
| Wi-Fi QR | Replaced by an on-demand QR-code sharing flow in Control Center's Wi-Fi panel; the code is generated only while shown and written to tmpfs, never persisted |
|
||||||
| GSConnect | Replaced by capability-aware KDE Connect phone continuity in Control Center; the paired iPhone exposes file, clipboard, and Ring actions when reachable |
|
| GSConnect | Replaced by capability-aware KDE Connect phone continuity in Control Center; the paired iPhone exposes file, clipboard, and Ring actions when reachable |
|
||||||
| Home Assistant | Replaced by secure favourites in Control Center; explicit private environment values take precedence over the existing GNOME extension and Secret Service setup |
|
| Home Assistant | Replaced by secure favorites in Control Center; explicit private environment values take precedence over the existing GNOME extension and Secret Service setup |
|
||||||
| Custom Hot Corners Extended | No action was configured, so there is no behavior to port |
|
| Custom Hot Corners Extended | No action was configured, so there is no behavior to port |
|
||||||
| App Hider | Hidden app list is now applied in Vicinae |
|
| App Hider | Hidden app list is now applied in Vicinae |
|
||||||
| Allow Locked Remote Desktop | Mutter-specific patch; RustDesk is independent, but lock-screen access needs a real remote test |
|
| Allow Locked Remote Desktop | Mutter-specific patch; RustDesk is independent, but lock-screen access needs a real remote test |
|
||||||
@@ -111,4 +111,4 @@ menu for a minority, which is worse than omitting it. Relevant references:
|
|||||||
- <https://github.com/hyprwm/Hyprland/discussions/1358>
|
- <https://github.com/hyprwm/Hyprland/discussions/1358>
|
||||||
|
|
||||||
A future focused-window menu could expose compositor actions such as float,
|
A future focused-window menu could expose compositor actions such as float,
|
||||||
move, fullscreen, and close. It should not be labelled as an application menu.
|
move, fullscreen, and close. It should not be labeled as an application menu.
|
||||||
|
|||||||
+13
-13
@@ -30,7 +30,7 @@ Don't "fix" them.
|
|||||||
| `prefs.lua` | Reads the settings file the Settings app writes. See below |
|
| `prefs.lua` | Reads the settings file the Settings app writes. See below |
|
||||||
| `env.lua` | Environment. Note the uwsm caveat below |
|
| `env.lua` | Environment. Note the uwsm caveat below |
|
||||||
| `monitors.lua` | DP-2 geometry, scaling, and the HDR decision |
|
| `monitors.lua` | DP-2 geometry, scaling, and the HDR decision |
|
||||||
| `looks.lua` | Colours, blur, glow, shadows, animations, VRR, scanout |
|
| `looks.lua` | Colors, blur, glow, shadows, animations, VRR, scanout |
|
||||||
| `input.lua` | Keyboard/mouse. Click-to-focus, like GNOME |
|
| `input.lua` | Keyboard/mouse. Click-to-focus, like GNOME |
|
||||||
| `rules.lua` | Window rules, gaming rules, layer rules for the shell |
|
| `rules.lua` | Window rules, gaming rules, layer rules for the shell |
|
||||||
| `keybinds.lua` | The full keymap |
|
| `keybinds.lua` | The full keymap |
|
||||||
@@ -87,7 +87,7 @@ persistence, validation, reset, and the live write are all derived from that
|
|||||||
entry.
|
entry.
|
||||||
|
|
||||||
`prefs.lua` never raises. A missing, empty, truncated, malformed, or
|
`prefs.lua` never raises. A missing, empty, truncated, malformed, or
|
||||||
wrong-typed settings file costs you your customisations and nothing else;
|
wrong-typed settings file costs you your customizations and nothing else;
|
||||||
`tests/hypr/prefs-fallback-contract.sh` pins that, including that Hyprland still
|
`tests/hypr/prefs-fallback-contract.sh` pins that, including that Hyprland still
|
||||||
accepts the config in each of those states.
|
accepts the config in each of those states.
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ four places, and nowhere else —
|
|||||||
dock, popovers), running blue on the left to orchid on the right and fading
|
dock, popovers), running blue on the left to orchid on the right and fading
|
||||||
out before the corners. See `quickshell/widgets/PrismEdge.qml`.
|
out before the corners. See `quickshell/widgets/PrismEdge.qml`.
|
||||||
2. The focused window's border — `general.col.active_border`, blue→orchid at
|
2. The focused window's border — `general.col.active_border`, blue→orchid at
|
||||||
115°. Unfocused windows get no colour at all, because the gradient only
|
115°. Unfocused windows get no color at all, because the gradient only
|
||||||
means something if one window on screen is wearing it.
|
means something if one window on screen is wearing it.
|
||||||
3. The active workspace pill in the bar.
|
3. The active workspace pill in the bar.
|
||||||
4. Slider fills.
|
4. Slider fills.
|
||||||
@@ -179,9 +179,9 @@ which is the opposite of the intent.
|
|||||||
|
|
||||||
The Nerd Font is still used, but only to draw **icon glyphs** — it is the
|
The Nerd Font is still used, but only to draw **icon glyphs** — it is the
|
||||||
pragmatic alternative to freedesktop symbolic icons, which ship with a
|
pragmatic alternative to freedesktop symbolic icons, which ship with a
|
||||||
hardcoded `#2e3436` fill that Qt (unlike GTK) will not recolour. Where a
|
hardcoded `#2e3436` fill that Qt (unlike GTK) will not recolor. Where a
|
||||||
themed freedesktop icon is wanted instead, `quickshell/widgets/ThemedIcon.qml`
|
themed freedesktop icon is wanted instead, `quickshell/widgets/ThemedIcon.qml`
|
||||||
paints a palette colour through the icon's alpha.
|
paints a palette color through the icon's alpha.
|
||||||
|
|
||||||
Anything whose digits change in place — the clock, the vitals percentages, the
|
Anything whose digits change in place — the clock, the vitals percentages, the
|
||||||
recording timer, the selection readout — sets `font.features:
|
recording timer, the selection readout — sets `font.features:
|
||||||
@@ -256,7 +256,7 @@ The mental model is unchanged from Forge:
|
|||||||
| `SUPER + CTRL + G` / `Z` / `V` | Toggle split / preselect right / preselect down |
|
| `SUPER + CTRL + G` / `Z` / `V` | Toggle split / preselect right / preselect down |
|
||||||
| `SUPER + Tab` / `SHIFT + Tab` | Cycle windows |
|
| `SUPER + Tab` / `SHIFT + Tab` | Cycle windows |
|
||||||
| `SUPER + SHIFT + grave` | Last window |
|
| `SUPER + SHIFT + grave` | Last window |
|
||||||
| `SUPER + X` / `SUPER + SHIFT + X` | Restore scratchpad / minimise to scratchpad |
|
| `SUPER + X` / `SUPER + SHIFT + X` | Restore scratchpad / minimize to scratchpad |
|
||||||
|
|
||||||
### Workspaces (dynamic, like GNOME)
|
### Workspaces (dynamic, like GNOME)
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
@@ -270,19 +270,19 @@ The mental model is unchanged from Forge:
|
|||||||
### Launcher and shell
|
### Launcher and shell
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `SUPER + A` / `R` / `Space` | Launcher (vicinae) — all three, pick your favourite |
|
| `SUPER + A` / `R` / `Space` | Launcher (vicinae) — all three, pick your favorite |
|
||||||
| `SUPER + SHIFT + R` | Fallback launcher (wofi) if the shell is broken |
|
| `SUPER + SHIFT + R` | Fallback launcher (wofi) if the shell is broken |
|
||||||
| `SUPER + V` | Clipboard history |
|
| `SUPER + V` | Clipboard history |
|
||||||
| `SUPER + .` | Emoji picker |
|
| `SUPER + .` | Emoji picker |
|
||||||
| `SUPER + S` | Quick settings |
|
| `SUPER + S` | Quick settings |
|
||||||
| `SUPER + I` | Settings |
|
| `SUPER + I` | Settings |
|
||||||
| `SUPER + SHIFT + F` | Start or reveal focus session |
|
| `SUPER + SHIFT + F` | Start or reveal focus session |
|
||||||
| `SUPER + B` | Notification centre |
|
| `SUPER + B` | Notification center |
|
||||||
| `SUPER + grave` | Workspace overview |
|
| `SUPER + grave` | Workspace overview |
|
||||||
| `Print` | Screenshot / record picker |
|
| `Print` | Screenshot / record picker |
|
||||||
| `SHIFT` / `ALT + Print` | Screenshot screen / window immediately |
|
| `SHIFT` / `ALT + Print` | Screenshot screen / window immediately |
|
||||||
| `SUPER + SHIFT + S` | Screen Intelligence — read text and codes from a selection |
|
| `SUPER + SHIFT + S` | Screen Intelligence — read text and codes from a selection |
|
||||||
| `SUPER + SHIFT + P` | Colour picker |
|
| `SUPER + SHIFT + P` | Color picker |
|
||||||
| `CTRL + ALT + L` | Lock (SUPER+L is "focus right") |
|
| `CTRL + ALT + L` | Lock (SUPER+L is "focus right") |
|
||||||
| `CTRL + ALT + Delete` | Power menu |
|
| `CTRL + ALT + Delete` | Power menu |
|
||||||
|
|
||||||
@@ -325,8 +325,8 @@ Caffeine, Night Light, Focus, audio input/output, user, settings, and power in
|
|||||||
one place. Home and Phone continue the same surface rather than opening extra
|
one place. Home and Phone continue the same surface rather than opening extra
|
||||||
dashboard windows.
|
dashboard windows.
|
||||||
|
|
||||||
Home shows the first four selected favourites at rest and every selected light
|
Home shows the first four selected favorites at rest and every selected light
|
||||||
when expanded. Use **Settings → Home & Phone** to choose favourites,
|
when expanded. Use **Settings → Home & Phone** to choose favorites,
|
||||||
set Panama-only aliases, and arrange their order. Dragging a brightness control
|
set Panama-only aliases, and arrange their order. Dragging a brightness control
|
||||||
only previews the value; releasing it sends one brightness request. A normal
|
only previews the value; releasing it sends one brightness request. A normal
|
||||||
power toggle leaves Home Assistant responsible for restoring its previous
|
power toggle leaves Home Assistant responsible for restoring its previous
|
||||||
@@ -334,7 +334,7 @@ level.
|
|||||||
|
|
||||||
Credentials stay private in the gitignored `config/bash/env` file, with the
|
Credentials stay private in the gitignored `config/bash/env` file, with the
|
||||||
existing GNOME extension and Secret Service setup retained as a compatibility
|
existing GNOME extension and Secret Service setup retained as a compatibility
|
||||||
fallback. Favourites, aliases, and order live in Quickshell state. No shell
|
fallback. Favorites, aliases, and order live in Quickshell state. No shell
|
||||||
restart is required after changing credentials; close and reopen Control Center
|
restart is required after changing credentials; close and reopen Control Center
|
||||||
to refresh. If Home Assistant is offline, the last known values stay visible
|
to refresh. If Home Assistant is offline, the last known values stay visible
|
||||||
with a stale-state label and Retry action.
|
with a stale-state label and Retry action.
|
||||||
@@ -361,7 +361,7 @@ These are the places a 1:1 port was impossible, and what was done instead:
|
|||||||
|
|
||||||
- **Per-edge resize.** Forge resized one named edge; Hyprland resizes along an
|
- **Per-edge resize.** Forge resized one named edge; Hyprland resizes along an
|
||||||
axis and lets the layout pick the edge. The eight Forge keys collapse to four
|
axis and lets the layout pick the edge. The eight Forge keys collapse to four
|
||||||
behaviours, keeping the horizontal/vertical and grow/shrink pairing.
|
behaviors, keeping the horizontal/vertical and grow/shrink pairing.
|
||||||
- **Overview on `SUPER + grave`, not a bare SUPER tap.** Tap-detection on a
|
- **Overview on `SUPER + grave`, not a bare SUPER tap.** Tap-detection on a
|
||||||
modifier misfires when you're quick with SUPER combos.
|
modifier misfires when you're quick with SUPER combos.
|
||||||
- **Lock on `CTRL + ALT + L`.** `SUPER + L` is "focus right" in this keymap.
|
- **Lock on `CTRL + ALT + L`.** `SUPER + L` is "focus right" in this keymap.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- ─────────────────────────────────────────────────────────────────────────────
|
-- ─────────────────────────────────────────────────────────────────────────────
|
||||||
-- Environment
|
-- Environment
|
||||||
--
|
--
|
||||||
-- hl.env() sets variables before the display server initialises, which is what
|
-- hl.env() sets variables before the display server initializes, which is what
|
||||||
-- makes it valid for AQ_* and cursor variables.
|
-- makes it valid for AQ_* and cursor variables.
|
||||||
--
|
--
|
||||||
-- NOTE for uwsm sessions: if you log in via "Hyprland (uwsm-managed)", uwsm
|
-- NOTE for uwsm sessions: if you log in via "Hyprland (uwsm-managed)", uwsm
|
||||||
@@ -58,7 +58,7 @@ hl.env("QT_QPA_PLATFORM", "wayland;xcb")
|
|||||||
|
|
||||||
-- "gtk3" makes Qt derive its palette from the live GTK3 theme via the qgtk3
|
-- "gtk3" makes Qt derive its palette from the live GTK3 theme via the qgtk3
|
||||||
-- platform plugin, so Qt apps match adw-gtk3-dark exactly rather than
|
-- platform plugin, so Qt apps match adw-gtk3-dark exactly rather than
|
||||||
-- approximating it -- and it gives them GTK file/font/colour dialogs. It also
|
-- approximating it -- and it gives them GTK file/font/color dialogs. It also
|
||||||
-- covers Qt5 and Qt6 with one value.
|
-- covers Qt5 and Qt6 with one value.
|
||||||
--
|
--
|
||||||
-- Note this is a single value, NOT a fallback list: Qt splits on ":" and uses
|
-- Note this is a single value, NOT a fallback list: Qt splits on ":" and uses
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# hypridle — idle behaviour
|
# hypridle — idle behavior
|
||||||
#
|
#
|
||||||
# Mirrors the GNOME power profile this replaces, exactly:
|
# Mirrors the GNOME power profile this replaces, exactly:
|
||||||
# org.gnome.desktop.session idle-delay = 300 (screen off at 5min)
|
# org.gnome.desktop.session idle-delay = 300 (screen off at 5min)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-- ─────────────────────────────────────────────────────────────────────────────
|
-- ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
-- Shared preferences first: looks/input/monitors read their defaults through it.
|
-- Shared preferences first: looks/input/monitors read their defaults through it.
|
||||||
-- It never raises, so a missing or malformed settings file costs customisations
|
-- It never raises, so a missing or malformed settings file costs customizations
|
||||||
-- and nothing else.
|
-- and nothing else.
|
||||||
require("prefs")
|
require("prefs")
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
#
|
#
|
||||||
# GENERATED FILE. Edit hyprlock.conf.template and re-run
|
# GENERATED FILE. Edit hyprlock.conf.template and re-run
|
||||||
# quickshell/scripts/panama-theme-apps; editing this copy is overwritten on the
|
# quickshell/scripts/panama-theme-apps; editing this copy is overwritten on the
|
||||||
# next colour scheme change.
|
# next color scheme change.
|
||||||
#
|
#
|
||||||
# The colours here follow the desktop's light/dark setting. They used to be
|
# The colors here follow the desktop's light/dark setting. They used to be
|
||||||
# hardcoded Tokyo Night Moon, which meant the one screen you see most often
|
# hardcoded Tokyo Night Moon, which meant the one screen you see most often
|
||||||
# stayed dark when everything else went light.
|
# stayed dark when everything else went light.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
# hyprland-guiutils hyprland-dialog / hyprland-run
|
# hyprland-guiutils hyprland-dialog / hyprland-run
|
||||||
# hyprpolkitagent authentication prompts (via hyprland-qt-support)
|
# hyprpolkitagent authentication prompts (via hyprland-qt-support)
|
||||||
#
|
#
|
||||||
# Colours are Tokyo Night Moon, matching quickshell/config/Theme.qml and
|
# Colors are Tokyo Night Moon, matching quickshell/config/Theme.qml and
|
||||||
# hypr/looks.lua. Format is hyprlang; path is fixed at
|
# hypr/looks.lua. Format is hyprlang; path is fixed at
|
||||||
# $XDG_CONFIG_HOME/hypr/hyprtoolkit.conf (confirmed in libhyprtoolkit).
|
# $XDG_CONFIG_HOME/hypr/hyprtoolkit.conf (confirmed in libhyprtoolkit).
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ hl.config({
|
|||||||
repeat_rate = prefs.get("keyRepeatRate", 33),
|
repeat_rate = prefs.get("keyRepeatRate", 33),
|
||||||
|
|
||||||
-- 1 = FOLLOW. The window under the pointer takes focus. This comment
|
-- 1 = FOLLOW. The window under the pointer takes focus. This comment
|
||||||
-- previously claimed 1 was "click to focus, GNOME's behaviour", which
|
-- previously claimed 1 was "click to focus, GNOME's behavior", which
|
||||||
-- is the opposite of what Hyprland does -- `hyprctl descriptions` gives
|
-- is the opposite of what Hyprland does -- `hyprctl descriptions` gives
|
||||||
-- map: [{"separate":3},{"detached":2},{"follow":1},{"disabled":0}],
|
-- map: [{"separate":3},{"detached":2},{"follow":1},{"disabled":0}],
|
||||||
-- so click-to-focus is 0. Changing the shipped value is a behaviour
|
-- so click-to-focus is 0. Changing the shipped value is a behavior
|
||||||
-- decision rather than a correction, so the value is left alone and
|
-- decision rather than a correction, so the value is left alone and
|
||||||
-- only the description is fixed; Settings exposes all four.
|
-- only the description is fixed; Settings exposes all four.
|
||||||
follow_mouse = prefs.getInt("followMouse", 1),
|
follow_mouse = prefs.getInt("followMouse", 1),
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ bind(mod .. " + SHIFT + F", hl.dsp.exec_cmd(qs("focus", "reveal")), { descriptio
|
|||||||
-- which Hyprland has no equivalent for.
|
-- which Hyprland has no equivalent for.
|
||||||
bind(mod .. " + grave", hl.dsp.exec_cmd(qs("overview", "toggle")), { description = "Overview" })
|
bind(mod .. " + grave", hl.dsp.exec_cmd(qs("overview", "toggle")), { description = "Overview" })
|
||||||
|
|
||||||
-- Notification centre.
|
-- Notification center.
|
||||||
bind(mod .. " + B", hl.dsp.exec_cmd(qs("notifications", "toggle")), { description = "Notifications" })
|
bind(mod .. " + B", hl.dsp.exec_cmd(qs("notifications", "toggle")), { description = "Notifications" })
|
||||||
|
|
||||||
-- Screenshot / screen record. One key, then pick screen / window / region and
|
-- Screenshot / screen record. One key, then pick screen / window / region and
|
||||||
@@ -133,8 +133,8 @@ bind("ALT + Print", hl.dsp.exec_cmd(qs("capture", "windowNow")), { description =
|
|||||||
bind(mod .. " + SHIFT + S", hl.dsp.exec_cmd(qs("screen-intelligence", "open")),
|
bind(mod .. " + SHIFT + S", hl.dsp.exec_cmd(qs("screen-intelligence", "open")),
|
||||||
{ description = "Screen Intelligence" })
|
{ description = "Screen Intelligence" })
|
||||||
|
|
||||||
-- Colour picker: copies the hex under the cursor to the clipboard.
|
-- Color picker: copies the hex under the cursor to the clipboard.
|
||||||
bind(mod .. " + SHIFT + P", hl.dsp.exec_cmd("hyprpicker -a -f hex"), { description = "Colour picker" })
|
bind(mod .. " + SHIFT + P", hl.dsp.exec_cmd("hyprpicker -a -f hex"), { description = "Color picker" })
|
||||||
|
|
||||||
-- ── Window management ───────────────────────────────────────────────────────
|
-- ── Window management ───────────────────────────────────────────────────────
|
||||||
bind(mod .. " + Q", hl.dsp.window.close(), { description = "Close window" })
|
bind(mod .. " + Q", hl.dsp.window.close(), { description = "Close window" })
|
||||||
@@ -182,7 +182,7 @@ bind(mod .. " + CTRL + L", hl.dsp.window.swap({ direction = "r" }), { descriptio
|
|||||||
--
|
--
|
||||||
-- Forge resized one named edge at a time. Hyprland resizes the active window
|
-- Forge resized one named edge at a time. Hyprland resizes the active window
|
||||||
-- along an axis and lets the layout decide which edge actually moves, so the
|
-- along an axis and lets the layout decide which edge actually moves, so the
|
||||||
-- eight Forge keys collapse onto four behaviours. The pairing is kept
|
-- eight Forge keys collapse onto four behaviors. The pairing is kept
|
||||||
-- consistent with the original: Y/B/O/M are horizontal, I/P/U/N are vertical,
|
-- consistent with the original: Y/B/O/M are horizontal, I/P/U/N are vertical,
|
||||||
-- and "increase" always grows while "decrease" always shrinks.
|
-- and "increase" always grows while "decrease" always shrinks.
|
||||||
local step = 60
|
local step = 60
|
||||||
@@ -192,7 +192,7 @@ bind(mod .. " + SHIFT + B", hl.dsp.window.resize({ x = -step, y = 0, relative =
|
|||||||
bind(mod .. " + SHIFT + M", hl.dsp.window.resize({ x = -step, y = 0, relative = true }), { repeating = true, description = "Narrower" })
|
bind(mod .. " + SHIFT + M", hl.dsp.window.resize({ x = -step, y = 0, relative = true }), { repeating = true, description = "Narrower" })
|
||||||
bind(mod .. " + SHIFT + I", hl.dsp.window.resize({ x = 0, y = step, relative = true }), { repeating = true, description = "Taller" })
|
bind(mod .. " + SHIFT + I", hl.dsp.window.resize({ x = 0, y = step, relative = true }), { repeating = true, description = "Taller" })
|
||||||
bind(mod .. " + SHIFT + U", hl.dsp.window.resize({ x = 0, y = step, relative = true }), { repeating = true, description = "Taller" })
|
bind(mod .. " + SHIFT + U", hl.dsp.window.resize({ x = 0, y = step, relative = true }), { repeating = true, description = "Taller" })
|
||||||
-- SUPER+SHIFT+P was double-bound with the colour picker above; moved to
|
-- SUPER+SHIFT+P was double-bound with the color picker above; moved to
|
||||||
-- Comma, which continues the bottom-row cluster (B/M/N) this axis already
|
-- Comma, which continues the bottom-row cluster (B/M/N) this axis already
|
||||||
-- uses rather than landing on an arbitrary free key.
|
-- uses rather than landing on an arbitrary free key.
|
||||||
bind(mod .. " + SHIFT + Comma", hl.dsp.window.resize({ x = 0, y = -step, relative = true }), { repeating = true, description = "Shorter" })
|
bind(mod .. " + SHIFT + Comma", hl.dsp.window.resize({ x = 0, y = -step, relative = true }), { repeating = true, description = "Shorter" })
|
||||||
@@ -227,7 +227,7 @@ bind(mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true, description
|
|||||||
-- moving right past the last workspace creates a new one, and moving left from
|
-- moving right past the last workspace creates a new one, and moving left from
|
||||||
-- the first clamps instead of wrapping.
|
-- the first clamps instead of wrapping.
|
||||||
|
|
||||||
-- Behaviour for the relative/cyclic binds below. These are Hyprland's own
|
-- Behavior for the relative/cyclic binds below. These are Hyprland's own
|
||||||
-- `binds:` options -- not part of general/dwindle -- and have no other home
|
-- `binds:` options -- not part of general/dwindle -- and have no other home
|
||||||
-- in the config, so they are read here rather than in looks.lua.
|
-- in the config, so they are read here rather than in looks.lua.
|
||||||
hl.config({
|
hl.config({
|
||||||
@@ -259,18 +259,18 @@ end
|
|||||||
bind(mod .. " + mouse_down", hl.dsp.focus({ workspace = "+1" }), { description = "Workspace right" })
|
bind(mod .. " + mouse_down", hl.dsp.focus({ workspace = "+1" }), { description = "Workspace right" })
|
||||||
bind(mod .. " + mouse_up", hl.dsp.focus({ workspace = "-1" }), { description = "Workspace left" })
|
bind(mod .. " + mouse_up", hl.dsp.focus({ workspace = "-1" }), { description = "Workspace left" })
|
||||||
|
|
||||||
-- Minimise, as far as Hyprland has one.
|
-- Minimize, as far as Hyprland has one.
|
||||||
--
|
--
|
||||||
-- Hyprland has no minimise: it receives the request (the binary has
|
-- Hyprland has no minimize: it receives the request (the binary has
|
||||||
-- setSetMinimized handlers for xdg, XWayland and foreign-toplevel) but exposes
|
-- setSetMinimized handlers for xdg, XWayland and foreign-toplevel) but exposes
|
||||||
-- no dispatcher, no config option and not even an event to hook, so titlebar
|
-- no dispatcher, no config option and not even an event to hook, so titlebar
|
||||||
-- minimise buttons are inert and cannot be made to work. A tiling WM has no
|
-- minimize buttons are inert and cannot be made to work. A tiling WM has no
|
||||||
-- iconified state and no taskbar to restore from.
|
-- iconified state and no taskbar to restore from.
|
||||||
--
|
--
|
||||||
-- The scratchpad is the honest equivalent: the window goes away, and the same
|
-- The scratchpad is the honest equivalent: the window goes away, and the same
|
||||||
-- key brings it back. Bound to X to match the muscle memory it replaces.
|
-- key brings it back. Bound to X to match the muscle memory it replaces.
|
||||||
bind(mod .. " + X", hl.dsp.workspace.toggle_special("scratch"), { description = "Toggle scratchpad (restore minimised)" })
|
bind(mod .. " + X", hl.dsp.workspace.toggle_special("scratch"), { description = "Toggle scratchpad (restore minimized)" })
|
||||||
bind(mod .. " + SHIFT + X", hl.dsp.window.move({ workspace = "special:scratch" }), { description = "Minimise to scratchpad" })
|
bind(mod .. " + SHIFT + X", hl.dsp.window.move({ workspace = "special:scratch" }), { description = "Minimize to scratchpad" })
|
||||||
|
|
||||||
-- ── Session ─────────────────────────────────────────────────────────────────
|
-- ── Session ─────────────────────────────────────────────────────────────────
|
||||||
-- GNOME's lock was SUPER+L, which is "focus right" here, so lock moves to
|
-- GNOME's lock was SUPER+L, which is "focus right" here, so lock moves to
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
-- ─────────────────────────────────────────────────────────────────────────────
|
-- ─────────────────────────────────────────────────────────────────────────────
|
||||||
-- Look and feel -- Tokyo Night Moon
|
-- Look and feel -- Tokyo Night Moon
|
||||||
--
|
--
|
||||||
-- Colours here must stay in sync with quickshell/config/Theme.qml.
|
-- Colors here must stay in sync with quickshell/config/Theme.qml.
|
||||||
-- accent user-selectable, see `accents` below -- blue (#82aaff) ships
|
-- accent user-selectable, see `accents` below -- blue (#82aaff) ships
|
||||||
-- bg #222436 base
|
-- bg #222436 base
|
||||||
--
|
--
|
||||||
@@ -53,7 +53,7 @@ hl.config({
|
|||||||
-- from Theme.accent/Theme.accentSecondary on every scheme change
|
-- from Theme.accent/Theme.accentSecondary on every scheme change
|
||||||
-- too, since each accent carries a separate pair per scheme.
|
-- too, since each accent carries a separate pair per scheme.
|
||||||
active_border = { colors = { "rgba(" .. accentStart .. "ee)", "rgba(" .. accentEnd .. "ee)" }, angle = 115 },
|
active_border = { colors = { "rgba(" .. accentStart .. "ee)", "rgba(" .. accentEnd .. "ee)" }, angle = 115 },
|
||||||
-- The neutral inactive role follows the colour scheme because a
|
-- The neutral inactive role follows the color scheme because a
|
||||||
-- dark neutral disappears against a light desktop.
|
-- dark neutral disappears against a light desktop.
|
||||||
-- services/ColorScheme.qml applies the same values live; this is
|
-- services/ColorScheme.qml applies the same values live; this is
|
||||||
-- the value a fresh session starts from.
|
-- the value a fresh session starts from.
|
||||||
@@ -193,12 +193,12 @@ hl.config({
|
|||||||
-- Let a crashed lock screen be recovered rather than stranding you.
|
-- Let a crashed lock screen be recovered rather than stranding you.
|
||||||
allow_session_lock_restore = true,
|
allow_session_lock_restore = true,
|
||||||
|
|
||||||
-- Don't let apps steal focus by shouting; matches GNOME's behaviour.
|
-- Don't let apps steal focus by shouting; matches GNOME's behavior.
|
||||||
focus_on_activate = false,
|
focus_on_activate = false,
|
||||||
},
|
},
|
||||||
|
|
||||||
render = {
|
render = {
|
||||||
-- Colour management is stable and on by default in 0.56.
|
-- Color management is stable and on by default in 0.56.
|
||||||
cm_enabled = true,
|
cm_enabled = true,
|
||||||
|
|
||||||
-- 1 = automatically flip the monitor into HDR for fullscreen content
|
-- 1 = automatically flip the monitor into HDR for fullscreen content
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ local prefs = require("prefs")
|
|||||||
-- x = 0, y = 0, primary = true,
|
-- x = 0, y = 0, primary = true,
|
||||||
-- } }
|
-- } }
|
||||||
--
|
--
|
||||||
-- Only mode, scale, and transform are read. Colour management and bit depth
|
-- Only mode, scale, and transform are read. Color management and bit depth
|
||||||
-- stay here, because those are the settings with a documented reason attached
|
-- stay here, because those are the settings with a documented reason attached
|
||||||
-- (see the header) rather than preferences, and a settings page has no way to
|
-- (see the header) rather than preferences, and a settings page has no way to
|
||||||
-- explain the screencopy tradeoff at the moment you would be changing it.
|
-- explain the screencopy tradeoff at the moment you would be changing it.
|
||||||
@@ -147,7 +147,7 @@ hl.monitor({
|
|||||||
})
|
})
|
||||||
|
|
||||||
-- Other connected outputs use the same validated per-output store. They keep
|
-- Other connected outputs use the same validated per-output store. They keep
|
||||||
-- automatic placement and the compositor's normal colour policy; DP-2 alone
|
-- automatic placement and the compositor's normal color policy; DP-2 alone
|
||||||
-- carries the panel-specific 10-bit policy documented above.
|
-- carries the panel-specific 10-bit policy documented above.
|
||||||
for output, _ in pairs(displays) do
|
for output, _ in pairs(displays) do
|
||||||
if output ~= "DP-2" then
|
if output ~= "DP-2" then
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
-- cannot drift apart.
|
-- cannot drift apart.
|
||||||
--
|
--
|
||||||
-- Nothing here may raise. A missing, empty, truncated, or actively malformed
|
-- Nothing here may raise. A missing, empty, truncated, or actively malformed
|
||||||
-- file must cost the user nothing worse than their customisations; it must
|
-- file must cost the user nothing worse than their customizations; it must
|
||||||
-- never cost them a working compositor. Every failure path returns the caller's
|
-- never cost them a working compositor. Every failure path returns the caller's
|
||||||
-- fallback.
|
-- fallback.
|
||||||
-- ─────────────────────────────────────────────────────────────────────────────
|
-- ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ hl.window_rule({
|
|||||||
float = true,
|
float = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Settings-style utility windows and pickers: float and centre, like GNOME did.
|
-- Settings-style utility windows and pickers: float and center, like GNOME did.
|
||||||
hl.window_rule({
|
hl.window_rule({
|
||||||
match = { class = "^(pavucontrol|org\\.pulseaudio\\.pavucontrol|nm-connection-editor|blueman-manager|org\\.gnome\\.Settings)$" },
|
match = { class = "^(pavucontrol|org\\.pulseaudio\\.pavucontrol|nm-connection-editor|blueman-manager|org\\.gnome\\.Settings)$" },
|
||||||
float = true,
|
float = true,
|
||||||
@@ -150,7 +150,7 @@ hl.layer_rule({
|
|||||||
ignore_alpha = 0.3,
|
ignore_alpha = 0.3,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Popovers: calendar, quick settings, notification centre, tray menus.
|
-- Popovers: calendar, quick settings, notification center, tray menus.
|
||||||
hl.layer_rule({
|
hl.layer_rule({
|
||||||
name = "qs-popover",
|
name = "qs-popover",
|
||||||
match = { namespace = "^qs-popover" },
|
match = { namespace = "^qs-popover" },
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Tokyo Night Moon — the dark theme Panama ships.
|
# Tokyo Night Moon — the dark theme Panama ships.
|
||||||
#
|
#
|
||||||
# Extracted from kitty.conf so the two schemes can be swapped. kitty.conf
|
# Extracted from kitty.conf so the two schemes can be swapped. kitty.conf
|
||||||
# includes current-theme.conf, which Panama generates from the colour scheme
|
# includes current-theme.conf, which Panama generates from the color scheme
|
||||||
# setting; that generated file is gitignored because it is machine state.
|
# setting; that generated file is gitignored because it is machine state.
|
||||||
#
|
#
|
||||||
# Live changes go through `kitty @ set-colors`, which is why kitty.conf enables
|
# Live changes go through `kitty @ set-colors`, which is why kitty.conf enables
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
-- Hyprland config read.
|
-- Hyprland config read.
|
||||||
--
|
--
|
||||||
-- Nothing here may raise. A missing or malformed settings file must cost the
|
-- Nothing here may raise. A missing or malformed settings file must cost the
|
||||||
-- user their colour scheme preference and nothing else; editing text is more
|
-- user their color scheme preference and nothing else; editing text is more
|
||||||
-- important than matching the desktop.
|
-- important than matching the desktop.
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
-- Tokyo Night, following the desktop's colour scheme.
|
-- Tokyo Night, following the desktop's color scheme.
|
||||||
--
|
--
|
||||||
-- Moon when Panama is dark, Day when it is light. Same theme family either way,
|
-- Moon when Panama is dark, Day when it is light. Same theme family either way,
|
||||||
-- so the editor keeps the identity the rest of the desktop has rather than
|
-- so the editor keeps the identity the rest of the desktop has rather than
|
||||||
-- becoming a different-looking application when the scheme flips.
|
-- becoming a different-looking application when the scheme flips.
|
||||||
--
|
--
|
||||||
-- The readability fixes below are deliberately dark-only. They were written
|
-- The readability fixes below are deliberately dark-only. They were written
|
||||||
-- against Moon's palette -- a pale comment colour, a mid-grey gutter -- and
|
-- against Moon's palette -- a pale comment color, a mid-gray gutter -- and
|
||||||
-- applying them to Day would put light grey text on a light background, which
|
-- applying them to Day would put light gray text on a light background, which
|
||||||
-- is exactly the legibility problem they exist to solve, inverted.
|
-- is exactly the legibility problem they exist to solve, inverted.
|
||||||
|
|
||||||
local panama = require("config.panama")
|
local panama = require("config.panama")
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ console_title_template = '{{ .Shell }} in {{ .Folder }}'
|
|||||||
[[blocks.segments]]
|
[[blocks.segments]]
|
||||||
type = 'git'
|
type = 'git'
|
||||||
style = 'plain'
|
style = 'plain'
|
||||||
foreground = 'p:grey'
|
foreground = 'p:gray'
|
||||||
background = 'transparent'
|
background = 'transparent'
|
||||||
template = ' {{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed) }}*{{ end }} <cyan>{{ if gt .Behind 0 }}⇣{{ end }}{{ if gt .Ahead 0 }}⇡{{ end }}</>'
|
template = ' {{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed) }}*{{ end }} <cyan>{{ if gt .Behind 0 }}⇣{{ end }}{{ if gt .Ahead 0 }}⇡{{ end }}</>'
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ Singleton {
|
|||||||
const raw = (parsed && typeof parsed === "object") ? parsed : {};
|
const raw = (parsed && typeof parsed === "object") ? parsed : {};
|
||||||
|
|
||||||
// Upgrade before anything reads a value. A stored key the current
|
// Upgrade before anything reads a value. A stored key the current
|
||||||
// schema no longer recognises is carried through untouched and silently
|
// schema no longer recognizes is carried through untouched and silently
|
||||||
// stops taking effect, so the conversion has to happen here rather than
|
// stops taking effect, so the conversion has to happen here rather than
|
||||||
// being noticed later by whoever owns that setting.
|
// being noticed later by whoever owns that setting.
|
||||||
const result = Migrations.apply(raw);
|
const result = Migrations.apply(raw);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Singleton {
|
|||||||
printErrors: false
|
printErrors: false
|
||||||
atomicWrites: true
|
atomicWrites: true
|
||||||
onSaved: root.saveError = ""
|
onSaved: root.saveError = ""
|
||||||
onSaveFailed: error => root.saveError = "Could not save Home favourites."
|
onSaveFailed: error => root.saveError = "Could not save Home favorites."
|
||||||
|
|
||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: values
|
id: values
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ pragma Singleton
|
|||||||
// The schema is the single source of truth for what a setting IS, but it cannot
|
// The schema is the single source of truth for what a setting IS, but it cannot
|
||||||
// describe what a setting USED to be. Renaming a key, changing its units, or
|
// describe what a setting USED to be. Renaming a key, changing its units, or
|
||||||
// splitting one setting into two all leave a stored value that the new schema
|
// splitting one setting into two all leave a stored value that the new schema
|
||||||
// does not recognise -- and an unrecognised key is silently carried through
|
// does not recognize -- and an unrecognized key is silently carried through
|
||||||
// untouched, so the user's choice simply stops taking effect with nothing to
|
// untouched, so the user's choice simply stops taking effect with nothing to
|
||||||
// say why. That is the failure this exists to prevent.
|
// say why. That is the failure this exists to prevent.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ Singleton {
|
|||||||
unit: "px",
|
unit: "px",
|
||||||
group: "windows",
|
group: "windows",
|
||||||
label: "Inner gaps",
|
label: "Inner gaps",
|
||||||
detail: "Space between neighbouring tiled windows",
|
detail: "Space between neighboring tiled windows",
|
||||||
hypr: { path: ["general", "gaps_in"], option: "general:gaps_in", readAs: "css" }
|
hypr: { path: ["general", "gaps_in"], option: "general:gaps_in", readAs: "css" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -278,7 +278,7 @@ Singleton {
|
|||||||
// ── Master layout ───────────────────────────────────────────────────
|
// ── Master layout ───────────────────────────────────────────────────
|
||||||
// Only meaningful when the tiling layout is Master and stack. Offering
|
// Only meaningful when the tiling layout is Master and stack. Offering
|
||||||
// that layout with none of its options was an omission: it is the one
|
// that layout with none of its options was an omission: it is the one
|
||||||
// layout whose whole behaviour is in these settings.
|
// layout whose whole behavior is in these settings.
|
||||||
{
|
{
|
||||||
key: "masterFactor", type: "real", def: 0.55, min: 0.1, max: 0.9, step: 0.05,
|
key: "masterFactor", type: "real", def: 0.55, min: 0.1, max: 0.9, step: 0.05,
|
||||||
group: "master",
|
group: "master",
|
||||||
@@ -295,7 +295,7 @@ Singleton {
|
|||||||
{ value: "right", label: "Right" },
|
{ value: "right", label: "Right" },
|
||||||
{ value: "top", label: "Top" },
|
{ value: "top", label: "Top" },
|
||||||
{ value: "bottom", label: "Bottom" },
|
{ value: "bottom", label: "Bottom" },
|
||||||
{ value: "center", label: "Centre" }
|
{ value: "center", label: "Center" }
|
||||||
],
|
],
|
||||||
hypr: { path: ["master", "orientation"], option: "master:orientation", readAs: "str" }
|
hypr: { path: ["master", "orientation"], option: "master:orientation", readAs: "str" }
|
||||||
},
|
},
|
||||||
@@ -429,7 +429,7 @@ Singleton {
|
|||||||
{
|
{
|
||||||
key: "keyboardVariant", type: "string", def: "", group: "input",
|
key: "keyboardVariant", type: "string", def: "", group: "input",
|
||||||
// Same shape as the layout list and for the same reason: this is
|
// Same shape as the layout list and for the same reason: this is
|
||||||
// serialised into an hl.config string.
|
// serialized into an hl.config string.
|
||||||
pattern: "^$|^[a-z0-9_]{1,24}(,[a-z0-9_]{1,24})*$",
|
pattern: "^$|^[a-z0-9_]{1,24}(,[a-z0-9_]{1,24})*$",
|
||||||
label: "Layout variant",
|
label: "Layout variant",
|
||||||
detail: "XKB variant, such as dvorak or colemak. Empty for the standard layout",
|
detail: "XKB variant, such as dvorak or colemak. Empty for the standard layout",
|
||||||
@@ -475,7 +475,7 @@ Singleton {
|
|||||||
// The compositor publishes the authoritative mapping itself --
|
// The compositor publishes the authoritative mapping itself --
|
||||||
// `hyprctl descriptions` gives
|
// `hyprctl descriptions` gives
|
||||||
// map: [{"separate":3},{"detached":2},{"follow":1},{"disabled":0}]
|
// map: [{"separate":3},{"detached":2},{"follow":1},{"disabled":0}]
|
||||||
// -- so a desktop labelled "Click to focus" was in fact following
|
// -- so a desktop labeled "Click to focus" was in fact following
|
||||||
// the pointer, and the way to actually get click-to-focus was to
|
// the pointer, and the way to actually get click-to-focus was to
|
||||||
// choose "Never". Value 3 was missing entirely.
|
// choose "Never". Value 3 was missing entirely.
|
||||||
//
|
//
|
||||||
@@ -852,14 +852,14 @@ Singleton {
|
|||||||
detail: "A time earlier than the start simply means the next morning"
|
detail: "A time earlier than the start simply means the next morning"
|
||||||
},
|
},
|
||||||
|
|
||||||
// ── Colour scheme ───────────────────────────────────────────────────
|
// ── Color scheme ───────────────────────────────────────────────────
|
||||||
// Light is Tokyo Night Day, the official light variant, rather than a
|
// Light is Tokyo Night Day, the official light variant, rather than a
|
||||||
// palette invented to merely not be dark. Both share the same hues at
|
// palette invented to merely not be dark. Both share the same hues at
|
||||||
// different lightness, which is what keeps the Prism identity intact
|
// different lightness, which is what keeps the Prism identity intact
|
||||||
// across the switch.
|
// across the switch.
|
||||||
//
|
//
|
||||||
// services/ColorScheme.qml pushes the choice to GTK and to the
|
// services/ColorScheme.qml pushes the choice to GTK and to the
|
||||||
// compositor's border colours, because an application toolbar or a
|
// compositor's border colors, because an application toolbar or a
|
||||||
// window border still wearing the other scheme is more jarring than
|
// window border still wearing the other scheme is more jarring than
|
||||||
// either scheme on its own.
|
// either scheme on its own.
|
||||||
{
|
{
|
||||||
@@ -873,10 +873,10 @@ Singleton {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "accentName", type: "enum", def: "blue", group: "appearance",
|
key: "accentName", type: "enum", def: "blue", group: "appearance",
|
||||||
label: "Accent colour",
|
label: "Accent color",
|
||||||
detail: "Drives the focused window border, the bar hairline, and every active state",
|
detail: "Drives the focused window border, the bar hairline, and every active state",
|
||||||
// NAMED accents, not a free colour. Each name carries a curated
|
// NAMED accents, not a free color. Each name carries a curated
|
||||||
// pair per scheme, because one hex cannot serve both: a colour
|
// pair per scheme, because one hex cannot serve both: a color
|
||||||
// legible on the dark ground is usually illegible on the light one.
|
// legible on the dark ground is usually illegible on the light one.
|
||||||
// The palette and its measured contrast live in config/Theme.qml,
|
// The palette and its measured contrast live in config/Theme.qml,
|
||||||
// which is also what stops this list drifting from what is drawn.
|
// which is also what stops this list drifting from what is drawn.
|
||||||
@@ -998,7 +998,7 @@ Singleton {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// ── Application titlebars ──────────────────────────────────────────
|
// ── Application titlebars ──────────────────────────────────────────
|
||||||
// These affect applications that honour GNOME's window preferences.
|
// These affect applications that honor GNOME's window preferences.
|
||||||
// Hyprland itself has no server-side titlebar buttons, so minimize is
|
// Hyprland itself has no server-side titlebar buttons, so minimize is
|
||||||
// deliberately absent rather than presented as a switch that lies.
|
// deliberately absent rather than presented as a switch that lies.
|
||||||
{
|
{
|
||||||
@@ -1061,7 +1061,7 @@ Singleton {
|
|||||||
// ── Which GPU the vitals readout tracks ─────────────────────────────
|
// ── Which GPU the vitals readout tracks ─────────────────────────────
|
||||||
// A sysfs path rather than a card number, because the number is neither
|
// A sysfs path rather than a card number, because the number is neither
|
||||||
// stable across machines nor meaningful. Constrained to the one shape
|
// stable across machines nor meaningful. Constrained to the one shape
|
||||||
// that can be read for utilisation; VitalsWidget hides itself when the
|
// that can be read for utilization; VitalsWidget hides itself when the
|
||||||
// path is unreadable, so a stale value degrades to no readout rather
|
// path is unreadable, so a stale value degrades to no readout rather
|
||||||
// than a wrong one.
|
// than a wrong one.
|
||||||
{
|
{
|
||||||
@@ -1077,7 +1077,7 @@ Singleton {
|
|||||||
// Coordinates rather than a place name, because that is what Open-Meteo
|
// Coordinates rather than a place name, because that is what Open-Meteo
|
||||||
// takes and it needs no API key. weatherLocation is only the label shown
|
// takes and it needs no API key. weatherLocation is only the label shown
|
||||||
// in the UI; it is never sent anywhere, so it can say whatever makes the
|
// in the UI; it is never sent anywhere, so it can say whatever makes the
|
||||||
// reading recognisable.
|
// reading recognizable.
|
||||||
{
|
{
|
||||||
key: "weatherLatitude", type: "real", def: 27.7375, min: -90, max: 90, step: 0.0001,
|
key: "weatherLatitude", type: "real", def: 27.7375, min: -90, max: 90, step: 0.0001,
|
||||||
group: "weather", internal: true,
|
group: "weather", internal: true,
|
||||||
@@ -1212,7 +1212,7 @@ Singleton {
|
|||||||
|
|
||||||
// ── Display configuration ───────────────────────────────────────────
|
// ── Display configuration ───────────────────────────────────────────
|
||||||
// { "<output>": { mode, scale, transform, x, y, primary } }, applied by
|
// { "<output>": { mode, scale, transform, x, y, primary } }, applied by
|
||||||
// hypr/monitors.lua on top of the shipped values. Colour management and
|
// hypr/monitors.lua on top of the shipped values. Color management and
|
||||||
// bit depth are deliberately not here: those carry a documented
|
// bit depth are deliberately not here: those carry a documented
|
||||||
// screencopy tradeoff that a settings page cannot explain at the moment
|
// screencopy tradeoff that a settings page cannot explain at the moment
|
||||||
// you would be changing it.
|
// you would be changing it.
|
||||||
@@ -1325,7 +1325,7 @@ Singleton {
|
|||||||
case "string": {
|
case "string": {
|
||||||
const text = typeof value === "string" ? value : String(value);
|
const text = typeof value === "string" ? value : String(value);
|
||||||
// A constrained string is rejected rather than sanitised. Several
|
// A constrained string is rejected rather than sanitised. Several
|
||||||
// of these are serialised into an hl.config payload, and quietly
|
// of these are serialized into an hl.config payload, and quietly
|
||||||
// stripping characters would turn a typo into a different setting
|
// stripping characters would turn a typo into a different setting
|
||||||
// instead of an error the user can see.
|
// instead of an error the user can see.
|
||||||
if (entry.pattern && !new RegExp(entry.pattern).test(text))
|
if (entry.pattern && !new RegExp(entry.pattern).test(text))
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Singleton {
|
|||||||
readonly property int focusDurationMinutes: DesktopPreferences.get("focusDurationMinutes")
|
readonly property int focusDurationMinutes: DesktopPreferences.get("focusDurationMinutes")
|
||||||
|
|
||||||
// ── Dock ────────────────────────────────────────────────────────────────
|
// ── Dock ────────────────────────────────────────────────────────────────
|
||||||
// Pinned apps, in order, taken from the GNOME dash favourites.
|
// Pinned apps, in order, taken from the GNOME dash favorites.
|
||||||
readonly property var dockPinned: DesktopPreferences.get("dockPinned")
|
readonly property var dockPinned: DesktopPreferences.get("dockPinned")
|
||||||
|
|
||||||
// Dash-to-Dock was set to intellihide against all windows: the dock hides
|
// Dash-to-Dock was set to intellihide against all windows: the dock hides
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
// Tokyo Night Moon — the single source of truth for every colour, radius,
|
// Tokyo Night Moon — the single source of truth for every color, radius,
|
||||||
// duration and font in the shell. Nothing below this file should hardcode a
|
// duration and font in the shell. Nothing below this file should hardcode a
|
||||||
// colour; if you find yourself writing "#" outside this file, add a token here.
|
// color; if you find yourself writing "#" outside this file, add a token here.
|
||||||
//
|
//
|
||||||
// The bar keeps GNOME's 36px information density but sits directly on the
|
// The bar keeps GNOME's 36px information density but sits directly on the
|
||||||
// desktop, edge to edge. The dock retains the former glass vocabulary: bottom,
|
// desktop, edge to edge. The dock retains the former glass vocabulary: bottom,
|
||||||
@@ -18,7 +18,7 @@ import QtQuick
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// ── Colour scheme ───────────────────────────────────────────────────────
|
// ── Color scheme ───────────────────────────────────────────────────────
|
||||||
// Tokyo Night ships an official light variant (Day), so light mode is that
|
// Tokyo Night ships an official light variant (Day), so light mode is that
|
||||||
// rather than a palette invented to merely not be dark. The two share the
|
// rather than a palette invented to merely not be dark. The two share the
|
||||||
// same hues at different lightness, which is what lets the Prism identity
|
// same hues at different lightness, which is what lets the Prism identity
|
||||||
@@ -46,12 +46,12 @@ Singleton {
|
|||||||
//
|
//
|
||||||
// `accent` is the primary and carries every state meaning (focused, active,
|
// `accent` is the primary and carries every state meaning (focused, active,
|
||||||
// on). `accentSecondary` never appears alone, only as the far end of a
|
// on). `accentSecondary` never appears alone, only as the far end of a
|
||||||
// gradient. That restraint is the whole point: the two colours meeting is
|
// gradient. That restraint is the whole point: the two colors meeting is
|
||||||
// the signature, so the second colour stops being special the moment it is
|
// the signature, so the second color stops being special the moment it is
|
||||||
// used as a flat fill.
|
// used as a flat fill.
|
||||||
//
|
//
|
||||||
// NAMED accents rather than a free colour. Each name carries a curated
|
// NAMED accents rather than a free color. Each name carries a curated
|
||||||
// triple per scheme, because an arbitrary hex cannot work in both: a colour
|
// triple per scheme, because an arbitrary hex cannot work in both: a color
|
||||||
// legible on the Moon background is usually illegible on the Day one, and a
|
// legible on the Moon background is usually illegible on the Day one, and a
|
||||||
// picker that lets someone choose an unreadable desktop is not a feature.
|
// picker that lets someone choose an unreadable desktop is not a feature.
|
||||||
// Every pair below measures at least 3:1 against the ground it sits on.
|
// Every pair below measures at least 3:1 against the ground it sits on.
|
||||||
@@ -72,7 +72,7 @@ Singleton {
|
|||||||
|
|
||||||
// Falls back to blue for an unknown name, so a settings file written by a
|
// Falls back to blue for an unknown name, so a settings file written by a
|
||||||
// newer Panama -- or edited by hand -- degrades to the shipped identity
|
// newer Panama -- or edited by hand -- degrades to the shipped identity
|
||||||
// rather than to an undefined colour.
|
// rather than to an undefined color.
|
||||||
readonly property var accentPair: root.accents[DesktopPreferences.get("accentName")] ?? root.accents["blue"]
|
readonly property var accentPair: root.accents[DesktopPreferences.get("accentName")] ?? root.accents["blue"]
|
||||||
|
|
||||||
readonly property color accent: root.dark ? root.accentPair.dark : root.accentPair.light
|
readonly property color accent: root.dark ? root.accentPair.dark : root.accentPair.light
|
||||||
@@ -136,7 +136,7 @@ Singleton {
|
|||||||
|
|
||||||
// Nerd Font, used ONLY to draw icon glyphs — never for text. It is the
|
// Nerd Font, used ONLY to draw icon glyphs — never for text. It is the
|
||||||
// pragmatic alternative to freedesktop symbolic icons, which ship with a
|
// pragmatic alternative to freedesktop symbolic icons, which ship with a
|
||||||
// hardcoded dark fill Qt will not recolour (see widgets/ThemedIcon.qml).
|
// hardcoded dark fill Qt will not recolor (see widgets/ThemedIcon.qml).
|
||||||
readonly property string fontMono: DesktopPreferences.get("iconFont")
|
readonly property string fontMono: DesktopPreferences.get("iconFont")
|
||||||
|
|
||||||
// Apply to any text whose digits change in place — clocks, percentages,
|
// Apply to any text whose digits change in place — clocks, percentages,
|
||||||
@@ -180,7 +180,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Blend two tokens — used for hover/pressed states so we never invent a
|
// Blend two tokens — used for hover/pressed states so we never invent a
|
||||||
// colour that isn't derived from the palette.
|
// color that isn't derived from the palette.
|
||||||
function mix(a: color, b: color, ratio: real): color {
|
function mix(a: color, b: color, ratio: real): color {
|
||||||
return Qt.rgba(a.r + (b.r - a.r) * ratio, a.g + (b.g - a.g) * ratio, a.b + (b.b - a.b) * ratio, a.a + (b.a - a.a) * ratio);
|
return Qt.rgba(a.r + (b.r - a.r) * ratio, a.g + (b.g - a.g) * ratio, a.b + (b.b - a.b) * ratio, a.a + (b.a - a.a) * ratio);
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ Singleton {
|
|||||||
// the active workspace pill and slider fills.
|
// the active workspace pill and slider fills.
|
||||||
//
|
//
|
||||||
// Where the gradient runs left-to-right the blue leads, because the eye
|
// Where the gradient runs left-to-right the blue leads, because the eye
|
||||||
// reads left first and blue is the colour that carries meaning.
|
// reads left first and blue is the color that carries meaning.
|
||||||
readonly property real prismStart: 0.22
|
readonly property real prismStart: 0.22
|
||||||
readonly property real prismEnd: 0.78
|
readonly property real prismEnd: 0.78
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ ShellRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function refreshIdentityFixture(): string {
|
function refreshIdentityFixture(): string {
|
||||||
const modes = Displays.normaliseModes([
|
const modes = Displays.normalizeModes([
|
||||||
"[email protected]",
|
"[email protected]",
|
||||||
"[email protected]"
|
"[email protected]"
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Fixture steps rather than the real list: the real one is empty until the
|
// Fixture steps rather than the real list: the real one is empty until the
|
||||||
// first breaking schema change, and a mechanism that has never been run against
|
// first breaking schema change, and a mechanism that has never been run against
|
||||||
// a failing step is not one to discover the behaviour of during an upgrade.
|
// a failing step is not one to discover the behavior of during an upgrade.
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
// Bar {}
|
// Bar {}
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Layout mirrors GNOME's: workspaces + vitals left, clock + weather centre,
|
// Layout mirrors GNOME's: workspaces + vitals left, clock + weather center,
|
||||||
// media + tray + status cluster right.
|
// media + tray + status cluster right.
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
@@ -83,7 +83,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Centre ──────────────────────────────────────────────────────────
|
// ── Center ──────────────────────────────────────────────────────────
|
||||||
Row {
|
Row {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// The centre clock, kept in the same place and the same format GNOME had it:
|
// The center clock, kept in the same place and the same format GNOME had it:
|
||||||
// weekday, date, 12-hour time with seconds. Clicking it opens the calendar,
|
// weekday, date, 12-hour time with seconds. Clicking it opens the calendar,
|
||||||
// exactly like GNOME's date menu.
|
// exactly like GNOME's date menu.
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ Pill {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: Qt.formatDateTime(clock.date, root.format)
|
text: Qt.formatDateTime(clock.date, root.format)
|
||||||
font.family: Theme.fontFamily
|
font.family: Theme.fontFamily
|
||||||
// Seconds tick once a second in the centre of the bar; without tabular
|
// Seconds tick once a second in the center of the bar; without tabular
|
||||||
// figures the whole clock shifts sideways on every digit change.
|
// figures the whole clock shifts sideways on every digit change.
|
||||||
font.features: Theme.tabularFigures
|
font.features: Theme.tabularFigures
|
||||||
font.pixelSize: Theme.fontSize
|
font.pixelSize: Theme.fontSize
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Pill {
|
|||||||
if (!root.wifiNetwork)
|
if (!root.wifiNetwork)
|
||||||
return "\u{F092D}"; // md-wifi_strength_off
|
return "\u{F092D}"; // md-wifi_strength_off
|
||||||
|
|
||||||
// NetworkManager reports strength 0-100; some backends normalise to
|
// NetworkManager reports strength 0-100; some backends normalize to
|
||||||
// 0-1, so accept either rather than showing one bar forever.
|
// 0-1, so accept either rather than showing one bar forever.
|
||||||
const raw = root.wifiNetwork.signalStrength ?? 0;
|
const raw = root.wifiNetwork.signalStrength ?? 0;
|
||||||
const strength = raw <= 1 ? raw * 100 : raw;
|
const strength = raw <= 1 ? raw * 100 : raw;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// One glyph + percentage pair inside VitalsWidget. Split out so the three
|
// One glyph + percentage pair inside VitalsWidget. Split out so the three
|
||||||
// fields cannot drift apart in spacing, width or colour thresholds.
|
// fields cannot drift apart in spacing, width or color thresholds.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.config
|
import qs.config
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Vitals extension was configured with (_processor_usage_, _memory_usage_,
|
// Vitals extension was configured with (_processor_usage_, _memory_usage_,
|
||||||
// _gpu#1_usage_).
|
// _gpu#1_usage_).
|
||||||
//
|
//
|
||||||
// Values are colour-coded rather than graphed: at bar size a number you can
|
// Values are color-coded rather than graphed: at bar size a number you can
|
||||||
// glance at beats a sparkline you have to squint at.
|
// glance at beats a sparkline you have to squint at.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ Item {
|
|||||||
|
|
||||||
implicitWidth: row.implicitWidth + 12
|
implicitWidth: row.implicitWidth + 12
|
||||||
// Full bar height makes (0, 0) part of the wheel target. The dots stay
|
// Full bar height makes (0, 0) part of the wheel target. The dots stay
|
||||||
// optically centred by the row and active-pill geometry below.
|
// optically centered by the row and active-pill geometry below.
|
||||||
implicitHeight: Theme.barHeight
|
implicitHeight: Theme.barHeight
|
||||||
|
|
||||||
// Scroll over the padding either side of the row, not just over a dot.
|
// Scroll over the padding either side of the row, not just over a dot.
|
||||||
@@ -59,7 +59,7 @@ Item {
|
|||||||
border.width: 0 // QTBUG-137166: rounded rects can lose their corners
|
border.width: 0 // QTBUG-137166: rounded rects can lose their corners
|
||||||
|
|
||||||
// The prism, as a fill rather than a hairline. This is the one element
|
// The prism, as a fill rather than a hairline. This is the one element
|
||||||
// in the bar that is always coloured, so it is where the pair belongs.
|
// in the bar that is always colored, so it is where the pair belongs.
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
orientation: Gradient.Horizontal
|
orientation: Gradient.Horizontal
|
||||||
GradientStop {
|
GradientStop {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// The floating control panel at the bottom of the capture overlay.
|
// The floating control panel at the bottom of the capture overlay.
|
||||||
//
|
//
|
||||||
// Layout is a deliberate copy of GNOME 42's screenshot UI: the area segmented
|
// Layout is a deliberate copy of GNOME 42's screenshot UI: the area segmented
|
||||||
// control on top, and below it the shutter dead-centre with "Show Pointer" on
|
// control on top, and below it the shutter dead-center with "Show Pointer" on
|
||||||
// the left and the screenshot/screencast switch on the right.
|
// the left and the screenshot/screencast switch on the right.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -13,7 +13,7 @@ Rectangle {
|
|||||||
|
|
||||||
signal captureRequested
|
signal captureRequested
|
||||||
|
|
||||||
// Set by the overlay so the shutter can grey out when Window mode has
|
// Set by the overlay so the shutter can gray out when Window mode has
|
||||||
// nothing pickable (no Hyprland, or an empty workspace).
|
// nothing pickable (no Hyprland, or an empty workspace).
|
||||||
property bool captureEnabled: true
|
property bool captureEnabled: true
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// One segment of the Screen / Window / Selection control.
|
// One segment of the Screen / Window / Selection control.
|
||||||
//
|
//
|
||||||
// Icons are Nerd Font glyphs rather than freedesktop icons on purpose: the
|
// Icons are Nerd Font glyphs rather than freedesktop icons on purpose: the
|
||||||
// Adwaita "symbolic" SVGs are flat black and Qt, unlike GTK, will not recolour
|
// Adwaita "symbolic" SVGs are flat black and Qt, unlike GTK, will not recolor
|
||||||
// them, so they'd be invisible on this dark overlay.
|
// them, so they'd be invisible on this dark overlay.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Selection mode: a GNOME-style rubber band over the frozen screen.
|
// Selection mode: a GNOME-style rubber band over the frozen screen.
|
||||||
//
|
//
|
||||||
// Behaviours copied from GNOME 42: the overlay opens with a sensible centred
|
// Behaviors copied from GNOME 42: the overlay opens with a sensible centered
|
||||||
// selection already in place (so the shutter is immediately useful), dragging
|
// selection already in place (so the shutter is immediately useful), dragging
|
||||||
// inside moves it, dragging a corner resizes from the opposite corner, and
|
// inside moves it, dragging a corner resizes from the opposite corner, and
|
||||||
// dragging anywhere else starts a fresh band.
|
// dragging anywhere else starts a fresh band.
|
||||||
@@ -52,7 +52,7 @@ Item {
|
|||||||
root.resetSelection();
|
root.resetSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Centred, roughly the middle half of the screen.
|
// Centered, roughly the middle half of the screen.
|
||||||
function resetSelection(): void {
|
function resetSelection(): void {
|
||||||
if (root.width <= 0 || root.height <= 0)
|
if (root.width <= 0 || root.height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// The month grid from GNOME's date menu.
|
// The month grid from GNOME's date menu.
|
||||||
//
|
//
|
||||||
// Six week rows always, so the grid height never changes as you page through
|
// Six week rows always, so the grid height never changes as you page through
|
||||||
// months and the panel below it never jumps. Days belonging to the neighbouring
|
// months and the panel below it never jumps. Days belonging to the neighboring
|
||||||
// months fill the edges, dimmed. Today wears the accent.
|
// months fill the edges, dimmed. Today wears the accent.
|
||||||
//
|
//
|
||||||
// Days become real navigation targets now that Evolution Data Server backs the
|
// Days become real navigation targets now that Evolution Data Server backs the
|
||||||
// panel. Up to three source-coloured markers show whether a date has events.
|
// panel. Up to three source-colored markers show whether a date has events.
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -134,7 +134,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Centred on the row rather than between the pill and the arrows,
|
// Centered on the row rather than between the pill and the arrows,
|
||||||
// so it does not shift sideways when the pill appears.
|
// so it does not shift sideways when the pill appears.
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// GNOME's date/time menu: calendar, ongoing activity and messages in one panel,
|
// GNOME's date/time menu: calendar, ongoing activity and messages in one panel,
|
||||||
// dropping from the top centre because that is where GNOME put it and the
|
// dropping from the top center because that is where GNOME put it and the
|
||||||
// muscle memory is the whole point.
|
// muscle memory is the whole point.
|
||||||
//
|
//
|
||||||
// A layer-shell surface rather than a PopupWindow because the inline reply
|
// A layer-shell surface rather than a PopupWindow because the inline reply
|
||||||
// fields have to be typeable, and because the clock it hangs from is owned by a
|
// fields have to be typeable, and because the clock it hangs from is owned by a
|
||||||
// different module.
|
// different module.
|
||||||
//
|
//
|
||||||
// Layer-shell centres a surface on whichever axis it is not anchored to, so
|
// Layer-shell centers a surface on whichever axis it is not anchored to, so
|
||||||
// anchoring only `top` is what puts it in the middle.
|
// anchoring only `top` is what puts it in the middle.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -87,7 +87,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grows out of the top edge it is anchored to, rather than out of its
|
// Grows out of the top edge it is anchored to, rather than out of its
|
||||||
// own centre — the panel should look like it came from the bar.
|
// own center — the panel should look like it came from the bar.
|
||||||
transform: Scale {
|
transform: Scale {
|
||||||
id: openScale
|
id: openScale
|
||||||
origin.x: surface.width / 2
|
origin.x: surface.width / 2
|
||||||
|
|||||||
@@ -172,14 +172,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Centred on the hovered item, clamped inside the dock. Reads the item's
|
// Centered on the hovered item, clamped inside the dock. Reads the item's
|
||||||
// x directly (rather than mapToItem) so the binding re-evaluates when
|
// x directly (rather than mapToItem) so the binding re-evaluates when
|
||||||
// the row reflows.
|
// the row reflows.
|
||||||
x: {
|
x: {
|
||||||
if (!root.hoveredItem)
|
if (!root.hoveredItem)
|
||||||
return 0;
|
return 0;
|
||||||
const centre = row.x + root.hoveredItem.x + root.hoveredItem.width / 2;
|
const center = row.x + root.hoveredItem.x + root.hoveredItem.width / 2;
|
||||||
return Math.max(4, Math.min(root.width - width - 4, centre - width / 2));
|
return Math.max(4, Math.min(root.width - width - 4, center - width / 2));
|
||||||
}
|
}
|
||||||
y: -height - 8
|
y: -height - 8
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// One dock icon: the app, its running-window dots, hover scale and click
|
// One dock icon: the app, its running-window dots, hover scale and click
|
||||||
// behaviour. Reproduces Dash-to-Dock's item: 48px icon, up to four dots
|
// behavior. Reproduces Dash-to-Dock's item: 48px icon, up to four dots
|
||||||
// underneath, grow-on-hover, click to focus / cycle / launch.
|
// underneath, grow-on-hover, click to focus / cycle / launch.
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
@@ -72,7 +72,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Last resort for an app with no resolvable icon: an initial, which is
|
// Last resort for an app with no resolvable icon: an initial, which is
|
||||||
// still recognisable, unlike the theme's broken-icon placeholder.
|
// still recognizable, unlike the theme's broken-icon placeholder.
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: root.iconSource === ""
|
visible: root.iconSource === ""
|
||||||
@@ -155,7 +155,7 @@ Item {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Quickshell reports the address without the 0x prefix Hyprland's
|
// Quickshell reports the address without the 0x prefix Hyprland's
|
||||||
// window selector expects; normalise so either form works.
|
// window selector expects; normalize so either form works.
|
||||||
if (next.address) {
|
if (next.address) {
|
||||||
const addr = next.address.startsWith("0x") ? next.address : "0x" + next.address;
|
const addr = next.address.startsWith("0x") ? next.address : "0x" + next.address;
|
||||||
Hyprland.dispatch(`hl.dsp.focus({ window = "address:${addr}" })`);
|
Hyprland.dispatch(`hl.dsp.focus({ window = "address:${addr}" })`);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// One notification, rendered GNOME-style: app icon, app name, summary, body,
|
// One notification, rendered GNOME-style: app icon, app name, summary, body,
|
||||||
// optional image, action buttons and an inline reply box.
|
// optional image, action buttons and an inline reply box.
|
||||||
//
|
//
|
||||||
// Shared by the toasts and the notification centre so a notification looks the
|
// Shared by the toasts and the notification center so a notification looks the
|
||||||
// same wherever you meet it.
|
// same wherever you meet it.
|
||||||
//
|
//
|
||||||
// IconButton/ThemedIcon come from the quicksettings module — they belong in
|
// IconButton/ThemedIcon come from the quicksettings module — they belong in
|
||||||
@@ -21,7 +21,7 @@ Rectangle {
|
|||||||
|
|
||||||
required property var notification
|
required property var notification
|
||||||
|
|
||||||
// The centre renders a denser card than a toast banner.
|
// The center renders a denser card than a toast banner.
|
||||||
property bool compact: false
|
property bool compact: false
|
||||||
|
|
||||||
signal dismissed
|
signal dismissed
|
||||||
@@ -43,7 +43,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Critical notifications get a red edge rather than a colour wash, so the
|
// Critical notifications get a red edge rather than a color wash, so the
|
||||||
// text contrast never changes.
|
// text contrast never changes.
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// One workspace in the overview: a proportional card holding live thumbnails
|
// One workspace in the overview: a proportional card holding live thumbnails
|
||||||
// of its windows, labelled underneath. The focused workspace is outlined in the
|
// of its windows, labeled underneath. The focused workspace is outlined in the
|
||||||
// accent colour, as GNOME outlines the current workspace.
|
// accent color, as GNOME outlines the current workspace.
|
||||||
//
|
//
|
||||||
// A card with a null `workspace` is the trailing "new workspace" affordance
|
// A card with a null `workspace` is the trailing "new workspace" affordance
|
||||||
// that dynamic-workspace setups (GNOME's, and Hyprland's) always show.
|
// that dynamic-workspace setups (GNOME's, and Hyprland's) always show.
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ Item {
|
|||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
// BlueZ reports a plain freedesktop name ("audio-headphones");
|
// BlueZ reports a plain freedesktop name ("audio-headphones");
|
||||||
// the symbolic variant is the one that can be recoloured.
|
// the symbolic variant is the one that can be recolored.
|
||||||
icon: deviceRow.modelData.icon !== "" ? deviceRow.modelData.icon + "-symbolic" : "bluetooth-symbolic"
|
icon: deviceRow.modelData.icon !== "" ? deviceRow.modelData.icon + "-symbolic" : "bluetooth-symbolic"
|
||||||
iconFallback: "bluetooth-symbolic"
|
iconFallback: "bluetooth-symbolic"
|
||||||
label: deviceRow.modelData.name || deviceRow.modelData.address
|
label: deviceRow.modelData.name || deviceRow.modelData.address
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Item {
|
|||||||
property real backlightValue: 0
|
property real backlightValue: 0
|
||||||
|
|
||||||
readonly property int rowCount: (root.backlightAvailable ? 1 : 0) + Brightness.displays.length
|
readonly property int rowCount: (root.backlightAvailable ? 1 : 0) + Brightness.displays.length
|
||||||
readonly property bool labelled: root.rowCount > 1
|
readonly property bool labeled: root.rowCount > 1
|
||||||
|
|
||||||
visible: root.rowCount > 0
|
visible: root.rowCount > 0
|
||||||
implicitHeight: rows.implicitHeight
|
implicitHeight: rows.implicitHeight
|
||||||
@@ -89,7 +89,7 @@ Item {
|
|||||||
// Hyprland already knows what each output is called, so the
|
// Hyprland already knows what each output is called, so the
|
||||||
// name comes from there rather than from a second source that
|
// name comes from there rather than from a second source that
|
||||||
// could disagree with the Displays page. The connector is the
|
// could disagree with the Displays page. The connector is the
|
||||||
// fallback, so a display is never an unlabelled slider.
|
// fallback, so a display is never an unlabeled slider.
|
||||||
label: Displays.monitorNamed(modelData.connector)?.description || modelData.connector
|
label: Displays.monitorNamed(modelData.connector)?.description || modelData.connector
|
||||||
value: modelData.value / 100
|
value: modelData.value / 100
|
||||||
onMoved: v => Brightness.set(modelData.bus, Math.round(v * 100))
|
onMoved: v => Brightness.set(modelData.bus, Math.round(v * 100))
|
||||||
@@ -113,7 +113,7 @@ Item {
|
|||||||
anchors.leftMargin: 6
|
anchors.leftMargin: 6
|
||||||
anchors.rightMargin: 6
|
anchors.rightMargin: 6
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
visible: root.labelled
|
visible: root.labeled
|
||||||
height: visible ? implicitHeight + 2 : 0
|
height: visible ? implicitHeight + 2 : 0
|
||||||
text: row.label
|
text: row.label
|
||||||
color: Theme.fgDim
|
color: Theme.fgDim
|
||||||
@@ -124,7 +124,7 @@ Item {
|
|||||||
|
|
||||||
// The slider and its glyph share one strip so the two stay aligned
|
// The slider and its glyph share one strip so the two stay aligned
|
||||||
// whether or not a caption sits above them. Anchoring the glyph to
|
// whether or not a caption sits above them. Anchoring the glyph to
|
||||||
// both a caption and a centre line instead would conflict, and an
|
// both a caption and a center line instead would conflict, and an
|
||||||
// anchor set to undefined is not released.
|
// anchor set to undefined is not released.
|
||||||
Item {
|
Item {
|
||||||
id: control
|
id: control
|
||||||
@@ -134,7 +134,7 @@ Item {
|
|||||||
height: 32
|
height: 32
|
||||||
|
|
||||||
// ValueSlider draws its own leading icon, but symbolic icons need
|
// ValueSlider draws its own leading icon, but symbolic icons need
|
||||||
// recolouring to be visible — see ThemedIcon.
|
// recoloring to be visible — see ThemedIcon.
|
||||||
ThemedIcon {
|
ThemedIcon {
|
||||||
id: glyph
|
id: glyph
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Full-height rather than vertically centred so slot contents can anchor
|
// Full-height rather than vertically centered so slot contents can anchor
|
||||||
// their own verticalCenter to it without a size loop.
|
// their own verticalCenter to it without a size loop.
|
||||||
Row {
|
Row {
|
||||||
id: trailingRow
|
id: trailingRow
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
//
|
//
|
||||||
// Each swatch is drawn as the GRADIENT it will actually produce, not a flat
|
// Each swatch is drawn as the GRADIENT it will actually produce, not a flat
|
||||||
// dot, because the gradient is the thing being chosen -- the focused window
|
// dot, because the gradient is the thing being chosen -- the focused window
|
||||||
// border, the bar hairline and every active state are the two colours meeting.
|
// border, the bar hairline and every active state are the two colors meeting.
|
||||||
// A row of flat circles would misrepresent all of them.
|
// A row of flat circles would misrepresent all of them.
|
||||||
//
|
//
|
||||||
// Named accents rather than a colour wheel: each name carries a curated pair
|
// Named accents rather than a color wheel: each name carries a curated pair
|
||||||
// per scheme, so every choice stays legible in both light and dark. See
|
// per scheme, so every choice stays legible in both light and dark. See
|
||||||
// config/Theme.qml for the palette and the reasoning.
|
// config/Theme.qml for the palette and the reasoning.
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ Flow {
|
|||||||
|
|
||||||
// The hit target is the whole swatch+label unit, not just the
|
// The hit target is the whole swatch+label unit, not just the
|
||||||
// 46px circle: the label exists specifically so someone with a
|
// 46px circle: the label exists specifically so someone with a
|
||||||
// colour vision deficiency can identify an accent without it, and
|
// color vision deficiency can identify an accent without it, and
|
||||||
// a label that cannot itself be tapped defeats that.
|
// a label that cannot itself be tapped defeats that.
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
@@ -66,7 +66,7 @@ Flow {
|
|||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
// The ring sits outside the gradient rather than over it, so a
|
// The ring sits outside the gradient rather than over it, so a
|
||||||
// selected swatch still shows its true colours.
|
// selected swatch still shows its true colors.
|
||||||
border.width: entry.selected ? 2 : 1
|
border.width: entry.selected ? 2 : 1
|
||||||
border.color: entry.selected ? Theme.fg : Theme.alpha(Theme.fg, 0.14)
|
border.color: entry.selected ? Theme.fg : Theme.alpha(Theme.fg, 0.14)
|
||||||
|
|
||||||
@@ -83,8 +83,8 @@ Flow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always shown, not a tooltip. Telling swatches apart by colour is
|
// Always shown, not a tooltip. Telling swatches apart by color is
|
||||||
// exactly what someone with a colour vision deficiency cannot do,
|
// exactly what someone with a color vision deficiency cannot do,
|
||||||
// and it is the reason the palette is named rather than freeform --
|
// and it is the reason the palette is named rather than freeform --
|
||||||
// hiding the names behind a hover would waste that.
|
// hiding the names behind a hover would waste that.
|
||||||
Text {
|
Text {
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ SettingsPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
title: "Colour scheme"
|
title: "Color scheme"
|
||||||
subtitle: ColorScheme.lastError !== ""
|
subtitle: ColorScheme.lastError !== ""
|
||||||
? ColorScheme.lastError
|
? ColorScheme.lastError
|
||||||
: "Light is Tokyo Night Day, the official light variant — the same hues at a different lightness, so the blue-into-orchid signature survives the switch. Applications and window borders follow."
|
: "Light is Tokyo Night Day, the official light variant — the same hues at a different lightness, so the blue-into-orchid signature survives the switch. Applications and window borders follow."
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
// because that genuinely is a Panama preference.
|
// because that genuinely is a Panama preference.
|
||||||
//
|
//
|
||||||
// Changing the timezone or network time needs privilege. timedatectl asks
|
// Changing the timezone or network time needs privilege. timedatectl asks
|
||||||
// polkit, and a cancelled dialog surfaces as an error rather than as a value
|
// polkit, and a canceled dialog surfaces as an error rather than as a value
|
||||||
// that appears to have been accepted.
|
// that appears to have been accepted.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -33,7 +33,7 @@ SettingsPage {
|
|||||||
SettingRow {
|
SettingRow {
|
||||||
label: "Set automatically"
|
label: "Set automatically"
|
||||||
detail: DateTime.ntpEnabled
|
detail: DateTime.ntpEnabled
|
||||||
? (DateTime.ntpSynchronised ? "Synchronised with a time server" : "Waiting to synchronise")
|
? (DateTime.ntpSynchronized ? "Synchronized with a time server" : "Waiting to synchronize")
|
||||||
: "The clock is set by hand"
|
: "The clock is set by hand"
|
||||||
controlWidth: 48
|
controlWidth: 48
|
||||||
divider: false
|
divider: false
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Rectangle {
|
|||||||
|
|
||||||
// Stands in for the wallpaper. Static: an animated gradient here would
|
// Stands in for the wallpaper. Static: an animated gradient here would
|
||||||
// repaint forever behind a settings page.
|
// repaint forever behind a settings page.
|
||||||
// Follows the colour scheme. A preview that stays dark while the shell
|
// Follows the color scheme. A preview that stays dark while the shell
|
||||||
// around it is light does not read as "your desktop" -- it reads as a
|
// around it is light does not read as "your desktop" -- it reads as a
|
||||||
// screenshot of someone else's.
|
// screenshot of someone else's.
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
@@ -129,7 +129,7 @@ Rectangle {
|
|||||||
required property bool focused
|
required property bool focused
|
||||||
|
|
||||||
// The gradient border is drawn as a filled rounded rect with the window
|
// The gradient border is drawn as a filled rounded rect with the window
|
||||||
// body inset on top of it: QML's Rectangle border takes a colour, not a
|
// body inset on top of it: QML's Rectangle border takes a color, not a
|
||||||
// gradient, and the prism border is the whole signature here.
|
// gradient, and the prism border is the whole signature here.
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: frame
|
id: frame
|
||||||
|
|||||||
@@ -440,9 +440,9 @@ SettingsPage {
|
|||||||
|
|
||||||
ActionRow {
|
ActionRow {
|
||||||
objectName: "health-fedora-handoff:color"
|
objectName: "health-fedora-handoff:color"
|
||||||
label: "Colour profiles"
|
label: "Color profiles"
|
||||||
detail: "Assigning an ICC profile here has no visible effect in this session: the colord daemon that loads it onto a display isn't running under Hyprland"
|
detail: "Assigning an ICC profile here has no visible effect in this session: the colord daemon that loads it onto a display isn't running under Hyprland"
|
||||||
action: "Open colour"
|
action: "Open color"
|
||||||
onTriggered: SystemSettings.openGnomePanel("color")
|
onTriggered: SystemSettings.openGnomePanel("color")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ SettingsPage {
|
|||||||
|
|
||||||
title: "Mouse & Touchpad"
|
title: "Mouse & Touchpad"
|
||||||
lede: InputDevices.hasTouchpad
|
lede: InputDevices.hasTouchpad
|
||||||
? "Pointer behaviour for your mouse and touchpad."
|
? "Pointer behavior for your mouse and touchpad."
|
||||||
: "Pointer behaviour. Touchpad settings appear when a touchpad is attached."
|
: "Pointer behavior. Touchpad settings appear when a touchpad is attached."
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
title: "Mouse"
|
title: "Mouse"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ SettingsPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
title: "Idle behaviour"
|
title: "Idle behavior"
|
||||||
subtitle: IdleLock.managed
|
subtitle: IdleLock.managed
|
||||||
? "Idle timings are managed here. Changes take effect immediately."
|
? "Idle timings are managed here. Changes take effect immediately."
|
||||||
: "hypridle is running its shipped configuration. Turn on management below to make these adjustable."
|
: "hypridle is running its shipped configuration. Turn on management below to make these adjustable."
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Settings
|
# Settings
|
||||||
|
|
||||||
The control centre for everything Panama owns. Anything the system owns —
|
The control center for everything Panama owns. Anything the system owns —
|
||||||
hardware, accounts, printers — is delegated to GNOME Settings and labelled as
|
hardware, accounts, printers — is delegated to GNOME Settings and labeled as
|
||||||
such rather than half-reimplemented.
|
such rather than half-reimplemented.
|
||||||
|
|
||||||
## System Health
|
## System Health
|
||||||
@@ -28,7 +28,7 @@ package, runs `sudo`, deletes user data, or repairs a service Panama does not
|
|||||||
own. A repair remains degraded until a fresh scan observes recovery.
|
own. A repair remains degraded until a fresh scan observes recovery.
|
||||||
|
|
||||||
The final card is the ownership boundary. Network configuration and the exact
|
The final card is the ownership boundary. Network configuration and the exact
|
||||||
Users, Sharing, Colour profiles, and Digital wellbeing handoffs open GNOME
|
Users, Sharing, Color profiles, and Digital wellbeing handoffs open GNOME
|
||||||
Settings because Fedora's system services own those areas.
|
Settings because Fedora's system services own those areas.
|
||||||
|
|
||||||
## Adding a setting
|
## Adding a setting
|
||||||
@@ -64,7 +64,7 @@ file.
|
|||||||
Every preference has **one primary page**, derived from its schema `group` and
|
Every preference has **one primary page**, derived from its schema `group` and
|
||||||
the route in `services/SettingsSearch.qml`. Search results always open that
|
the route in `services/SettingsSearch.qml`. Search results always open that
|
||||||
owner. A control may appear on a second page only when the same adaptation is
|
owner. A control may appear on a second page only when the same adaptation is
|
||||||
part of another established mental model; otherwise use a labelled handoff to
|
part of another established mental model; otherwise use a labeled handoff to
|
||||||
the owner instead of duplicating it.
|
the owner instead of duplicating it.
|
||||||
|
|
||||||
### Intentional mirrors
|
### Intentional mirrors
|
||||||
@@ -72,7 +72,7 @@ the owner instead of duplicating it.
|
|||||||
| Setting | Primary page | Mirror | Why the mirror earns its place |
|
| Setting | Primary page | Mirror | Why the mirror earns its place |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `animationsEnabled` | Appearance | Accessibility | Reduced motion belongs both to visual polish and motion accessibility. |
|
| `animationsEnabled` | Appearance | Accessibility | Reduced motion belongs both to visual polish and motion accessibility. |
|
||||||
| `cursorInactiveTimeout` | Mouse | Accessibility | Pointer visibility is configured with pointer behaviour but affects motor and visual access. |
|
| `cursorInactiveTimeout` | Mouse | Accessibility | Pointer visibility is configured with pointer behavior but affects motor and visual access. |
|
||||||
| `cursorSize` | Accessibility | Mouse | Large cursors are an accessibility adaptation that users also look for beside pointer controls. |
|
| `cursorSize` | Accessibility | Mouse | Large cursors are an accessibility adaptation that users also look for beside pointer controls. |
|
||||||
| `inactiveOpacity` | Appearance | Accessibility | Window translucency is an appearance choice with a direct readability impact. |
|
| `inactiveOpacity` | Appearance | Accessibility | Window translucency is an appearance choice with a direct readability impact. |
|
||||||
| `lockMinutes` | Power | Privacy | Idle timing owns the mechanism; privacy owns the expectation that the unattended desktop locks. |
|
| `lockMinutes` | Power | Privacy | Idle timing owns the mechanism; privacy owns the expectation that the unattended desktop locks. |
|
||||||
@@ -93,7 +93,7 @@ Mirrors must remain the same schema-backed control, never a second preference
|
|||||||
or a copied default. Additions to this table require a concrete discoverability
|
or a copied default. Additions to this table require a concrete discoverability
|
||||||
reason and an update to `tests/quickshell/settings-ownership-contract.sh`.
|
reason and an update to `tests/quickshell/settings-ownership-contract.sh`.
|
||||||
|
|
||||||
Window border colour follows the same ownership rule. The inactive border is a
|
Window border color follows the same ownership rule. The inactive border is a
|
||||||
**scheme-relative role** owned by `ColorScheme.qml`: it changes only to retain
|
**scheme-relative role** owned by `ColorScheme.qml`: it changes only to retain
|
||||||
neutral contrast in light and dark modes. The focused Prism border is the
|
neutral contrast in light and dark modes. The focused Prism border is the
|
||||||
**accent role**, driven by the chosen `accentName` and also owned by
|
**accent role**, driven by the chosen `accentName` and also owned by
|
||||||
@@ -165,7 +165,7 @@ file with `qs -p`, and discover its PID from the exact Config path in
|
|||||||
| File | Holds |
|
| File | Holds |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `~/.config/panama/settings.json` | Everything in the schema. Read by the shell *and* by `hypr/prefs.lua` |
|
| `~/.config/panama/settings.json` | Everything in the schema. Read by the shell *and* by `hypr/prefs.lua` |
|
||||||
| `$XDG_STATE_HOME/panama/panama-home.json` | Home accessory favourites and aliases |
|
| `$XDG_STATE_HOME/panama/panama-home.json` | Home accessory favorites and aliases |
|
||||||
| `$XDG_STATE_HOME/panama/backups/` | Settings snapshots |
|
| `$XDG_STATE_HOME/panama/backups/` | Settings snapshots |
|
||||||
| `$XDG_STATE_HOME/panama/hypridle.conf` | Generated idle config |
|
| `$XDG_STATE_HOME/panama/hypridle.conf` | Generated idle config |
|
||||||
| `$XDG_STATE_HOME/panama/hyprlock.conf` | Generated lock-screen appearance |
|
| `$XDG_STATE_HOME/panama/hyprlock.conf` | Generated lock-screen appearance |
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ FocusScope {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
signal captured(string chord)
|
signal captured(string chord)
|
||||||
signal cancelled
|
signal canceled
|
||||||
|
|
||||||
property string message: ""
|
property string message: ""
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ FocusScope {
|
|||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
|
|
||||||
if (event.key === 0x01000000) { // Escape
|
if (event.key === 0x01000000) { // Escape
|
||||||
root.cancelled();
|
root.canceled();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (root.isModifierOnly(event.key))
|
if (root.isModifierOnly(event.key))
|
||||||
@@ -127,6 +127,6 @@ FocusScope {
|
|||||||
|
|
||||||
onActiveFocusChanged: {
|
onActiveFocusChanged: {
|
||||||
if (!activeFocus)
|
if (!activeFocus)
|
||||||
root.cancelled();
|
root.canceled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
// description in hypr/keybinds.lua, and this page just groups and renders them.
|
// description in hypr/keybinds.lua, and this page just groups and renders them.
|
||||||
//
|
//
|
||||||
// The hardware settings above the list are real controls. Keyboard layout,
|
// The hardware settings above the list are real controls. Keyboard layout,
|
||||||
// repeat behaviour, and pointer response are Hyprland's, so Panama owns them;
|
// repeat behavior, and pointer response are Hyprland's, so Panama owns them;
|
||||||
// device-specific configuration stays with GNOME.
|
// device-specific configuration stays with GNOME.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
@@ -174,7 +174,7 @@ SettingsPage {
|
|||||||
Keybinds.rebind(bindRow.modelData.luaChord, chord);
|
Keybinds.rebind(bindRow.modelData.luaChord, chord);
|
||||||
root.capturingChord = "";
|
root.capturingChord = "";
|
||||||
}
|
}
|
||||||
onCancelled: root.capturingChord = ""
|
onCanceled: root.capturingChord = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
//
|
//
|
||||||
// Range, step, label, explanation, and unit all come from PreferenceSchema.
|
// Range, step, label, explanation, and unit all come from PreferenceSchema.
|
||||||
//
|
//
|
||||||
// Three behaviours worth knowing:
|
// Three behaviors worth knowing:
|
||||||
//
|
//
|
||||||
// * The row is responsive. The Settings window is a normal tiled window, so
|
// * The row is responsive. The Settings window is a normal tiled window, so
|
||||||
// its width is whatever the layout gives it -- anywhere from a half-screen
|
// its width is whatever the layout gives it -- anywhere from a half-screen
|
||||||
@@ -63,7 +63,7 @@ Item {
|
|||||||
|
|
||||||
// A fixed trailing width rather than a share of the row. A proportional
|
// A fixed trailing width rather than a share of the row. A proportional
|
||||||
// control looks reasonable at 900px and absurd at 4500px, where the slider
|
// control looks reasonable at 900px and absurd at 4500px, where the slider
|
||||||
// would be a metre long next to a two-word label -- and this window is
|
// would be a meter long next to a two-word label -- and this window is
|
||||||
// tiled, so it really can be that wide.
|
// tiled, so it really can be that wide.
|
||||||
readonly property int controlSpan: 300
|
readonly property int controlSpan: 300
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// setting it edits.
|
// setting it edits.
|
||||||
//
|
//
|
||||||
// Rejected input is shown as rejected rather than silently dropped or quietly
|
// Rejected input is shown as rejected rather than silently dropped or quietly
|
||||||
// sanitised. Several of these strings are serialised into an hl.config payload,
|
// sanitised. Several of these strings are serialized into an hl.config payload,
|
||||||
// where stripping an unexpected character would turn a typo into a different
|
// where stripping an unexpected character would turn a typo into a different
|
||||||
// working setting -- so the schema's pattern decides, the field turns red when
|
// working setting -- so the schema's pattern decides, the field turns red when
|
||||||
// it fails, and nothing is committed until it passes.
|
// it fails, and nothing is committed until it passes.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// clock. This is the same control with the readout formatted as a time, so the
|
// clock. This is the same control with the readout formatted as a time, so the
|
||||||
// night light schedule says "5:30 PM" rather than a number you have to convert.
|
// night light schedule says "5:30 PM" rather than a number you have to convert.
|
||||||
//
|
//
|
||||||
// Honours the 24-hour clock preference, because a user who has asked for 18:30
|
// Honors the 24-hour clock preference, because a user who has asked for 18:30
|
||||||
// everywhere else should not be shown 6:30 PM here.
|
// everywhere else should not be shown 6:30 PM here.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ def valid_home(value: Any) -> bool:
|
|||||||
|
|
||||||
def validate_home(value: Any, label: str) -> dict[str, Any]:
|
def validate_home(value: Any, label: str) -> dict[str, Any]:
|
||||||
if not valid_home(value):
|
if not valid_home(value):
|
||||||
fail(f"{label} does not contain valid Home favourites.")
|
fail(f"{label} does not contain valid Home favorites.")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Propagates the colour scheme to applications that do not read the desktop
|
# Propagates the color scheme to applications that do not read the desktop
|
||||||
# portal.
|
# portal.
|
||||||
#
|
#
|
||||||
# Most modern applications DO follow org.freedesktop.portal.Settings and need
|
# Most modern applications DO follow org.freedesktop.portal.Settings and need
|
||||||
@@ -47,7 +47,7 @@ esac
|
|||||||
|
|
||||||
# Same 8 named accents as config/Theme.qml's `accents` map (kept in sync by
|
# Same 8 named accents as config/Theme.qml's `accents` map (kept in sync by
|
||||||
# hand -- there is no shared source between QML and a shell script), primary
|
# hand -- there is no shared source between QML and a shell script), primary
|
||||||
# hue per scheme only: both consumers below draw a flat colour, not the
|
# hue per scheme only: both consumers below draw a flat color, not the
|
||||||
# two-stop gradient the window border does.
|
# two-stop gradient the window border does.
|
||||||
accent_hex() {
|
accent_hex() {
|
||||||
local name="$1" scheme="$2"
|
local name="$1" scheme="$2"
|
||||||
@@ -108,7 +108,7 @@ status_hyprlock="skipped"
|
|||||||
if [[ -r "$lock_template" ]]; then
|
if [[ -r "$lock_template" ]]; then
|
||||||
# Written atomically: a lock triggered mid-write would otherwise read a
|
# Written atomically: a lock triggered mid-write would otherwise read a
|
||||||
# truncated config and fall back to hyprlock's own defaults, which is a
|
# truncated config and fall back to hyprlock's own defaults, which is a
|
||||||
# bright grey screen with none of this desktop's identity.
|
# bright gray screen with none of this desktop's identity.
|
||||||
if sed -e "s/@FG@/$lock_fg/g" \
|
if sed -e "s/@FG@/$lock_fg/g" \
|
||||||
-e "s/@MUTED@/$lock_muted/g" \
|
-e "s/@MUTED@/$lock_muted/g" \
|
||||||
-e "s/@ACCENT@/$lock_accent/g" \
|
-e "s/@ACCENT@/$lock_accent/g" \
|
||||||
@@ -159,7 +159,7 @@ fi
|
|||||||
# it on the next write.
|
# it on the next write.
|
||||||
#
|
#
|
||||||
# btop reads its theme once at startup, so a running instance keeps the old
|
# btop reads its theme once at startup, so a running instance keeps the old
|
||||||
# colours until it is restarted. That is acceptable for a monitor you open when
|
# colors until it is restarted. That is acceptable for a monitor you open when
|
||||||
# you want it, and forcing a restart would kill a process the user is watching.
|
# you want it, and forcing a restart would kill a process the user is watching.
|
||||||
btop_conf="${XDG_CONFIG_HOME:-$HOME/.config}/btop/btop.conf"
|
btop_conf="${XDG_CONFIG_HOME:-$HOME/.config}/btop/btop.conf"
|
||||||
btop_theme="tokyonight-moon"
|
btop_theme="tokyonight-moon"
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
root.entries = JSON.parse(text).map(row => root._normalise(row));
|
root.entries = JSON.parse(text).map(row => root._normalize(row));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Clipboard: could not parse history —", e);
|
console.warn("Clipboard: could not parse history —", e);
|
||||||
root.entries = [];
|
root.entries = [];
|
||||||
@@ -231,7 +231,7 @@ Singleton {
|
|||||||
|
|
||||||
// Turn a raw row into what the UI actually asks questions of, so no
|
// Turn a raw row into what the UI actually asks questions of, so no
|
||||||
// delegate has to know about column names or Vicinae's integer kinds.
|
// delegate has to know about column names or Vicinae's integer kinds.
|
||||||
function _normalise(row: var): var {
|
function _normalize(row: var): var {
|
||||||
const encrypted = row.enc !== 0;
|
const encrypted = row.enc !== 0;
|
||||||
const textual = row.kind === root.kindText || row.kind === root.kindLink;
|
const textual = row.kind === root.kindText || row.kind === root.kindLink;
|
||||||
const raw = row.preview || "";
|
const raw = row.preview || "";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pragma Singleton
|
|||||||
// because every token there is a binding. Two other things draw on this desktop
|
// because every token there is a binding. Two other things draw on this desktop
|
||||||
// and do not read Panama's store:
|
// and do not read Panama's store:
|
||||||
//
|
//
|
||||||
// GTK applications read gsettings colour-scheme and gtk-theme
|
// GTK applications read gsettings color-scheme and gtk-theme
|
||||||
// the compositor draws window borders and shadows
|
// the compositor draws window borders and shadows
|
||||||
//
|
//
|
||||||
// A toolbar or a window border still wearing the other scheme is more jarring
|
// A toolbar or a window border still wearing the other scheme is more jarring
|
||||||
@@ -31,10 +31,10 @@ Singleton {
|
|||||||
readonly property string inactiveBorder: root.dark ? root.inactiveBorderDark : root.inactiveBorderLight
|
readonly property string inactiveBorder: root.dark ? root.inactiveBorderDark : root.inactiveBorderLight
|
||||||
|
|
||||||
// The focused border follows the chosen accent. `ee` is the shipped alpha
|
// The focused border follows the chosen accent. `ee` is the shipped alpha
|
||||||
// for the Prism gradient; Theme owns which colours, this owns the form the
|
// for the Prism gradient; Theme owns which colors, this owns the form the
|
||||||
// compositor wants them in.
|
// compositor wants them in.
|
||||||
function hyprColor(value: var): string {
|
function hyprColor(value: var): string {
|
||||||
// Qt gives "#rrggbb" -- or "#aarrggbb" if the colour ever carries an
|
// Qt gives "#rrggbb" -- or "#aarrggbb" if the color ever carries an
|
||||||
// alpha channel. slice(-6) keeps the trailing rrggbb either way;
|
// alpha channel. slice(-6) keeps the trailing rrggbb either way;
|
||||||
// slice(0, 6) would instead grab "aarrgg" out of an 8-digit string and
|
// slice(0, 6) would instead grab "aarrgg" out of an 8-digit string and
|
||||||
// call it RGB. Hyprland wants rgba(rrggbbaa).
|
// call it RGB. Hyprland wants rgba(rrggbbaa).
|
||||||
@@ -59,7 +59,7 @@ Singleton {
|
|||||||
id: runner
|
id: runner
|
||||||
onExited: (exitCode, exitStatus) => {
|
onExited: (exitCode, exitStatus) => {
|
||||||
if (exitCode !== 0)
|
if (exitCode !== 0)
|
||||||
root.lastError = "The colour scheme could not be applied everywhere.";
|
root.lastError = "The color scheme could not be applied everywhere.";
|
||||||
root.drain();
|
root.drain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,16 +153,16 @@ Singleton {
|
|||||||
// Each accent carries a separate pair for light and dark, so this
|
// Each accent carries a separate pair for light and dark, so this
|
||||||
// runs on either kind of change: a scheme flip restates the same
|
// runs on either kind of change: a scheme flip restates the same
|
||||||
// accent's other pair, and an accent change restates the same
|
// accent's other pair, and an accent change restates the same
|
||||||
// scheme's other colours.
|
// scheme's other colors.
|
||||||
//
|
//
|
||||||
// A two-stop gradient at the shipped angle. Written as a Lua TABLE:
|
// A two-stop gradient at the shipped angle. Written as a Lua TABLE:
|
||||||
// the string form of a gradient carries only one stop, and passing
|
// the string form of a gradient carries only one stop, and passing
|
||||||
// "rgba(a) rgba(b) 115deg" as a string is accepted and silently
|
// "rgba(a) rgba(b) 115deg" as a string is accepted and silently
|
||||||
// keeps the previous value. Multi-stop must be the table form --
|
// keeps the previous value. Multi-stop must be the table form --
|
||||||
// built by the same serialiseValue() SystemSettings uses for every
|
// built by the same serializeValue() SystemSettings uses for every
|
||||||
// other gradient, rather than a second hand-rolled copy of that
|
// other gradient, rather than a second hand-rolled copy of that
|
||||||
// escaping here.
|
// escaping here.
|
||||||
const activeBorder = SystemSettings.serialiseValue({
|
const activeBorder = SystemSettings.serializeValue({
|
||||||
colors: [root.accentBorderStart, root.accentBorderEnd],
|
colors: [root.accentBorderStart, root.accentBorderEnd],
|
||||||
angle: 115
|
angle: 115
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Singleton {
|
|||||||
|
|
||||||
property string timezone: ""
|
property string timezone: ""
|
||||||
property bool ntpEnabled: false
|
property bool ntpEnabled: false
|
||||||
property bool ntpSynchronised: false
|
property bool ntpSynchronized: false
|
||||||
property string localTime: ""
|
property string localTime: ""
|
||||||
property string universalTime: ""
|
property string universalTime: ""
|
||||||
property string rtcTime: ""
|
property string rtcTime: ""
|
||||||
@@ -79,7 +79,7 @@ Singleton {
|
|||||||
// status is re-read either way.
|
// status is re-read either way.
|
||||||
root.lastError = exitCode === 0
|
root.lastError = exitCode === 0
|
||||||
? ""
|
? ""
|
||||||
: "The system rejected that change, or authentication was cancelled.";
|
: "The system rejected that change, or authentication was canceled.";
|
||||||
root.refresh();
|
root.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ Singleton {
|
|||||||
else if (key === "NTP")
|
else if (key === "NTP")
|
||||||
root.ntpEnabled = value === "yes";
|
root.ntpEnabled = value === "yes";
|
||||||
else if (key === "NTPSynchronized")
|
else if (key === "NTPSynchronized")
|
||||||
root.ntpSynchronised = value === "yes";
|
root.ntpSynchronized = value === "yes";
|
||||||
}
|
}
|
||||||
root.lastError = "";
|
root.lastError = "";
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ Singleton {
|
|||||||
// caller-supplied text reaches the command.
|
// caller-supplied text reaches the command.
|
||||||
function setTimezone(zone: string): bool {
|
function setTimezone(zone: string): bool {
|
||||||
if (root.zones.indexOf(zone) < 0) {
|
if (root.zones.indexOf(zone) < 0) {
|
||||||
root.lastError = "That is not a timezone this system recognises.";
|
root.lastError = "That is not a timezone this system recognizes.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (writeRun.running)
|
if (writeRun.running)
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ Singleton {
|
|||||||
? persistedPrimaries[0].name
|
? persistedPrimaries[0].name
|
||||||
: (origin?.name ?? raw[0]?.name ?? "");
|
: (origin?.name ?? raw[0]?.name ?? "");
|
||||||
root.monitors = raw.map(monitor => {
|
root.monitors = raw.map(monitor => {
|
||||||
const modes = root.normaliseModes(monitor.availableModes ?? []);
|
const modes = root.normalizeModes(monitor.availableModes ?? []);
|
||||||
const width = monitor.width ?? 0;
|
const width = monitor.width ?? 0;
|
||||||
const height = monitor.height ?? 0;
|
const height = monitor.height ?? 0;
|
||||||
const refreshRate = monitor.refreshRate ?? 0;
|
const refreshRate = monitor.refreshRate ?? 0;
|
||||||
@@ -200,7 +200,7 @@ Singleton {
|
|||||||
// resolution at distinct rates such as 60.00 and 59.94. Those identities
|
// resolution at distinct rates such as 60.00 and 59.94. Those identities
|
||||||
// remain separate because confirmation and recovery must read back the
|
// remain separate because confirmation and recovery must read back the
|
||||||
// exact mode the user chose, even when their rounded labels look similar.
|
// exact mode the user chose, even when their rounded labels look similar.
|
||||||
function normaliseModes(raw: var): var {
|
function normalizeModes(raw: var): var {
|
||||||
const seen = {};
|
const seen = {};
|
||||||
const out = [];
|
const out = [];
|
||||||
for (const entry of raw) {
|
for (const entry of raw) {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stores a chosen place. Coordinates are rounded to four decimals -- roughly
|
// Stores a chosen place. Coordinates are rounded to four decimals -- roughly
|
||||||
// ten metres, far finer than a weather reading resolves, and it keeps a
|
// ten meters, far finer than a weather reading resolves, and it keeps a
|
||||||
// precise home location out of the settings file.
|
// precise home location out of the settings file.
|
||||||
function choose(place: var): bool {
|
function choose(place: var): bool {
|
||||||
const latitude = Math.round(place.latitude * 10000) / 10000;
|
const latitude = Math.round(place.latitude * 10000) / 10000;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "AMD ... [Radeon RX 7700 XT / 7800 XT] (rev c8)" is what lspci gives; the
|
// "AMD ... [Radeon RX 7700 XT / 7800 XT] (rev c8)" is what lspci gives; the
|
||||||
// bracketed marketing name is the part anyone recognises.
|
// bracketed marketing name is the part anyone recognizes.
|
||||||
function shortName(name: string): string {
|
function shortName(name: string): string {
|
||||||
const bracketed = String(name).match(/\[([^\]]+)\]\s*(?:\(rev[^)]*\))?\s*$/);
|
const bracketed = String(name).match(/\[([^\]]+)\]\s*(?:\(rev[^)]*\))?\s*$/);
|
||||||
return bracketed ? bracketed[1] : String(name).replace(/\s*\(rev[^)]*\)\s*$/, "");
|
return bracketed ? bracketed[1] : String(name).replace(/\s*\(rev[^)]*\)\s*$/, "");
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Singleton {
|
|||||||
readonly property bool scheduled: root.inWindow(clock.hours + clock.minutes / 60)
|
readonly property bool scheduled: root.inWindow(clock.hours + clock.minutes / 60)
|
||||||
|
|
||||||
// A manual toggle always wins: it drops out of the schedule rather than
|
// A manual toggle always wins: it drops out of the schedule rather than
|
||||||
// being silently reverted a minute later. Same as GNOME's behaviour when
|
// being silently reverted a minute later. Same as GNOME's behavior when
|
||||||
// you flip night light off during a scheduled evening.
|
// you flip night light off during a scheduled evening.
|
||||||
function toggle(): void {
|
function toggle(): void {
|
||||||
if (root.automatic) {
|
if (root.automatic) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pragma Singleton
|
|||||||
// the *live* objects rather than copies: that keeps actions and inline replies
|
// the *live* objects rather than copies: that keeps actions and inline replies
|
||||||
// working from the tray, which is what GNOME does. The cost is that a
|
// working from the tray, which is what GNOME does. The cost is that a
|
||||||
// notification an app closes itself (progress bars, "download finished"
|
// notification an app closes itself (progress bars, "download finished"
|
||||||
// replacing "downloading") disappears from history too — correct behaviour,
|
// replacing "downloading") disappears from history too — correct behavior,
|
||||||
// but the reason history is not append-only.
|
// but the reason history is not append-only.
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ Singleton {
|
|||||||
// Suppresses toasts entirely. Notifications still reach history.
|
// Suppresses toasts entirely. Notifications still reach history.
|
||||||
property bool doNotDisturb: false
|
property bool doNotDisturb: false
|
||||||
|
|
||||||
// Cleared when the notification centre is opened. The bar binds to this.
|
// Cleared when the notification center is opened. The bar binds to this.
|
||||||
property int unreadCount: 0
|
property int unreadCount: 0
|
||||||
|
|
||||||
// Kept separate from the persisted map so this version can safely run
|
// Kept separate from the persisted map so this version can safely run
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ Singleton {
|
|||||||
|
|
||||||
// Non-empty when the machine cannot actually deliver the profile it is set
|
// Non-empty when the machine cannot actually deliver the profile it is set
|
||||||
// to -- thermal throttling, or a laptop running on battery. Worth showing,
|
// to -- thermal throttling, or a laptop running on battery. Worth showing,
|
||||||
// because otherwise "performance" is a claim the hardware is not honouring.
|
// because otherwise "performance" is a claim the hardware is not honoring.
|
||||||
property string degraded: ""
|
property string degraded: ""
|
||||||
|
|
||||||
readonly property bool available: root.profiles.length > 0
|
readonly property bool available: root.profiles.length > 0
|
||||||
@@ -52,7 +52,7 @@ Singleton {
|
|||||||
function detail(profile: string): string {
|
function detail(profile: string): string {
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
case "power-saver": return "Reduces performance to save energy and run quieter";
|
case "power-saver": return "Reduces performance to save energy and run quieter";
|
||||||
case "balanced": return "Standard behaviour, scaling up only when needed";
|
case "balanced": return "Standard behavior, scaling up only when needed";
|
||||||
case "performance": return "Holds higher clocks, using more power and making more noise";
|
case "performance": return "Holds higher clocks, using more power and making more noise";
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ Singleton {
|
|||||||
if (restoreAccepted)
|
if (restoreAccepted)
|
||||||
root.lastError = "";
|
root.lastError = "";
|
||||||
else if (root.lastError === "")
|
else if (root.lastError === "")
|
||||||
root.lastError = "Desktop settings were restored, but Home favourites could not be reloaded.";
|
root.lastError = "Desktop settings were restored, but Home favorites could not be reloaded.";
|
||||||
if (!restoreAccepted) {
|
if (!restoreAccepted) {
|
||||||
root.setDisplayBlocked(false);
|
root.setDisplayBlocked(false);
|
||||||
root.protectedDisplays = ({});
|
root.protectedDisplays = ({});
|
||||||
@@ -192,10 +192,10 @@ Singleton {
|
|||||||
if (actionRun.running)
|
if (actionRun.running)
|
||||||
return;
|
return;
|
||||||
actionRun.restoring = false;
|
actionRun.restoring = false;
|
||||||
actionRun.exec([root.helperPath, "save", root.serialiseHomeState()]);
|
actionRun.exec([root.helperPath, "save", root.serializeHomeState()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialiseHomeState(): string {
|
function serializeHomeState(): string {
|
||||||
const current = root.readHomeState();
|
const current = root.readHomeState();
|
||||||
const favorites = [];
|
const favorites = [];
|
||||||
for (const favorite of current.favorites ?? []) {
|
for (const favorite of current.favorites ?? []) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Singleton {
|
|||||||
// on a settings app that plainly has one.
|
// on a settings app that plainly has one.
|
||||||
readonly property var extraEntries: [
|
readonly property var extraEntries: [
|
||||||
{ label: "Timezone", detail: "Set the system timezone", page: "datetime" },
|
{ label: "Timezone", detail: "Set the system timezone", page: "datetime" },
|
||||||
{ label: "Network time", detail: "Synchronise the clock with a time server", page: "datetime" },
|
{ label: "Network time", detail: "Synchronize the clock with a time server", page: "datetime" },
|
||||||
{ label: "Wi-Fi", detail: "Managed by GNOME Settings", page: "connectivity" },
|
{ label: "Wi-Fi", detail: "Managed by GNOME Settings", page: "connectivity" },
|
||||||
{ label: "Bluetooth", detail: "Managed by GNOME Settings", page: "connectivity" },
|
{ label: "Bluetooth", detail: "Managed by GNOME Settings", page: "connectivity" },
|
||||||
{ label: "Printers", detail: "Managed by GNOME Settings", page: "connectivity" },
|
{ label: "Printers", detail: "Managed by GNOME Settings", page: "connectivity" },
|
||||||
@@ -68,7 +68,7 @@ Singleton {
|
|||||||
{ label: "Keyboard shortcuts", detail: "Every shortcut the compositor has bound", page: "shortcuts" },
|
{ label: "Keyboard shortcuts", detail: "Every shortcut the compositor has bound", page: "shortcuts" },
|
||||||
{ label: "System Health", detail: "Check Panama services, integrations, tools, and recovery actions", page: "services" },
|
{ label: "System Health", detail: "Check Panama services, integrations, tools, and recovery actions", page: "services" },
|
||||||
{ label: "Copy health report", detail: "Copy a redacted Panama doctor report", page: "services" },
|
{ label: "Copy health report", detail: "Copy a redacted Panama doctor report", page: "services" },
|
||||||
{ label: "Lock screen background", detail: "Choose a blurred desktop, wallpaper, or solid colour", page: "appearance" },
|
{ label: "Lock screen background", detail: "Choose a blurred desktop, wallpaper, or solid color", page: "appearance" },
|
||||||
{ label: "Password field", detail: "Choose whether the empty lock-screen field stays visible", page: "appearance" },
|
{ label: "Password field", detail: "Choose whether the empty lock-screen field stays visible", page: "appearance" },
|
||||||
{ label: "Per-display wallpaper", detail: "Assign a different image to each connected display", page: "appearance" },
|
{ label: "Per-display wallpaper", detail: "Assign a different image to each connected display", page: "appearance" },
|
||||||
{ label: "Arrange displays", detail: "Drag connected displays into their physical positions", page: "displays" },
|
{ label: "Arrange displays", detail: "Drag connected displays into their physical positions", page: "displays" },
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
// GNOME and GTK applications already honour these desktop sound preferences.
|
// GNOME and GTK applications already honor these desktop sound preferences.
|
||||||
// Panama controls the same durable keys so moving between sessions does not
|
// Panama controls the same durable keys so moving between sessions does not
|
||||||
// create two competing notions of whether event feedback is enabled.
|
// create two competing notions of whether event feedback is enabled.
|
||||||
|
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ Singleton {
|
|||||||
function hyprValue(entry: var, value: var): var {
|
function hyprValue(entry: var, value: var): var {
|
||||||
// Some options are phrased as a negative by the compositor -- the four
|
// Some options are phrased as a negative by the compositor -- the four
|
||||||
// Hyprland notices are all `disable_x` -- while the setting reads as
|
// Hyprland notices are all `disable_x` -- while the setting reads as
|
||||||
// "show x", because a switch labelled "Disable splash text" that must
|
// "show x", because a switch labeled "Disable splash text" that must
|
||||||
// be ON to hide something is a small cruelty. `invert` bridges the two,
|
// be ON to hide something is a small cruelty. `invert` bridges the two,
|
||||||
// in exactly one place, so nothing downstream has to remember which
|
// in exactly one place, so nothing downstream has to remember which
|
||||||
// options are backwards.
|
// options are backwards.
|
||||||
@@ -289,7 +289,7 @@ Singleton {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialises validated values into a nested hl.config{} call. Table paths
|
// Serializes validated values into a nested hl.config{} call. Table paths
|
||||||
// come from the schema and values have already passed coerce(), including
|
// come from the schema and values have already passed coerce(), including
|
||||||
// the pattern check on constrained strings, so nothing caller-supplied
|
// the pattern check on constrained strings, so nothing caller-supplied
|
||||||
// reaches the payload unchecked.
|
// reaches the payload unchecked.
|
||||||
@@ -301,12 +301,12 @@ Singleton {
|
|||||||
let node = tree;
|
let node = tree;
|
||||||
for (let i = 0; i < path.length - 1; i++)
|
for (let i = 0; i < path.length - 1; i++)
|
||||||
node = node[path[i]] = node[path[i]] ?? {};
|
node = node[path[i]] = node[path[i]] ?? {};
|
||||||
node[path[path.length - 1]] = root.serialiseValue(root.hyprValue(entry, requested[key]));
|
node[path[path.length - 1]] = root.serializeValue(root.hyprValue(entry, requested[key]));
|
||||||
}
|
}
|
||||||
return `hl.config(${root.serialiseTable(tree)})`;
|
return `hl.config(${root.serializeTable(tree)})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialiseValue(value: var): string {
|
function serializeValue(value: var): string {
|
||||||
if (typeof value === "boolean")
|
if (typeof value === "boolean")
|
||||||
return value ? "true" : "false";
|
return value ? "true" : "false";
|
||||||
if (typeof value === "number")
|
if (typeof value === "number")
|
||||||
@@ -330,22 +330,22 @@ Singleton {
|
|||||||
if (Array.isArray(value) && value.length === 2)
|
if (Array.isArray(value) && value.length === 2)
|
||||||
return `{ ${Number(value[0])}, ${Number(value[1])} }`;
|
return `{ ${Number(value[0])}, ${Number(value[1])} }`;
|
||||||
// Strings only reach here after the schema's pattern check; quoting is
|
// Strings only reach here after the schema's pattern check; quoting is
|
||||||
// belt-and-braces rather than the primary defence.
|
// belt-and-braces rather than the primary defense.
|
||||||
return `"${String(value).replace(/["\\]/g, "")}"`;
|
return `"${String(value).replace(/["\\]/g, "")}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialiseTable(node: var): string {
|
function serializeTable(node: var): string {
|
||||||
const parts = [];
|
const parts = [];
|
||||||
for (const name in node) {
|
for (const name in node) {
|
||||||
const child = node[name];
|
const child = node[name];
|
||||||
// A leaf arrives pre-serialised as a string; anything else is
|
// A leaf arrives pre-serialized as a string; anything else is
|
||||||
// either a nested section or a structured value (gradient, vec2)
|
// either a nested section or a structured value (gradient, vec2)
|
||||||
// that serialiseValue knows how to render.
|
// that serializeValue knows how to render.
|
||||||
const rendered = typeof child === "string"
|
const rendered = typeof child === "string"
|
||||||
? child
|
? child
|
||||||
: (Array.isArray(child) || (child && child.colors !== undefined)
|
: (Array.isArray(child) || (child && child.colors !== undefined)
|
||||||
? root.serialiseValue(child)
|
? root.serializeValue(child)
|
||||||
: root.serialiseTable(child));
|
: root.serializeTable(child));
|
||||||
parts.push(`${name} = ${rendered}`);
|
parts.push(`${name} = ${rendered}`);
|
||||||
}
|
}
|
||||||
return `{ ${parts.join(", ")} }`;
|
return `{ ${parts.join(", ")} }`;
|
||||||
@@ -403,11 +403,11 @@ Singleton {
|
|||||||
function gradientMatches(expected: var, observed: string): bool {
|
function gradientMatches(expected: var, observed: string): bool {
|
||||||
if (typeof observed !== "string")
|
if (typeof observed !== "string")
|
||||||
return false;
|
return false;
|
||||||
return root.normaliseGradient(expected) === root.normaliseGradient(observed);
|
return root.normalizeGradient(expected) === root.normalizeGradient(observed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both notations reduced to "aarrggbb aarrggbb Ndeg".
|
// Both notations reduced to "aarrggbb aarrggbb Ndeg".
|
||||||
function normaliseGradient(value: var): string {
|
function normalizeGradient(value: var): string {
|
||||||
const stops = [];
|
const stops = [];
|
||||||
let angle = 0;
|
let angle = 0;
|
||||||
|
|
||||||
@@ -518,8 +518,8 @@ Singleton {
|
|||||||
// Panama's shipped DP-2 placement and automatic placement elsewhere.
|
// Panama's shipped DP-2 placement and automatic placement elsewhere.
|
||||||
|
|
||||||
// Home accessories keep their own store (panama-home.json), so a reset
|
// Home accessories keep their own store (panama-home.json), so a reset
|
||||||
// that only cleared the schema store would silently leave a customised
|
// that only cleared the schema store would silently leave a customized
|
||||||
// favourites list behind while claiming to restore Panama's defaults.
|
// favorites list behind while claiming to restore Panama's defaults.
|
||||||
//
|
//
|
||||||
// HomePreferences owns the write-through boundary so the state file is
|
// HomePreferences owns the write-through boundary so the state file is
|
||||||
// rewritten before this reset can be considered complete.
|
// rewritten before this reset can be considered complete.
|
||||||
@@ -593,7 +593,7 @@ Singleton {
|
|||||||
|
|
||||||
// `subpage` reaches the panels GNOME 50 nests under System -- users,
|
// `subpage` reaches the panels GNOME 50 nests under System -- users,
|
||||||
// about, datetime, region -- which its own desktop entries open as
|
// about, datetime, region -- which its own desktop entries open as
|
||||||
// `gnome-control-center system users`. Without it, a row labelled "Users"
|
// `gnome-control-center system users`. Without it, a row labeled "Users"
|
||||||
// lands on System's front page and leaves the user to navigate, which is
|
// lands on System's front page and leaves the user to navigate, which is
|
||||||
// most of the way to a broken button.
|
// most of the way to a broken button.
|
||||||
function openGnomePanel(panel: string, subpage: string): bool {
|
function openGnomePanel(panel: string, subpage: string): bool {
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ Singleton {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalisePolicy(policy: var): var {
|
function normalizePolicy(policy: var): var {
|
||||||
if (!policy || typeof policy !== "object")
|
if (!policy || typeof policy !== "object")
|
||||||
return null;
|
return null;
|
||||||
const mode = ["single", "slideshow", "per-monitor"].includes(policy.mode)
|
const mode = ["single", "slideshow", "per-monitor"].includes(policy.mode)
|
||||||
@@ -220,8 +220,8 @@ Singleton {
|
|||||||
function applyPolicy(policy: var, persist: bool, automatic: bool): bool {
|
function applyPolicy(policy: var, persist: bool, automatic: bool): bool {
|
||||||
if (root.busy)
|
if (root.busy)
|
||||||
return false;
|
return false;
|
||||||
const normalised = root.normalisePolicy(policy);
|
const normalized = root.normalizePolicy(policy);
|
||||||
if (normalised === null) {
|
if (normalized === null) {
|
||||||
root.lastError = "That wallpaper policy is not valid.";
|
root.lastError = "That wallpaper policy is not valid.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -231,8 +231,8 @@ Singleton {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const expected = WallpaperPolicy.effectiveMap(
|
const expected = WallpaperPolicy.effectiveMap(
|
||||||
normalised.mode, normalised.globalPath, normalised.slideshowPath,
|
normalized.mode, normalized.globalPath, normalized.slideshowPath,
|
||||||
normalised.assignments, outputs, normalised.candidates);
|
normalized.assignments, outputs, normalized.candidates);
|
||||||
if (Object.keys(expected).length !== outputs.length
|
if (Object.keys(expected).length !== outputs.length
|
||||||
|| Object.values(expected).some(path => path === "")) {
|
|| Object.values(expected).some(path => path === "")) {
|
||||||
root.lastError = "That wallpaper policy is not valid.";
|
root.lastError = "That wallpaper policy is not valid.";
|
||||||
@@ -242,7 +242,7 @@ Singleton {
|
|||||||
root.transaction = {
|
root.transaction = {
|
||||||
expected,
|
expected,
|
||||||
remaining: outputs.slice(),
|
remaining: outputs.slice(),
|
||||||
policy: normalised,
|
policy: normalized,
|
||||||
persist: persist === true,
|
persist: persist === true,
|
||||||
automatic: automatic === true
|
automatic: automatic === true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Rectangle {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Horizontal inset, normally the parent's corner radius. Below that the
|
// Horizontal inset, normally the parent's corner radius. Below that the
|
||||||
// line runs out onto the curve and looks like a rendering artefact.
|
// line runs out onto the curve and looks like a rendering artifact.
|
||||||
property real inset: Theme.popoverRadius
|
property real inset: Theme.popoverRadius
|
||||||
|
|
||||||
anchors.leftMargin: root.inset
|
anchors.leftMargin: root.inset
|
||||||
@@ -33,7 +33,7 @@ Rectangle {
|
|||||||
implicitHeight: 1
|
implicitHeight: 1
|
||||||
height: 1
|
height: 1
|
||||||
|
|
||||||
// The colour stops are the only place the two accents touch.
|
// The color stops are the only place the two accents touch.
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
orientation: Gradient.Horizontal
|
orientation: Gradient.Horizontal
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// A freedesktop symbolic icon, recoloured to a Theme token.
|
// A freedesktop symbolic icon, recolored to a Theme token.
|
||||||
//
|
//
|
||||||
// Adwaita's symbolic SVGs carry a hardcoded near-black fill (#2e3436) and Qt
|
// Adwaita's symbolic SVGs carry a hardcoded near-black fill (#2e3436) and Qt
|
||||||
// does not do GTK's runtime recolouring, so drawn as-is they are invisible on
|
// does not do GTK's runtime recoloring, so drawn as-is they are invisible on
|
||||||
// a Tokyo Night background — verified on this machine. The fix is to paint a
|
// a Tokyo Night background — verified on this machine. The fix is to paint a
|
||||||
// themed rectangle through the icon's alpha channel.
|
// themed rectangle through the icon's alpha channel.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// A GNOME-style quick-settings tile: big rounded button with an icon and a
|
// A GNOME-style quick-settings tile: big rounded button with an icon and a
|
||||||
// label, filled with the accent colour when active.
|
// label, filled with the accent color when active.
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
@@ -52,7 +52,7 @@ Rectangle {
|
|||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
// ThemedIcon, not a bare IconImage: Adwaita's symbolic SVGs carry a
|
// ThemedIcon, not a bare IconImage: Adwaita's symbolic SVGs carry a
|
||||||
// hardcoded #2e3436 fill and Qt does not recolour them the way GTK
|
// hardcoded #2e3436 fill and Qt does not recolor them the way GTK
|
||||||
// does, so drawn directly they are all but invisible on this palette.
|
// does, so drawn directly they are all but invisible on this palette.
|
||||||
ThemedIcon {
|
ThemedIcon {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Item {
|
|||||||
opacity: enabled ? 1.0 : 0.45
|
opacity: enabled ? 1.0 : 0.45
|
||||||
|
|
||||||
// ThemedIcon, not a bare IconImage — see the note in Toggle.qml: Adwaita
|
// ThemedIcon, not a bare IconImage — see the note in Toggle.qml: Adwaita
|
||||||
// symbolic icons have a hardcoded near-black fill that Qt will not recolour.
|
// symbolic icons have a hardcoded near-black fill that Qt will not recolor.
|
||||||
ThemedIcon {
|
ThemedIcon {
|
||||||
id: leadingIcon
|
id: leadingIcon
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -57,7 +57,7 @@ Item {
|
|||||||
border.width: 0
|
border.width: 0
|
||||||
|
|
||||||
// The gradient is anchored to the full track, not to the fill, so
|
// The gradient is anchored to the full track, not to the fill, so
|
||||||
// the colour at a given position never moves as the value changes —
|
// the color at a given position never moves as the value changes —
|
||||||
// dragging reveals the prism rather than squashing it.
|
// dragging reveals the prism rather than squashing it.
|
||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
orientation: Gradient.Horizontal
|
orientation: Gradient.Horizontal
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# Same structure, same roles, Day's palette. Mapped role for role rather than by
|
# Same structure, same roles, Day's palette. Mapped role for role rather than by
|
||||||
# hue: #1b1d2b was text drawn ON an accent block, so it becomes the LIGHT ground
|
# hue: #1b1d2b was text drawn ON an accent block, so it becomes the LIGHT ground
|
||||||
# rather than a dark colour, or the status bar would be dark text on a dark
|
# rather than a dark color, or the status bar would be dark text on a dark
|
||||||
# accent in light mode.
|
# accent in light mode.
|
||||||
#
|
#
|
||||||
# The accents are Day's DARKER variants, not its standard ones. Measured against
|
# The accents are Day's DARKER variants, not its standard ones. Measured against
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# Extracted from tmux.conf so the two schemes can be swapped. tmux.conf sources
|
# Extracted from tmux.conf so the two schemes can be swapped. tmux.conf sources
|
||||||
# current-theme.conf, which panama-theme-apps generates from one of these.
|
# current-theme.conf, which panama-theme-apps generates from one of these.
|
||||||
#
|
#
|
||||||
# Every colour here was already in tmux.conf; this file is that block verbatim.
|
# Every color here was already in tmux.conf; this file is that block verbatim.
|
||||||
|
|
||||||
set -g mode-style "fg=#82aaff,bg=#3b4261"
|
set -g mode-style "fg=#82aaff,bg=#3b4261"
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ bind C-Space send-prefix
|
|||||||
# Set status bar
|
# Set status bar
|
||||||
#set -g status-bg pink
|
#set -g status-bg pink
|
||||||
# Tokyo Night Moon color palette
|
# Tokyo Night Moon color palette
|
||||||
# Colours live in themes/ and are generated into current-theme.conf by
|
# Colors live in themes/ and are generated into current-theme.conf by
|
||||||
# panama-theme-apps, which regenerates it whenever the desktop colour scheme
|
# panama-theme-apps, which regenerates it whenever the desktop color scheme
|
||||||
# changes. -q so a fresh checkout without the generated file still starts.
|
# changes. -q so a fresh checkout without the generated file still starts.
|
||||||
source-file -q "~/.config/tmux/current-theme.conf"
|
source-file -q "~/.config/tmux/current-theme.conf"
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Tokyo Night Day — the light counterpart to tokyonight-moon.toml.
|
# Tokyo Night Day — the light counterpart to tokyonight-moon.toml.
|
||||||
#
|
#
|
||||||
# Same schema and the same role for every colour; only the palette differs, so
|
# Same schema and the same role for every color; only the palette differs, so
|
||||||
# the launcher keeps its identity when the desktop switches to light rather
|
# the launcher keeps its identity when the desktop switches to light rather
|
||||||
# than becoming a different-looking application.
|
# than becoming a different-looking application.
|
||||||
#
|
#
|
||||||
# Colours are the Tokyo Night Day palette, taken from kitty/themes/tokyonight-day.conf
|
# Colors are the Tokyo Night Day palette, taken from kitty/themes/tokyonight-day.conf
|
||||||
# so the launcher and the terminal cannot drift apart.
|
# so the launcher and the terminal cannot drift apart.
|
||||||
|
|
||||||
[meta]
|
[meta]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<!--
|
<!--
|
||||||
Panama Settings.
|
Panama Settings.
|
||||||
|
|
||||||
A gear, because a settings icon has to be recognisable at 48px in a dock
|
A gear, because a settings icon has to be recognizable at 48px in a dock
|
||||||
before it is anything else - but rendered in the Prism identity rather than
|
before it is anything else - but rendered in the Prism identity rather than
|
||||||
the flat monochrome symbolic icon this replaces. Blue leads into orchid, the
|
the flat monochrome symbolic icon this replaces. Blue leads into orchid, the
|
||||||
same pair that marks the focused window, the active workspace, and the
|
same pair that marks the focused window, the active workspace, and the
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
@@ -2,14 +2,14 @@
|
|||||||
<!--
|
<!--
|
||||||
Panama Settings.
|
Panama Settings.
|
||||||
|
|
||||||
A gear, because a settings icon has to be recognisable at 48px in a dock
|
A gear, because a settings icon has to be recognizable at 48px in a dock
|
||||||
before it is clever — but rendered in the Prism identity rather than the flat
|
before it is clever — but rendered in the Prism identity rather than the flat
|
||||||
monochrome of the symbolic icon this replaces. Blue leads into orchid across
|
monochrome of the symbolic icon this replaces. Blue leads into orchid across
|
||||||
the gradient, the same pair that marks the focused window, the active
|
the gradient, the same pair that marks the focused window, the active
|
||||||
workspace and the hairline on every glass surface.
|
workspace and the hairline on every glass surface.
|
||||||
|
|
||||||
Drawn on the dark tile (#222436) so it reads as an application icon among
|
Drawn on the dark tile (#222436) so it reads as an application icon among
|
||||||
full-colour ones, rather than as a UI glyph that wandered out of a toolbar.
|
full-color ones, rather than as a UI glyph that wandered out of a toolbar.
|
||||||
-->
|
-->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128" height="128">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" width="128" height="128">
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -90,7 +90,7 @@
|
|||||||
- Produces: `ShellState.openOverview(workspaceId)`, filmstrip selection, large workspace preview, cross-workspace window search
|
- Produces: `ShellState.openOverview(workspaceId)`, filmstrip selection, large workspace preview, cross-workspace window search
|
||||||
|
|
||||||
- [x] Add requested-overview-workspace state without coupling `ShellState` to the focus service.
|
- [x] Add requested-overview-workspace state without coupling `ShellState` to the focus service.
|
||||||
- [x] Replace the centred equal-card row with a top filmstrip and a large selected-workspace preview.
|
- [x] Replace the centered equal-card row with a top filmstrip and a large selected-workspace preview.
|
||||||
- [x] Keep the trailing dynamic-workspace card and one-shot thumbnail capture behavior.
|
- [x] Keep the trailing dynamic-workspace card and one-shot thumbnail capture behavior.
|
||||||
- [x] Add wheel navigation over the strip and keep the overview mapped while switching workspaces.
|
- [x] Add wheel navigation over the strip and keep the overview mapped while switching workspaces.
|
||||||
- [x] Add a keyboard-focused search field and filtered cross-workspace window results.
|
- [x] Add a keyboard-focused search field and filtered cross-workspace window results.
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ FileView {
|
|||||||
printErrors: false
|
printErrors: false
|
||||||
atomicWrites: true
|
atomicWrites: true
|
||||||
onSaved: root.saveError = ""
|
onSaved: root.saveError = ""
|
||||||
onSaveFailed: error => root.saveError = "Could not save Home favourites."
|
onSaveFailed: error => root.saveError = "Could not save Home favorites."
|
||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: values
|
id: values
|
||||||
property bool initialized: false
|
property bool initialized: false
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ holds the shipped defaults; one JSON file is the truth both sides read.
|
|||||||
- Verify every write by reading the value back (`hyprctl getoption`), never by
|
- Verify every write by reading the value back (`hyprctl getoption`), never by
|
||||||
trusting an exit code.
|
trusting an exit code.
|
||||||
- No UI-supplied string is interpolated into `eval`, a shell command, or a config
|
- No UI-supplied string is interpolated into `eval`, a shell command, or a config
|
||||||
value. Numbers range-checked, choices allow-listed, colours hex-validated.
|
value. Numbers range-checked, choices allow-listed, colors hex-validated.
|
||||||
- A missing or malformed `settings.json` degrades to shipped defaults. The Lua
|
- A missing or malformed `settings.json` degrades to shipped defaults. The Lua
|
||||||
read is `pcall`-wrapped so it can never take down the compositor config.
|
read is `pcall`-wrapped so it can never take down the compositor config.
|
||||||
- Tokyo Night Moon and Prism stay the only identity; customisation adjusts its
|
- Tokyo Night Moon and Prism stay the only identity; customization adjusts its
|
||||||
parameters, it does not replace it.
|
parameters, it does not replace it.
|
||||||
- Motion stays event-driven at every setting. No idle repaint.
|
- Motion stays event-driven at every setting. No idle repaint.
|
||||||
- Do not restart the running Quickshell process during development; it hot-reloads.
|
- Do not restart the running Quickshell process during development; it hot-reloads.
|
||||||
@@ -30,7 +30,7 @@ holds the shipped defaults; one JSON file is the truth both sides read.
|
|||||||
## Stage 0 — Stop the lying (ship first, standalone)
|
## Stage 0 — Stop the lying (ship first, standalone)
|
||||||
|
|
||||||
The display-policy toggles report success while doing nothing. This is a
|
The display-policy toggles report success while doing nothing. This is a
|
||||||
correctness bug in shipped behaviour and does not depend on any of the
|
correctness bug in shipped behavior and does not depend on any of the
|
||||||
architecture below.
|
architecture below.
|
||||||
|
|
||||||
**Files:** Modify `config/dot/quickshell/services/SystemSettings.qml`;
|
**Files:** Modify `config/dot/quickshell/services/SystemSettings.qml`;
|
||||||
@@ -40,7 +40,7 @@ Test `tests/quickshell/settings-hyprland-write-contract.sh`
|
|||||||
asserts via `hyprctl getoption` that the compositor value actually changed —
|
asserts via `hyprctl getoption` that the compositor value actually changed —
|
||||||
and that a rejected write leaves `lastError` non-empty.
|
and that a rejected write leaves `lastError` non-empty.
|
||||||
- [x] Run it; confirm it fails against the current `hyprctl keyword` implementation.
|
- [x] Run it; confirm it fails against the current `hyprctl keyword` implementation.
|
||||||
- [x] Add a single `applyOptions(values)` boundary that serialises validated values
|
- [x] Add a single `applyOptions(values)` boundary that serializes validated values
|
||||||
into `hl.config{}` and runs them through `hyprctl eval`.
|
into `hl.config{}` and runs them through `hyprctl eval`.
|
||||||
- [x] Route `setAutoHdr`, `setVrrPolicy`, and `setDirectScanoutPolicy` through it.
|
- [x] Route `setAutoHdr`, `setVrrPolicy`, and `setDirectScanoutPolicy` through it.
|
||||||
- [x] Treat "wrote it back and read it back equal" as the only success condition;
|
- [x] Treat "wrote it back and read it back equal" as the only success condition;
|
||||||
@@ -134,9 +134,9 @@ Test `tests/hypr/prefs-fallback-contract.sh`
|
|||||||
- [x] Implement a dependency-free JSON reader exposing `prefs.get(key, fallback)`,
|
- [x] Implement a dependency-free JSON reader exposing `prefs.get(key, fallback)`,
|
||||||
`pcall`-wrapped, reading `$XDG_CONFIG_HOME/panama/settings.json`.
|
`pcall`-wrapped, reading `$XDG_CONFIG_HOME/panama/settings.json`.
|
||||||
- [x] Require it first in `hyprland.lua`, before `looks`.
|
- [x] Require it first in `hyprland.lua`, before `looks`.
|
||||||
- [x] Convert the appearance and behaviour literals in `looks.lua` and `input.lua`
|
- [x] Convert the appearance and behavior literals in `looks.lua` and `input.lua`
|
||||||
to `prefs.get("<key>", <current literal>)`, keeping every current value as
|
to `prefs.get("<key>", <current literal>)`, keeping every current value as
|
||||||
the fallback so shipped behaviour is byte-identical.
|
the fallback so shipped behavior is byte-identical.
|
||||||
- [x] Extend `PreferenceSchema.qml` with the Hyprland-owned keys, each carrying
|
- [x] Extend `PreferenceSchema.qml` with the Hyprland-owned keys, each carrying
|
||||||
the `hl.config` path it maps to.
|
the `hl.config` path it maps to.
|
||||||
- [x] Have `SystemSettings` derive its `eval` payload from that mapping, so a new
|
- [x] Have `SystemSettings` derive its `eval` payload from that mapping, so a new
|
||||||
@@ -208,7 +208,7 @@ Modify all eleven `*Page.qml`; Test `tests/quickshell/settings-rows-contract.sh`
|
|||||||
- [ ] Move the remaining pages (Home, Displays, Connectivity, Sound,
|
- [ ] Move the remaining pages (Home, Displays, Connectivity, Sound,
|
||||||
Notifications, Screen Intelligence, Services, About) onto `SettingsPage`.
|
Notifications, Screen Intelligence, Services, About) onto `SettingsPage`.
|
||||||
|
|
||||||
**Exit criteria:** no shipped behaviour value is reachable only by editing a file.
|
**Exit criteria:** no shipped behavior value is reachable only by editing a file.
|
||||||
|
|
||||||
**Landed (first pass).** `SettingsPage` plus `ToggleRow`, `SliderRow`,
|
**Landed (first pass).** `SettingsPage` plus `ToggleRow`, `SliderRow`,
|
||||||
`ChoiceRow`, `ActionRow`, and `TextRow`. A row names a schema key and needs
|
`ChoiceRow`, `ActionRow`, and `TextRow`. A row names a schema key and needs
|
||||||
@@ -218,7 +218,7 @@ explanation, bounds, and unit from the schema, and writes through
|
|||||||
apply-and-verify and local keys straight to the store. Rows never need to know
|
apply-and-verify and local keys straight to the store. Rows never need to know
|
||||||
which kind they hold.
|
which kind they hold.
|
||||||
|
|
||||||
`DesktopPreview` is the direction-B centrepiece: two tiled windows drawn at the
|
`DesktopPreview` is the direction-B centerpiece: two tiled windows drawn at the
|
||||||
settings actually in effect, scaled by the ratio between the preview's width and
|
settings actually in effect, scaled by the ratio between the preview's width and
|
||||||
the real monitor's, so a 10px gap on a 4500px display looks as small as it is.
|
the real monitor's, so a 10px gap on a 4500px display looks as small as it is.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
**Goal:** Expand Panama Quick Settings into the approved Control Center with secure Home Assistant favourites and capability-aware iPhone continuity.
|
**Goal:** Expand Panama Quick Settings into the approved Control Center with secure Home Assistant favorites and capability-aware iPhone continuity.
|
||||||
|
|
||||||
**Architecture:** Two executable Python helpers own the external boundaries: KDE Connect CLI/D-Bus and the Home Assistant REST API/credential lookup. Quickshell singletons normalize those JSON contracts for focused Home and Phone components inside the existing Quick Settings window; Ongoing and Signal Glass consume transfer lifecycle without duplicating state.
|
**Architecture:** Two executable Python helpers own the external boundaries: KDE Connect CLI/D-Bus and the Home Assistant REST API/credential lookup. Quickshell singletons normalize those JSON contracts for focused Home and Phone components inside the existing Quick Settings window; Ongoing and Signal Glass consume transfer lifecycle without duplicating state.
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
- Only one of Wi-Fi, Bluetooth, sink, source, Home, and Phone may be expanded at once.
|
- Only one of Wi-Fi, Bluetooth, sink, source, Home, and Phone may be expanded at once.
|
||||||
- Never print Home Assistant tokens, Authorization headers, clipboard text, certificate fingerprints, IP addresses, response bodies, or full local file paths.
|
- Never print Home Assistant tokens, Authorization headers, clipboard text, certificate fingerprints, IP addresses, response bodies, or full local file paths.
|
||||||
- Home Assistant tokens remain in the gitignored environment file or Secret Service; never write one into tracked content.
|
- Home Assistant tokens remain in the gitignored environment file or Secret Service; never write one into tracked content.
|
||||||
- Home Assistant toggle commands accept only entity IDs from the configured favourites snapshot.
|
- Home Assistant toggle commands accept only entity IDs from the configured favorites snapshot.
|
||||||
- KDE Connect actions derive from advertised plugins; no fake battery or remote-input control is allowed.
|
- KDE Connect actions derive from advertised plugins; no fake battery or remote-input control is allowed.
|
||||||
- Every Home toggle, file chooser, file send, clipboard send, and Ring action requires a user click.
|
- Every Home toggle, file chooser, file send, clipboard send, and Ring action requires a user click.
|
||||||
- Home toggle success, phone Ring, and clipboard success remain globally quiet.
|
- Home toggle success, phone Ring, and clipboard success remain globally quiet.
|
||||||
@@ -49,8 +49,8 @@
|
|||||||
- `config/dot/quickshell/modules/quicksettings/QuickSettings.qml` — tighter top attachment and service preparation.
|
- `config/dot/quickshell/modules/quicksettings/QuickSettings.qml` — tighter top attachment and service preparation.
|
||||||
- `config/dot/quickshell/modules/quicksettings/QuickSettingsPanel.qml` — expanded composition and exclusive section routing.
|
- `config/dot/quickshell/modules/quicksettings/QuickSettingsPanel.qml` — expanded composition and exclusive section routing.
|
||||||
- `config/dot/quickshell/modules/quicksettings/ControlSectionHeader.qml` — quiet section label and optional trailing action.
|
- `config/dot/quickshell/modules/quicksettings/ControlSectionHeader.qml` — quiet section label and optional trailing action.
|
||||||
- `config/dot/quickshell/modules/quicksettings/HomeControls.qml` — four favourites, expanded configured list, loading/stale/failure states.
|
- `config/dot/quickshell/modules/quicksettings/HomeControls.qml` — four favorites, expanded configured list, loading/stale/failure states.
|
||||||
- `config/dot/quickshell/modules/quicksettings/HomeTile.qml` — one domain-aware favourite tile.
|
- `config/dot/quickshell/modules/quicksettings/HomeTile.qml` — one domain-aware favorite tile.
|
||||||
- `config/dot/quickshell/modules/quicksettings/PhoneControls.qml` — approved compact Continuity Card.
|
- `config/dot/quickshell/modules/quicksettings/PhoneControls.qml` — approved compact Continuity Card.
|
||||||
- `config/dot/quickshell/modules/quicksettings/RecentExchange.qml` — one session-local completed transfer row.
|
- `config/dot/quickshell/modules/quicksettings/RecentExchange.qml` — one session-local completed transfer row.
|
||||||
- `config/dot/quickshell/modules/bar/StatusCluster.qml` — reachable-phone glyph inside the existing click target.
|
- `config/dot/quickshell/modules/bar/StatusCluster.qml` — reachable-phone glyph inside the existing click target.
|
||||||
@@ -340,7 +340,7 @@ Expected: all tests PASS and the fake server records no unexpected route.
|
|||||||
- [ ] **Step 5: Add and run the redacted live contract**
|
- [ ] **Step 5: Add and run the redacted live contract**
|
||||||
|
|
||||||
The contract runs `probe` and `snapshot`, validates the schema, and prints only
|
The contract runs `probe` and `snapshot`, validates the schema, and prints only
|
||||||
`PASS (configured=true, N favourites; contents redacted)`. It must pipe JSON to
|
`PASS (configured=true, N favorites; contents redacted)`. It must pipe JSON to
|
||||||
`jq` without printing friendly names, entity IDs, URL, or raw errors.
|
`jq` without printing friendly names, entity IDs, URL, or raw errors.
|
||||||
|
|
||||||
- [ ] **Step 6: Commit Task 2**
|
- [ ] **Step 6: Commit Task 2**
|
||||||
@@ -599,7 +599,7 @@ git commit -m "Build the Panama Control Center"
|
|||||||
|
|
||||||
- [ ] **Step 1: Update desktop documentation**
|
- [ ] **Step 1: Update desktop documentation**
|
||||||
|
|
||||||
Mark Home Assistant favourites and KDE Connect phone integration Live. Document
|
Mark Home Assistant favorites and KDE Connect phone integration Live. Document
|
||||||
the 430-pixel Control Center, two-pixel bar attachment, environment/keyring
|
the 430-pixel Control Center, two-pixel bar attachment, environment/keyring
|
||||||
configuration precedence, BlueBubbles messaging boundary, and current iOS
|
configuration precedence, BlueBubbles messaging boundary, and current iOS
|
||||||
capabilities. Remove those two items from `System UI still worth adding` while
|
capabilities. Remove those two items from `System UI still worth adding` while
|
||||||
@@ -628,7 +628,7 @@ inspect only the new process's journal for QML errors or warnings.
|
|||||||
- [ ] **Step 4: Perform read-only live checks**
|
- [ ] **Step 4: Perform read-only live checks**
|
||||||
|
|
||||||
Verify the Control Center reports one reachable phone with the confirmed action
|
Verify the Control Center reports one reachable phone with the confirmed action
|
||||||
names and seven configured Home favourites without printing identities. Open
|
names and seven configured Home favorites without printing identities. Open
|
||||||
and close the panel, expand Home and Phone, and confirm Wi-Fi, Bluetooth, audio,
|
and close the panel, expand Home and Phone, and confirm Wi-Fi, Bluetooth, audio,
|
||||||
Focus, Caffeine, Night Light, settings, power, Escape, and outside-click remain
|
Focus, Caffeine, Night Light, settings, power, Escape, and outside-click remain
|
||||||
usable. Do not trigger an external-device action.
|
usable. Do not trigger an external-device action.
|
||||||
|
|||||||
@@ -503,7 +503,7 @@ Accounts destinations while this feature was in review. Merge commit `4ef2f01`
|
|||||||
preserves those routes and the newer Settings navigation architecture, keeps
|
preserves those routes and the newer Settings navigation architecture, keeps
|
||||||
the stable `services` route rendered by `HealthPage`, and leaves
|
the stable `services` route rendered by `HealthPage`, and leaves
|
||||||
`ServicesPage.qml` retired. Its useful Fedora handoffs for Users, Sharing,
|
`ServicesPage.qml` retired. Its useful Fedora handoffs for Users, Sharing,
|
||||||
Colour profiles, and Digital wellbeing now live in the boundary-last System
|
Color profiles, and Digital wellbeing now live in the boundary-last System
|
||||||
Health card alongside the existing network handoff, with focused static and
|
Health card alongside the existing network handoff, with focused static and
|
||||||
isolated runtime coverage.
|
isolated runtime coverage.
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ Panama gains a polished focus-session surface and a GNOME-like workspace overvie
|
|||||||
|
|
||||||
## Signal Glass surface
|
## Signal Glass surface
|
||||||
|
|
||||||
- The main capsule is a top-centred blurred glass surface below the bar, carrying Panama's Prism edge, Tokyo Night Moon palette, and event-driven open/close motion.
|
- The main capsule is a top-centered blurred glass surface below the bar, carrying Panama's Prism edge, Tokyo Night Moon palette, and event-driven open/close motion.
|
||||||
- Its primary row shows the focus icon, workspace label, remaining time, and whether DND and Caffeine are being held.
|
- Its primary row shows the focus icon, workspace label, remaining time, and whether DND and Caffeine are being held.
|
||||||
- Clicking the primary row activates the bound workspace and dismisses the capsule without ending the session.
|
- Clicking the primary row activates the bound workspace and dismisses the capsule without ending the session.
|
||||||
- The action row contains Pause or Resume, Workspace, and End.
|
- The action row contains Pause or Resume, Workspace, and End.
|
||||||
- Workspace opens the Continuum overview with the session's bound workspace selected.
|
- Workspace opens the Continuum overview with the session's bound workspace selected.
|
||||||
- A labelled close button hides the capsule while the session continues.
|
- A labeled close button hides the capsule while the session continues.
|
||||||
- While a session exists, a compact bar indicator remains visible. Clicking it reopens the capsule, so dismissal never makes the running session undiscoverable.
|
- While a session exists, a compact bar indicator remains visible. Clicking it reopens the capsule, so dismissal never makes the running session undiscoverable.
|
||||||
- No focus UI animates while idle. The only periodic update is the once-per-second remaining-time text while a session is running and not paused.
|
- No focus UI animates while idle. The only periodic update is the once-per-second remaining-time text while a session is running and not paused.
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ Devices and Desktop & Dock. Its page contains three cards.
|
|||||||
|
|
||||||
1. **Home Assistant** shows connection health, discovered-light count, Refresh,
|
1. **Home Assistant** shows connection health, discovered-light count, Refresh,
|
||||||
and Open Home Assistant.
|
and Open Home Assistant.
|
||||||
2. **Control Center favourites** shows selected accessories as a two-column
|
2. **Control Center favorites** shows selected accessories as a two-column
|
||||||
card shelf. Each item exposes a drag handle, editable alias, source friendly
|
card shelf. Each item exposes a drag handle, editable alias, source friendly
|
||||||
name, and Remove action. Dragging reorders the list; the first four are
|
name, and Remove action. Dragging reorders the list; the first four are
|
||||||
explicitly marked as the resting Control Center shelf.
|
explicitly marked as the resting Control Center shelf.
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ $ hyprctl getoption decoration:rounding -j → "int": 4
|
|||||||
`eval` is also strictly more capable than `keyword` — it can set *any* config
|
`eval` is also strictly more capable than `keyword` — it can set *any* config
|
||||||
value, including gradients, animation curves, and nested tables. It executes
|
value, including gradients, animation curves, and nested tables. It executes
|
||||||
arbitrary Lua, so the existing "never interpolate UI text into a command" rule
|
arbitrary Lua, so the existing "never interpolate UI text into a command" rule
|
||||||
must extend to it: values are validated and serialised numerically, never
|
must extend to it: values are validated and serialized numerically, never
|
||||||
concatenated from user input.
|
concatenated from user input.
|
||||||
|
|
||||||
### Finding 2: three disconnected sources of truth for the same three values
|
### Finding 2: three disconnected sources of truth for the same three values
|
||||||
@@ -206,7 +206,7 @@ promote the ~40 hardcoded `Settings.qml` values into real controls, and give
|
|||||||
Appearance genuine content: accent pair, window rounding, gaps, border size,
|
Appearance genuine content: accent pair, window rounding, gaps, border size,
|
||||||
blur, animation speed, bar height, font scale, and wallpaper.
|
blur, animation speed, bar height, font scale, and wallpaper.
|
||||||
|
|
||||||
Appearance customisation stays inside the design language. The user picks how much
|
Appearance customization stays inside the design language. The user picks how much
|
||||||
of it there is — spacing, softness, motion — not a free-form palette editor that
|
of it there is — spacing, softness, motion — not a free-form palette editor that
|
||||||
would let the Prism identity be dismantled by accident.
|
would let the Prism identity be dismantled by accident.
|
||||||
|
|
||||||
@@ -223,13 +223,13 @@ defaults, and Settings applies them live with `hyprctl eval`.
|
|||||||
|
|
||||||
- No UI-supplied string is ever interpolated into an `eval`, a shell command, or
|
- No UI-supplied string is ever interpolated into an `eval`, a shell command, or
|
||||||
a config value. Numbers are range-checked; choices are matched against an
|
a config value. Numbers are range-checked; choices are matched against an
|
||||||
allow-list; colours are validated as hex before serialisation.
|
allow-list; colors are validated as hex before serialization.
|
||||||
- A malformed or absent `settings.json` must degrade to shipped defaults, never
|
- A malformed or absent `settings.json` must degrade to shipped defaults, never
|
||||||
to a broken compositor.
|
to a broken compositor.
|
||||||
- `hyprctl keyword` is banned in this codebase. It exits 0 without acting.
|
- `hyprctl keyword` is banned in this codebase. It exits 0 without acting.
|
||||||
- Every write path must be observably verified — read the value back rather than
|
- Every write path must be observably verified — read the value back rather than
|
||||||
trusting an exit code. Finding 1 exists because an exit code was trusted.
|
trusting an exit code. Finding 1 exists because an exit code was trusted.
|
||||||
- Tokyo Night Moon and Prism remain the only visual identity. Customisation
|
- Tokyo Night Moon and Prism remain the only visual identity. Customization
|
||||||
adjusts its parameters, it does not replace it.
|
adjusts its parameters, it does not replace it.
|
||||||
- Motion stays event-driven. No idle repaint, at any setting.
|
- Motion stays event-driven. No idle repaint, at any setting.
|
||||||
- GNOME keeps ownership of hardware, accounts, printers, and users.
|
- GNOME keeps ownership of hardware, accounts, printers, and users.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Panama will expand the existing top-right Quick Settings popover into a complete
|
Panama will expand the existing top-right Quick Settings popover into a complete
|
||||||
Control Center. Wi-Fi, Bluetooth, Focus, Caffeine, Night Light, audio, account,
|
Control Center. Wi-Fi, Bluetooth, Focus, Caffeine, Night Light, audio, account,
|
||||||
settings, and power remain in place. Home Assistant favourites and lightweight
|
settings, and power remain in place. Home Assistant favorites and lightweight
|
||||||
iPhone continuity join that same surface instead of creating separate windows
|
iPhone continuity join that same surface instead of creating separate windows
|
||||||
or permanent bar widgets.
|
or permanent bar widgets.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ the paired iPhone exposes only a useful subset of KDE Connect.
|
|||||||
|
|
||||||
- Make the top-right popover feel like a complete desktop Control Center rather
|
- Make the top-right popover feel like a complete desktop Control Center rather
|
||||||
than a small collection of connectivity toggles.
|
than a small collection of connectivity toggles.
|
||||||
- Toggle the existing Home Assistant favourites without opening a browser.
|
- Toggle the existing Home Assistant favorites without opening a browser.
|
||||||
- Preserve the user's seven enabled Home Assistant lights and use Home
|
- Preserve the user's seven enabled Home Assistant lights and use Home
|
||||||
Assistant friendly names and live states.
|
Assistant friendly names and live states.
|
||||||
- Show the paired iPhone's real reachability and expose Send File, Send
|
- Show the paired iPhone's real reachability and expose Send File, Send
|
||||||
@@ -67,7 +67,7 @@ The resting panel is ordered by frequency and scope:
|
|||||||
|
|
||||||
1. Wi-Fi, Bluetooth, Caffeine, and Night Light toggle grid.
|
1. Wi-Fi, Bluetooth, Caffeine, and Night Light toggle grid.
|
||||||
2. Focus and audio controls.
|
2. Focus and audio controls.
|
||||||
3. Home favourites.
|
3. Home favorites.
|
||||||
4. Phone continuity.
|
4. Phone continuity.
|
||||||
5. User, Panama Settings, and power footer.
|
5. User, Panama Settings, and power footer.
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ panel remains predictable.
|
|||||||
|
|
||||||
## Home section
|
## Home section
|
||||||
|
|
||||||
The resting Home card shows the first four enabled favourites in their saved
|
The resting Home card shows the first four enabled favorites in their saved
|
||||||
order. Each tile contains a domain-appropriate glyph, a friendly name, and a
|
order. Each tile contains a domain-appropriate glyph, a friendly name, and a
|
||||||
plain state such as `On`, `Off`, or `Unavailable`. Enabled lights use a quiet
|
plain state such as `On`, `Off`, or `Unavailable`. Enabled lights use a quiet
|
||||||
amber light treatment; Panama blue remains reserved for desktop selection and
|
amber light treatment; Panama blue remains reserved for desktop selection and
|
||||||
@@ -96,7 +96,7 @@ without a toast or Signal Glass event. A failure restores the last known state
|
|||||||
and displays a concise inline error inside the Home section.
|
and displays a concise inline error inside the Home section.
|
||||||
|
|
||||||
The trailing `N accessories` action expands a full list of configured
|
The trailing `N accessories` action expands a full list of configured
|
||||||
favourites inside the Control Center. No unconfigured Home Assistant entity is
|
favorites inside the Control Center. No unconfigured Home Assistant entity is
|
||||||
shown. An `Open Home Assistant` action launches the configured base URL.
|
shown. An `Open Home Assistant` action launches the configured base URL.
|
||||||
|
|
||||||
If Home Assistant is unreachable, Panama retains the last good states for the
|
If Home Assistant is unreachable, Panama retains the last good states for the
|
||||||
@@ -165,7 +165,7 @@ reliable byte progress for this device.
|
|||||||
Add `scripts/panama-home-assistant`, a small local bridge with four commands:
|
Add `scripts/panama-home-assistant`, a small local bridge with four commands:
|
||||||
|
|
||||||
- `probe` reports configuration and API availability without entity details;
|
- `probe` reports configuration and API availability without entity details;
|
||||||
- `snapshot` returns only configured favourites and normalized state;
|
- `snapshot` returns only configured favorites and normalized state;
|
||||||
- `toggle ENTITY_ID` calls the Home Assistant service for an allow-listed
|
- `toggle ENTITY_ID` calls the Home Assistant service for an allow-listed
|
||||||
configured entity; and
|
configured entity; and
|
||||||
- `open` launches the configured Home Assistant URL.
|
- `open` launches the configured Home Assistant URL.
|
||||||
@@ -212,7 +212,7 @@ outside-click behavior remain intact.
|
|||||||
- Helpers never echo tokens, Authorization headers, clipboard text, entity
|
- Helpers never echo tokens, Authorization headers, clipboard text, entity
|
||||||
response bodies, IP addresses, or full local file paths to logs.
|
response bodies, IP addresses, or full local file paths to logs.
|
||||||
- Home Assistant commands accept only entity IDs present in the configured
|
- Home Assistant commands accept only entity IDs present in the configured
|
||||||
favourites snapshot.
|
favorites snapshot.
|
||||||
- KDE Connect device IDs and file paths are passed as separate process
|
- KDE Connect device IDs and file paths are passed as separate process
|
||||||
arguments, never interpolated into a shell command.
|
arguments, never interpolated into a shell command.
|
||||||
- A user click is required for every Home toggle, phone ring, clipboard send,
|
- A user click is required for every Home toggle, phone ring, clipboard send,
|
||||||
@@ -231,7 +231,7 @@ outside-click behavior remain intact.
|
|||||||
is offered.
|
is offered.
|
||||||
- Invalid or expired token: Home shows `Authentication required` without
|
- Invalid or expired token: Home shows `Authentication required` without
|
||||||
exposing the response body.
|
exposing the response body.
|
||||||
- One malformed entity is omitted without suppressing healthy favourites.
|
- One malformed entity is omitted without suppressing healthy favorites.
|
||||||
|
|
||||||
## Testing and verification
|
## Testing and verification
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ checks require an explicit user action from the finished Control Center.
|
|||||||
|
|
||||||
## Documentation updates
|
## Documentation updates
|
||||||
|
|
||||||
- Update `config/dot/hypr/DESKTOP-PARITY.md` to mark Home Assistant favourites
|
- Update `config/dot/hypr/DESKTOP-PARITY.md` to mark Home Assistant favorites
|
||||||
and KDE Connect phone integration live.
|
and KDE Connect phone integration live.
|
||||||
- Document Control Center behavior, credential resolution, and iOS limitations
|
- Document Control Center behavior, credential resolution, and iOS limitations
|
||||||
in `config/dot/hypr/README.md`.
|
in `config/dot/hypr/README.md`.
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ The feature is deliberately local-first. Screen pixels are captured into Panama'
|
|||||||
- Tokyo Night Moon tokens are the only colors.
|
- Tokyo Night Moon tokens are the only colors.
|
||||||
- Processing uses a static status treatment; there is no spinner, pulse, shimmer, or idle animation.
|
- Processing uses a static status treatment; there is no spinner, pulse, shimmer, or idle animation.
|
||||||
- OCR text is readable interface typography in a selectable editor, not a terminal-like dump.
|
- OCR text is readable interface typography in a selectable editor, not a terminal-like dump.
|
||||||
- The primary action is Copy. Network-leaving actions are visually secondary and clearly labelled.
|
- The primary action is Copy. Network-leaving actions are visually secondary and clearly labeled.
|
||||||
|
|
||||||
## Settings and discoverability
|
## Settings and discoverability
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ for dir in "${dirs[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# tmux.conf ends with a source-file of current-theme.conf, generated from the
|
# tmux.conf ends with a source-file of current-theme.conf, generated from the
|
||||||
# colour scheme rather than committed. Seed it so a fresh checkout starts themed
|
# color scheme rather than committed. Seed it so a fresh checkout starts themed
|
||||||
# -- the source-file is -q, so a missing file is silent, which would leave tmux
|
# -- the source-file is -q, so a missing file is silent, which would leave tmux
|
||||||
# unstyled with nothing to explain it.
|
# unstyled with nothing to explain it.
|
||||||
TMUX_THEME="$PANAMA_DOT/tmux/current-theme.conf"
|
TMUX_THEME="$PANAMA_DOT/tmux/current-theme.conf"
|
||||||
@@ -95,9 +95,9 @@ elif [ -d "$PANAMA_DOT/tmux/themes" ]; then
|
|||||||
log "Seeded tmux $tmux_scheme theme ($tmux_name) → $TMUX_THEME"
|
log "Seeded tmux $tmux_scheme theme ($tmux_name) → $TMUX_THEME"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# hyprlock.conf is generated from a template on every colour scheme change and
|
# hyprlock.conf is generated from a template on every color scheme change and
|
||||||
# is not committed. Seed it so the FIRST lock of a fresh install is themed --
|
# is not committed. Seed it so the FIRST lock of a fresh install is themed --
|
||||||
# without it hyprlock falls back to its own defaults, which is a bare grey
|
# without it hyprlock falls back to its own defaults, which is a bare gray
|
||||||
# screen with none of this desktop's identity, and the first time anyone would
|
# screen with none of this desktop's identity, and the first time anyone would
|
||||||
# find out is when they walked away from the machine.
|
# find out is when they walked away from the machine.
|
||||||
HYPRLOCK_TEMPLATE="$PANAMA_DOT/hypr/hyprlock.conf.template"
|
HYPRLOCK_TEMPLATE="$PANAMA_DOT/hypr/hyprlock.conf.template"
|
||||||
@@ -176,9 +176,9 @@ for gtk_version in 3.0 4.0; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# kitty.conf ends with `include current-theme.conf`, and that file is generated
|
# kitty.conf ends with `include current-theme.conf`, and that file is generated
|
||||||
# from the desktop colour scheme rather than committed -- it is machine state.
|
# from the desktop color scheme rather than committed -- it is machine state.
|
||||||
# A fresh checkout therefore has no such file, and kitty starts by complaining
|
# A fresh checkout therefore has no such file, and kitty starts by complaining
|
||||||
# about a missing include and falling back to its stock colours. Seed it from
|
# about a missing include and falling back to its stock colors. Seed it from
|
||||||
# the scheme in settings.json (dark unless the user has chosen otherwise) so a
|
# the scheme in settings.json (dark unless the user has chosen otherwise) so a
|
||||||
# first launch is themed; ColorScheme.qml overwrites it on every change after.
|
# first launch is themed; ColorScheme.qml overwrites it on every change after.
|
||||||
KITTY_THEME="$PANAMA_DOT/kitty/current-theme.conf"
|
KITTY_THEME="$PANAMA_DOT/kitty/current-theme.conf"
|
||||||
@@ -226,7 +226,7 @@ done
|
|||||||
# the repository and expose it with a narrow per-file symlink.
|
# the repository and expose it with a narrow per-file symlink.
|
||||||
# Panama ships its own application icons. Without these the desktop entries fall
|
# Panama ships its own application icons. Without these the desktop entries fall
|
||||||
# back to a generic symbolic glyph, which is drawn for 16px toolbar use and
|
# back to a generic symbolic glyph, which is drawn for 16px toolbar use and
|
||||||
# looks wrong beside full-colour application icons in the dock.
|
# looks wrong beside full-color application icons in the dock.
|
||||||
PANAMA_ICON_DIR="$PANAMA_PATH/config/local/share/icons/hicolor/scalable/apps"
|
PANAMA_ICON_DIR="$PANAMA_PATH/config/local/share/icons/hicolor/scalable/apps"
|
||||||
USER_ICON_DIR="$HOME/.local/share/icons/hicolor/scalable/apps"
|
USER_ICON_DIR="$HOME/.local/share/icons/hicolor/scalable/apps"
|
||||||
mkdir -p "$USER_ICON_DIR"
|
mkdir -p "$USER_ICON_DIR"
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ grep -q 'timeout = 0' "$generated" && fail 'a zero timeout was written as an imm
|
|||||||
grep -qE '^listener' "$generated" && fail 'a listener was written when everything is set to never'
|
grep -qE '^listener' "$generated" && fail 'a listener was written when everything is set to never'
|
||||||
grep -q 'after_sleep_cmd' "$generated" || fail 'the general block was lost when all timers are off'
|
grep -q 'after_sleep_cmd' "$generated" || fail 'the general block was lost when all timers are off'
|
||||||
|
|
||||||
# ── Values are honoured ──────────────────────────────────────────────────────
|
# ── Values are honored ──────────────────────────────────────────────────────
|
||||||
run_with '{"screenBlankMinutes":2,"lockMinutes":7,"suspendMinutes":45}'
|
run_with '{"screenBlankMinutes":2,"lockMinutes":7,"suspendMinutes":45}'
|
||||||
grep -q 'timeout = 120' "$generated" || fail '2 minute blank not honoured'
|
grep -q 'timeout = 120' "$generated" || fail '2 minute blank not honored'
|
||||||
grep -q 'timeout = 420' "$generated" || fail '7 minute lock not honoured'
|
grep -q 'timeout = 420' "$generated" || fail '7 minute lock not honored'
|
||||||
grep -q 'timeout = 2700' "$generated" || fail '45 minute suspend not honoured'
|
grep -q 'timeout = 2700' "$generated" || fail '45 minute suspend not honored'
|
||||||
grep -q 'systemctl suspend' "$generated" || fail 'suspend listener missing when set'
|
grep -q 'systemctl suspend' "$generated" || fail 'suspend listener missing when set'
|
||||||
|
|
||||||
# ── lockOnSleep off removes the pre-sleep lock ───────────────────────────────
|
# ── lockOnSleep off removes the pre-sleep lock ───────────────────────────────
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# monitors.lua. It is therefore the one piece of Panama that can cost the user a
|
# monitors.lua. It is therefore the one piece of Panama that can cost the user a
|
||||||
# working compositor rather than merely a working feature.
|
# working compositor rather than merely a working feature.
|
||||||
#
|
#
|
||||||
# This contract pins the only behaviour that matters: whatever is in the
|
# This contract pins the only behavior that matters: whatever is in the
|
||||||
# settings file -- including nothing, garbage, or values of the wrong type --
|
# settings file -- including nothing, garbage, or values of the wrong type --
|
||||||
# the config still parses, and every setting either takes the stored value or
|
# the config still parses, and every setting either takes the stored value or
|
||||||
# falls back to the value shipped in the Lua.
|
# falls back to the value shipped in the Lua.
|
||||||
@@ -106,7 +106,7 @@ result="$(probe '{"note": "a \"quoted\" value\nwith escapes", "nested": {"a": [1
|
|||||||
# defaults is only useful if Hyprland still accepts the config around it.
|
# defaults is only useful if Hyprland still accepts the config around it.
|
||||||
#
|
#
|
||||||
# Hyprland resolves its own config from $HOME/.config/hypr regardless of
|
# Hyprland resolves its own config from $HOME/.config/hypr regardless of
|
||||||
# XDG_CONFIG_HOME, while prefs.lua honours XDG_CONFIG_HOME. That asymmetry is
|
# XDG_CONFIG_HOME, while prefs.lua honors XDG_CONFIG_HOME. That asymmetry is
|
||||||
# what makes this loop useful rather than vacuous: the *real* looks.lua and
|
# what makes this loop useful rather than vacuous: the *real* looks.lua and
|
||||||
# input.lua are parsed against a *fixture* settings file. The probe cases above
|
# input.lua are parsed against a *fixture* settings file. The probe cases above
|
||||||
# already establish that prefs.lua reads the fixture and not the live file.
|
# already establish that prefs.lua reads the fixture and not the live file.
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ fi
|
|||||||
# ── Signal strength is a ratio, and the labels must reflect that ─────────────
|
# ── Signal strength is a ratio, and the labels must reflect that ─────────────
|
||||||
while IFS='|' read -r value expect; do
|
while IFS='|' read -r value expect; do
|
||||||
got="$(run ipc call connectivity-test labelFor "$value")"
|
got="$(run ipc call connectivity-test labelFor "$value")"
|
||||||
[[ "$got" == "$expect" ]] || fail "signal $value labelled '$got', expected '$expect'"
|
[[ "$got" == "$expect" ]] || fail "signal $value labeled '$got', expected '$expect'"
|
||||||
done <<'CASES'
|
done <<'CASES'
|
||||||
1.0|Excellent
|
1.0|Excellent
|
||||||
0.85|Excellent
|
0.85|Excellent
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user