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
123 lines
4.5 KiB
QML
123 lines
4.5 KiB
QML
// Dock.
|
|
//
|
|
// The pinned applications come first because they are what the Dock is; the
|
|
// behaviour card below is how it gets out of the way. The dock timings used to
|
|
// be shown here as text -- "Instant", "250 ms" -- even though they were already
|
|
// stored, mutable integers. They are controls now.
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import qs.config
|
|
import qs.services
|
|
|
|
SettingsPage {
|
|
id: root
|
|
|
|
// Turning the last screen off would leave no dock anywhere and no obvious
|
|
// way back, so the final one cannot be removed -- it collapses to "every
|
|
// screen" instead, which is the same thing on one display and recoverable
|
|
// on several.
|
|
function toggleDockScreen(name: string): void {
|
|
const all = Quickshell.screens.map(screen => String(screen.name));
|
|
const current = Settings.dockScreens.length === 0
|
|
? all.slice()
|
|
: Settings.dockScreens.map(String);
|
|
const at = current.indexOf(name);
|
|
let next = current.slice();
|
|
if (at >= 0)
|
|
next.splice(at, 1);
|
|
else
|
|
next.push(name);
|
|
if (next.length === 0 || next.length === all.length)
|
|
next = [];
|
|
DesktopPreferences.set("dockScreens", next);
|
|
}
|
|
|
|
title: "Dock"
|
|
lede: "What sits in the Dock, and how it behaves when you are not using it."
|
|
|
|
SettingsCard {
|
|
title: "Pinned applications"
|
|
subtitle: "Drag an icon to reorder it, hover for the unpin button. Order here is the order on screen; these stay whether or not the application is running."
|
|
|
|
DockPinsStrip {
|
|
id: pins
|
|
width: parent.width
|
|
}
|
|
|
|
Item { width: 1; height: 13 }
|
|
|
|
DockAppPicker {
|
|
width: parent.width
|
|
pinned: pins.pinned
|
|
onPicked: id => pins.add(id)
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
title: "Behavior"
|
|
|
|
ChoiceRow { setting: "dockPosition" }
|
|
|
|
// One row per connected screen. Nothing selected means every screen,
|
|
// which is stated rather than left as an empty list somebody has to
|
|
// interpret -- and it is what a single-monitor machine should do
|
|
// without being configured at all.
|
|
SettingRow {
|
|
label: "Screens"
|
|
detail: Settings.dockScreens.length === 0
|
|
? "On every display"
|
|
: "On " + Settings.dockScreens.length + " of "
|
|
+ Quickshell.screens.length + " displays"
|
|
visible: Quickshell.screens.length > 1
|
|
controlWidth: 260
|
|
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 7
|
|
|
|
Repeater {
|
|
model: Quickshell.screens
|
|
|
|
delegate: Rectangle {
|
|
id: screenPill
|
|
|
|
required property var modelData
|
|
|
|
readonly property string screenName: String(screenPill.modelData.name ?? "")
|
|
// An empty list means all, so every pill reads as on.
|
|
readonly property bool on: Settings.dockScreens.length === 0
|
|
|| Settings.dockScreens.indexOf(screenPill.screenName) >= 0
|
|
|
|
width: pillLabel.implicitWidth + 20
|
|
height: 28
|
|
radius: 8
|
|
color: screenPill.on ? Theme.alpha(Theme.accent, 0.22)
|
|
: Theme.alpha(Theme.fg, 0.06)
|
|
border.width: screenPill.on ? 1 : 0
|
|
border.color: Theme.alpha(Theme.accent, 0.5)
|
|
|
|
Text {
|
|
id: pillLabel
|
|
anchors.centerIn: parent
|
|
text: screenPill.screenName
|
|
color: screenPill.on ? Theme.fg : Theme.fgDim
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
}
|
|
|
|
HoverHandler { cursorShape: Qt.PointingHandCursor }
|
|
TapHandler { onTapped: root.toggleDockScreen(screenPill.screenName) }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ToggleRow { setting: "dockAutohide" }
|
|
SliderRow { setting: "dockRevealDelayMs"; zeroLabel: "Instant" }
|
|
SliderRow { setting: "dockHideDelayMs"; zeroLabel: "Instant" }
|
|
SliderRow { setting: "dockIconSize"; divider: false }
|
|
}
|
|
}
|