pre-capture lock screen screenshots via hidden window and ScreenshotService
This commit is contained in:
parent
62cd0f9a76
commit
73e480d14b
7 changed files with 129 additions and 10 deletions
|
|
@ -20,12 +20,21 @@ Scope {
|
|||
lock: _lock
|
||||
}
|
||||
|
||||
// Capture screenshots before locking, with timeout for security
|
||||
Timer {
|
||||
id: _lockTimeout
|
||||
interval: 150
|
||||
onTriggered: _lock.locked = true
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: S.LockService
|
||||
|
||||
function onLockRequested() {
|
||||
if (S.LockService.enabled)
|
||||
_lock.locked = true;
|
||||
if (!S.LockService.enabled)
|
||||
return;
|
||||
S.ScreenshotService.capture(Quickshell.screens.length);
|
||||
_lockTimeout.start();
|
||||
}
|
||||
|
||||
function onUnlockRequested() {
|
||||
|
|
@ -39,6 +48,17 @@ Scope {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: S.ScreenshotService
|
||||
|
||||
function onCaptureComplete() {
|
||||
if (_lockTimeout.running) {
|
||||
_lockTimeout.stop();
|
||||
_lock.locked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _lock
|
||||
|
||||
|
|
|
|||
|
|
@ -15,15 +15,16 @@ WlSessionLockSurface {
|
|||
|
||||
property real _unlockFade: 1
|
||||
|
||||
// Clear desktop screenshot - visible immediately
|
||||
ScreencopyView {
|
||||
// Clear desktop screenshot from ScreenshotService - visible immediately
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
captureSource: root.screen
|
||||
visible: S.Modules.lock.screenshot ?? true
|
||||
source: S.ScreenshotService.get(root.screen?.name ?? "")
|
||||
visible: (S.Modules.lock.screenshot ?? true) && source !== ""
|
||||
opacity: _unlockFade
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
}
|
||||
|
||||
// Overlay group: blur + dim + hexes, revealed per-pixel by wave position
|
||||
// Overlay group: blur + hexes, revealed per-pixel by wave position
|
||||
Item {
|
||||
id: _overlay
|
||||
anchors.fill: parent
|
||||
|
|
@ -47,10 +48,11 @@ WlSessionLockSurface {
|
|||
}
|
||||
|
||||
// Blurred screenshot
|
||||
ScreencopyView {
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
captureSource: root.screen
|
||||
visible: S.Modules.lock.screenshot ?? true
|
||||
source: S.ScreenshotService.get(root.screen?.name ?? "")
|
||||
visible: (S.Modules.lock.screenshot ?? true) && source !== ""
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: MultiEffect {
|
||||
|
|
|
|||
44
shell/modules/ScreenCapture.qml
Normal file
44
shell/modules/ScreenCapture.qml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import "../services" as S
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
|
||||
required property var screen
|
||||
|
||||
color: "transparent"
|
||||
WlrLayershell.layer: WlrLayer.Background
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.namespace: "nova-screenshot"
|
||||
mask: Region {}
|
||||
|
||||
anchors.top: true
|
||||
anchors.left: true
|
||||
anchors.right: true
|
||||
anchors.bottom: true
|
||||
|
||||
ScreencopyView {
|
||||
id: _capture
|
||||
anchors.fill: parent
|
||||
captureSource: root.screen
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: S.ScreenshotService
|
||||
function onCaptureRequested() {
|
||||
_capture.captureFrame();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _capture
|
||||
function onHasContentChanged() {
|
||||
if (_capture.hasContent)
|
||||
_capture.grabToImage(result => {
|
||||
S.ScreenshotService.store(root.screen.name, result);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ PowerModule 1.0 PowerModule.qml
|
|||
PowerProfileModule 1.0 PowerProfileModule.qml
|
||||
PrivacyModule 1.0 PrivacyModule.qml
|
||||
ProcessList 1.0 ProcessList.qml
|
||||
ScreenCapture 1.0 ScreenCapture.qml
|
||||
ScreenCorners 1.0 ScreenCorners.qml
|
||||
TemperatureModule 1.0 TemperatureModule.qml
|
||||
ThemedIcon 1.0 ThemedIcon.qml
|
||||
|
|
|
|||
44
shell/services/ScreenshotService.qml
Normal file
44
shell/services/ScreenshotService.qml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
// Screen name -> in-memory image URL from grabToImage
|
||||
property var screenshots: ({})
|
||||
property int _pending: 0
|
||||
|
||||
// Keep references to prevent garbage collection of the image data
|
||||
property var _results: ({})
|
||||
|
||||
signal captureRequested
|
||||
signal captureComplete
|
||||
|
||||
function capture(screenCount) {
|
||||
_pending = screenCount;
|
||||
if (_pending === 0) {
|
||||
captureComplete();
|
||||
return;
|
||||
}
|
||||
captureRequested();
|
||||
}
|
||||
|
||||
function store(screenName, result) {
|
||||
const s = Object.assign({}, screenshots);
|
||||
s[screenName] = result.url;
|
||||
screenshots = s;
|
||||
|
||||
const r = Object.assign({}, _results);
|
||||
r[screenName] = result;
|
||||
_results = r;
|
||||
|
||||
_pending--;
|
||||
if (_pending <= 0)
|
||||
captureComplete();
|
||||
}
|
||||
|
||||
function get(screenName) {
|
||||
return screenshots[screenName] || "";
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ singleton NetworkService 1.0 NetworkService.qml
|
|||
singleton NiriIpc 1.0 NiriIpc.qml
|
||||
singleton NotifService 1.0 NotifService.qml
|
||||
singleton PowerProfileService 1.0 PowerProfileService.qml
|
||||
singleton ScreenshotService 1.0 ScreenshotService.qml
|
||||
singleton SystemStats 1.0 SystemStats.qml
|
||||
singleton Theme 1.0 Theme.qml
|
||||
# keep-sorted end
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ ShellRoot {
|
|||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
active: Modules.lock.enable && (Modules.lock.screenshot ?? true)
|
||||
ScreenCapture {
|
||||
screen: scope.modelData
|
||||
}
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
active: Modules.screenCorners.enable
|
||||
ScreenCorners {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue