diff options
| author | Don Williams <Don.e.williams@gmail.com> | 2026-07-11 20:50:52 -0400 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2026-08-29 21:40:34 -0700 |
| commit | 9dab91abe13fc6cf1c8e609f71131609ae9c64bb (patch) | |
| tree | d848f7b3c180aba0ae1576d1f7ede0f951e63f11 /config/quickshell/overview/modules | |
| parent | cfdf5b2c2c24d312b2f2ff3da8eb73f9dced8dcf (diff) | |
Using previous version of overview config seems to work better
Signed-off-by: Don Williams <Don.e.williams@gmail.com>
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
new file: overview-backup/README.md
renamed: overview/assets/Workspace_Wallpaper.png -> overview-backup/assets/Workspace_Wallpaper.png
new file: overview-backup/assets/image.png
new file: overview-backup/common/Appearance.qml
new file: overview-backup/common/Config.qml
new file: overview-backup/common/functions/ColorUtils.qml
new file: overview-backup/common/functions/qmldir
new file: overview-backup/common/qmldir
renamed: overview/common/widgets/RectangularShadow.qml -> overview-backup/common/widgets/RectangularShadow.qml
new file: overview-backup/common/widgets/StyledRectangularShadow.qml
new file: overview-backup/common/widgets/StyledText.qml
new file: overview-backup/common/widgets/StyledToolTip.qml
new file: overview-backup/common/widgets/StyledToolTipContent.qml
new file: overview-backup/common/widgets/qmldir
renamed: overview/config.example.json -> overview-backup/config.example.json
renamed: overview/config.json -> overview-backup/config.json
new file: overview-backup/modules/overview/Overview.qml
new file: overview-backup/modules/overview/OverviewWidget.qml
new file: overview-backup/modules/overview/OverviewWindow.qml
new file: overview-backup/modules/overview/qmldir
renamed: overview/quickshell-overview.qml -> overview-backup/quickshell-overview.qml
new file: overview-backup/services/GlobalStates.qml
new file: overview-backup/services/HyprlandData.qml
new file: overview-backup/services/qmldir
new file: overview-backup/shell.qml
modified: overview/README.md
modified: overview/assets/image.png
modified: overview/common/Appearance.qml
modified: overview/common/Config.qml
modified: overview/common/widgets/StyledRectangularShadow.qml
modified: overview/common/widgets/qmldir
modified: overview/modules/overview/Overview.qml
modified: overview/modules/overview/OverviewWidget.qml
modified: overview/modules/overview/OverviewWindow.qml
modified: overview/services/HyprlandData.qml
modified: overview/shell.qml
Diffstat (limited to 'config/quickshell/overview/modules')
3 files changed, 131 insertions, 1299 deletions
diff --git a/config/quickshell/overview/modules/overview/Overview.qml b/config/quickshell/overview/modules/overview/Overview.qml index 2fb08bb9..b3a299cb 100644 --- a/config/quickshell/overview/modules/overview/Overview.qml +++ b/config/quickshell/overview/modules/overview/Overview.qml @@ -19,23 +19,23 @@ Scope { required property var modelData readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.screen) property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor?.id) - property bool blurEnabled: Config.options.overview.effects.enableBlur - property bool backdropEnabled: Config.options.overview.effects.enableBackdrop - property real backdropOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.backdropOpacity)) - property bool closeOnFocusLoss: Config.options.overview.closeOnFocusLoss ?? true screen: modelData visible: GlobalStates.overviewOpen - WlrLayershell.namespace: blurEnabled ? "quickshell:overview-blur" : "quickshell:overview" + WlrLayershell.namespace: "quickshell:overview" WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive color: "transparent" + mask: Region { + item: GlobalStates.overviewOpen ? keyHandler : null + } + anchors { top: true bottom: true - left: true - right: true + left: !(Config?.options.overview.enable ?? true) + right: !(Config?.options.overview.enable ?? true) } HyprlandFocusGrab { @@ -44,8 +44,7 @@ Scope { property bool canBeActive: root.monitorIsFocused active: false onCleared: () => { - // Only the monitor that owns the grab may close the overview - if (root.closeOnFocusLoss && !active && canBeActive) + if (!active) GlobalStates.overviewOpen = false; } } @@ -59,21 +58,6 @@ Scope { } } - // Re-evaluate grab ownership when focused monitor changes - Connections { - target: Hyprland - function onFocusedMonitorChanged() { - if (!GlobalStates.overviewOpen) - return; - // Transfer the grab to the newly focused monitor - if (root.monitorIsFocused && !grab.active) { - grab.active = true; - } else if (!root.monitorIsFocused && grab.active) { - grab.active = false; - } - } - } - Timer { id: delayedGrabTimer interval: Config.options.hacks.arbitraryRaceConditionDelay @@ -85,130 +69,42 @@ Scope { } } - // Keep the layershell surface full-screen so backdrop/blur are not constrained by content size. - implicitWidth: screen.width - implicitHeight: screen.height + implicitWidth: columnLayout.implicitWidth + implicitHeight: columnLayout.implicitHeight Item { id: keyHandler anchors.fill: parent visible: GlobalStates.overviewOpen focus: GlobalStates.overviewOpen - z: 0 - - Rectangle { - id: backdropLayer - anchors.fill: parent - visible: root.backdropEnabled - color: "#000000" - opacity: root.backdropOpacity - z: 0 - } - - MouseArea { - id: outsideClickCatcher - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton - enabled: root.closeOnFocusLoss && GlobalStates.overviewOpen - z: 0 - onPressed: mouse => { - GlobalStates.overviewOpen = false; - mouse.accepted = true; - } - } Keys.onPressed: event => { - // close: Escape or Enter if (event.key === Qt.Key_Escape || event.key === Qt.Key_Return) { GlobalStates.overviewOpen = false; event.accepted = true; - return; - } - - // Helper: compute current group bounds - const workspacesPerGroup = Config.options.overview.rows * Config.options.overview.columns; - const currentId = Hyprland.focusedMonitor?.activeWorkspace?.id ?? 1; - const useWorkspaceMap = Config.options.overview.useWorkspaceMap; - const workspaceMap = Config.options.overview.workspaceMap ?? []; - const focusedMonitorId = Hyprland.focusedMonitor?.id ?? root.monitor?.id ?? 0; - const workspaceOffset = useWorkspaceMap ? Number(workspaceMap[focusedMonitorId] ?? 0) : 0; - const currentGroup = Math.floor((currentId - workspaceOffset - 1) / workspacesPerGroup); - const minWorkspaceId = currentGroup * workspacesPerGroup + 1 + workspaceOffset; - const maxWorkspaceId = minWorkspaceId + workspacesPerGroup - 1; - - const rows = Config.options.overview.rows; - const columns = Config.options.overview.columns; - const reverseColumns = Config.options.overview.orderRightLeft; - const reverseRows = Config.options.overview.orderBottomUp; - - const clampedIndex = Math.max(0, Math.min(workspacesPerGroup - 1, currentId - minWorkspaceId)); - const currentNormalRow = Math.floor(clampedIndex / columns); - const currentNormalColumn = clampedIndex % columns; - - function toVisualRow(normalRow) { - return reverseRows ? (rows - normalRow - 1) : normalRow; - } - - function toVisualColumn(normalColumn) { - return reverseColumns ? (columns - normalColumn - 1) : normalColumn; - } - - function toNormalRow(visualRow) { - return reverseRows ? (rows - visualRow - 1) : visualRow; - } - - function toNormalColumn(visualColumn) { - return reverseColumns ? (columns - visualColumn - 1) : visualColumn; - } - - let targetVisualRow = toVisualRow(currentNormalRow); - let targetVisualColumn = toVisualColumn(currentNormalColumn); - - let targetId = null; - - // Arrow keys and vim-style hjkl - if (event.key === Qt.Key_Left || event.key === Qt.Key_H) { - targetVisualColumn = (targetVisualColumn - 1 + columns) % columns; - } else if (event.key === Qt.Key_Right || event.key === Qt.Key_L) { - targetVisualColumn = (targetVisualColumn + 1) % columns; - } else if (event.key === Qt.Key_Up || event.key === Qt.Key_K) { - targetVisualRow = (targetVisualRow - 1 + rows) % rows; - } else if (event.key === Qt.Key_Down || event.key === Qt.Key_J) { - targetVisualRow = (targetVisualRow + 1) % rows; - } - - // Number keys: jump to workspace within the current group - // 1-9 map to positions 1-9, 0 maps to position 10 - else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) { - const position = event.key - Qt.Key_0; // 1-9 - if (position <= workspacesPerGroup) { - targetId = minWorkspaceId + position - 1; + } else if (event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Up || event.key === Qt.Key_Down) { + const workspacesPerGroup = Config.options.overview.rows * Config.options.overview.columns; + const currentId = Hyprland.focusedMonitor?.activeWorkspace?.id ?? 1; + const currentGroup = Math.floor((currentId - 1) / workspacesPerGroup); + const minWorkspaceId = currentGroup * workspacesPerGroup + 1; + const maxWorkspaceId = minWorkspaceId + workspacesPerGroup - 1; + + let targetId; + if (event.key === Qt.Key_Left) { + targetId = currentId - 1; + if (targetId < minWorkspaceId) targetId = maxWorkspaceId; + } else if (event.key === Qt.Key_Right) { + targetId = currentId + 1; + if (targetId > maxWorkspaceId) targetId = minWorkspaceId; + } else if (event.key === Qt.Key_Up) { + targetId = currentId - Config.options.overview.columns; + if (targetId < minWorkspaceId) targetId += workspacesPerGroup; + } else { + targetId = currentId + Config.options.overview.columns; + if (targetId > maxWorkspaceId) targetId -= workspacesPerGroup; } - } else if (event.key === Qt.Key_0) { - // 0 = 10th workspace in the group (if group has 10+ workspaces) - if (workspacesPerGroup >= 10) { - targetId = minWorkspaceId + 9; // 10th position = offset 9 - } - } - - if (targetId === null && ( - event.key === Qt.Key_Left || event.key === Qt.Key_H || - event.key === Qt.Key_Right || event.key === Qt.Key_L || - event.key === Qt.Key_Up || event.key === Qt.Key_K || - event.key === Qt.Key_Down || event.key === Qt.Key_J - )) { - const targetNormalRow = toNormalRow(targetVisualRow); - const targetNormalColumn = toNormalColumn(targetVisualColumn); - targetId = minWorkspaceId + targetNormalRow * columns + targetNormalColumn; - } - - if (targetId !== null) { - const clampedTarget = Math.max(minWorkspaceId, Math.min(maxWorkspaceId, targetId)); - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.focus({workspace = '${clampedTarget}'})`); - } else { - Hyprland.dispatch("workspace " + clampedTarget); - } + + Hyprland.dispatch("workspace " + targetId); event.accepted = true; } } @@ -217,16 +113,15 @@ Scope { ColumnLayout { id: columnLayout visible: GlobalStates.overviewOpen - z: 1 anchors { horizontalCenter: parent.horizontalCenter top: parent.top - topMargin: Config.options.position.topMargin + topMargin: 100 } Loader { id: overviewLoader - active: Config?.options.overview.enable ?? true + active: GlobalStates.overviewOpen && (Config?.options.overview.enable ?? true) sourceComponent: OverviewWidget { panelWindow: root visible: true @@ -235,7 +130,7 @@ Scope { } } } - + IpcHandler { target: "overview" diff --git a/config/quickshell/overview/modules/overview/OverviewWidget.qml b/config/quickshell/overview/modules/overview/OverviewWidget.qml index 6d00803b..7defa64d 100644 --- a/config/quickshell/overview/modules/overview/OverviewWidget.qml +++ b/config/quickshell/overview/modules/overview/OverviewWidget.qml @@ -1,5 +1,4 @@ import QtQuick -import QtQuick.Effects import QtQuick.Layouts import Quickshell import Quickshell.Wayland @@ -15,347 +14,32 @@ Item { required property var panelWindow readonly property HyprlandMonitor monitor: Hyprland.monitorFor(panelWindow.screen) readonly property var toplevels: ToplevelManager.toplevels - readonly property int effectiveActiveWorkspaceId: Math.max(1, Math.min(100, monitor?.activeWorkspace?.id ?? 1)) readonly property int workspacesShown: Config.options.overview.rows * Config.options.overview.columns - readonly property bool useWorkspaceMap: Config.options.overview.useWorkspaceMap - readonly property var workspaceMap: Config.options.overview.workspaceMap - readonly property int workspaceOffset: useWorkspaceMap ? Number(workspaceMap[root.monitor?.id] ?? 0) : 0 - readonly property int workspaceGroup: Math.floor((effectiveActiveWorkspaceId - workspaceOffset - 1) / workspacesShown) + readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / workspacesShown) property bool monitorIsFocused: (Hyprland.focusedMonitor?.name == monitor.name) property var windows: HyprlandData.windowList property var windowByAddress: HyprlandData.windowByAddress property var windowAddresses: HyprlandData.addresses - property var workspaceIds: HyprlandData.workspaceIds property var monitorData: HyprlandData.monitors.find(m => m.id === root.monitor?.id) property real scale: Config.options.overview.scale property color activeBorderColor: Appearance.colors.colSecondary - property real workspaceImplicitWidth: Math.round((monitorData?.transform % 2 === 1) ? + property real workspaceImplicitWidth: (monitorData?.transform % 2 === 1) ? ((monitor.height / monitor.scale - (monitorData?.reserved?.[0] ?? 0) - (monitorData?.reserved?.[2] ?? 0)) * root.scale) : - ((monitor.width / monitor.scale - (monitorData?.reserved?.[0] ?? 0) - (monitorData?.reserved?.[2] ?? 0)) * root.scale)) - property real workspaceImplicitHeight: Math.round((monitorData?.transform % 2 === 1) ? + ((monitor.width / monitor.scale - (monitorData?.reserved?.[0] ?? 0) - (monitorData?.reserved?.[2] ?? 0)) * root.scale) + property real workspaceImplicitHeight: (monitorData?.transform % 2 === 1) ? ((monitor.width / monitor.scale - (monitorData?.reserved?.[1] ?? 0) - (monitorData?.reserved?.[3] ?? 0)) * root.scale) : - ((monitor.height / monitor.scale - (monitorData?.reserved?.[1] ?? 0) - (monitorData?.reserved?.[3] ?? 0)) * root.scale)) + ((monitor.height / monitor.scale - (monitorData?.reserved?.[1] ?? 0) - (monitorData?.reserved?.[3] ?? 0)) * root.scale) property real workspaceNumberMargin: 80 - property real workspaceNumberSize: Config.options.overview.workspaceNumberBaseSize * monitor.scale + property real workspaceNumberSize: 250 * monitor.scale property int workspaceZ: 0 property int windowZ: 1 property int windowDraggingZ: 99999 - property real workspaceSpacing: Config.options.overview.workspaceSpacing - property string emptyWorkspaceWallpaperPath: Config.options.overview.emptyWorkspaceWallpaper - property string specialEmptyWorkspaceWallpaperPath: Config.options.overview.specialEmptyWorkspaceWallpaper - property bool showSpecialWorkspaces: Config.options.overview.showSpecialWorkspaces - property var configuredSpecialWorkspaces: Config.options.overview.specialWorkspaces ?? [] - property int specialWorkspaceColumns: Math.max(1, Config.options.overview.specialWorkspaceColumns) - property real panelOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.panelOpacity)) - property real workspaceOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.workspaceOpacity)) - property real emptyWorkspaceWallpaperOverlayOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.emptyWorkspaceWallpaperOverlayOpacity)) - property bool glassMode: Config.options.overview.effects.glassMode - property real glassTintStrength: Math.max(0, Math.min(1, Config.options.overview.effects.glassTintStrength)) - property real glassBorderOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.glassBorderOpacity)) - property real glassShineOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.glassShineOpacity)) - property real effectivePanelOpacity: glassMode ? Math.min(panelOpacity, 0.72) : panelOpacity - property real effectiveWorkspaceOpacity: glassMode ? Math.min(workspaceOpacity, 0.62) : workspaceOpacity + property real workspaceSpacing: 5 property int draggingFromWorkspace: -1 property int draggingTargetWorkspace: -1 - property string draggingTargetSpecialWorkspace: "" - property int previewRecaptureToken: 0 - property var allWorkspaces: HyprlandData.allWorkspaces - property bool previewsEnabled: Config.options.overview.previewsEnabled - property string previewModeRaw: Config.options.overview.previewMode - property string previewMode: { - const mode = `${previewModeRaw ?? "live"}`.trim().toLowerCase(); - return (mode === "event" || mode === "snapshot") ? "event" : "live"; - } - property bool useEventPreviewRefresh: previewsEnabled && previewMode === "event" - - readonly property var monitorSpecialWorkspaceNames: { - const names = []; - for (const ws of (allWorkspaces ?? [])) { - const name = `${ws?.name ?? ""}`; - if (!name.startsWith("special:")) - continue; - if (`${ws?.monitor ?? ""}` !== `${root.monitor?.name ?? ""}`) - continue; - names.push(name.slice(8)); - } - return names; - } - - readonly property var specialWorkspaceNamesFromWindows: { - const names = []; - for (const addr in windowByAddress) { - const win = windowByAddress[addr]; - if ((win?.monitor ?? -1) !== (root.monitor?.id ?? -1)) - continue; - const wsName = `${win?.workspace?.name ?? ""}`; - if (!wsName.startsWith("special:")) - continue; - names.push(wsName.slice(8)); - } - return names; - } - - readonly property var visibleSpecialWorkspaces: { - if (!showSpecialWorkspaces) - return []; - - const out = []; - const pushUnique = (value) => { - const cleaned = `${value ?? ""}`.trim(); - if (cleaned.length === 0 || out.includes(cleaned)) - return; - out.push(cleaned); - }; - - for (const configured of configuredSpecialWorkspaces ?? []) - pushUnique(configured); - for (const name of monitorSpecialWorkspaceNames) - pushUnique(name); - for (const name of specialWorkspaceNamesFromWindows) - pushUnique(name); - - return out; - } - - readonly property bool hasSpecialWorkspaceSection: visibleSpecialWorkspaces.length > 0 - readonly property bool hasEmptyWorkspaceWallpaper: `${emptyWorkspaceWallpaperPath ?? ""}`.trim().length > 0 - readonly property bool hasSpecialEmptyWorkspaceWallpaper: `${specialEmptyWorkspaceWallpaperPath ?? ""}`.trim().length > 0 - readonly property string createSpecialWorkspaceTarget: "__create_special_workspace__" - readonly property real specialWorkspaceTileHeight: root.workspaceImplicitHeight - readonly property real specialStripGap: workspaceSpacing * 1.8 - readonly property real specialStripPadding: Math.max(8, 12 * root.scale) - readonly property real specialStripTitleHeight: Math.max(14, Appearance.font.pixelSize.small * root.scale) - readonly property real specialStripTitleGap: Math.max(6, 8 * root.scale) - readonly property int totalSpecialTiles: visibleSpecialWorkspaces.length + 1 - readonly property real specialSectionWidth: workspaceColumnLayout.implicitWidth - readonly property real specialGridInnerWidth: Math.max(0, root.specialSectionWidth - root.specialStripPadding * 2) - readonly property int effectiveSpecialColumns: Math.max(1, Math.min(root.specialWorkspaceColumns, root.totalSpecialTiles)) - readonly property int specialWorkspaceRows: Math.ceil(root.totalSpecialTiles / root.effectiveSpecialColumns) - readonly property real specialWorkspaceAspectCap: { - let maxAspect = Math.max(1, root.workspaceImplicitWidth / Math.max(1, root.workspaceImplicitHeight)); - for (const name of visibleSpecialWorkspaces) { - const geometry = root.specialWorkspaceGeometry(name, root.monitor?.id); - const width = geometry?.width; - const height = geometry?.height; - if (!Number.isFinite(width) || !Number.isFinite(height) || height <= 0) - continue; - maxAspect = Math.max(maxAspect, width / height); - } - return maxAspect; - } - readonly property real specialWorkspaceTileWidth: { - const gaps = Math.max(0, root.effectiveSpecialColumns - 1); - const rawWidth = (root.specialGridInnerWidth - gaps * workspaceSpacing) / root.effectiveSpecialColumns; - const aspectWidth = root.specialWorkspaceTileHeight * root.specialWorkspaceAspectCap; - const cappedWidth = Math.min(rawWidth, aspectWidth); - return Math.max(80 * root.scale, cappedWidth); - } - readonly property real specialGridUsedWidth: root.effectiveSpecialColumns * root.specialWorkspaceTileWidth + Math.max(0, root.effectiveSpecialColumns - 1) * workspaceSpacing - readonly property real specialGridOffsetX: root.specialStripPadding + Math.max(0, (root.specialGridInnerWidth - root.specialGridUsedWidth) / 2) - readonly property real specialStripTop: workspaceColumnLayout.implicitHeight + workspaceSpacing + root.specialStripGap - readonly property real specialStripTilesTop: root.specialStripTop + root.specialStripPadding + root.specialStripTitleHeight + root.specialStripTitleGap - readonly property real specialGridHeight: root.specialWorkspaceRows * root.specialWorkspaceTileHeight + Math.max(0, root.specialWorkspaceRows - 1) * workspaceSpacing - readonly property real specialStripHeight: root.specialStripPadding * 2 + root.specialStripTitleHeight + root.specialStripTitleGap + root.specialGridHeight - - function getWorkspaceRow(workspaceId) { - if (!Number.isFinite(workspaceId)) - return 0; - const adjusted = workspaceId - workspaceOffset; - const normalRow = Math.floor((adjusted - 1) / Config.options.overview.columns) % Config.options.overview.rows; - return Config.options.overview.orderBottomUp ? (Config.options.overview.rows - normalRow - 1) : normalRow; - } - - function getWorkspaceColumn(workspaceId) { - if (!Number.isFinite(workspaceId)) - return 0; - const adjusted = workspaceId - workspaceOffset; - const normalCol = (adjusted - 1) % Config.options.overview.columns; - return Config.options.overview.orderRightLeft ? (Config.options.overview.columns - normalCol - 1) : normalCol; - } - - function getWorkspaceInCell(rowIndex, colIndex) { - const mappedRow = Config.options.overview.orderBottomUp ? (Config.options.overview.rows - rowIndex - 1) : rowIndex; - const mappedCol = Config.options.overview.orderRightLeft ? (Config.options.overview.columns - colIndex - 1) : colIndex; - return (workspaceGroup * workspacesShown) + (mappedRow * Config.options.overview.columns) + mappedCol + 1 + workspaceOffset; - } - - function getVisibleRowPosition(rowIndex) { - if (!Number.isFinite(rowIndex) || rowIndex < 0) - return 0; - if (!Config.options.overview.hideEmptyRows || !(rowsWithContent instanceof Set)) - return rowIndex; - - let visibleRow = 0; - for (let i = 0; i < rowIndex; i += 1) { - if (rowsWithContent.has(i)) - visibleRow += 1; - } - return visibleRow; - } - - function stepWorkspace(delta) { - if (!Number.isFinite(delta) || delta === 0) - return; - - const currentId = monitor?.activeWorkspace?.id ?? effectiveActiveWorkspaceId; - const minWorkspaceId = workspaceOffset + 1; - let maxWorkspaceId = minWorkspaceId + workspacesShown - 1; - for (const workspaceId of (workspaceIds ?? [])) { - if (Number.isFinite(workspaceId) && workspaceId >= minWorkspaceId) { - maxWorkspaceId = Math.max(maxWorkspaceId, workspaceId); - } - } - maxWorkspaceId = Math.max(maxWorkspaceId, currentId); - - let targetId = currentId + delta; - if (targetId < minWorkspaceId) { - targetId = maxWorkspaceId; - } else if (targetId > maxWorkspaceId) { - targetId = minWorkspaceId; - } - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.focus({workspace = '${targetId}'})`); - } else { - Hyprland.dispatch(`workspace ${targetId}`); - } - } - - function isSpecialWorkspace(windowData) { - const wsName = `${windowData?.workspace?.name ?? ""}`; - return wsName.startsWith("special:"); - } - - function specialWorkspaceName(windowData) { - const wsName = `${windowData?.workspace?.name ?? ""}`; - return wsName.startsWith("special:") ? wsName.slice(8) : ""; - } - - function specialWorkspaceIndex(name) { - return visibleSpecialWorkspaces.indexOf(`${name ?? ""}`); - } - - function specialWorkspaceLabel(name) { - const raw = `${name ?? ""}`.trim(); - if (raw.length === 0) - return "Special"; - return raw.replace(/[-_]+/g, " "); - } - - function nextSpecialWorkspaceName() { - const taken = new Set(); - for (const name of visibleSpecialWorkspaces) - taken.add(`${name ?? ""}`.trim().toLowerCase()); - - const base = "stash"; - if (!taken.has(base)) - return base; - - let index = 2; - while (taken.has(`${base}-${index}`)) - index += 1; - - return `${base}-${index}`; - } - - function wallpaperSource(path) { - const trimmed = `${path ?? ""}`.trim(); - if (trimmed.length === 0) - return ""; - if (trimmed.startsWith("file:/") || trimmed.startsWith("qrc:/") || trimmed.startsWith("image://") || trimmed.startsWith("http://") || trimmed.startsWith("https://")) - return trimmed; - if (trimmed.startsWith("/")) - return `file://${trimmed}`; - return trimmed; - } - - function workspaceHasWindows(workspaceId) { - if (!Number.isFinite(workspaceId)) - return false; - - for (const addr in windowByAddress) { - const win = windowByAddress[addr]; - if (root.isSpecialWorkspace(win)) - continue; - if ((win?.workspace?.id ?? -1) === workspaceId) - return true; - } - return false; - } - - function specialWindowZ(win) { - const pinned = win?.pinned ? 200000 : 0; - const floating = win?.floating ? 100000 : 0; - const focus = 10000 - (win?.focusHistoryID ?? 9999); - return pinned + floating + focus; - } - - function specialWorkspaceGeometry(name, monitorId) { - const trimmedName = `${name ?? ""}`.trim(); - const currentMonitorId = monitorId ?? -1; - let minX = null; - let minY = null; - let maxX = null; - let maxY = null; - - for (const addr in windowByAddress) { - const win = windowByAddress[addr]; - if ((win?.monitor ?? -1) !== currentMonitorId) - continue; - if (root.specialWorkspaceName(win) !== trimmedName) - continue; - - const atX = win?.at?.[0]; - const atY = win?.at?.[1]; - const width = win?.size?.[0]; - const height = win?.size?.[1]; - if (!Number.isFinite(atX) || !Number.isFinite(atY)) - continue; - if (!Number.isFinite(width) || !Number.isFinite(height)) - continue; - - minX = minX === null ? atX : Math.min(minX, atX); - minY = minY === null ? atY : Math.min(minY, atY); - maxX = maxX === null ? (atX + width) : Math.max(maxX, atX + width); - maxY = maxY === null ? (atY + height) : Math.max(maxY, atY + height); - } - - return { - x: minX, - y: minY, - width: (minX !== null && maxX !== null) ? Math.max(1, maxX - minX) : null, - height: (minY !== null && maxY !== null) ? Math.max(1, maxY - minY) : null - }; - } - - // Calculate which rows have windows or current workspace - property var rowsWithContent: { - if (!Config.options.overview.hideEmptyRows) return null; - - let rows = new Set(); - const firstWorkspace = root.workspaceGroup * root.workspacesShown + 1 + workspaceOffset; - const lastWorkspace = (root.workspaceGroup + 1) * root.workspacesShown + workspaceOffset; - - // Add row containing current workspace - const currentWorkspace = effectiveActiveWorkspaceId; - if (currentWorkspace >= firstWorkspace && currentWorkspace <= lastWorkspace) { - rows.add(getWorkspaceRow(currentWorkspace)); - } - - // Add rows with windows - for (let addr in windowByAddress) { - const win = windowByAddress[addr]; - const wsId = win?.workspace?.id; - if (wsId >= firstWorkspace && wsId <= lastWorkspace) { - const rowIndex = getWorkspaceRow(wsId); - rows.add(rowIndex); - } - } - - return rows; - } implicitWidth: overviewBackground.implicitWidth + Appearance.sizes.elevationMargin * 2 implicitHeight: overviewBackground.implicitHeight + Appearance.sizes.elevationMargin * 2 @@ -363,101 +47,41 @@ Item { property Component windowComponent: OverviewWindow {} property list<OverviewWindow> windowWidgets: [] - Connections { - target: Hyprland - function onRawEvent(event) { - if (!GlobalStates.overviewOpen || !root.useEventPreviewRefresh) - return; - - const eventName = `${event?.name ?? event?.event ?? event?.type ?? ""}`; - if (eventName === "closewindow" || eventName === "openwindow" || eventName === "movewindow") { - root.previewRecaptureToken += 1; - } - } - } - StyledRectangularShadow { target: overviewBackground } Rectangle { // Background id: overviewBackground - property real padding: Config.options.overview.backgroundPadding + property real padding: 10 anchors.fill: parent anchors.margins: Appearance.sizes.elevationMargin - implicitWidth: contentLayout.implicitWidth + padding * 2 - implicitHeight: contentLayout.implicitHeight + padding * 2 + implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2 + implicitHeight: workspaceColumnLayout.implicitHeight + padding * 2 radius: Appearance.rounding.screenRounding * root.scale + padding - clip: true - color: ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(Appearance.colors.colLayer0, Appearance.colors.colLayer1, 0.78 - root.glassTintStrength * 0.35) - : Appearance.colors.colLayer0, - root.effectivePanelOpacity - ) + color: Appearance.colors.colLayer0 border.width: 1 - border.color: ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(Appearance.colors.colLayer0Border, Appearance.m3colors.m3outline, 0.52) - : Appearance.colors.colLayer0Border, - root.glassMode ? root.glassBorderOpacity : root.effectivePanelOpacity - ) - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton - onPressed: mouse => mouse.accepted = true - } - - Rectangle { - visible: root.glassMode - anchors.fill: parent - radius: parent.radius - color: "transparent" - gradient: Gradient { - GradientStop { position: 0.0; color: ColorUtils.applyAlpha("#FFFFFF", root.glassShineOpacity * 0.35) } - GradientStop { position: 0.42; color: ColorUtils.applyAlpha("#FFFFFF", 0.0) } - GradientStop { position: 1.0; color: ColorUtils.applyAlpha("#000000", root.glassShineOpacity * 0.22) } - } - } - - Rectangle { - visible: root.glassMode - anchors.fill: parent - anchors.margins: 1 - radius: Math.max(parent.radius - 1, 0) - color: "transparent" - border.width: 1 - border.color: ColorUtils.applyAlpha("#FFFFFF", root.glassBorderOpacity * 0.20) - } + border.color: Appearance.colors.colLayer0Border ColumnLayout { // Workspaces - id: contentLayout + id: workspaceColumnLayout z: root.workspaceZ anchors.centerIn: parent spacing: workspaceSpacing - ColumnLayout { - id: workspaceColumnLayout - spacing: workspaceSpacing - - Repeater { - model: Config.options.overview.rows - delegate: RowLayout { + Repeater { + model: Config.options.overview.rows + delegate: RowLayout { id: row property int rowIndex: index spacing: workspaceSpacing - visible: !Config.options.overview.hideEmptyRows || - (root.rowsWithContent && root.rowsWithContent.has(rowIndex)) - height: visible ? implicitHeight : 0 Repeater { // Workspace repeater model: Config.options.overview.columns Rectangle { // Workspace id: workspace property int colIndex: index - property int workspaceValue: root.getWorkspaceInCell(rowIndex, colIndex) - property bool showWallpaper: root.hasEmptyWorkspaceWallpaper + property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * Config.options.overview.columns + colIndex + 1 property color defaultWorkspaceColor: Appearance.colors.colLayer1 property color hoveredWorkspaceColor: ColorUtils.mix(defaultWorkspaceColor, Appearance.colors.colLayer1Hover, 0.1) property color hoveredBorderColor: Appearance.colors.colLayer2Hover @@ -465,89 +89,13 @@ Item { implicitWidth: root.workspaceImplicitWidth implicitHeight: root.workspaceImplicitHeight - color: showWallpaper ? "transparent" : ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor, Appearance.colors.colLayer0, 0.46) - : (hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor), - root.effectiveWorkspaceOpacity - ) + color: hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor radius: Appearance.rounding.screenRounding * root.scale border.width: 2 - border.color: hoveredWhileDragging - ? ColorUtils.applyAlpha(hoveredBorderColor, root.glassMode ? root.glassBorderOpacity : 1) - : "transparent" - - Image { - id: workspaceWallpaper - visible: workspace.showWallpaper - anchors.fill: parent - source: root.wallpaperSource(root.emptyWorkspaceWallpaperPath) - fillMode: Image.PreserveAspectCrop - asynchronous: true - cache: true - smooth: true - mipmap: true - layer.enabled: workspace.showWallpaper - layer.smooth: true - layer.effect: MultiEffect { - maskEnabled: true - maskSource: workspaceWallpaperMask - maskThresholdMin: 0.5 - maskSpreadAtMin: 1.0 - } - } - - Item { - id: workspaceWallpaperMask - anchors.fill: parent - visible: false - layer.enabled: true - layer.smooth: true - Rectangle { - anchors.fill: parent - radius: workspace.radius - } - } - - Rectangle { - visible: workspace.showWallpaper - anchors.fill: parent - radius: parent.radius - color: ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(workspace.hoveredWhileDragging ? workspace.hoveredWorkspaceColor : workspace.defaultWorkspaceColor, Appearance.colors.colLayer0, 0.40) - : (workspace.hoveredWhileDragging ? workspace.hoveredWorkspaceColor : workspace.defaultWorkspaceColor), - workspace.hoveredWhileDragging - ? Math.min(0.28, root.emptyWorkspaceWallpaperOverlayOpacity + 0.08) - : root.emptyWorkspaceWallpaperOverlayOpacity - ) - } - - Rectangle { - visible: root.glassMode - anchors.fill: parent - radius: parent.radius - color: "transparent" - gradient: Gradient { - GradientStop { position: 0.0; color: ColorUtils.applyAlpha("#FFFFFF", root.glassShineOpacity * 0.22) } - GradientStop { position: 0.46; color: ColorUtils.applyAlpha("#FFFFFF", 0.0) } - GradientStop { position: 1.0; color: ColorUtils.applyAlpha("#000000", root.glassShineOpacity * 0.14) } - } - } - - Rectangle { - visible: root.glassMode - anchors.fill: parent - anchors.margins: 1 - radius: Math.max(parent.radius - 1, 0) - color: "transparent" - border.width: 1 - border.color: ColorUtils.applyAlpha("#FFFFFF", root.glassBorderOpacity * 0.16) - } + border.color: hoveredWhileDragging ? hoveredBorderColor : "transparent" StyledText { anchors.centerIn: parent - visible: !workspace.showWallpaper text: workspaceValue font { pixelSize: root.workspaceNumberSize * root.scale @@ -566,11 +114,7 @@ Item { onClicked: { if (root.draggingTargetWorkspace === -1) { GlobalStates.overviewOpen = false - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.focus({workspace = '${workspaceValue}'})`); - } else { - Hyprland.dispatch(`workspace ${workspaceValue}`) - } + Hyprland.dispatch(`workspace ${workspaceValue}`) } } } @@ -579,7 +123,6 @@ Item { anchors.fill: parent onEntered: { root.draggingTargetWorkspace = workspaceValue - root.draggingTargetSpecialWorkspace = "" if (root.draggingFromWorkspace == root.draggingTargetWorkspace) return; hoveredWhileDragging = true } @@ -591,413 +134,6 @@ Item { } } - } - } - } - - Item { - visible: root.showSpecialWorkspaces - implicitWidth: 1 - implicitHeight: root.specialStripGap - } - - Item { - id: specialWorkspaceSection - visible: root.showSpecialWorkspaces - implicitWidth: root.specialSectionWidth - implicitHeight: root.specialStripHeight - - Rectangle { - anchors.fill: parent - radius: Appearance.rounding.normal * root.scale - color: ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(Appearance.colors.colLayer0, Appearance.colors.colLayer1, 0.70) - : Appearance.colors.colLayer1, - root.glassMode ? Math.min(0.74, root.effectivePanelOpacity) : root.effectiveWorkspaceOpacity - ) - border.width: 1 - border.color: ColorUtils.applyAlpha(Appearance.colors.colLayer2Border, root.glassMode ? root.glassBorderOpacity : 0.65) - - Rectangle { - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Math.max(18 * root.scale, root.specialStripPadding + root.specialStripTitleHeight * 0.8) - radius: parent.radius - color: ColorUtils.applyAlpha(Appearance.colors.colSecondary, root.glassMode ? 0.12 : 0.08) - } - - StyledText { - anchors.left: parent.left - anchors.top: parent.top - anchors.leftMargin: root.specialStripPadding - anchors.topMargin: root.specialStripPadding - text: "Special Workspaces" - font.family: Appearance.font.family.title - font.pixelSize: root.specialStripTitleHeight - font.weight: Font.DemiBold - color: ColorUtils.applyAlpha(Appearance.colors.colOnLayer1, 0.84) - } - - Grid { - id: specialWorkspaceGrid - x: root.specialGridOffsetX - y: root.specialStripPadding + root.specialStripTitleHeight + root.specialStripTitleGap - width: root.specialGridUsedWidth - columns: root.effectiveSpecialColumns - rowSpacing: workspaceSpacing - columnSpacing: workspaceSpacing - - Repeater { - model: root.visibleSpecialWorkspaces - delegate: Rectangle { - id: specialWorkspaceTile - required property string modelData - property string specialName: modelData - property var specialGeometry: root.specialWorkspaceGeometry(specialName, root.monitor?.id) - property color baseColor: ColorUtils.mix(Appearance.colors.colLayer1, Appearance.colors.colLayer0, 0.52) - property bool hasRenderableGeometry: Number.isFinite(specialGeometry?.width) - && Number.isFinite(specialGeometry?.height) - && specialGeometry.width > 0 - && specialGeometry.height > 0 - property bool showWallpaper: root.hasSpecialEmptyWorkspaceWallpaper - property real geometryWidth: hasRenderableGeometry ? specialGeometry.width : Math.max(1, root.workspaceImplicitWidth / root.scale) - property real geometryHeight: hasRenderableGeometry ? specialGeometry.height : Math.max(1, root.workspaceImplicitHeight / root.scale) - property real fitScale: hasRenderableGeometry ? Math.min(width / geometryWidth, height / geometryHeight) : root.scale - property real contentWidth: hasRenderableGeometry ? (geometryWidth * fitScale) : width - property real contentHeight: hasRenderableGeometry ? (geometryHeight * fitScale) : height - property real contentOffsetX: Math.max(0, (width - contentWidth) / 2) - property real contentOffsetY: Math.max(0, (height - contentHeight) / 2) - implicitWidth: root.specialWorkspaceTileWidth - implicitHeight: root.specialWorkspaceTileHeight - radius: Appearance.rounding.screenRounding * root.scale - clip: true - color: showWallpaper ? "transparent" : ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(baseColor, Appearance.colors.colLayer0, 0.44) - : baseColor, - root.effectiveWorkspaceOpacity - ) - border.width: 1 - border.color: ColorUtils.applyAlpha(Appearance.colors.colLayer2Border, root.glassMode ? root.glassBorderOpacity : 0.75) - - Image { - visible: specialWorkspaceTile.showWallpaper - anchors.fill: parent - source: root.wallpaperSource(root.specialEmptyWorkspaceWallpaperPath) - fillMode: Image.PreserveAspectCrop - asynchronous: true - cache: true - smooth: true - mipmap: true - } - - Rectangle { - visible: specialWorkspaceTile.showWallpaper - anchors.fill: parent - radius: parent.radius - color: ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(specialWorkspaceTile.baseColor, Appearance.colors.colLayer0, 0.40) - : specialWorkspaceTile.baseColor, - root.emptyWorkspaceWallpaperOverlayOpacity - ) - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - onClicked: { - if (root.draggingTargetWorkspace === -1 && !root.draggingTargetSpecialWorkspace) { - GlobalStates.overviewOpen = false; - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.workspace.toggle_special('${specialWorkspaceTile.specialName}')`); - } else { - Hyprland.dispatch(`togglespecialworkspace ${specialWorkspaceTile.specialName}`); - } - } - } - } - - DropArea { - anchors.fill: parent - onEntered: { - root.draggingTargetWorkspace = -1; - root.draggingTargetSpecialWorkspace = specialWorkspaceTile.specialName; - } - onExited: { - if (root.draggingTargetSpecialWorkspace === specialWorkspaceTile.specialName) - root.draggingTargetSpecialWorkspace = ""; - } - } - - Item { - id: specialWorkspaceContent - x: specialWorkspaceTile.contentOffsetX - y: specialWorkspaceTile.contentOffsetY - width: specialWorkspaceTile.contentWidth - height: specialWorkspaceTile.contentHeight - clip: true - - Repeater { - model: ScriptModel { - values: { - if (!specialWorkspaceTile.hasRenderableGeometry) - return []; - return ToplevelManager.toplevels.values.filter((toplevel) => { - const address = `0x${toplevel.HyprlandToplevel.address}`; - const win = windowByAddress[address]; - if ((win?.monitor ?? -1) !== (root.monitor?.id ?? -1)) - return false; - return root.specialWorkspaceName(win) === specialWorkspaceTile.specialName; - }).sort((a, b) => { - const addrA = `0x${a.HyprlandToplevel.address}`; - const addrB = `0x${b.HyprlandToplevel.address}`; - return addrA.localeCompare(addrB); - }); - } - } - delegate: OverviewWindow { - id: specialWindow - required property var modelData - required property int index - property var address: `0x${modelData.HyprlandToplevel.address}` - property int monitorId: windowData?.monitor - property var monitor: HyprlandData.monitors.find(m => m.id === monitorId) - property Item homeParent: specialWorkspaceContent - windowData: windowByAddress[address] - toplevel: modelData - monitorData: monitor - widgetMonitorData: root.monitorData - scale: root.scale - availableWorkspaceWidth: specialWorkspaceContent.width - availableWorkspaceHeight: specialWorkspaceContent.height - positionBaseX: Number.isFinite(specialWorkspaceTile.specialGeometry?.x) ? specialWorkspaceTile.specialGeometry.x : ((monitor?.x ?? 0) + (monitor?.reserved?.[0] ?? 0)) - positionBaseY: Number.isFinite(specialWorkspaceTile.specialGeometry?.y) ? specialWorkspaceTile.specialGeometry.y : ((monitor?.y ?? 0) + (monitor?.reserved?.[1] ?? 0)) - geometryScaleX: specialWorkspaceTile.fitScale / root.scale - geometryScaleY: specialWorkspaceTile.fitScale / root.scale - xOffset: 0 - yOffset: 0 - widgetMonitorId: root.monitor.id - recaptureToken: root.previewRecaptureToken - restrictToWorkspace: false - animateSize: false - z: root.specialWindowZ(windowData) - - function moveToDragLayer() { - const mapped = specialWindow.mapToItem(specialWindowDragLayer, 0, 0); - specialWindow.suspendPositionAnimation = true; - specialWindow.parent = specialWindowDragLayer; - specialWindow.x = mapped.x; - specialWindow.y = mapped.y; - specialWindow.z = root.windowDraggingZ + 1; - Qt.callLater(() => specialWindow.suspendPositionAnimation = false); - } - - function returnToHomeParent() { - specialWindow.suspendPositionAnimation = true; - specialWindow.parent = homeParent; - specialWindow.z = root.specialWindowZ(windowData); - Qt.callLater(() => specialWindow.suspendPositionAnimation = false); - } - - MouseArea { - id: specialDragArea - anchors.fill: parent - hoverEnabled: true - onEntered: hovered = true - onExited: hovered = false - acceptedButtons: Qt.LeftButton | Qt.MiddleButton - drag.target: parent - onPressed: (mouse) => { - root.draggingFromWorkspace = -1 - root.draggingTargetSpecialWorkspace = "" - specialWindow.pressed = true - specialWindow.dragInProgress = true - specialWindow.Drag.source = specialWindow - specialWindow.Drag.hotSpot.x = mouse.x - specialWindow.Drag.hotSpot.y = mouse.y - specialWindow.moveToDragLayer() - specialWindow.Drag.active = true - } - onReleased: { - const targetWorkspace = root.draggingTargetWorkspace - const targetSpecialWorkspace = root.draggingTargetSpecialWorkspace - specialWindow.pressed = false - specialWindow.Drag.active = false - specialWindow.dragInProgress = false - root.draggingFromWorkspace = -1 - root.draggingTargetWorkspace = -1 - root.draggingTargetSpecialWorkspace = "" - if (targetSpecialWorkspace === root.createSpecialWorkspaceTarget) { - const createdName = root.nextSpecialWorkspaceName() - //INFO: From special TO NEW special - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.move({workspace = 'special:${createdName}', follow = false, window = 'address:${specialWindow.windowData?.address}'})`); - } else { - Hyprland.dispatch(`movetoworkspacesilent special:${createdName}, address:${specialWindow.windowData?.address}`) - } - specialWindow.returnToHomeParent() - specialWindow.x = specialWindow.initX - specialWindow.y = specialWindow.initY - } - else if (targetSpecialWorkspace && targetSpecialWorkspace !== specialWorkspaceTile.specialName) { - // Idk - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.move({workspace = 'special:${targetSpecialWorkspace}', follow = false, window = 'address:${specialWindow.windowData?.address}'})`); - } else { - Hyprland.dispatch(`movetoworkspacesilent special:${targetSpecialWorkspace}, address:${specialWindow.windowData?.address}`) - } - specialWindow.returnToHomeParent() - specialWindow.x = specialWindow.initX - specialWindow.y = specialWindow.initY - } - else if (targetWorkspace !== -1) { - //INFO: From Special TO Normal workspace - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.move({workspace = '${targetWorkspace}', follow = false, window = 'address:${specialWindow.windowData?.address}'})`); - } else { - Hyprland.dispatch(`movetoworkspacesilent ${targetWorkspace}, address:${specialWindow.windowData?.address}`) - } - specialWindow.returnToHomeParent() - specialWindow.x = specialWindow.initX - specialWindow.y = specialWindow.initY - } - else { - specialWindow.returnToHomeParent() - specialWindow.x = specialWindow.initX - specialWindow.y = specialWindow.initY - } - } - onClicked: (event) => { - if (!windowData) - return; - if (event.button === Qt.LeftButton) { - GlobalStates.overviewOpen = false; - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.focus({ window = 'address:${windowData.address}' })`); - } else { - Hyprland.dispatch(`focuswindow address:${windowData.address}`); - } - event.accepted = true; - } else if (event.button === Qt.MiddleButton) { - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.close('address:${windowData.address}')`); - } else { - Hyprland.dispatch(`closewindow address:${windowData.address}`); - } - event.accepted = true; - } - } - - StyledToolTip { - extraVisibleCondition: false - alternativeVisibleCondition: specialDragArea.containsMouse && !specialWindow.Drag.active - text: `${windowData?.title ?? "Unknown"}\n[${windowData?.class ?? "unknown"}] ${windowData?.xwayland ? "[XWayland] " : ""}` - } - } - } - } - } - } - } - Rectangle { - id: createSpecialWorkspaceTile - property bool showWallpaper: root.hasSpecialEmptyWorkspaceWallpaper - implicitWidth: root.specialWorkspaceTileWidth - implicitHeight: root.specialWorkspaceTileHeight - radius: Appearance.rounding.screenRounding * root.scale - color: showWallpaper ? "transparent" : ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(Appearance.colors.colSecondaryContainer, Appearance.colors.colLayer1, 0.58) - : ColorUtils.mix(Appearance.colors.colLayer2, Appearance.colors.colLayer1, 0.55), - root.draggingTargetSpecialWorkspace === root.createSpecialWorkspaceTarget ? 0.90 : root.effectiveWorkspaceOpacity - ) - border.width: 1 - border.color: root.draggingTargetSpecialWorkspace === root.createSpecialWorkspaceTarget - ? ColorUtils.applyAlpha(root.activeBorderColor, 0.96) - : ColorUtils.applyAlpha(Appearance.colors.colSecondary, 0.46) - - Image { - visible: createSpecialWorkspaceTile.showWallpaper - anchors.fill: parent - source: root.wallpaperSource(root.specialEmptyWorkspaceWallpaperPath) - fillMode: Image.PreserveAspectCrop - asynchronous: true - cache: true - smooth: true - mipmap: true - } - - Rectangle { - visible: createSpecialWorkspaceTile.showWallpaper - anchors.fill: parent - radius: parent.radius - color: ColorUtils.applyAlpha( - root.glassMode - ? ColorUtils.mix(Appearance.colors.colSecondaryContainer, Appearance.colors.colLayer0, 0.40) - : ColorUtils.mix(Appearance.colors.colLayer2, Appearance.colors.colLayer1, 0.55), - root.draggingTargetSpecialWorkspace === root.createSpecialWorkspaceTarget - ? Math.min(0.28, root.emptyWorkspaceWallpaperOverlayOpacity + 0.08) - : root.emptyWorkspaceWallpaperOverlayOpacity - ) - } - - Rectangle { - anchors.fill: parent - anchors.margins: 1 - radius: Math.max(parent.radius - 1, 0) - color: "transparent" - border.width: 1 - border.color: ColorUtils.applyAlpha("#FFFFFF", root.glassMode ? 0.12 : 0.08) - } - - Column { - anchors.centerIn: parent - spacing: 0 - - StyledText { - anchors.horizontalCenter: parent.horizontalCenter - visible: !createSpecialWorkspaceTile.showWallpaper - text: root.draggingTargetSpecialWorkspace === root.createSpecialWorkspaceTarget ? "Release" : "+" - font.family: Appearance.font.family.expressive - font.pixelSize: root.draggingTargetSpecialWorkspace === root.createSpecialWorkspaceTarget - ? Appearance.font.pixelSize.larger * root.scale - : Appearance.font.pixelSize.huge * 1.25 * root.scale - font.weight: Font.DemiBold - color: ColorUtils.applyAlpha(Appearance.colors.colOnLayer1, 0.92) - horizontalAlignment: Text.AlignHCenter - } - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - onClicked: { - const createdName = root.nextSpecialWorkspaceName(); - GlobalStates.overviewOpen = false; - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.workspace.toggle_special('${createdName}')`); - } else { - Hyprland.dispatch(`togglespecialworkspace ${createdName}`); - } - } - } - - DropArea { - anchors.fill: parent - onEntered: { - root.draggingTargetWorkspace = -1; - root.draggingTargetSpecialWorkspace = root.createSpecialWorkspaceTarget; - } - onExited: { - if (root.draggingTargetSpecialWorkspace === root.createSpecialWorkspaceTarget) - root.draggingTargetSpecialWorkspace = ""; - } - } - } - } } } } @@ -1005,20 +141,8 @@ Item { Item { // Windows & focused workspace indicator id: windowSpace anchors.centerIn: parent - implicitWidth: contentLayout.implicitWidth - implicitHeight: contentLayout.implicitHeight - - WheelHandler { - target: null - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - onWheel: event => { - const deltaY = event.angleDelta.y; - if (!deltaY) - return; - root.stepWorkspace(deltaY > 0 ? -1 : 1); - event.accepted = true; - } - } + implicitWidth: workspaceColumnLayout.implicitWidth + implicitHeight: workspaceColumnLayout.implicitHeight Repeater { // Window repeater model: ScriptModel { @@ -1026,11 +150,7 @@ Item { return ToplevelManager.toplevels.values.filter((toplevel) => { const address = `0x${toplevel.HyprlandToplevel.address}` var win = windowByAddress[address] - if (root.isSpecialWorkspace(win)) - return false; - const minWorkspace = root.workspaceGroup * root.workspacesShown + 1 + workspaceOffset; - const maxWorkspace = (root.workspaceGroup + 1) * root.workspacesShown + workspaceOffset; - const inWorkspaceGroup = (minWorkspace <= win?.workspace?.id && win?.workspace?.id <= maxWorkspace) + const inWorkspaceGroup = (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown) return inWorkspaceGroup; }).sort((a, b) => { // Proper stacking order based on Hyprland's window properties @@ -1038,17 +158,17 @@ Item { const addrB = `0x${b.HyprlandToplevel.address}` const winA = windowByAddress[addrA] const winB = windowByAddress[addrB] - + // 1. Pinned windows are always on top if (winA?.pinned !== winB?.pinned) { return winA?.pinned ? 1 : -1 } - + // 2. Floating windows above tiled windows if (winA?.floating !== winB?.floating) { return winA?.floating ? 1 : -1 } - + // 3. Within same category, sort by focus history // Lower focusHistoryID = more recently focused = higher in stack return (winB?.focusHistoryID ?? 0) - (winA?.focusHistoryID ?? 0) @@ -1065,20 +185,31 @@ Item { windowData: windowByAddress[address] toplevel: modelData monitorData: monitor - widgetMonitorData: root.monitorData - scale: root.scale + + // Calculate scale relative to window's source monitor + property real sourceMonitorWidth: (monitor?.transform % 2 === 1) ? + (monitor?.height ?? 1920) / (monitor?.scale ?? 1) - (monitor?.reserved?.[0] ?? 0) - (monitor?.reserved?.[2] ?? 0) : + (monitor?.width ?? 1920) / (monitor?.scale ?? 1) - (monitor?.reserved?.[0] ?? 0) - (monitor?.reserved?.[2] ?? 0) + property real sourceMonitorHeight: (monitor?.transform % 2 === 1) ? + (monitor?.width ?? 1080) / (monitor?.scale ?? 1) - (monitor?.reserved?.[1] ?? 0) - (monitor?.reserved?.[3] ?? 0) : + (monitor?.height ?? 1080) / (monitor?.scale ?? 1) - (monitor?.reserved?.[1] ?? 0) - (monitor?.reserved?.[3] ?? 0) + + // Scale windows to fit the workspace size, accounting for different monitor sizes + scale: Math.min( + root.workspaceImplicitWidth / sourceMonitorWidth, + root.workspaceImplicitHeight / sourceMonitorHeight + ) + availableWorkspaceWidth: root.workspaceImplicitWidth availableWorkspaceHeight: root.workspaceImplicitHeight widgetMonitorId: root.monitor.id - recaptureToken: root.previewRecaptureToken property bool atInitPosition: (initX == x && initY == y) - property int workspaceColIndex: root.getWorkspaceColumn(windowData?.workspace.id) - property int workspaceRowIndex: root.getWorkspaceRow(windowData?.workspace.id) - property int visibleWorkspaceRowIndex: root.getVisibleRowPosition(workspaceRowIndex) + property int workspaceColIndex: (windowData?.workspace.id - 1) % Config.options.overview.columns + property int workspaceRowIndex: Math.floor((windowData?.workspace.id - 1) % root.workspacesShown / Config.options.overview.columns) xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex - yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * visibleWorkspaceRowIndex + yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * workspaceRowIndex Timer { id: updateWindowPosition @@ -1086,8 +217,8 @@ Item { repeat: false running: false onTriggered: { - window.x = Math.round(Math.max((windowData?.at[0] - (monitor?.x ?? 0) - (monitorData?.reserved?.[0] ?? 0)) * root.scale * window.widthRatio, 0) + xOffset) - window.y = Math.round(Math.max((windowData?.at[1] - (monitor?.y ?? 0) - (monitorData?.reserved?.[1] ?? 0)) * root.scale * window.heightRatio, 0) + yOffset) + window.x = Math.round(Math.max((windowData?.at[0] - (monitor?.x ?? 0) - (monitorData?.reserved?.[0] ?? 0)) * root.scale, 0) + xOffset) + window.y = Math.round(Math.max((windowData?.at[1] - (monitor?.y ?? 0) - (monitorData?.reserved?.[1] ?? 0)) * root.scale, 0) + yOffset) } } @@ -1104,7 +235,6 @@ Item { drag.target: parent onPressed: (mouse) => { root.draggingFromWorkspace = windowData?.workspace.id - root.draggingTargetSpecialWorkspace = "" window.pressed = true window.Drag.active = true window.Drag.source = window @@ -1113,38 +243,11 @@ Item { } onReleased: { const targetWorkspace = root.draggingTargetWorkspace - const targetSpecialWorkspace = root.draggingTargetSpecialWorkspace window.pressed = false window.Drag.active = false root.draggingFromWorkspace = -1 - root.draggingTargetWorkspace = -1 - root.draggingTargetSpecialWorkspace = "" - if (targetSpecialWorkspace === root.createSpecialWorkspaceTarget) { - const createdName = root.nextSpecialWorkspaceName() - //INFO: From normal TO special - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.move({workspace = 'special:${createdName}', follow = false, window = 'address:${window.windowData?.address}'})`); - } else { - Hyprland.dispatch(`movetoworkspacesilent special:${createdName}, address:${window.windowData?.address}`) - } - updateWindowPosition.restart() - } - else if (targetSpecialWorkspace && targetSpecialWorkspace !== root.specialWorkspaceName(windowData)) { - // Idk - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.move({workspace = 'special:${targetSpecialWorkspace}', follow = false, window = 'address:${window.windowData?.address}'})`); - } else { - Hyprland.dispatch(`movetoworkspacesilent special:${targetSpecialWorkspace}, address:${window.windowData?.address}`) - } - updateWindowPosition.restart() - } - else if (targetWorkspace !== -1 && targetWorkspace !== windowData?.workspace.id) { - //INFO: From normal TO normal - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.move({workspace = '${targetWorkspace}', follow = false, window = 'address:${window.windowData?.address}'})`); - } else { - Hyprland.dispatch(`movetoworkspacesilent ${targetWorkspace}, address:${window.windowData?.address}`) - } + if (targetWorkspace !== -1 && targetWorkspace !== windowData?.workspace.id) { + Hyprland.dispatch(`movetoworkspacesilent ${targetWorkspace}, address:${window.windowData?.address}`) updateWindowPosition.restart() } else { @@ -1157,18 +260,10 @@ Item { if (event.button === Qt.LeftButton) { GlobalStates.overviewOpen = false - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.focus({ window = 'address:${windowData.address}' })`); - } else { - Hyprland.dispatch(`focuswindow address:${windowData.address}`) - } + Hyprland.dispatch(`focuswindow address:${windowData.address}`) event.accepted = true } else if (event.button === Qt.MiddleButton) { - if (Hyprland.usingLua) { - Hyprland.dispatch(`hl.dsp.window.close('address:${windowData.address}')`); - } else { - Hyprland.dispatch(`closewindow address:${windowData.address}`) - } + Hyprland.dispatch(`closewindow address:${windowData.address}`) event.accepted = true } } @@ -1184,12 +279,12 @@ Item { Rectangle { // Focused workspace indicator id: focusedWorkspaceIndicator - property int activeWorkspaceRowIndex: root.getWorkspaceRow(root.effectiveActiveWorkspaceId) - property int visibleActiveWorkspaceRowIndex: root.getVisibleRowPosition(activeWorkspaceRowIndex) - property int activeWorkspaceColIndex: root.getWorkspaceColumn(root.effectiveActiveWorkspaceId) + property int activeWorkspaceInGroup: monitor.activeWorkspace?.id - (root.workspaceGroup * root.workspacesShown) + property int activeWorkspaceRowIndex: Math.floor((activeWorkspaceInGroup - 1) / Config.options.overview.columns) + property int activeWorkspaceColIndex: (activeWorkspaceInGroup - 1) % Config.options.overview.columns x: (root.workspaceImplicitWidth + workspaceSpacing) * activeWorkspaceColIndex - y: (root.workspaceImplicitHeight + workspaceSpacing) * visibleActiveWorkspaceRowIndex - z: root.windowDraggingZ - 1 + y: (root.workspaceImplicitHeight + workspaceSpacing) * activeWorkspaceRowIndex + z: root.windowZ width: root.workspaceImplicitWidth height: root.workspaceImplicitHeight color: "transparent" @@ -1204,11 +299,5 @@ Item { } } } - - Item { - id: specialWindowDragLayer - anchors.fill: parent - z: root.windowDraggingZ + 1 - } } } diff --git a/config/quickshell/overview/modules/overview/OverviewWindow.qml b/config/quickshell/overview/modules/overview/OverviewWindow.qml index 3b2652a9..fac3e22e 100644 --- a/config/quickshell/overview/modules/overview/OverviewWindow.qml +++ b/config/quickshell/overview/modules/overview/OverviewWindow.qml @@ -1,6 +1,6 @@ +import QtQuick.Effects import QtQuick import QtQuick.Layouts -import QtQuick.Effects import Quickshell import Quickshell.Wayland import "../../common" @@ -12,197 +12,75 @@ Item { // Window property var toplevel property var windowData property var monitorData - property var widgetMonitorData property var scale property var availableWorkspaceWidth property var availableWorkspaceHeight - property real positionBaseX: (monitorData?.x ?? 0) + (monitorData?.reserved?.[0] ?? 0) - property real positionBaseY: (monitorData?.y ?? 0) + (monitorData?.reserved?.[1] ?? 0) - property int recaptureToken: 0 property bool restrictToWorkspace: true - property real widthRatio: { - if (!widgetMonitorData || !monitorData) - return 1; - - const widgetWidth = (widgetMonitorData.transform % 2 === 1) ? (widgetMonitorData.height ?? 1) : (widgetMonitorData.width ?? 1); - const sourceWidth = (monitorData.transform % 2 === 1) ? (monitorData.height ?? 1) : (monitorData.width ?? 1); - const sourceScale = monitorData.scale ?? 1; - const widgetScale = widgetMonitorData.scale ?? 1; - return (widgetWidth * sourceScale) / (sourceWidth * widgetScale); - } - property real heightRatio: { - if (!widgetMonitorData || !monitorData) - return 1; - - const widgetHeight = (widgetMonitorData.transform % 2 === 1) ? (widgetMonitorData.width ?? 1) : (widgetMonitorData.height ?? 1); - const sourceHeight = (monitorData.transform % 2 === 1) ? (monitorData.width ?? 1) : (monitorData.height ?? 1); - const sourceScale = monitorData.scale ?? 1; - const widgetScale = widgetMonitorData.scale ?? 1; - return (widgetHeight * sourceScale) / (sourceHeight * widgetScale); - } - property real initX: Math.max(((windowData?.at[0] ?? 0) - positionBaseX) * root.scale * geometryScaleX, 0) + xOffset - property real initY: Math.max(((windowData?.at[1] ?? 0) - positionBaseY) * root.scale * geometryScaleY, 0) + yOffset + property real initX: Math.max(((windowData?.at[0] ?? 0) - (monitorData?.x ?? 0) - (monitorData?.reserved?.[0] ?? 0)) * root.scale, 0) + xOffset + property real initY: Math.max(((windowData?.at[1] ?? 0) - (monitorData?.y ?? 0) - (monitorData?.reserved?.[1] ?? 0)) * root.scale, 0) + yOffset property real xOffset: 0 property real yOffset: 0 property int widgetMonitorId: 0 - property real geometryScaleX: widthRatio - property real geometryScaleY: heightRatio - property var targetWindowWidth: (windowData?.size[0] ?? 100) * scale * geometryScaleX - property var targetWindowHeight: (windowData?.size[1] ?? 100) * scale * geometryScaleY + property var targetWindowWidth: (windowData?.size[0] ?? 100) * scale + property var targetWindowHeight: (windowData?.size[1] ?? 100) * scale property bool hovered: false property bool pressed: false - property bool showIcons: Config.options.windowPreview.showIcons - property var iconToWindowRatio: Config.options.windowPreview.iconToWindowRatio - property var xwaylandIndicatorToIconRatio: Config.options.windowPreview.xwaylandIndicatorToIconRatio - property var iconToWindowRatioCompact: Config.options.windowPreview.iconToWindowRatioCompact - property bool cropToFill: Config.options.windowPreview.cropToFill - property bool previewsEnabled: Config.options.overview.previewsEnabled - property bool includeInactiveMonitorPreviews: Config.options.overview.includeInactiveMonitorPreviews - property int previewRecaptureDelayMs: Config.options.overview.previewRecaptureDelayMs - property real windowOverlayOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.windowOverlayOpacity)) - property bool glassMode: Config.options.overview.effects.glassMode - property real glassShineOpacity: Math.max(0, Math.min(1, Config.options.overview.effects.glassShineOpacity)) - property real effectiveWindowOverlayOpacity: glassMode ? Math.min(windowOverlayOpacity, 0.10) : windowOverlayOpacity - property string previewModeRaw: Config.options.overview.previewMode - property string previewMode: { - const mode = `${previewModeRaw ?? "live"}`.trim().toLowerCase(); - return (mode === "event" || mode === "snapshot") ? "event" : "live"; - } - property bool livePreviewEnabled: previewsEnabled && previewMode === "live" - property bool shouldCapturePreview: { - if (!GlobalStates.overviewOpen || !previewsEnabled || !previewCaptureEnabled) - return false; - if (includeInactiveMonitorPreviews) - return true; - return (windowData?.monitor ?? -1) === widgetMonitorId; - } - property var entry: { - DesktopEntries.applications.values; // re-run when the entry index updates - return DesktopEntries.heuristicLookup(windowData?.class); - } - property string iconName: { - const raw = `${entry?.icon ?? ""}`.trim(); - const withoutProviderPrefix = raw.replace(/^image:\/\/icon\//, ""); - const withoutQuery = withoutProviderPrefix.split("?")[0].trim(); - return withoutQuery.length > 0 ? withoutQuery : "application-x-executable"; - } - property var iconPath: Quickshell.iconPath(iconName, "image-missing") + property var iconToWindowRatio: 0.25 + property var xwaylandIndicatorToIconRatio: 0.35 + property var iconToWindowRatioCompact: 0.45 + property var entry: DesktopEntries.heuristicLookup(windowData?.class) + property var iconPath: Quickshell.iconPath(entry?.icon ?? windowData?.class ?? "application-x-executable", "image-missing") property bool compactMode: Appearance.font.pixelSize.smaller * 4 > targetWindowHeight || Appearance.font.pixelSize.smaller * 4 > targetWindowWidth property bool indicateXWayland: windowData?.xwayland ?? false - property bool previewCaptureEnabled: true - property bool initialized: false - property bool dragInProgress: false - property bool suspendPositionAnimation: false - property bool animateSize: true x: initX y: initY - width: Math.min(targetWindowWidth, availableWorkspaceWidth) - height: Math.min(targetWindowHeight, availableWorkspaceHeight) - opacity: (windowData?.monitor ?? -1) == widgetMonitorId ? 1 : Config.options.windowPreview.inactiveMonitorOpacity - visible: { - const thisWsId = windowData?.workspace?.id; - const isFullscreen = (windowData?.fullscreen ?? 0) > 0; - if (isFullscreen || thisWsId === undefined) return true; - return !HyprlandData.windowList.some(w => w.workspace?.id === thisWsId && (w.fullscreen ?? 0) > 0); - } + width: Math.min((windowData?.size[0] ?? 100) * root.scale, availableWorkspaceWidth) + height: Math.min((windowData?.size[1] ?? 100) * root.scale, availableWorkspaceHeight) + opacity: (windowData?.monitor ?? -1) == widgetMonitorId ? 1 : 0.4 - clip: true - Component.onCompleted: Qt.callLater(() => root.initialized = true) + layer.enabled: true + layer.smooth: true + layer.mipmap: true Behavior on x { - enabled: root.initialized && !root.dragInProgress && !root.suspendPositionAnimation animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) } Behavior on y { - enabled: root.initialized && !root.dragInProgress && !root.suspendPositionAnimation animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) } Behavior on width { - enabled: root.initialized && root.animateSize && !root.dragInProgress && !root.suspendPositionAnimation animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) } Behavior on height { - enabled: root.initialized && root.animateSize && !root.dragInProgress && !root.suspendPositionAnimation animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) } - // Opaque background for windows on the active monitor. - // The simplest solution for making those windows fully opaque and not interacting with actual - // windows behind the overview, e.g., applying blur to them. Rectangle { - visible: (root.windowData?.monitor ?? -1) === root.widgetMonitorId + id: clipContainer anchors.fill: parent radius: Appearance.rounding.windowRounding * root.scale - color: root.glassMode - ? ColorUtils.mix(Appearance.colors.colLayer2, Appearance.colors.colLayer0, 0.38) - : Appearance.colors.colLayer2 - } + clip: true + color: "transparent" - ScreencopyView { - id: windowPreview - readonly property real srcAspect: { - const w = root.windowData?.size?.[0] ?? 0; - const h = root.windowData?.size?.[1] ?? 0; - return (w > 0 && h > 0) ? (w / h) : 1; - } - anchors.centerIn: parent - width: root.cropToFill - ? Math.max(parent.width, parent.height * srcAspect) - : Math.min(parent.width, parent.height * srcAspect) - height: root.cropToFill - ? Math.max(parent.height, parent.width / srcAspect) - : Math.min(parent.height, parent.width / srcAspect) - captureSource: shouldCapturePreview ? root.toplevel : null - live: livePreviewEnabled - layer.enabled: true - layer.smooth: true - layer.effect: MultiEffect { - maskEnabled: true - maskSource: previewMask - maskThresholdMin: 0.5 - maskSpreadAtMin: 1.0 - } - } - - Rectangle { - anchors.fill: parent - radius: Appearance.rounding.windowRounding * root.scale - color: pressed ? ColorUtils.applyAlpha(Appearance.colors.colLayer2Active, Math.min(1, root.effectiveWindowOverlayOpacity + 0.30)) : - hovered ? ColorUtils.applyAlpha(Appearance.colors.colLayer2Hover, Math.min(1, root.effectiveWindowOverlayOpacity + 0.20)) : - ColorUtils.applyAlpha( - root.glassMode ? ColorUtils.mix(Appearance.colors.colLayer2, Appearance.colors.colLayer0, 0.38) : Appearance.colors.colLayer2, - root.effectiveWindowOverlayOpacity - ) - border.color: root.glassMode - ? ColorUtils.applyAlpha(Appearance.m3colors.m3outline, 0.62) - : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.7) - border.width: 1 - - Rectangle { - visible: root.glassMode + ScreencopyView { + id: windowPreview anchors.fill: parent - radius: parent.radius - color: "transparent" - gradient: Gradient { - GradientStop { position: 0.0; color: ColorUtils.applyAlpha("#FFFFFF", root.glassShineOpacity * 0.24) } - GradientStop { position: 0.5; color: ColorUtils.applyAlpha("#FFFFFF", 0.0) } - GradientStop { position: 1.0; color: ColorUtils.applyAlpha("#000000", root.glassShineOpacity * 0.14) } - } - } + captureSource: GlobalStates.overviewOpen ? root.toplevel : null + live: true - Rectangle { - visible: root.glassMode - anchors.fill: parent - anchors.margins: 1 - radius: Math.max(parent.radius - 1, 0) - color: "transparent" - border.width: 1 - border.color: ColorUtils.applyAlpha("#FFFFFF", root.glassShineOpacity * 0.32) - } + Rectangle { + anchors.fill: parent + radius: Appearance.rounding.windowRounding * root.scale + color: pressed ? ColorUtils.transparentize(Appearance.colors.colLayer2Active, 0.5) : + hovered ? ColorUtils.transparentize(Appearance.colors.colLayer2Hover, 0.7) : + ColorUtils.transparentize(Appearance.colors.colLayer2) + border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.7) + border.width : 1 + } ColumnLayout { anchors.verticalCenter: parent.verticalCenter @@ -212,53 +90,23 @@ Item { // Window Image { id: windowIcon - visible: root.showIcons property var iconSize: { - const renderedSize = Math.min(root.width, root.height); - return renderedSize * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / (root.monitorData?.scale ?? 1); + return Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / (root.monitorData?.scale ?? 1); } Layout.alignment: Qt.AlignHCenter source: root.iconPath width: iconSize height: iconSize - sourceSize: Qt.size(Math.max(1, Math.round(iconSize)), Math.max(1, Math.round(iconSize))) - } - } - } + sourceSize: Qt.size(iconSize, iconSize) - Item { - id: previewMask - width: windowPreview.width - height: windowPreview.height - anchors.centerIn: parent - visible: false - layer.enabled: true - layer.smooth: true - Rectangle { - anchors.centerIn: parent - width: root.width - height: root.height - radius: Appearance.rounding.windowRounding * root.scale + Behavior on width { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + Behavior on height { + animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) + } + } } } - - function refreshCapture() { - if (!GlobalStates.overviewOpen || livePreviewEnabled || !previewsEnabled) - return; - - root.previewCaptureEnabled = false; - previewResetTimer.restart(); - } - - Timer { - id: previewResetTimer - interval: Math.max(1, previewRecaptureDelayMs) - repeat: false - onTriggered: root.previewCaptureEnabled = true - } - - onRecaptureTokenChanged: { - if (recaptureToken > 0) - root.refreshCapture(); } } |
