aboutsummaryrefslogtreecommitdiffstats
path: root/config/quickshell/overview-backup/modules/overview/Overview.qml
diff options
context:
space:
mode:
Diffstat (limited to 'config/quickshell/overview-backup/modules/overview/Overview.qml')
-rw-r--r--config/quickshell/overview-backup/modules/overview/Overview.qml252
1 files changed, 252 insertions, 0 deletions
diff --git a/config/quickshell/overview-backup/modules/overview/Overview.qml b/config/quickshell/overview-backup/modules/overview/Overview.qml
new file mode 100644
index 00000000..2fb08bb9
--- /dev/null
+++ b/config/quickshell/overview-backup/modules/overview/Overview.qml
@@ -0,0 +1,252 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Quickshell
+import Quickshell.Io
+import Quickshell.Wayland
+import Quickshell.Hyprland
+import "../../common"
+import "../../services"
+import "."
+
+Scope {
+ id: overviewScope
+ Variants {
+ id: overviewVariants
+ model: Quickshell.screens
+ PanelWindow {
+ id: root
+ 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.layer: WlrLayer.Overlay
+ WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
+ color: "transparent"
+
+ anchors {
+ top: true
+ bottom: true
+ left: true
+ right: true
+ }
+
+ HyprlandFocusGrab {
+ id: grab
+ windows: [root]
+ property bool canBeActive: root.monitorIsFocused
+ active: false
+ onCleared: () => {
+ // Only the monitor that owns the grab may close the overview
+ if (root.closeOnFocusLoss && !active && canBeActive)
+ GlobalStates.overviewOpen = false;
+ }
+ }
+
+ Connections {
+ target: GlobalStates
+ function onOverviewOpenChanged() {
+ if (GlobalStates.overviewOpen) {
+ delayedGrabTimer.start();
+ }
+ }
+ }
+
+ // 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
+ repeat: false
+ onTriggered: {
+ if (!grab.canBeActive)
+ return;
+ grab.active = GlobalStates.overviewOpen;
+ }
+ }
+
+ // Keep the layershell surface full-screen so backdrop/blur are not constrained by content size.
+ implicitWidth: screen.width
+ implicitHeight: screen.height
+
+ 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_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);
+ }
+ event.accepted = true;
+ }
+ }
+ }
+
+ ColumnLayout {
+ id: columnLayout
+ visible: GlobalStates.overviewOpen
+ z: 1
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ topMargin: Config.options.position.topMargin
+ }
+
+ Loader {
+ id: overviewLoader
+ active: Config?.options.overview.enable ?? true
+ sourceComponent: OverviewWidget {
+ panelWindow: root
+ visible: true
+ }
+ }
+ }
+ }
+ }
+
+ IpcHandler {
+ target: "overview"
+
+ function toggle() {
+ GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
+ }
+ function close() {
+ GlobalStates.overviewOpen = false;
+ }
+ function open() {
+ GlobalStates.overviewOpen = true;
+ }
+ }
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage