148 lines
5.3 KiB
QML
148 lines
5.3 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Wayland
|
|
import Quickshell.Hyprland
|
|
import qs.Config
|
|
|
|
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)
|
|
screen: modelData
|
|
visible: false
|
|
|
|
WlrLayershell.namespace: "quickshell:overview"
|
|
WlrLayershell.layer: WlrLayer.Overlay
|
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
|
color: "transparent"
|
|
|
|
mask: Region {
|
|
item: keyHandler
|
|
}
|
|
|
|
anchors {
|
|
top: true
|
|
bottom: true
|
|
left: true
|
|
right: true
|
|
}
|
|
|
|
HyprlandFocusGrab {
|
|
id: grab
|
|
windows: [root]
|
|
property bool canBeActive: root.monitorIsFocused
|
|
active: false
|
|
onCleared: () => {
|
|
if (!active)
|
|
root.visible = false;
|
|
}
|
|
}
|
|
|
|
implicitWidth: columnLayout.implicitWidth
|
|
implicitHeight: columnLayout.implicitHeight
|
|
|
|
Item {
|
|
id: keyHandler
|
|
anchors.fill: parent
|
|
visible: root.visible
|
|
focus: root.visible
|
|
|
|
Keys.onPressed: event => {
|
|
// close: Escape or Enter
|
|
if (event.key === Qt.Key_Escape || event.key === Qt.Key_Return) {
|
|
root.visible = false;
|
|
event.accepted = true;
|
|
return;
|
|
}
|
|
|
|
// Helper: compute current group bounds
|
|
const workspacesPerGroup = Config.overview.rows * Config.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 = null;
|
|
|
|
// Arrow keys and vim-style hjkl
|
|
if (event.key === Qt.Key_Left || event.key === Qt.Key_H) {
|
|
targetId = currentId - 1;
|
|
if (targetId < minWorkspaceId) targetId = maxWorkspaceId;
|
|
} else if (event.key === Qt.Key_Right || event.key === Qt.Key_L) {
|
|
targetId = currentId + 1;
|
|
if (targetId > maxWorkspaceId) targetId = minWorkspaceId;
|
|
} else if (event.key === Qt.Key_Up || event.key === Qt.Key_K) {
|
|
targetId = currentId - Config.overview.columns;
|
|
if (targetId < minWorkspaceId) targetId += workspacesPerGroup;
|
|
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_J) {
|
|
targetId = currentId + Config.overview.columns;
|
|
if (targetId > maxWorkspaceId) targetId -= workspacesPerGroup;
|
|
}
|
|
|
|
// 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) {
|
|
Hyprland.dispatch("workspace " + targetId);
|
|
event.accepted = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: columnLayout
|
|
visible: root.visible
|
|
anchors {
|
|
horizontalCenter: parent.horizontalCenter
|
|
top: parent.top
|
|
topMargin: 100
|
|
}
|
|
|
|
Loader {
|
|
id: overviewLoader
|
|
active: true && (Config.overview.enable ?? true)
|
|
sourceComponent: OverviewWidget {
|
|
panelWindow: root
|
|
visible: true
|
|
}
|
|
}
|
|
}
|
|
IpcHandler {
|
|
target: "overview"
|
|
|
|
function toggle() {
|
|
root.visible = !root.visible;
|
|
}
|
|
function close() {
|
|
root.visible = false;
|
|
}
|
|
function open() {
|
|
root.visible = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|