From ca9c06b689926ed0d5c04b535616f3385ad222f1 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Thu, 12 Jun 2025 23:43:03 +1000 Subject: dashboard: not full rounding for face --- modules/dashboard/dash/User.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules') diff --git a/modules/dashboard/dash/User.qml b/modules/dashboard/dash/User.qml index c7d2bfd..f1b9b18 100644 --- a/modules/dashboard/dash/User.qml +++ b/modules/dashboard/dash/User.qml @@ -10,13 +10,13 @@ Row { id: root padding: Appearance.padding.large - spacing: Appearance.spacing.large + spacing: Appearance.spacing.normal StyledClippingRect { implicitWidth: info.implicitHeight implicitHeight: info.implicitHeight - radius: Appearance.rounding.full + radius: Appearance.rounding.large color: Colours.palette.m3surfaceContainerHigh MaterialIcon { -- cgit v1.2.3-freya From 5da1b64da09e4c12bf850750cd1cf18b5bab3210 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Fri, 13 Jun 2025 23:31:47 +1000 Subject: internal: better caching impl WARNING: causes blocking when caching image on first load --- modules/background/Wallpaper.qml | 14 +++----- run.fish | 3 +- services/Thumbnailer.qml | 72 ---------------------------------------- utils/Paths.qml | 16 +++++++++ widgets/CachingImage.qml | 42 +++++++++++++++++++++-- 5 files changed, 61 insertions(+), 86 deletions(-) delete mode 100644 services/Thumbnailer.qml (limited to 'modules') diff --git a/modules/background/Wallpaper.qml b/modules/background/Wallpaper.qml index 2734034..f4e3243 100644 --- a/modules/background/Wallpaper.qml +++ b/modules/background/Wallpaper.qml @@ -8,7 +8,7 @@ import QtQuick Item { id: root - property url source: Wallpapers.current ? `file://${Wallpapers.current}` : "" + property string source: Wallpapers.current property Image current: one anchors.fill: parent @@ -32,20 +32,14 @@ Item { id: img function update(): void { - const srcPath = `${root.source}`.slice(7); - if (thumbnail.originalPath === srcPath) { + if (path === root.source) root.current = this; - } else - path = srcPath; + else + path = root.source; } anchors.fill: parent - loadOriginal: true - asynchronous: true - cache: false - fillMode: Image.PreserveAspectCrop - opacity: 0 scale: Wallpapers.showPreview ? 1 : 0.8 diff --git a/run.fish b/run.fish index 2e6c039..ada4152 100755 --- a/run.fish +++ b/run.fish @@ -4,5 +4,6 @@ set -l dbus 'quickshell.dbus.properties.warning = false;quickshell.dbus.dbusmenu set -l notifs 'quickshell.service.notifications.warning = false' # Notification server warnings on reload set -l sni 'quickshell.service.sni.host.warning = false' # StatusNotifierItem warnings on reload set -l process 'QProcess: Destroyed while process' # Long running processes on reload +set -l cache "Cannot open: file://$XDG_CACHE_HOME/caelestia/imagecache/" -qs -p (dirname (status filename)) --log-rules "$dbus;$notifs;$sni" | grep -vE -e $process +qs -p (dirname (status filename)) --log-rules "$dbus;$notifs;$sni" | grep -vF -e $process -e $cache diff --git a/services/Thumbnailer.qml b/services/Thumbnailer.qml deleted file mode 100644 index 6a6066c..0000000 --- a/services/Thumbnailer.qml +++ /dev/null @@ -1,72 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound - -import "root:/utils" -import Quickshell -import Quickshell.Io -import QtQuick - -Singleton { - id: root - - readonly property string thumbDir: `${Paths.cache}/thumbnails`.slice(7) - - function go(obj: var): var { - return thumbComp.createObject(obj, { - originalPath: obj.path, - width: obj.width, - height: obj.height, - loadOriginal: obj.loadOriginal - }); - } - - component Thumbnail: QtObject { - id: obj - - required property string originalPath - required property int width - required property int height - required property bool loadOriginal - - property string path - - readonly property Process proc: Process { - running: true - command: ["fish", "-c", ` -set -l path "${root.thumbDir}/$(sha1sum ${obj.originalPath} | cut -d ' ' -f 1)@${obj.width}x${obj.height}-exact.png" -if test -f $path - echo $path -else - echo 'start' - set -l size (identify -ping -format '%w\n%h' ${obj.originalPath}) - if test $size[1] -gt ${obj.width} -o $size[2] -gt ${obj.height} - magick ${obj.originalPath} -${obj.width > 1024 || obj.height > 1024 ? "resize" : "thumbnail"} ${obj.width}x${obj.height}^ -background none -gravity center -extent ${obj.width}x${obj.height} -unsharp 0x.5 $path - else - cp ${obj.originalPath} $path - end - echo $path -end`] - stdout: SplitParser { - onRead: data => { - if (data === "start") { - if (obj.loadOriginal) - obj.path = obj.originalPath; - } else { - obj.path = data; - } - } - } - } - - function reload(): void { - proc.signal(9); - proc.running = true; - } - } - - Component { - id: thumbComp - - Thumbnail {} - } -} diff --git a/utils/Paths.qml b/utils/Paths.qml index 011bb1f..88267ea 100644 --- a/utils/Paths.qml +++ b/utils/Paths.qml @@ -1,6 +1,7 @@ pragma Singleton import Quickshell +import Quickshell.Io import Qt.labs.platform Singleton { @@ -12,4 +13,19 @@ Singleton { readonly property url data: `${StandardPaths.standardLocations(StandardPaths.GenericDataLocation)[0]}/caelestia` readonly property url state: `${StandardPaths.standardLocations(StandardPaths.GenericStateLocation)[0]}/caelestia` readonly property url cache: `${StandardPaths.standardLocations(StandardPaths.GenericCacheLocation)[0]}/caelestia` + + readonly property url imagecache: `${cache}/imagecache` + + function mkdir(path: url): void { + mkdirProc.path = path.toString().replace("file://", ""); + mkdirProc.startDetached(); + } + + Process { + id: mkdirProc + + property string path + + command: ["mkdir", "-p", path] + } } diff --git a/widgets/CachingImage.qml b/widgets/CachingImage.qml index cd164b4..3382615 100644 --- a/widgets/CachingImage.qml +++ b/widgets/CachingImage.qml @@ -1,14 +1,50 @@ import "root:/services" +import "root:/utils" +import Quickshell.Io import QtQuick Image { id: root property string path - property bool loadOriginal - readonly property Thumbnailer.Thumbnail thumbnail: Thumbnailer.go(this) + property string hash + readonly property string cachePath: `${Paths.imagecache}/${hash}@${width}x${height}.png`.slice(7) - source: thumbnail.path ? `file://${thumbnail.path}` : "" asynchronous: true + cache: false fillMode: Image.PreserveAspectCrop + sourceSize.width: width + sourceSize.height: height + + onPathChanged: { + shaProc.signal(9); + shaProc.path = path.replace("file://", ""); + shaProc.running = true; + } + + onCachePathChanged: { + if (hash) + source = cachePath; + } + + onStatusChanged: { + if (source == cachePath && status === Image.Error) + source = path; + else if (source == path && status === Image.Ready) { + Paths.mkdir(Paths.imagecache); + const grabPath = cachePath; + grabToImage(res => res.saveToFile(grabPath)); + } + } + + Process { + id: shaProc + + property string path + + command: ["sha256sum", path] + stdout: SplitParser { + onRead: data => root.hash = data.split(" ")[0] + } + } } -- cgit v1.2.3-freya From 4621c3695ed26862af70901605172bb1acaaae91 Mon Sep 17 00:00:00 2001 From: Tim Hämisch Date: Fri, 13 Jun 2025 16:08:02 +0200 Subject: Add custom shortcut for launcher, dashboard and osd all in one (#53) * Add custom shortcut for launcher, dashboard and osd all in one * Fix Shortcut description * shortcuts: fix showall Some fixes: - no need for the complex shortcut - fix formatting - fix unqualified access --------- Co-authored-by: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> --- modules/Shortcuts.qml | 9 +++++ modules/drawers/Interactions.qml | 86 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 6 deletions(-) (limited to 'modules') diff --git a/modules/Shortcuts.qml b/modules/Shortcuts.qml index bed620c..3d665ff 100644 --- a/modules/Shortcuts.qml +++ b/modules/Shortcuts.qml @@ -8,6 +8,15 @@ Scope { property bool launcherInterrupted + CustomShortcut { + name: "showall" + description: "Toggle launcher, dashboard and osd" + onPressed: { + const v = Visibilities.getForActive(); + v.launcher = v.dashboard = v.osd = !(v.launcher || v.dashboard || v.osd); + } + } + CustomShortcut { name: "session" description: "Toggle session menu" diff --git a/modules/drawers/Interactions.qml b/modules/drawers/Interactions.qml index 3ec522b..10e37a8 100644 --- a/modules/drawers/Interactions.qml +++ b/modules/drawers/Interactions.qml @@ -16,6 +16,8 @@ MouseArea { property bool osdHovered property point dragStart + property bool dashboardShortcutActive + property bool osdShortcutActive function withinPanelHeight(panel: Item, x: real, y: real): bool { const panelY = BorderConfig.thickness + panel.y; @@ -37,9 +39,14 @@ MouseArea { onPressed: event => dragStart = Qt.point(event.x, event.y) onContainsMouseChanged: { if (!containsMouse) { - visibilities.osd = false; - osdHovered = false; - visibilities.dashboard = false; + // Only hide if not activated by shortcut + if (!osdShortcutActive) { + visibilities.osd = false; + osdHovered = false; + } + if (!dashboardShortcutActive) { + visibilities.dashboard = false; + } popouts.hasCurrent = false; } } @@ -47,8 +54,16 @@ MouseArea { onPositionChanged: ({x, y}) => { // Show osd on hover const showOsd = inRightPanel(panels.osd, x, y); - visibilities.osd = showOsd; - osdHovered = showOsd; + + // Always update visibility based on hover if not in shortcut mode + if (!osdShortcutActive) { + visibilities.osd = showOsd; + osdHovered = showOsd; + } else if (showOsd) { + // If hovering over OSD area while in shortcut mode, transition to hover control + osdShortcutActive = false; + osdHovered = true; + } // Show/hide session on drag if (pressed && withinPanelHeight(panels.session, x, y)) { @@ -60,7 +75,15 @@ MouseArea { } // Show dashboard on hover - visibilities.dashboard = inTopPanel(panels.dashboard, x, y); + const showDashboard = inTopPanel(panels.dashboard, x, y); + + // Always update visibility based on hover if not in shortcut mode + if (!dashboardShortcutActive) { + visibilities.dashboard = showDashboard; + } else if (showDashboard) { + // If hovering over dashboard area while in shortcut mode, transition to hover control + dashboardShortcutActive = false; + } // Show popouts on hover const popout = panels.popouts; @@ -75,6 +98,57 @@ MouseArea { popouts.hasCurrent = false; } + // Monitor individual visibility changes + Connections { + target: root.visibilities + + function onLauncherChanged() { + // If launcher is hidden, clear shortcut flags for dashboard and OSD + if (!root.visibilities.launcher) { + root.dashboardShortcutActive = false; + root.osdShortcutActive = false; + + // Also hide dashboard and OSD if they're not being hovered + const inDashboardArea = root.inTopPanel(root.panels.dashboard, root.mouseX, root.mouseY); + const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY); + + if (!inDashboardArea) { + root.visibilities.dashboard = false; + } + if (!inOsdArea) { + root.visibilities.osd = false; + root.osdHovered = false; + } + } + } + + function onDashboardChanged() { + if (root.visibilities.dashboard) { + // Dashboard became visible, immediately check if this should be shortcut mode + const inDashboardArea = root.inTopPanel(root.panels.dashboard, root.mouseX, root.mouseY); + if (!inDashboardArea) { + root.dashboardShortcutActive = true; + } + } else { + // Dashboard hidden, clear shortcut flag + root.dashboardShortcutActive = false; + } + } + + function onOsdChanged() { + if (root.visibilities.osd) { + // OSD became visible, immediately check if this should be shortcut mode + const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY); + if (!inOsdArea) { + root.osdShortcutActive = true; + } + } else { + // OSD hidden, clear shortcut flag + root.osdShortcutActive = false; + } + } + } + Osd.Interactions { screen: root.screen visibilities: root.visibilities -- cgit v1.2.3-freya