Make Shell a category, the bar legible, and the dock a real dock
Desktop & Dock becomes Shell — Bar, Dock, Control Center, Tiling, Workspaces — the home for everything Quickshell draws. The settings- management cluster moves to System as Sync & Backup, Appearance's Shell tab dissolves, and 24-hour time finally lives on Date & Time, which always owned it. The bar gets what it never had: a way to survive the wallpaper. A second neutral text family (follow theme, or forced light or dark), a one-layer shadow under every glyph, and a gradient scrim for wallpapers nothing else survives — all off by default, pixel-identical until asked. Widgets earn toggles (weather, media, clipboard, calendar countdown), the vitals cluster stops leaving a dead pill behind, and Control Center's sections learn to step aside. The dock graduates from MVP: a context menu with window rows, pin, unpin, quit and new-window; scroll an icon to cycle its windows; drag to reorder on the dock itself; hover previews with one-shot captures; and "Add App to Dock" in the launcher. Three real bugs died en route — menus that slid away with the autohide, a readonly-property crash on every menu open, and a drag that drifted half a slot per icon on side docks. The pinned-apps editor in Settings becomes a drag strip. 166 contracts; the full suite is green except two live display and switcher tests that cannot run behind a locked session — re-verified on unlock. Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -52,11 +52,74 @@ Singleton {
|
||||
|
||||
readonly property var entries: [
|
||||
// ── Clock ───────────────────────────────────────────────────────────
|
||||
// Group datetime, not clock: this drives the date menu, notification
|
||||
// timestamps, and the lock screen — Date & Time owns it.
|
||||
{
|
||||
key: "use24Hour", type: "bool", def: false, group: "clock",
|
||||
key: "use24Hour", type: "bool", def: false, group: "datetime",
|
||||
label: "24-hour time",
|
||||
detail: "Use 18:30 instead of 6:30 PM"
|
||||
},
|
||||
// ── Bar ─────────────────────────────────────────────────────────────
|
||||
// The bar floats directly on the wallpaper; these keep it legible on
|
||||
// grounds the theme never met, and choose which widgets earn a place.
|
||||
{
|
||||
key: "barTextTone", type: "enum", def: "theme", group: "bar",
|
||||
label: "Bar text",
|
||||
detail: "Follow the theme, or force a light or dark tone for the wallpaper you actually use",
|
||||
options: [
|
||||
{ value: "theme", label: "Follow theme" },
|
||||
{ value: "light", label: "Light" },
|
||||
{ value: "dark", label: "Dark" }
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "barTextShadow", type: "bool", def: false, group: "bar",
|
||||
label: "Bar text shadow",
|
||||
detail: "A soft dark halo under every glyph and label in the bar"
|
||||
},
|
||||
{
|
||||
key: "barBackdrop", type: "bool", def: false, group: "bar",
|
||||
label: "Bar backdrop",
|
||||
detail: "A subtle scrim fading down from the top edge"
|
||||
},
|
||||
{
|
||||
key: "showWeatherWidget", type: "bool", def: true, group: "bar",
|
||||
label: "Weather in the bar",
|
||||
detail: "Beside the clock, once a forecast has been fetched"
|
||||
},
|
||||
{
|
||||
key: "showMediaWidget", type: "bool", def: true, group: "bar",
|
||||
label: "Media in the bar",
|
||||
detail: "Now playing, click to pause"
|
||||
},
|
||||
{
|
||||
key: "showClipboardButton", type: "bool", def: true, group: "bar",
|
||||
label: "Clipboard button",
|
||||
detail: "The history stays on Super+V either way"
|
||||
},
|
||||
{
|
||||
key: "showCalendarCountdown", type: "bool", def: true, group: "bar",
|
||||
label: "Calendar countdown",
|
||||
detail: "Appears in the bar fifteen minutes before an event"
|
||||
},
|
||||
|
||||
// ── Control Center ──────────────────────────────────────────────────
|
||||
{
|
||||
key: "ccShowFocus", type: "bool", def: true, group: "controlCenter",
|
||||
label: "Focus in Control Center",
|
||||
detail: "The session row at the top of the panel"
|
||||
},
|
||||
{
|
||||
key: "ccShowHome", type: "bool", def: true, group: "controlCenter",
|
||||
label: "Home in Control Center",
|
||||
detail: "Your accessory shelf"
|
||||
},
|
||||
{
|
||||
key: "ccShowPhone", type: "bool", def: true, group: "controlCenter",
|
||||
label: "Phone in Control Center",
|
||||
detail: "Vitals and reach-it actions"
|
||||
},
|
||||
|
||||
{
|
||||
key: "showSeconds", type: "bool", def: true, group: "clock",
|
||||
label: "Show seconds",
|
||||
@@ -811,31 +874,31 @@ Singleton {
|
||||
hypr: { path: ["general", "snap", "enabled"], option: "general:snap:enabled", readAs: "bool" }
|
||||
},
|
||||
{
|
||||
key: "workspaceBackAndForth", type: "bool", def: false, group: "multitasking",
|
||||
key: "workspaceBackAndForth", type: "bool", def: false, group: "workspaces",
|
||||
label: "Switch back and forth",
|
||||
detail: "Selecting the workspace you are already on returns you to the previous one",
|
||||
hypr: { path: ["binds", "workspace_back_and_forth"], option: "binds:workspace_back_and_forth", readAs: "bool" }
|
||||
},
|
||||
{
|
||||
key: "allowWorkspaceCycles", type: "bool", def: false, group: "multitasking",
|
||||
key: "allowWorkspaceCycles", type: "bool", def: false, group: "workspaces",
|
||||
label: "Wrap around at the ends",
|
||||
detail: "Moving past the last workspace continues from the first",
|
||||
hypr: { path: ["binds", "allow_workspace_cycles"], option: "binds:allow_workspace_cycles", readAs: "bool" }
|
||||
},
|
||||
{
|
||||
key: "focusOnActivate", type: "bool", def: false, group: "multitasking",
|
||||
key: "focusOnActivate", type: "bool", def: false, group: "workspaces",
|
||||
label: "Let applications take focus",
|
||||
detail: "An application asking for attention is switched to, rather than only highlighted",
|
||||
hypr: { path: ["misc", "focus_on_activate"], option: "misc:focus_on_activate", readAs: "bool" }
|
||||
},
|
||||
{
|
||||
key: "windowSwallow", type: "bool", def: false, group: "multitasking",
|
||||
key: "windowSwallow", type: "bool", def: false, group: "workspaces",
|
||||
label: "Hide the terminal that launched a window",
|
||||
detail: "A terminal disappears while an application started from it is open, and returns when it closes",
|
||||
hypr: { path: ["misc", "enable_swallow"], option: "misc:enable_swallow", readAs: "bool" }
|
||||
},
|
||||
{
|
||||
key: "mouseMoveFocusesMonitor", type: "bool", def: true, group: "multitasking",
|
||||
key: "mouseMoveFocusesMonitor", type: "bool", def: true, group: "workspaces",
|
||||
label: "Pointer changes active display",
|
||||
detail: "Moving the pointer to another display makes it the active one",
|
||||
hypr: { path: ["misc", "mouse_move_focuses_monitor"], option: "misc:mouse_move_focuses_monitor", readAs: "bool" }
|
||||
@@ -980,10 +1043,10 @@ Singleton {
|
||||
label: "Video wallpaper folder",
|
||||
detail: "Where the picker looks for videos. Relative to your home folder unless it starts with /"
|
||||
},
|
||||
// Its own key, not wallpaperPath: the still pipeline persists its
|
||||
// policy transactionally and once clobbered a stored video path.
|
||||
// Two owners, two keys.
|
||||
{
|
||||
// Its own key, not wallpaperPath: the still pipeline persists its
|
||||
// policy transactionally and once clobbered a stored video path.
|
||||
// Two owners, two keys.
|
||||
key: "videoWallpaperPath", type: "string", def: "", group: "wallpaper", internal: true,
|
||||
pattern: "^(|/[^,\n]+)$",
|
||||
label: "Video wallpaper",
|
||||
|
||||
@@ -19,6 +19,26 @@ Singleton {
|
||||
readonly property bool showSeconds: DesktopPreferences.get("showSeconds")
|
||||
readonly property bool showWeekday: DesktopPreferences.get("showWeekday")
|
||||
|
||||
// ── Bar ─────────────────────────────────────────────────────────────────
|
||||
// Legibility first: the bar sits on the wallpaper, so it may need a tone,
|
||||
// a shadow or a scrim the theme cannot know about. `barTextTone` itself is
|
||||
// read by Theme, which turns it into the barFg family the widgets bind to.
|
||||
readonly property bool barTextShadow: DesktopPreferences.get("barTextShadow")
|
||||
readonly property bool barBackdrop: DesktopPreferences.get("barBackdrop")
|
||||
|
||||
// Which widgets earn a place. Each is ANDed with the widget's own state
|
||||
// condition, so turning one on never conjures a pill with nothing in it.
|
||||
readonly property bool showWeatherWidget: DesktopPreferences.get("showWeatherWidget")
|
||||
readonly property bool showMediaWidget: DesktopPreferences.get("showMediaWidget")
|
||||
readonly property bool showClipboardButton: DesktopPreferences.get("showClipboardButton")
|
||||
readonly property bool showCalendarCountdown: DesktopPreferences.get("showCalendarCountdown")
|
||||
|
||||
// ── Control Center ──────────────────────────────────────────────────────
|
||||
// One bool per section of the quick settings panel that is worth hiding.
|
||||
readonly property bool ccShowFocus: DesktopPreferences.get("ccShowFocus")
|
||||
readonly property bool ccShowHome: DesktopPreferences.get("ccShowHome")
|
||||
readonly property bool ccShowPhone: DesktopPreferences.get("ccShowPhone")
|
||||
|
||||
// ── Weather ─────────────────────────────────────────────────────────────
|
||||
// Coordinates taken from the GNOME night-light setting, which had already
|
||||
// resolved the location. Uses Open-Meteo, which needs no API key.
|
||||
|
||||
@@ -46,6 +46,43 @@ Singleton {
|
||||
readonly property color fgMuted: root.palette.fgMuted
|
||||
readonly property color gutter: root.palette.gutter
|
||||
|
||||
// ── Bar text ────────────────────────────────────────────────────────────
|
||||
// Every other surface in the shell draws on a ground the theme chose. The
|
||||
// bar draws on the wallpaper, which the theme has never seen — so a
|
||||
// photograph with a bright sky can leave the palette's own fg unreadable
|
||||
// exactly where the clock is.
|
||||
//
|
||||
// Hence a second neutral family, used by the bar and nowhere else. Left
|
||||
// alone it *is* the fg family, so nothing changes for anyone who never
|
||||
// asks. Forced light or dark, it becomes a run that survives whatever is
|
||||
// underneath it, and the two dims are mixed toward the opposite end rather
|
||||
// than picked by hand, so the three stay a family either way.
|
||||
readonly property string barTextTone: DesktopPreferences.get("barTextTone")
|
||||
|
||||
readonly property color barFg: {
|
||||
if (root.barTextTone === "light")
|
||||
return "#f4f6ff";
|
||||
if (root.barTextTone === "dark")
|
||||
return "#1b2130";
|
||||
return root.fg;
|
||||
}
|
||||
|
||||
readonly property color barFgDim: {
|
||||
if (root.barTextTone === "light")
|
||||
return root.mix(root.barFg, "#20242f", 0.35);
|
||||
if (root.barTextTone === "dark")
|
||||
return root.mix(root.barFg, "#ffffff", 0.35);
|
||||
return root.fgDim;
|
||||
}
|
||||
|
||||
readonly property color barFgMuted: {
|
||||
if (root.barTextTone === "light")
|
||||
return root.mix(root.barFg, "#20242f", 0.5);
|
||||
if (root.barTextTone === "dark")
|
||||
return root.mix(root.barFg, "#ffffff", 0.5);
|
||||
return root.fgMuted;
|
||||
}
|
||||
|
||||
// ── The accent ──────────────────────────────────────────────────────────
|
||||
//
|
||||
// `accent` is the primary and carries every state meaning (focused, active,
|
||||
|
||||
Reference in New Issue
Block a user