From the 2026-06-15 hardware-test feedback (redesign passed end-to-end):
- Glyphs: map the 12 unmapped additions-page icon names (brush, cloud_sync,
data_object, deployed_code, movie_edit, neurology, psychology, robot_2,
smart_toy, sports_esports, videocam, vpn_lock) so the nexus Additional
Software page stops rendering "?" boxes. Verified Nerd Font codepoints.
- Glyphs: cp() now uses String.fromCodePoint, not fromCharCode — the 5 MDI
glyphs above 0xFFFF were being truncated by the 16-bit fromCharCode.
- Shortcuts: Super+Escape (session) now drives the redesigned full-screen
Power Menu via NsShell.toggle("power"); old caelestia session panel is
now dead code.
- nexus LanguageAndRegion: replace the "coming soon" weather placeholder with
a real location input bound to GlobalConfig.services.weatherLocation (the
Weather backend already geocodes / IP-auto-detects).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
166 lines
4.9 KiB
QML
166 lines
4.9 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Caelestia
|
|
import qs.components.misc
|
|
import qs.services
|
|
import qs.modules.nexus
|
|
|
|
Scope {
|
|
id: root
|
|
|
|
property bool launcherInterrupted
|
|
readonly property bool hasFullscreen: Hypr.focusedWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen > 1) ?? false
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "nexus"
|
|
description: "Open nexus"
|
|
onPressed: WindowFactory.create()
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "showall"
|
|
description: "Toggle launcher, dashboard and osd"
|
|
onPressed: {
|
|
if (root.hasFullscreen)
|
|
return;
|
|
const v = Visibilities.getForActive();
|
|
v.launcher = v.dashboard = v.osd = v.utilities = !(v.launcher || v.dashboard || v.osd || v.utilities);
|
|
}
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "dashboard"
|
|
description: "Toggle dashboard"
|
|
onPressed: {
|
|
if (root.hasFullscreen)
|
|
return;
|
|
const visibilities = Visibilities.getForActive();
|
|
visibilities.dashboard = !visibilities.dashboard;
|
|
}
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "session"
|
|
description: "Toggle session menu"
|
|
onPressed: {
|
|
if (root.hasFullscreen)
|
|
return;
|
|
// NoSignal: drive the redesigned full-screen Power Menu (NsOverlay),
|
|
// not the old caelestia session panel (now dead code).
|
|
NsShell.toggle("power", 0);
|
|
}
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "launcher"
|
|
description: "Toggle launcher"
|
|
onPressed: root.launcherInterrupted = false
|
|
onReleased: {
|
|
if (!root.launcherInterrupted && !root.hasFullscreen) {
|
|
const visibilities = Visibilities.getForActive();
|
|
visibilities.launcher = !visibilities.launcher;
|
|
}
|
|
root.launcherInterrupted = false;
|
|
}
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "launcherInterrupt"
|
|
description: "Interrupt launcher keybind"
|
|
onPressed: root.launcherInterrupted = true
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "sidebar"
|
|
description: "Toggle sidebar"
|
|
onPressed: {
|
|
if (root.hasFullscreen)
|
|
return;
|
|
const visibilities = Visibilities.getForActive();
|
|
visibilities.sidebar = !visibilities.sidebar;
|
|
}
|
|
}
|
|
|
|
// qmllint disable unresolved-type
|
|
CustomShortcut {
|
|
// qmllint enable unresolved-type
|
|
name: "utilities"
|
|
description: "Toggle utilities"
|
|
onPressed: {
|
|
if (root.hasFullscreen)
|
|
return;
|
|
const visibilities = Visibilities.getForActive();
|
|
visibilities.utilities = !visibilities.utilities;
|
|
}
|
|
}
|
|
|
|
IpcHandler {
|
|
function toggle(drawer: string): void {
|
|
if (list().split("\n").includes(drawer)) {
|
|
if (root.hasFullscreen && ["launcher", "session", "dashboard"].includes(drawer))
|
|
return;
|
|
const visibilities = Visibilities.getForActive();
|
|
visibilities[drawer] = !visibilities[drawer];
|
|
} else {
|
|
console.warn(lc, `Drawer "${drawer}" does not exist`);
|
|
}
|
|
}
|
|
|
|
function list(): string {
|
|
const visibilities = Visibilities.getForActive();
|
|
return Object.keys(visibilities).filter(k => typeof visibilities[k] === "boolean").join("\n");
|
|
}
|
|
|
|
target: "drawers"
|
|
}
|
|
|
|
IpcHandler {
|
|
function open(): void {
|
|
WindowFactory.create();
|
|
}
|
|
|
|
target: "nexus"
|
|
}
|
|
|
|
IpcHandler {
|
|
function info(title: string, message: string, icon: string): void {
|
|
Toaster.toast(title, message, icon, Toast.Info);
|
|
}
|
|
|
|
function success(title: string, message: string, icon: string): void {
|
|
Toaster.toast(title, message, icon, Toast.Success);
|
|
}
|
|
|
|
function warn(title: string, message: string, icon: string): void {
|
|
Toaster.toast(title, message, icon, Toast.Warning);
|
|
}
|
|
|
|
function error(title: string, message: string, icon: string): void {
|
|
Toaster.toast(title, message, icon, Toast.Error);
|
|
}
|
|
|
|
target: "toaster"
|
|
}
|
|
|
|
LoggingCategory {
|
|
id: lc
|
|
|
|
name: "caelestia.qml.shortcuts"
|
|
defaultLogLevel: LoggingCategory.Info
|
|
}
|
|
}
|