Repository navigation
Expand file tree
/
Copy pathOverlay.qml
More file actions
168 lines (158 loc) · 7.39 KB
/
Copy pathOverlay.qml
File metadata and controls
168 lines (158 loc) · 7.39 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import qs.Commons
import qs.Ui
// Summonable fullscreen twin of the desk, for when windows cover the
// wallpaper. Bind e.g. SUPER+D → `omarchy-shell shell toggle nixfred.infomarchy`.
// Esc or a click outside the cards closes it.
Scope {
id: root
property bool opened: false
InfoModel { id: infoModel; refreshMs: 3000; active: root.opened; instance: "overlay"; demoMode: demoMarker.present; ollamaHost: dashboardSettings.ollamaHost; usageVisible: root.opened && dashboardSettings.ready && dashboardSettings.dashboardVisible && dashboardSettings.sectionEnabled("usage") }
InfoSettings { id: dashboardSettings }
// Demo mode is set on the wallpaper service; a screenshot taken with the
// overlay open must not leak live prompts. Mirror the runtime marker.
FileView {
id: demoMarker
property bool present: false
path: (Quickshell.env("XDG_RUNTIME_DIR") || ("/run/user/" + Quickshell.env("UID"))) + "/infomarchy-demo"
watchChanges: true
printErrors: false
onLoaded: present = true
onLoadFailed: present = false
onFileChanged: reload()
}
// SUPER+D means "show me the desktop": the real wallpaper, dimmed exactly as
// the background layer dims it, with the dashboard on top only when SUPER+I
// has it visible. The old 88% theme-colour scrim hid the wallpaper photo and
// ignored SUPER+I, so toggling the dashboard while the overlay was open
// changed the desk underneath without changing what was on screen.
property string background: ""
readonly property real wallpaperOpacity: 0.32
// Same rule as the wallpaper layer: Omarchy decides what a video is, and the
// literal list is only the fallback for an Omarchy whose Util predates them.
readonly property bool videoBackground: root.isVideo(root.background)
function isVideo(path) {
if (typeof Util.isVideoPath === "function") return Util.isVideoPath(path)
return /\.(mp4|m4v|mov|webm|mkv|avi)$/i.test(String(path || ""))
}
Process {
id: backgroundLink
command: ["readlink", "-f", Quickshell.env("HOME") + "/.local/state/omarchy/current/background"]
stdout: StdioCollector { onStreamFinished: root.background = String(text || "").trim() }
}
function open(payload) {
root.opened = true
backgroundLink.running = true
demoMarker.reload()
infoModel.refresh()
}
function close() { root.opened = false }
function toggle(payload) { if (root.opened) close(); else open(payload) }
// `omarchy-shell shell call nixfred.infomarchy refresh` hits the overlay
// loader, not the wallpaper IpcHandler.
function refresh() { infoModel.refresh() }
function hardRefresh() { infoModel.hardRefresh() }
Variants {
model: Quickshell.screens
PanelWindow {
id: panel
required property var modelData
screen: modelData
visible: root.opened && !remapGuard.remapping
anchors { top: true; bottom: true; left: true; right: true }
color: "transparent"
updatesEnabled: root.opened
WlrLayershell.namespace: "infomarchy-overlay"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.keyboardFocus: root.opened ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
exclusionMode: ExclusionMode.Ignore
ScreenMoveRemap {
id: remapGuard
window: panel
}
Rectangle {
id: keyCatcher
anchors.fill: parent
color: infoModel.themeBackground
// The wallpaper may be a video, which an Image cannot decode; each
// surface is given a source only for its own kind of file. See
// BackgroundWallpaper.qml for why the player is loaded by URL.
Item {
anchors.fill: parent
opacity: dashboardSettings.ready && dashboardSettings.dashboardVisible ? root.wallpaperOpacity : 1.0
Behavior on opacity { NumberAnimation { duration: 300 } }
WaveWallpaper {
anchors.fill: parent
visible: !root.videoBackground
source: root.videoBackground ? "" : Util.fileUrl(root.background)
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: true
playing: root.opened
}
Loader {
id: videoWallpaper
anchors.fill: parent
// The overlay covers the desk's own player, so this one decodes
// only while it is on screen.
active: root.videoBackground && root.opened
source: "BackgroundWallpaper.qml"
}
Binding {
target: videoWallpaper.item
property: "path"
value: root.background
when: videoWallpaper.item !== null && root.videoBackground
restoreMode: Binding.RestoreNone
}
// The player stopped hardcoding silence when the desk gained a sound
// switch, and that switch is bound on the desk's surface only. This
// surface has no switch, so without an explicit binding the overlay
// would fall back to whatever BackgroundMedia defaults to. Say it.
Binding {
target: videoWallpaper.item
property: "audioEnabled"
value: false
when: videoWallpaper.item !== null
}
}
focus: root.opened
// Esc closes ABOUT first, then the overlay — one panel deep, so a
// reader who opened it does not lose the whole desk on the way out.
Keys.onEscapePressed: { if (infoView.settingsOpen) infoView.settingsOpen = false; else if (infoView.aboutOpen) infoView.aboutOpen = false; else root.close() }
Keys.onPressed: function(event) {
if ((event.modifiers & Qt.MetaModifier) && event.key === Qt.Key_I) {
if (event.modifiers & Qt.ShiftModifier) {
if (!event.isAutoRepeat) dashboardSettings.togglePrivacyMode()
} else dashboardSettings.toggleDashboardVisible()
event.accepted = true
return
}
if (event.key >= Qt.Key_0 && event.key <= Qt.Key_9) { var i = event.key === Qt.Key_0 ? 9 : event.key - Qt.Key_1; var def = dashboardSettings.definitions[i]; if (def) dashboardSettings.toggleSection(def.id); event.accepted = true; return }
if (event.key === Qt.Key_J || event.key === Qt.Key_Down) { infoView.keyboardStep(1); event.accepted = true; return }
if (event.key === Qt.Key_K || event.key === Qt.Key_Up) { infoView.keyboardStep(-1); event.accepted = true; return }
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { infoView.activateKeyboardSession(); event.accepted = true; return }
if (event.key === Qt.Key_A) { infoView.clearActivityFilter(); event.accepted = true }
}
// Exclusive keyboard focus on the layer is not enough — Qt still
// needs an item with activeFocus or Esc never fires.
onVisibleChanged: if (visible) Qt.callLater(function() { keyCatcher.forceActiveFocus() })
MouseArea { anchors.fill: parent; onClicked: root.close() }
InfoView {
id: infoView
anchors.fill: parent
desk: infoModel
settings: dashboardSettings
interactive: true
topInset: Style.spacing.xl
// SUPER+I applies here too: hidden dashboard = plain wallpaper, same as the desk.
visible: dashboardSettings.ready && dashboardSettings.dashboardVisible
onNavigated: root.close()
}
}
}
}
}