mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-31 08:52:49 -05:00
hyprland repairs
This commit is contained in:
@@ -9,6 +9,7 @@ import qs.Widgets
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
clip: false
|
||||||
property var appData
|
property var appData
|
||||||
property var contextMenu: null
|
property var contextMenu: null
|
||||||
property var dockApps: null
|
property var dockApps: null
|
||||||
@@ -23,6 +24,20 @@ Item {
|
|||||||
property string windowTitle: ""
|
property string windowTitle: ""
|
||||||
property bool isHovered: mouseArea.containsMouse && !dragging
|
property bool isHovered: mouseArea.containsMouse && !dragging
|
||||||
property bool showTooltip: mouseArea.containsMouse && !dragging
|
property bool showTooltip: mouseArea.containsMouse && !dragging
|
||||||
|
property bool isWindowFocused: {
|
||||||
|
if (!appData || appData.type !== "window") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var toplevels = CompositorService.sortedToplevels
|
||||||
|
for (var i = 0; i < toplevels.length; i++) {
|
||||||
|
var toplevel = toplevels[i]
|
||||||
|
if (toplevel.appId === appData.appId) {
|
||||||
|
return toplevel.activated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
property string tooltipText: {
|
property string tooltipText: {
|
||||||
if (!appData)
|
if (!appData)
|
||||||
return ""
|
return ""
|
||||||
@@ -198,13 +213,17 @@ Item {
|
|||||||
"comment": desktopEntry.comment || ""
|
"comment": desktopEntry.comment || ""
|
||||||
})
|
})
|
||||||
|
|
||||||
Quickshell.execDetached(
|
desktopEntry.execute()
|
||||||
["gtk-launch", appData.appId])
|
|
||||||
}
|
}
|
||||||
} else if (appData.type === "window") {
|
} else if (appData.type === "window") {
|
||||||
// Focus the specific window using toplevel
|
// Find the toplevel by matching appId from sorted list
|
||||||
if (appData.toplevelObject) {
|
var toplevels = CompositorService.sortedToplevels
|
||||||
appData.toplevelObject.activate()
|
for (var i = 0; i < toplevels.length; i++) {
|
||||||
|
var toplevel = toplevels[i]
|
||||||
|
if (toplevel.appId === appData.appId && toplevel.title === appData.windowTitle) {
|
||||||
|
toplevel.activate()
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (mouse.button === Qt.MiddleButton) {
|
} else if (mouse.button === Qt.MiddleButton) {
|
||||||
@@ -224,8 +243,7 @@ Item {
|
|||||||
|| ""
|
|| ""
|
||||||
})
|
})
|
||||||
|
|
||||||
Quickshell.execDetached(
|
desktopEntry.execute()
|
||||||
["gtk-launch", appData.appId])
|
|
||||||
}
|
}
|
||||||
} else if (mouse.button === Qt.RightButton) {
|
} else if (mouse.button === Qt.RightButton) {
|
||||||
if (contextMenu)
|
if (contextMenu)
|
||||||
@@ -237,9 +255,8 @@ Item {
|
|||||||
IconImage {
|
IconImage {
|
||||||
id: iconImg
|
id: iconImg
|
||||||
|
|
||||||
width: 40
|
|
||||||
height: 40
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
implicitSize: 40
|
||||||
source: {
|
source: {
|
||||||
if (!appData || !appData.appId)
|
if (!appData || !appData.appId)
|
||||||
return ""
|
return ""
|
||||||
@@ -253,11 +270,9 @@ Item {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
smooth: true
|
|
||||||
mipmap: true
|
mipmap: true
|
||||||
|
smooth: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
visible: status === Image.Ready
|
|
||||||
implicitSize: 40
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -302,7 +317,7 @@ Item {
|
|||||||
return "transparent"
|
return "transparent"
|
||||||
|
|
||||||
// For window type, check if focused using reactive property
|
// For window type, check if focused using reactive property
|
||||||
if (appData.type === "window" && appData.toplevelObject && appData.toplevelObject.activated)
|
if (isWindowFocused)
|
||||||
return Theme.primary
|
return Theme.primary
|
||||||
|
|
||||||
// For running apps, show dimmer indicator
|
// For running apps, show dimmer indicator
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SessionData
|
target: SessionData
|
||||||
function onPinnedAppsChanged() {
|
function onPinnedAppsChanged() {
|
||||||
|
|||||||
@@ -10,62 +10,69 @@ Rectangle {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string screenName: ""
|
property string screenName: ""
|
||||||
property int currentWorkspace: getDisplayActiveWorkspace()
|
property int currentWorkspace: {
|
||||||
|
if (CompositorService.isNiri) {
|
||||||
|
return getNiriActiveWorkspace()
|
||||||
|
} else if (CompositorService.isHyprland) {
|
||||||
|
return Hyprland.focusedWorkspace ? Hyprland.focusedWorkspace.id : 1
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
property var workspaceList: {
|
property var workspaceList: {
|
||||||
var baseList = getDisplayWorkspaces()
|
if (CompositorService.isNiri) {
|
||||||
return SettingsData.showWorkspacePadding ? padWorkspaces(
|
var baseList = getNiriWorkspaces()
|
||||||
baseList) : baseList
|
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||||
|
} else if (CompositorService.isHyprland) {
|
||||||
|
var workspaces = Hyprland.workspaces ? Hyprland.workspaces.values : []
|
||||||
|
if (workspaces.length === 0) {
|
||||||
|
return [{id: 1, name: "1"}]
|
||||||
|
}
|
||||||
|
var sorted = workspaces.slice().sort((a, b) => a.id - b.id)
|
||||||
|
return SettingsData.showWorkspacePadding ? padWorkspaces(sorted) : sorted
|
||||||
|
}
|
||||||
|
return [1]
|
||||||
}
|
}
|
||||||
|
|
||||||
function padWorkspaces(list) {
|
function padWorkspaces(list) {
|
||||||
var padded = list.slice()
|
var padded = list.slice()
|
||||||
while (padded.length < 3)
|
while (padded.length < 3) {
|
||||||
padded.push(-1) // Use -1 as a placeholder
|
if (CompositorService.isHyprland) {
|
||||||
|
padded.push({id: -1, name: ""})
|
||||||
|
} else {
|
||||||
|
padded.push(-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
return padded
|
return padded
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayWorkspaces() {
|
function getNiriWorkspaces() {
|
||||||
if (CompositorService.isNiri) {
|
if (NiriService.allWorkspaces.length === 0)
|
||||||
if (NiriService.allWorkspaces.length === 0)
|
return [1, 2]
|
||||||
return [1, 2]
|
|
||||||
|
|
||||||
if (!root.screenName)
|
if (!root.screenName)
|
||||||
return NiriService.getCurrentOutputWorkspaceNumbers()
|
return NiriService.getCurrentOutputWorkspaceNumbers()
|
||||||
|
|
||||||
var displayWorkspaces = []
|
var displayWorkspaces = []
|
||||||
for (var i = 0; i < NiriService.allWorkspaces.length; i++) {
|
for (var i = 0; i < NiriService.allWorkspaces.length; i++) {
|
||||||
var ws = NiriService.allWorkspaces[i]
|
var ws = NiriService.allWorkspaces[i]
|
||||||
if (ws.output === root.screenName)
|
if (ws.output === root.screenName)
|
||||||
displayWorkspaces.push(ws.idx + 1)
|
displayWorkspaces.push(ws.idx + 1)
|
||||||
}
|
|
||||||
return displayWorkspaces.length > 0 ? displayWorkspaces : [1, 2]
|
|
||||||
} else if (CompositorService.isHyprland) {
|
|
||||||
var workspaces = HyprlandService.getWorkspaceDisplayNumbers()
|
|
||||||
return workspaces.length > 0 ? workspaces : [1]
|
|
||||||
}
|
}
|
||||||
|
return displayWorkspaces.length > 0 ? displayWorkspaces : [1, 2]
|
||||||
return [1, 2]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayActiveWorkspace() {
|
function getNiriActiveWorkspace() {
|
||||||
if (CompositorService.isNiri) {
|
if (NiriService.allWorkspaces.length === 0)
|
||||||
if (NiriService.allWorkspaces.length === 0)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if (!root.screenName)
|
|
||||||
return NiriService.getCurrentWorkspaceNumber()
|
|
||||||
|
|
||||||
for (var i = 0; i < NiriService.allWorkspaces.length; i++) {
|
|
||||||
var ws = NiriService.allWorkspaces[i]
|
|
||||||
if (ws.output === root.screenName && ws.is_active)
|
|
||||||
return ws.idx + 1
|
|
||||||
}
|
|
||||||
return 1
|
return 1
|
||||||
} else if (CompositorService.isHyprland) {
|
|
||||||
var activeWs = HyprlandService.getCurrentWorkspaceNumber()
|
|
||||||
return activeWs
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!root.screenName)
|
||||||
|
return NiriService.getCurrentWorkspaceNumber()
|
||||||
|
|
||||||
|
for (var i = 0; i < NiriService.allWorkspaces.length; i++) {
|
||||||
|
var ws = NiriService.allWorkspaces[i]
|
||||||
|
if (ws.output === root.screenName && ws.is_active)
|
||||||
|
return ws.idx + 1
|
||||||
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,15 +92,14 @@ Rectangle {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onAllWorkspacesChanged() {
|
function onAllWorkspacesChanged() {
|
||||||
root.workspaceList
|
if (CompositorService.isNiri) {
|
||||||
= SettingsData.showWorkspacePadding ? root.padWorkspaces(
|
root.workspaceList = SettingsData.showWorkspacePadding ? root.padWorkspaces(
|
||||||
root.getDisplayWorkspaces(
|
root.getNiriWorkspaces()) : root.getNiriWorkspaces()
|
||||||
)) : root.getDisplayWorkspaces()
|
}
|
||||||
root.currentWorkspace = root.getDisplayActiveWorkspace()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFocusedWorkspaceIndexChanged() {
|
function onFocusedWorkspaceIndexChanged() {
|
||||||
root.currentWorkspace = root.getDisplayActiveWorkspace()
|
// Niri workspace changes handled automatically by currentWorkspace binding
|
||||||
}
|
}
|
||||||
|
|
||||||
target: NiriService
|
target: NiriService
|
||||||
@@ -101,32 +107,47 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onWorkspacesUpdated() {
|
function onValuesChanged() {
|
||||||
root.workspaceList
|
if (CompositorService.isHyprland) {
|
||||||
= SettingsData.showWorkspacePadding ? root.padWorkspaces(
|
var workspaces = Hyprland.workspaces ? Hyprland.workspaces.values : []
|
||||||
root.getDisplayWorkspaces(
|
if (workspaces.length === 0) {
|
||||||
)) : root.getDisplayWorkspaces()
|
workspaces = [{id: 1, name: "1"}]
|
||||||
root.currentWorkspace = root.getDisplayActiveWorkspace()
|
}
|
||||||
|
var sorted = workspaces.slice().sort((a, b) => a.id - b.id)
|
||||||
|
root.workspaceList = SettingsData.showWorkspacePadding ? root.padWorkspaces(sorted) : sorted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFocusedWorkspaceUpdated() {
|
target: Hyprland.workspaces
|
||||||
root.currentWorkspace = root.getDisplayActiveWorkspace()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onFocusedMonitorUpdated() {
|
|
||||||
root.currentWorkspace = root.getDisplayActiveWorkspace()
|
|
||||||
}
|
|
||||||
|
|
||||||
target: HyprlandService
|
|
||||||
enabled: CompositorService.isHyprland
|
enabled: CompositorService.isHyprland
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onFocusedWorkspaceChanged() {
|
||||||
|
// Hyprland workspace changes handled automatically by currentWorkspace binding
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFocusedMonitorChanged() {
|
||||||
|
// Hyprland monitor changes handled automatically by currentWorkspace binding
|
||||||
|
}
|
||||||
|
|
||||||
|
target: Hyprland
|
||||||
|
enabled: CompositorService.isHyprland
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onShowWorkspacePaddingChanged() {
|
function onShowWorkspacePaddingChanged() {
|
||||||
var baseList = root.getDisplayWorkspaces()
|
if (CompositorService.isHyprland) {
|
||||||
root.workspaceList = SettingsData.showWorkspacePadding ? root.padWorkspaces(
|
var workspaces = Hyprland.workspaces ? Hyprland.workspaces.values : []
|
||||||
baseList) : baseList
|
if (workspaces.length === 0) {
|
||||||
|
workspaces = [{id: 1, name: "1"}]
|
||||||
|
}
|
||||||
|
var sorted = workspaces.slice().sort((a, b) => a.id - b.id)
|
||||||
|
root.workspaceList = SettingsData.showWorkspacePadding ? root.padWorkspaces(sorted) : sorted
|
||||||
|
} else {
|
||||||
|
var baseList = root.getNiriWorkspaces()
|
||||||
|
root.workspaceList = SettingsData.showWorkspacePadding ? root.padWorkspaces(baseList) : baseList
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
@@ -142,10 +163,19 @@ Rectangle {
|
|||||||
model: root.workspaceList
|
model: root.workspaceList
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
property bool isActive: modelData === root.currentWorkspace
|
property bool isActive: {
|
||||||
property bool isPlaceholder: modelData === -1
|
if (CompositorService.isHyprland) {
|
||||||
|
return modelData && modelData.id === root.currentWorkspace
|
||||||
|
}
|
||||||
|
return modelData === root.currentWorkspace
|
||||||
|
}
|
||||||
|
property bool isPlaceholder: {
|
||||||
|
if (CompositorService.isHyprland) {
|
||||||
|
return modelData && modelData.id === -1
|
||||||
|
}
|
||||||
|
return modelData === -1
|
||||||
|
}
|
||||||
property bool isHovered: mouseArea.containsMouse
|
property bool isHovered: mouseArea.containsMouse
|
||||||
property int sequentialNumber: index + 1
|
|
||||||
property var workspaceData: {
|
property var workspaceData: {
|
||||||
if (isPlaceholder)
|
if (isPlaceholder)
|
||||||
return null
|
return null
|
||||||
@@ -157,12 +187,7 @@ Rectangle {
|
|||||||
return ws
|
return ws
|
||||||
}
|
}
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
var hyprWorkspaces = HyprlandService.getWorkspacesForMonitor(root.screenName)
|
return modelData
|
||||||
for (var j = 0; j < hyprWorkspaces.length; j++) {
|
|
||||||
var hws = hyprWorkspaces[j]
|
|
||||||
if (hws.id === modelData)
|
|
||||||
return hws
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -189,13 +214,14 @@ Rectangle {
|
|||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
NiriService.switchToWorkspace(modelData - 1)
|
NiriService.switchToWorkspace(modelData - 1)
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
Hyprland.dispatch(`workspace ${modelData}`)
|
if (modelData && modelData.id) {
|
||||||
|
Hyprland.dispatch(`workspace ${modelData.id}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Icon display (priority over numbers)
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
visible: hasIcon && iconData.type === "icon"
|
visible: hasIcon && iconData.type === "icon"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -209,7 +235,6 @@ Rectangle {
|
|||||||
weight: isActive && !isPlaceholder ? 500 : 400
|
weight: isActive && !isPlaceholder ? 500 : 400
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom text display (priority over numbers)
|
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: hasIcon && iconData.type === "text"
|
visible: hasIcon && iconData.type === "text"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -224,11 +249,15 @@ Rectangle {
|
|||||||
&& !isPlaceholder ? Font.DemiBold : Font.Normal
|
&& !isPlaceholder ? Font.DemiBold : Font.Normal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number display (secondary priority, only when no icon)
|
|
||||||
StyledText {
|
StyledText {
|
||||||
visible: SettingsData.showWorkspaceIndex && !hasIcon
|
visible: SettingsData.showWorkspaceIndex && !hasIcon
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: isPlaceholder ? sequentialNumber : sequentialNumber
|
text: {
|
||||||
|
if (CompositorService.isHyprland) {
|
||||||
|
return modelData && modelData.id ? modelData.id : ""
|
||||||
|
}
|
||||||
|
return modelData
|
||||||
|
}
|
||||||
color: isActive ? Qt.rgba(
|
color: isActive ? Qt.rgba(
|
||||||
Theme.surfaceContainer.r,
|
Theme.surfaceContainer.r,
|
||||||
Theme.surfaceContainer.g,
|
Theme.surfaceContainer.g,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Singleton {
|
|||||||
readonly property string niriSocket: Quickshell.env("NIRI_SOCKET")
|
readonly property string niriSocket: Quickshell.env("NIRI_SOCKET")
|
||||||
|
|
||||||
property bool useNiriSorting: isNiri && NiriService
|
property bool useNiriSorting: isNiri && NiriService
|
||||||
property bool useHyprlandSorting: isHyprland && HyprlandService
|
property bool useHyprlandSorting: false
|
||||||
|
|
||||||
// Unified sorted toplevels - automatically chooses sorting based on compositor
|
// Unified sorted toplevels - automatically chooses sorting based on compositor
|
||||||
property var sortedToplevels: {
|
property var sortedToplevels: {
|
||||||
@@ -32,9 +32,34 @@ Singleton {
|
|||||||
return NiriService.sortToplevels(ToplevelManager.toplevels.values)
|
return NiriService.sortToplevels(ToplevelManager.toplevels.values)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Hyprland sorting when both compositor is Hyprland AND hyprland service is ready
|
if (isHyprland) {
|
||||||
if (useHyprlandSorting) {
|
const hyprlandToplevels = Array.from(Hyprland.toplevels.values)
|
||||||
return HyprlandService.sortToplevels(ToplevelManager.toplevels.values)
|
|
||||||
|
const sortedHyprland = hyprlandToplevels.sort((a, b) => {
|
||||||
|
// Sort by monitor first
|
||||||
|
if (a.monitor && b.monitor) {
|
||||||
|
const monitorCompare = a.monitor.name.localeCompare(b.monitor.name)
|
||||||
|
if (monitorCompare !== 0) return monitorCompare
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then by workspace
|
||||||
|
if (a.workspace && b.workspace) {
|
||||||
|
const workspaceCompare = a.workspace.id - b.workspace.id
|
||||||
|
if (workspaceCompare !== 0) return workspaceCompare
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then by position on workspace (x first for columns, then y within column)
|
||||||
|
if (a.lastIpcObject && b.lastIpcObject && a.lastIpcObject.at && b.lastIpcObject.at) {
|
||||||
|
const xCompare = a.lastIpcObject.at[0] - b.lastIpcObject.at[0]
|
||||||
|
if (xCompare !== 0) return xCompare
|
||||||
|
return a.lastIpcObject.at[1] - b.lastIpcObject.at[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// Return the wayland Toplevel objects
|
||||||
|
return sortedHyprland.map(hyprToplevel => hyprToplevel.wayland).filter(wayland => wayland !== null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For other compositors or when services aren't ready yet, return unsorted toplevels
|
// For other compositors or when services aren't ready yet, return unsorted toplevels
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var allWorkspaces: CompositorService.isHyprland && Hyprland.workspaces ? Hyprland.workspaces.values : []
|
|
||||||
property var focusedWorkspace: CompositorService.isHyprland ? Hyprland.focusedWorkspace : null
|
|
||||||
property var monitors: CompositorService.isHyprland ? Hyprland.monitors : []
|
|
||||||
property var focusedMonitor: CompositorService.isHyprland ? Hyprland.focusedMonitor : null
|
|
||||||
|
|
||||||
function getWorkspacesForMonitor(monitorName) {
|
|
||||||
const workspaces = Hyprland.workspaces ? Hyprland.workspaces.values : []
|
|
||||||
if (!workspaces || workspaces.length === 0) return []
|
|
||||||
|
|
||||||
// If no monitor name specified, return all workspaces
|
|
||||||
if (!monitorName) {
|
|
||||||
const allWorkspacesCopy = []
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const workspace = workspaces[i]
|
|
||||||
if (workspace) {
|
|
||||||
allWorkspacesCopy.push(workspace)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allWorkspacesCopy.sort((a, b) => a.id - b.id)
|
|
||||||
return allWorkspacesCopy
|
|
||||||
}
|
|
||||||
|
|
||||||
const filtered = []
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const workspace = workspaces[i]
|
|
||||||
if (workspace && workspace.monitor && workspace.monitor.name === monitorName) {
|
|
||||||
filtered.push(workspace)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by workspace ID
|
|
||||||
filtered.sort((a, b) => a.id - b.id)
|
|
||||||
return filtered
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentWorkspaceForMonitor(monitorName) {
|
|
||||||
// If no monitor name specified, return the globally focused workspace
|
|
||||||
if (!monitorName) {
|
|
||||||
return focusedWorkspace
|
|
||||||
}
|
|
||||||
|
|
||||||
if (focusedMonitor && focusedMonitor.name === monitorName) {
|
|
||||||
return focusedWorkspace
|
|
||||||
}
|
|
||||||
|
|
||||||
const monitorWorkspaces = getWorkspacesForMonitor(monitorName)
|
|
||||||
for (let i = 0; i < monitorWorkspaces.length; i++) {
|
|
||||||
const ws = monitorWorkspaces[i]
|
|
||||||
if (ws && ws.active) {
|
|
||||||
return ws
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWorkspaceDisplayNumbers() {
|
|
||||||
// Get all existing workspaces from Hyprland.workspaces.values
|
|
||||||
const workspaces = Hyprland.workspaces ? Hyprland.workspaces.values : []
|
|
||||||
if (!workspaces || workspaces.length === 0) {
|
|
||||||
// If no workspaces detected, show at least current + a few more
|
|
||||||
const current = getCurrentWorkspaceNumber()
|
|
||||||
return [Math.max(1, current - 1), current, current + 1, current + 2].filter((ws, i, arr) => arr.indexOf(ws) === i && ws > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get workspace IDs and ensure we show a reasonable range
|
|
||||||
const numbers = []
|
|
||||||
let maxId = 0
|
|
||||||
|
|
||||||
for (let i = 0; i < workspaces.length; i++) {
|
|
||||||
const ws = workspaces[i]
|
|
||||||
if (ws && ws.id > 0) {
|
|
||||||
numbers.push(ws.id)
|
|
||||||
maxId = Math.max(maxId, ws.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always ensure we have at least one workspace beyond the highest
|
|
||||||
// to allow easy navigation to new workspaces
|
|
||||||
if (maxId > 0 && numbers.indexOf(maxId + 1) === -1) {
|
|
||||||
numbers.push(maxId + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
return numbers.sort((a, b) => a - b)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentWorkspaceNumber() {
|
|
||||||
// Use the focused workspace directly
|
|
||||||
const focused = Hyprland.focusedWorkspace
|
|
||||||
return focused ? focused.id : 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortToplevels(toplevels) {
|
|
||||||
// Create a copy of the array since the original might be readonly
|
|
||||||
const sortedArray = Array.from(toplevels)
|
|
||||||
|
|
||||||
return sortedArray.sort((a, b) => {
|
|
||||||
if (a.workspace && b.workspace) {
|
|
||||||
if (a.workspace.monitor && b.workspace.monitor) {
|
|
||||||
const monitorCompare = a.workspace.monitor.name.localeCompare(b.workspace.monitor.name)
|
|
||||||
if (monitorCompare !== 0) return monitorCompare
|
|
||||||
}
|
|
||||||
|
|
||||||
const workspaceCompare = a.workspace.id - b.workspace.id
|
|
||||||
if (workspaceCompare !== 0) return workspaceCompare
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signals for workspace changes that WorkspaceSwitcher can connect to
|
|
||||||
signal workspacesUpdated()
|
|
||||||
signal focusedWorkspaceUpdated()
|
|
||||||
signal focusedMonitorUpdated()
|
|
||||||
|
|
||||||
// Monitor changes to properties and emit our signals
|
|
||||||
onAllWorkspacesChanged: workspacesUpdated()
|
|
||||||
onFocusedWorkspaceChanged: focusedWorkspaceUpdated()
|
|
||||||
onFocusedMonitorChanged: focusedMonitorUpdated()
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user