1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import QtQuick
import "modules/appearance"
import "modules/bluetooth"
import "modules/kdeconnect"
import "modules/mail"
import "modules/network"
import "modules/sound"
import "modules/status"
import "modules/vm"
ShellRoot {
// Quickshell exits once no window is visible, and the drawer is closed
// most of the time. See AGENTS.md.
//
// It is also the window the idle inhibitor attaches to: IdleInhibitor
// needs a non-null window, and this is the one window that exists for
// the whole life of the shell.
PanelWindow {
id: keepalive
visible: true
implicitWidth: 1
implicitHeight: 1
color: "transparent"
exclusionMode: ExclusionMode.Ignore
mask: Region {}
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
// The singleton has no window of its own and IdleInhibitor needs one.
Component.onCompleted: Status.inhibitWindow = keepalive
}
Drawer {
id: drawer
modules: [
SoundModule {},
NetworkModule {},
BluetoothModule {},
KdeConnectModule {},
MailModule {},
AppearanceModule {},
StatusModule {},
VmModule {},
]
}
// The waybar launcher and the deep-link keybinds all reach this:
// qs -p <this dir> ipc call drawer toggle -> the grid
// qs -p <this dir> ipc call drawer open mail -> the mail page
// Quickshell 0.3.1 IPC requires every declared argument to be present,
// and a parameter with a JS default registers as QVariant, which IPC
// rejects. So the page name cannot be optional: `open` always takes a
// page, and the page-less grid is `toggle`, the zero-argument shape the
// appearance shell uses for its routes and the waybar launcher calls.
IpcHandler {
target: "drawer"
function open(page: string) { drawer.show(page); }
function toggle() { drawer.toggle(""); }
function close() { drawer.close(); }
}
}
|