Files
Panama/config/dot/quickshell/modules/settings/SyncPage.qml
T
Gabriel Brown f8f5b25510 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
2026-08-24 04:28:20 -04:00

135 lines
5.2 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Sync & Backup.
//
// Three answers to three different questions, which is why they sit together:
// carrying settings to a different machine, putting this machine's settings
// back as they were, and throwing them away.
//
// The backups here are copies of the preferences file. They are not the btrfs
// snapshots one tab over in System Snapshots, which put the whole filesystem
// back -- the card says so, because the two used to share the word "Snapshots"
// and nothing distinguished them.
import QtQuick
import qs.config
import qs.services
SettingsPage {
id: root
title: "Sync & Backup"
lede: "Carry your settings to another machine, keep copies of them, or start over."
// Distinct from the backups below, which put THIS machine back as it was.
// This carries settings to a different one, and deliberately leaves behind
// anything that describes hardware.
SettingsCard {
title: "Carry settings to another machine"
subtitle: SettingsSync.lastError !== ""
? SettingsSync.lastError
: "Everything except what describes this machine: the display arrangement stays here."
ActionRow {
label: "Export"
detail: SettingsSync.lastAction === "export" && SettingsSync.carried > 0
? SettingsSync.carried + " settings written to " + SettingsSync.defaultPath
: "Writes " + SettingsSync.defaultPath
action: "Export"
enabled: !SettingsSync.busy
onTriggered: SettingsSync.exportTo(SettingsSync.defaultPath)
}
ActionRow {
label: "See what an import would change"
detail: SettingsSync.previewed
? SettingsSync.changes.length + " would change, "
+ SettingsSync.skipped.length + " skipped"
: "Reads " + SettingsSync.defaultPath + " without applying anything"
action: "Preview"
enabled: !SettingsSync.busy
onTriggered: SettingsSync.preview(SettingsSync.defaultPath)
}
// Only offered once a preview has said what it would do. Importing
// settings sight unseen is how somebody ends up wondering why their
// desktop changed.
ActionRow {
visible: SettingsSync.previewed && SettingsSync.changes.length > 0
label: "Apply those " + SettingsSync.changes.length + " changes"
detail: "Settings the file does not mention are left alone"
action: "Import"
enabled: !SettingsSync.busy
onTriggered: SettingsSync.importFrom(SettingsSync.defaultPath)
}
Repeater {
model: SettingsSync.previewed ? SettingsSync.skipped : []
delegate: TextRow {
required property var modelData
width: parent.width
label: String(modelData.key ?? "")
detail: "Skipped: " + String(modelData.reason ?? "")
value: ""
}
}
TextRow {
visible: SettingsSync.lastAction === "import" && SettingsSync.lastError === ""
label: SettingsSync.applied === 0
? "Nothing needed changing"
: SettingsSync.applied + " settings applied"
detail: "From " + (SettingsSync.exportedFrom || "the export")
value: ""
divider: false
}
}
SettingsCard {
title: "Settings backups"
subtitle: SettingsBackup.lastError !== ""
? SettingsBackup.lastError
: "Copies of your preferences, not of the filesystem — System Snapshots keeps the btrfs ones. Your whole desktop configuration is a single file, so a backup is a copy of it. Restoring also backs up what it replaces, so it is itself undoable."
ActionRow {
label: "Back up current settings"
detail: SettingsBackup.snapshots.length === 0
? "No backups yet"
: SettingsBackup.snapshots.length + (SettingsBackup.snapshots.length === 1 ? " backup kept" : " backups kept") + ", newest first"
action: "Back up now"
enabled: !SettingsBackup.busy
divider: SettingsBackup.snapshots.length > 0
onTriggered: SettingsBackup.save()
}
Repeater {
id: snapshotRows
model: SettingsBackup.snapshots
ActionRow {
required property var modelData
required property int index
label: modelData.when
detail: modelData.keys + " settings"
action: "Restore"
enabled: !SettingsBackup.busy
divider: index < snapshotRows.count - 1
onTriggered: SettingsBackup.restore(modelData.name)
}
}
}
SettingsCard {
title: "Reset"
subtitle: "Restores the appearance, dock, clock, focus, and display policy, and clears your Home accessory arrangement. Pinned applications, files, and paired devices are not changed."
ActionRow {
label: "Restore defaults"
detail: "Applies immediately, including to the compositor"
action: "Restore defaults"
divider: false
onTriggered: SystemSettings.restoreDefaults()
}
}
}