import QtQuick import QtQuick.Effects import Quickshell import Quickshell.Hyprland import Quickshell.Widgets import Quickshell.Wayland Grid { id: overview anchors { top: parent.top horizontalCenter: parent.horiontalCenter } spacing: 4 padding: 6 columns: 5 horizontalItemAlignment: Grid.AlignHCenter verticalItemAlignment: Grid.AlignVCenter onVisibleChanged: { if (!visible) return; Hyprland.refreshToplevels() } component WorkspaceView: ClippingRectangle { id: workspaceView color: "#282828" height: Hyprland.focusedMonitor?.height * widthRatio width: 192 radius: 8 topLeftRadius: modelData == 0 ? 12 : this.radius topRightRadius: modelData == 4 ? 12 : this.radius bottomLeftRadius: modelData == 5 ? 12 : this.radius property var widthRatio: this.width / Hyprland.focusedMonitor?.width property var toplevels: Hyprland.toplevels.values.filter( tl => tl.workspace?.id == modelData + 1 ) border { width: 2 color: { if (Hyprland.focusedWorkspace?.id == modelData + 1 || hover.hovered) { return "#ffffffff" } if (toplevels.length) { return "#44ffffff" } return "#00ffffff" } Behavior on color { ColorAnimation {duration: 150} } } required property var modelData Image { anchors.fill: parent source: Quickshell.shellPath('assets/wallpaper') fillMode: Image.PreserveAspectCrop } Repeater { model: Hyprland.toplevels.values .filter(tl => tl.workspace?.id == modelData + 1) .sort((a, b) => { if (a.lastIpcObject.floating) return 1; if (b.lastIpcObject.floating) return -1; return 0 }) delegate: ClippingRectangle { id: toplevelView x: modelData.lastIpcObject.at?.[0] * workspaceView.widthRatio - 2 y: modelData.lastIpcObject.at?.[1] * workspaceView.widthRatio - 2 width: modelData.lastIpcObject.size?.[0] * workspaceView.widthRatio height: modelData.lastIpcObject.size?.[1] * workspaceView.widthRatio radius: modelData.lastIpcObject.floating ? 4 : 0 ScreencopyView { anchors.fill: parent captureSource: modelData.wayland live: overview.visible layer.enabled: true layer.effect: MultiEffect { blurEnabled: true blurMax: 4 blur: 1 autoPaddingEnabled: false } } Image { id: appicon anchors.centerIn: parent width: 24 + 24 * Math.min( (parent.width / workspaceView.width), (parent.height / workspaceView.height) ) height: width sourceSize.width: width sourceSize.height: height source: { const appId = modelData.wayland?.appId const iconName = DesktopEntries.applications.values.find( app => app.startupClass === appId || app.id === appId )?.icon; return Quickshell.iconPath(iconName) } layer.enabled: true visible: false } MultiEffect { anchors.fill: appicon source: appicon blurMax: 12 shadowEnabled: true } MultiEffect { anchors.fill: appicon source: appicon blurMax: 12 shadowEnabled: true } Rectangle { anchors.fill: parent color: 'transparent' border { width: 1; color: "#44ffffff" } radius: toplevelView.radius + 1 } } } TapHandler { onTapped: { if (modelData < 0) return; Hyprland.dispatch(`hl.dsp.focus({workspace = ${modelData + 1}})`) root.close() }} HoverHandler { id: hover } } Repeater { model: 9 WorkspaceView {} } WorkspaceView { modelData: -100 bottomRightRadius: 12 TapHandler { onTapped: { Hyprland.dispatch('hl.dsp.workspace.toggle_special()') root.close() } } } }