Introduce the desktop to somebody who has just met it

Thirty settings pages is the opposite of the usual problem: a person
arriving from GNOME, macOS or Windows cannot tell which few things
matter. This is those few, once, on the first start.

Not a tour. Nobody reads a tour, and a multi-step wizard on a desktop
somebody just installed is one more thing between them and using it.
One card, five keys, and a way out.

The chords come from the live keymap rather than being written here, so
a machine whose owner has already rebound something teaches what they
actually have. A welcome screen is the one surface read by somebody
with no way to tell it is wrong, which is exactly why it must not be.

Two deliberate departures from how every other surface behaves. It does
not close on a click outside, because a stray click in the first thirty
seconds would throw away the only explanation on offer. And dismissing
by any route marks it seen, Escape included, because a desktop that
reintroduces itself every login has failed to take no for an answer.
It stays reachable from the launcher afterwards, since the moment
somebody wants it again is exactly when a one-shot has thrown it away.

Also teaches the keymap to spell punctuation: slash, period, comma and
the rest were rendering as their raw keysym names, so the welcome
screen offered "Super + slash" and the cheatsheet agreed with it.
This commit is contained in:
Gabriel Brown
2026-08-22 01:00:18 -04:00
parent 9fbbdd902b
commit 9202697734
10 changed files with 462 additions and 3 deletions
+16
View File
@@ -35,6 +35,7 @@ import qs.modules.notifications
import qs.modules.capture
import qs.modules.powermenu
import qs.modules.cheatsheet
import qs.modules.welcome
import qs.modules.clipboard
import qs.modules.datemenu
import qs.modules.focus
@@ -100,6 +101,7 @@ ShellRoot {
DateMenu { id: dateMenu }
ClipboardPanel {}
Cheatsheet {}
Welcome {}
CaptureOverlay {}
IntelligenceResult {}
ActivityPanel {}
@@ -146,6 +148,20 @@ ShellRoot {
}
}
// Shown once on a fresh machine, and reachable afterwards -- the moment
// somebody wants it again is exactly when a one-shot has thrown it away.
IpcHandler {
target: "welcome"
function open(): void { ShellState.open("welcome"); }
function close(): void { ShellState.close(); }
function status(): string {
return JSON.stringify({
open: ShellState.welcomeOpen,
seen: DesktopPreferences.get("welcomeSeen") === true
});
}
}
IpcHandler {
target: "overview"
function toggle(): void { ShellState.toggle("overview"); }