diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-17 13:11:22 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-17 13:11:22 +0200 |
| commit | 9eb8878da78a32ebc707075008a24ba78cf2d901 (patch) | |
| tree | 0945a42b8411d36a708457040841d2a13da4409d /desktop | |
| parent | 611fb6b05f5820d8acae823cbcddd19310f46c74 (diff) | |
| download | quickshell-9eb8878da78a32ebc707075008a24ba78cf2d901.tar.gz quickshell-9eb8878da78a32ebc707075008a24ba78cf2d901.zip | |
island: place the OBS pill and pulse the sliver while recording
Diffstat (limited to 'desktop')
| -rw-r--r-- | desktop/island/Island.qml | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/desktop/island/Island.qml b/desktop/island/Island.qml index 5efe9bf..04a6350 100644 --- a/desktop/island/Island.qml +++ b/desktop/island/Island.qml @@ -42,12 +42,12 @@ PanelWindow { WlrLayershell.namespace: "quickshell-island" WlrLayershell.keyboardFocus: panel !== "" ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None - // "", "sound" or "calendar". + // "", "sound", "calendar" or "obs". property string panel: "" // --- reveal and hide ------------------------------------------------- - readonly property bool hovered: sliverHit.containsMouse || clock.hovered || status.hovered || media.hovered + readonly property bool hovered: sliverHit.containsMouse || clock.hovered || status.hovered || media.hovered || obs.hovered property bool shown: false // A tray menu is a separate popup: moving onto it un-hovers the pills, @@ -129,6 +129,13 @@ PanelWindow { // --- dismissal ------------------------------------------------------- + // OBS quitting with its panel open would leave the island held open by a + // pill that no longer exists. + Connections { + target: Obs + function onConnectedChanged() { if (!Obs.connected && win.panel === "obs") win.panel = ""; } + } + HyprlandFocusGrab { windows: [win] active: win.panel !== "" @@ -153,6 +160,7 @@ PanelWindow { Region { item: clock; intersection: Intersection.Combine } Region { item: status; intersection: Intersection.Combine } Region { item: media.visible ? media : null; intersection: Intersection.Combine } + Region { item: obs.visible ? obs : null; intersection: Intersection.Combine } } // The visible sliver: neutral at rest, the capture colours while @@ -181,6 +189,27 @@ PanelWindow { } } + // Recording: a red pulse over the sliver, steady and dim while paused. + // Red alone would not say it: OBS's screen source already lights the + // privacy sliver's red segment whenever OBS is open. + Rectangle { + x: sliver.x + y: 0 + width: sliver.width + height: sliver.height + radius: 2 + color: Theme.red + visible: Obs.recording + property real pulse: 1 + opacity: Obs.paused ? 0.4 : pulse + SequentialAnimation on pulse { + running: Obs.recording && !Obs.paused + loops: Animation.Infinite + NumberAnimation { to: 0.25; duration: 700; easing.type: Easing.InOutSine } + NumberAnimation { to: 1; duration: 700; easing.type: Easing.InOutSine } + } + } + MouseArea { id: sliverHit x: win.cx - width / 2 @@ -297,4 +326,16 @@ PanelWindow { y: -height + (win.top + height) * win.reveal opacity: Math.min(1, win.reveal * 2) } + + // While OBS runs; right of the status pill, following it as the sound + // panel widens it. + ObsPill { + id: obs + visible: Obs.connected + panel: win.panel + onOpenPanel: win.panel = "obs" + x: win.cx - width / 2 + (win.gap * 1.5 + status.width + width / 2) * win.reveal + y: -height + (win.top + height) * win.reveal + opacity: Math.min(1, win.reveal * 2) + } } |
