forked from Shinonome/dots-hyprland
fix(quickshell): hide lock-screen temp workspace from UI, batch lock/unlock
This commit is contained in:
@@ -18,9 +18,11 @@ Item {
|
|||||||
property bool borderless: Config.options.bar.borderless
|
property bool borderless: Config.options.bar.borderless
|
||||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.QsWindow.window?.screen)
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(root.QsWindow.window?.screen)
|
||||||
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
|
||||||
|
// Clamp to avoid lock-screen temp workspace (2147483647 - N) leaking into UI
|
||||||
|
readonly property int effectiveActiveWorkspaceId: Math.max(1, Math.min(100, monitor?.activeWorkspace?.id ?? 1))
|
||||||
|
|
||||||
readonly property int workspacesShown: Config.options.bar.workspaces.shown
|
readonly property int workspacesShown: Config.options.bar.workspaces.shown
|
||||||
readonly property int workspaceGroup: Math.floor((monitor?.activeWorkspace?.id - 1) / root.workspacesShown)
|
readonly property int workspaceGroup: Math.floor((effectiveActiveWorkspaceId - 1) / root.workspacesShown)
|
||||||
property list<bool> workspaceOccupied: []
|
property list<bool> workspaceOccupied: []
|
||||||
property int widgetPadding: 4
|
property int widgetPadding: 4
|
||||||
property int workspaceButtonWidth: 26
|
property int workspaceButtonWidth: 26
|
||||||
@@ -29,7 +31,7 @@ Item {
|
|||||||
property real workspaceIconSizeShrinked: workspaceButtonWidth * 0.55
|
property real workspaceIconSizeShrinked: workspaceButtonWidth * 0.55
|
||||||
property real workspaceIconOpacityShrinked: 1
|
property real workspaceIconOpacityShrinked: 1
|
||||||
property real workspaceIconMarginShrinked: -4
|
property real workspaceIconMarginShrinked: -4
|
||||||
property int workspaceIndexInGroup: (monitor?.activeWorkspace?.id - 1) % root.workspacesShown
|
property int workspaceIndexInGroup: (effectiveActiveWorkspaceId - 1) % root.workspacesShown
|
||||||
|
|
||||||
property bool showNumbers: false
|
property bool showNumbers: false
|
||||||
Timer {
|
Timer {
|
||||||
@@ -122,8 +124,8 @@ Item {
|
|||||||
implicitWidth: workspaceButtonWidth
|
implicitWidth: workspaceButtonWidth
|
||||||
implicitHeight: workspaceButtonWidth
|
implicitHeight: workspaceButtonWidth
|
||||||
radius: (width / 2)
|
radius: (width / 2)
|
||||||
property var previousOccupied: (workspaceOccupied[index-1] && !(!activeWindow?.activated && monitor?.activeWorkspace?.id === index))
|
property var previousOccupied: (workspaceOccupied[index-1] && !(!activeWindow?.activated && root.effectiveActiveWorkspaceId === index))
|
||||||
property var rightOccupied: (workspaceOccupied[index+1] && !(!activeWindow?.activated && monitor?.activeWorkspace?.id === index+2))
|
property var rightOccupied: (workspaceOccupied[index+1] && !(!activeWindow?.activated && root.effectiveActiveWorkspaceId === index+2))
|
||||||
property var radiusPrev: previousOccupied ? 0 : (width / 2)
|
property var radiusPrev: previousOccupied ? 0 : (width / 2)
|
||||||
property var radiusNext: rightOccupied ? 0 : (width / 2)
|
property var radiusNext: rightOccupied ? 0 : (width / 2)
|
||||||
|
|
||||||
@@ -133,7 +135,7 @@ Item {
|
|||||||
bottomRightRadius: radiusNext
|
bottomRightRadius: radiusNext
|
||||||
|
|
||||||
color: ColorUtils.transparentize(Appearance.m3colors.m3secondaryContainer, 0.4)
|
color: ColorUtils.transparentize(Appearance.m3colors.m3secondaryContainer, 0.4)
|
||||||
opacity: (workspaceOccupied[index] && !(!activeWindow?.activated && monitor?.activeWorkspace?.id === index+1)) ? 1 : 0
|
opacity: (workspaceOccupied[index] && !(!activeWindow?.activated && root.effectiveActiveWorkspaceId === index+1)) ? 1 : 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||||
@@ -225,7 +227,7 @@ Item {
|
|||||||
}
|
}
|
||||||
text: Config.options?.bar.workspaces.numberMap[button.workspaceValue - 1] || button.workspaceValue
|
text: Config.options?.bar.workspaces.numberMap[button.workspaceValue - 1] || button.workspaceValue
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
color: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
color: (root.effectiveActiveWorkspaceId == button.workspaceValue) ?
|
||||||
Appearance.m3colors.m3onPrimary :
|
Appearance.m3colors.m3onPrimary :
|
||||||
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||||
Appearance.colors.colOnLayer1Inactive)
|
Appearance.colors.colOnLayer1Inactive)
|
||||||
@@ -245,7 +247,7 @@ Item {
|
|||||||
width: workspaceButtonWidth * 0.18
|
width: workspaceButtonWidth * 0.18
|
||||||
height: width
|
height: width
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
color: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
color: (root.effectiveActiveWorkspaceId == button.workspaceValue) ?
|
||||||
Appearance.m3colors.m3onPrimary :
|
Appearance.m3colors.m3onPrimary :
|
||||||
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||||
Appearance.colors.colOnLayer1Inactive)
|
Appearance.colors.colOnLayer1Inactive)
|
||||||
|
|||||||
@@ -11,11 +11,57 @@ import Quickshell.Hyprland
|
|||||||
LockScreen {
|
LockScreen {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
// Monitor name -> workspace id to restore on unlock (set when locking)
|
||||||
|
property var savedWorkspaces: ({})
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: restoreTimer
|
||||||
|
interval: 150
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
var batch = ""
|
||||||
|
for (var j = 0; j < Quickshell.screens.length; ++j) {
|
||||||
|
var monName = Quickshell.screens[j].name
|
||||||
|
var wsId = root.savedWorkspaces[monName]
|
||||||
|
if (wsId !== undefined && wsId >= 1 && wsId <= 100) {
|
||||||
|
batch += "dispatch focusmonitor " + monName + "; dispatch workspace " + wsId + "; "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (batch.length > 0) {
|
||||||
|
Quickshell.execDetached(["hyprctl", "--batch", batch + "reload"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lockSurface: LockSurface {
|
lockSurface: LockSurface {
|
||||||
context: root.context
|
context: root.context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push everything down
|
// Single batch for lock and unlock so we don't race multiple hyprctl calls
|
||||||
|
Connections {
|
||||||
|
target: GlobalStates
|
||||||
|
function onScreenLockedChanged() {
|
||||||
|
if (GlobalStates.screenLocked) {
|
||||||
|
// Lock: save workspace per monitor and move all to temp workspace in one batch
|
||||||
|
var next = {}
|
||||||
|
var batch = "keyword animation workspaces,1,7,menu_decel,slidevert; "
|
||||||
|
for (var i = 0; i < Quickshell.screens.length; ++i) {
|
||||||
|
var mon = Quickshell.screens[i].name
|
||||||
|
var mData = HyprlandData.monitors.find(m => m.name === mon)
|
||||||
|
var ws = (mData?.activeWorkspace?.id ?? 1)
|
||||||
|
if (ws < 1 || ws > 100) ws = 1
|
||||||
|
next[mon] = ws
|
||||||
|
batch += "dispatch focusmonitor " + mon + "; dispatch workspace " + (2147483647 - ws) + "; "
|
||||||
|
}
|
||||||
|
root.savedWorkspaces = next
|
||||||
|
Quickshell.execDetached(["hyprctl", "--batch", batch + "reload"])
|
||||||
|
} else {
|
||||||
|
restoreTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push everything down (visual only; workspace switch is in Connections above)
|
||||||
Variants {
|
Variants {
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
delegate: Scope {
|
delegate: Scope {
|
||||||
@@ -24,18 +70,6 @@ LockScreen {
|
|||||||
property string targetMonitorName: modelData.name
|
property string targetMonitorName: modelData.name
|
||||||
property int verticalMovementDistance: modelData.height
|
property int verticalMovementDistance: modelData.height
|
||||||
property int horizontalSqueeze: modelData.width * 0.2
|
property int horizontalSqueeze: modelData.width * 0.2
|
||||||
property int lastWorkspaceId
|
|
||||||
onShouldPushChanged: {
|
|
||||||
if (shouldPush) {
|
|
||||||
// Save workspace
|
|
||||||
print(targetMonitorName)
|
|
||||||
lastWorkspaceId = HyprlandData.monitors.find(m => m.name == targetMonitorName).activeWorkspace.id
|
|
||||||
// Set anim to vertical and move to very very big workspace for a sliding up effect
|
|
||||||
Quickshell.execDetached(["hyprctl", "--batch", `keyword animation workspaces,1,7,menu_decel,slidevert; dispatch workspace ${2147483647 - lastWorkspaceId}`]);
|
|
||||||
} else {
|
|
||||||
Quickshell.execDetached(["hyprctl", "--batch", `dispatch workspace ${lastWorkspaceId}; reload`]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ Item {
|
|||||||
required property var screen
|
required property var screen
|
||||||
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(screen)
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(screen)
|
||||||
readonly property var toplevels: ToplevelManager.toplevels
|
readonly property var toplevels: ToplevelManager.toplevels
|
||||||
|
// Clamp to avoid lock-screen temp workspace (2147483647 - N) leaking into UI
|
||||||
|
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 int workspacesShown: Config.options.overview.rows * Config.options.overview.columns
|
||||||
readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / workspacesShown)
|
readonly property int workspaceGroup: Math.floor((effectiveActiveWorkspaceId - 1) / workspacesShown)
|
||||||
property bool monitorIsFocused: (Hyprland.focusedMonitor?.name == monitor.name)
|
property bool monitorIsFocused: (Hyprland.focusedMonitor?.name == monitor.name)
|
||||||
property var windows: HyprlandData.windowList
|
property var windows: HyprlandData.windowList
|
||||||
property var windowByAddress: HyprlandData.windowByAddress
|
property var windowByAddress: HyprlandData.windowByAddress
|
||||||
@@ -301,8 +303,8 @@ Item {
|
|||||||
|
|
||||||
Rectangle { // Focused workspace indicator
|
Rectangle { // Focused workspace indicator
|
||||||
id: focusedWorkspaceIndicator
|
id: focusedWorkspaceIndicator
|
||||||
property int rowIndex: getWsRow(monitor.activeWorkspace?.id)
|
property int rowIndex: getWsRow(root.effectiveActiveWorkspaceId)
|
||||||
property int colIndex: getWsColumn(monitor.activeWorkspace?.id)
|
property int colIndex: getWsColumn(root.effectiveActiveWorkspaceId)
|
||||||
x: (root.workspaceImplicitWidth + workspaceSpacing) * colIndex
|
x: (root.workspaceImplicitWidth + workspaceSpacing) * colIndex
|
||||||
y: (root.workspaceImplicitHeight + workspaceSpacing) * rowIndex
|
y: (root.workspaceImplicitHeight + workspaceSpacing) * rowIndex
|
||||||
z: root.windowZ
|
z: root.windowZ
|
||||||
|
|||||||
@@ -139,7 +139,9 @@ Singleton {
|
|||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
id: workspacesCollector
|
id: workspacesCollector
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
root.workspaces = JSON.parse(workspacesCollector.text);
|
var rawWorkspaces = JSON.parse(workspacesCollector.text);
|
||||||
|
// Filter out invalid workspace ids (e.g. lock-screen temp workspace 2147483647 - N)
|
||||||
|
root.workspaces = rawWorkspaces.filter(ws => ws.id >= 1 && ws.id <= 100);
|
||||||
let tempWorkspaceById = {};
|
let tempWorkspaceById = {};
|
||||||
for (var i = 0; i < root.workspaces.length; ++i) {
|
for (var i = 0; i < root.workspaces.length; ++i) {
|
||||||
var ws = root.workspaces[i];
|
var ws = root.workspaces[i];
|
||||||
|
|||||||
Reference in New Issue
Block a user