mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-29 16:02:51 -05:00
feat: add configurable per-monitor workspace filtering and system tray monitor selection (#163)
This commit is contained in:
@@ -50,6 +50,10 @@ Singleton {
|
|||||||
function moddedAppId(appId: string): string {
|
function moddedAppId(appId: string): string {
|
||||||
if (appId === "Spotify")
|
if (appId === "Spotify")
|
||||||
return "spotify-launcher"
|
return "spotify-launcher"
|
||||||
|
if (appId === "beepertexts")
|
||||||
|
return "beeper"
|
||||||
|
if (appId === "home assistant desktop")
|
||||||
|
return "homeassistant-desktop"
|
||||||
return appId
|
return appId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ Singleton {
|
|||||||
property bool showWorkspacePadding: false
|
property bool showWorkspacePadding: false
|
||||||
property bool showWorkspaceApps: false
|
property bool showWorkspaceApps: false
|
||||||
property int maxWorkspaceIcons: 3
|
property int maxWorkspaceIcons: 3
|
||||||
|
property bool workspacesPerMonitor: true
|
||||||
property var workspaceNameIcons: ({})
|
property var workspaceNameIcons: ({})
|
||||||
property bool clockCompactMode: false
|
property bool clockCompactMode: false
|
||||||
property bool focusedWindowCompactMode: false
|
property bool focusedWindowCompactMode: false
|
||||||
@@ -199,6 +200,7 @@ Singleton {
|
|||||||
showWorkspaceApps = settings.showWorkspaceApps !== undefined ? settings.showWorkspaceApps : false
|
showWorkspaceApps = settings.showWorkspaceApps !== undefined ? settings.showWorkspaceApps : false
|
||||||
maxWorkspaceIcons = settings.maxWorkspaceIcons !== undefined ? settings.maxWorkspaceIcons : 3
|
maxWorkspaceIcons = settings.maxWorkspaceIcons !== undefined ? settings.maxWorkspaceIcons : 3
|
||||||
workspaceNameIcons = settings.workspaceNameIcons !== undefined ? settings.workspaceNameIcons : ({})
|
workspaceNameIcons = settings.workspaceNameIcons !== undefined ? settings.workspaceNameIcons : ({})
|
||||||
|
workspacesPerMonitor = settings.workspacesPerMonitor !== undefined ? settings.workspacesPerMonitor : true
|
||||||
clockCompactMode = settings.clockCompactMode !== undefined ? settings.clockCompactMode : false
|
clockCompactMode = settings.clockCompactMode !== undefined ? settings.clockCompactMode : false
|
||||||
focusedWindowCompactMode = settings.focusedWindowCompactMode !== undefined ? settings.focusedWindowCompactMode : false
|
focusedWindowCompactMode = settings.focusedWindowCompactMode !== undefined ? settings.focusedWindowCompactMode : false
|
||||||
runningAppsCompactMode = settings.runningAppsCompactMode !== undefined ? settings.runningAppsCompactMode : true
|
runningAppsCompactMode = settings.runningAppsCompactMode !== undefined ? settings.runningAppsCompactMode : true
|
||||||
@@ -307,6 +309,8 @@ Singleton {
|
|||||||
"showWorkspaceIndex": showWorkspaceIndex,
|
"showWorkspaceIndex": showWorkspaceIndex,
|
||||||
"showWorkspacePadding": showWorkspacePadding,
|
"showWorkspacePadding": showWorkspacePadding,
|
||||||
"showWorkspaceApps": showWorkspaceApps,
|
"showWorkspaceApps": showWorkspaceApps,
|
||||||
|
"maxWorkspaceIcons": maxWorkspaceIcons,
|
||||||
|
"workspacesPerMonitor": workspacesPerMonitor,
|
||||||
"workspaceNameIcons": workspaceNameIcons,
|
"workspaceNameIcons": workspaceNameIcons,
|
||||||
"clockCompactMode": clockCompactMode,
|
"clockCompactMode": clockCompactMode,
|
||||||
"focusedWindowCompactMode": focusedWindowCompactMode,
|
"focusedWindowCompactMode": focusedWindowCompactMode,
|
||||||
@@ -370,6 +374,11 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setWorkspacesPerMonitor(enabled) {
|
||||||
|
workspacesPerMonitor = enabled
|
||||||
|
saveSettings()
|
||||||
|
}
|
||||||
|
|
||||||
function setWorkspaceNameIcon(workspaceName, iconData) {
|
function setWorkspaceNameIcon(workspaceName, iconData) {
|
||||||
var iconMap = JSON.parse(JSON.stringify(workspaceNameIcons))
|
var iconMap = JSON.parse(JSON.stringify(workspaceNameIcons))
|
||||||
iconMap[workspaceName] = iconData
|
iconMap[workspaceName] = iconData
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ Item {
|
|||||||
"name": "Notepad Slideout",
|
"name": "Notepad Slideout",
|
||||||
"description": "Quick note-taking slideout panel",
|
"description": "Quick note-taking slideout panel",
|
||||||
"icon": "sticky_note_2"
|
"icon": "sticky_note_2"
|
||||||
|
}, {
|
||||||
|
"id": "systemTray",
|
||||||
|
"name": "System Tray",
|
||||||
|
"description": "System tray icons",
|
||||||
|
"icon": "notifications"
|
||||||
}]
|
}]
|
||||||
|
|
||||||
function getScreenPreferences(componentId) {
|
function getScreenPreferences(componentId) {
|
||||||
|
|||||||
@@ -284,6 +284,16 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
width: parent.width
|
||||||
|
text: "Per-Monitor Workspaces"
|
||||||
|
description: "Show only workspaces belonging to each specific monitor."
|
||||||
|
checked: SettingsData.workspacesPerMonitor
|
||||||
|
onToggled: checked => {
|
||||||
|
return SettingsData.setWorkspacesPerMonitor(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -729,6 +729,7 @@ PanelWindow {
|
|||||||
parentWindow: root
|
parentWindow: root
|
||||||
parentScreen: root.screen
|
parentScreen: root.screen
|
||||||
widgetHeight: root.widgetHeight
|
widgetHeight: root.widgetHeight
|
||||||
|
visible: SettingsData.getFilteredScreens("systemTray").includes(root.screen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Rectangle {
|
|||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
return getNiriActiveWorkspace()
|
return getNiriActiveWorkspace()
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
return Hyprland.focusedWorkspace ? Hyprland.focusedWorkspace.id : 1
|
return getHyprlandActiveWorkspace()
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -26,15 +26,8 @@ Rectangle {
|
|||||||
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||||
}
|
}
|
||||||
if (CompositorService.isHyprland) {
|
if (CompositorService.isHyprland) {
|
||||||
const workspaces = Hyprland.workspaces?.values || []
|
const baseList = getHyprlandWorkspaces()
|
||||||
if (workspaces.length === 0) {
|
return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList
|
||||||
return [{
|
|
||||||
"id": 1,
|
|
||||||
"name": "1"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
const sorted = workspaces.slice().sort((a, b) => a.id - b.id)
|
|
||||||
return SettingsData.showWorkspacePadding ? padWorkspaces(sorted) : sorted
|
|
||||||
}
|
}
|
||||||
return [1]
|
return [1]
|
||||||
}
|
}
|
||||||
@@ -61,7 +54,8 @@ Rectangle {
|
|||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const wins = CompositorService.isNiri ? (NiriService.windows || []) : (Hyprland.clients?.values || [])
|
const wins = CompositorService.isNiri ? (NiriService.windows || []) : CompositorService.sortedToplevels
|
||||||
|
|
||||||
|
|
||||||
const byApp = {}
|
const byApp = {}
|
||||||
const isActiveWs = CompositorService.isNiri ? NiriService.allWorkspaces.some(ws => ws.id === targetWorkspaceId && ws.is_active) : targetWorkspaceId === root.currentWorkspace
|
const isActiveWs = CompositorService.isNiri ? NiriService.allWorkspaces.some(ws => ws.id === targetWorkspaceId && ws.is_active) : targetWorkspaceId === root.currentWorkspace
|
||||||
@@ -71,13 +65,22 @@ Rectangle {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const winWs = CompositorService.isNiri ? w.workspace_id : (w.workspace?.id ?? w.workspaceId)
|
let winWs = null
|
||||||
|
if (CompositorService.isNiri) {
|
||||||
|
winWs = w.workspace_id
|
||||||
|
} else {
|
||||||
|
// For Hyprland, we need to find the corresponding Hyprland toplevel to get workspace
|
||||||
|
const hyprlandToplevels = Array.from(Hyprland.toplevels?.values || [])
|
||||||
|
const hyprToplevel = hyprlandToplevels.find(ht => ht.wayland === w)
|
||||||
|
winWs = hyprToplevel?.workspace?.id
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (winWs === undefined || winWs === null || winWs !== targetWorkspaceId) {
|
if (winWs === undefined || winWs === null || winWs !== targetWorkspaceId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyBase = (w.app_id || w.appId || w.class || w.windowClass || w.exe || "unknown").toLowerCase()
|
const keyBase = (w.appId || w.class || w.windowClass || "unknown").toLowerCase()
|
||||||
const key = isActiveWs ? `${keyBase}_${i}` : keyBase
|
const key = isActiveWs ? `${keyBase}_${i}` : keyBase
|
||||||
|
|
||||||
if (!byApp[key]) {
|
if (!byApp[key]) {
|
||||||
@@ -85,14 +88,14 @@ Rectangle {
|
|||||||
byApp[key] = {
|
byApp[key] = {
|
||||||
"type": "icon",
|
"type": "icon",
|
||||||
"icon": icon,
|
"icon": icon,
|
||||||
"active": !!(w.is_focused || w.activated),
|
"active": !!(w.activated || (CompositorService.isNiri && w.is_focused)),
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"windowId": w.id || w.address,
|
"windowId": w.address || w.id,
|
||||||
"fallbackText": w.app_id || w.appId || w.class || w.title || ""
|
"fallbackText": w.appId || w.class || w.title || ""
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byApp[key].count++
|
byApp[key].count++
|
||||||
if (w.is_focused || w.activated) {
|
if (w.activated || (CompositorService.isNiri && w.is_focused)) {
|
||||||
byApp[key].active = true
|
byApp[key].active = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +121,7 @@ Rectangle {
|
|||||||
return [1, 2]
|
return [1, 2]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!root.screenName) {
|
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||||
return NiriService.getCurrentOutputWorkspaceNumbers()
|
return NiriService.getCurrentOutputWorkspaceNumbers()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +134,7 @@ Rectangle {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!root.screenName) {
|
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||||
return NiriService.getCurrentWorkspaceNumber()
|
return NiriService.getCurrentWorkspaceNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,6 +142,53 @@ Rectangle {
|
|||||||
return activeWs ? activeWs.idx + 1 : 1
|
return activeWs ? activeWs.idx + 1 : 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHyprlandWorkspaces() {
|
||||||
|
const workspaces = Hyprland.workspaces?.values || []
|
||||||
|
|
||||||
|
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||||
|
// Show all workspaces on all monitors if per-monitor filtering is disabled
|
||||||
|
const sorted = workspaces.slice().sort((a, b) => a.id - b.id)
|
||||||
|
return sorted.length > 0 ? sorted : [{
|
||||||
|
"id": 1,
|
||||||
|
"name": "1"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter workspaces for this specific monitor using lastIpcObject.monitor
|
||||||
|
// This matches the approach from the original kyle-config
|
||||||
|
const monitorWorkspaces = workspaces.filter(ws => {
|
||||||
|
return ws.lastIpcObject && ws.lastIpcObject.monitor === root.screenName
|
||||||
|
})
|
||||||
|
|
||||||
|
if (monitorWorkspaces.length === 0) {
|
||||||
|
// Fallback if no workspaces exist for this monitor
|
||||||
|
return [{
|
||||||
|
"id": 1,
|
||||||
|
"name": "1"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all workspaces for this monitor, sorted by ID
|
||||||
|
return monitorWorkspaces.sort((a, b) => a.id - b.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHyprlandActiveWorkspace() {
|
||||||
|
if (!root.screenName || !SettingsData.workspacesPerMonitor) {
|
||||||
|
return Hyprland.focusedWorkspace ? Hyprland.focusedWorkspace.id : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the monitor object for this screen
|
||||||
|
const monitors = Hyprland.monitors?.values || []
|
||||||
|
const currentMonitor = monitors.find(monitor => monitor.name === root.screenName)
|
||||||
|
|
||||||
|
if (!currentMonitor) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the monitor's active workspace ID (like original config)
|
||||||
|
return currentMonitor.activeWorkspace?.id ?? 1
|
||||||
|
}
|
||||||
|
|
||||||
readonly property real padding: (widgetHeight - workspaceRow.implicitHeight) / 2
|
readonly property real padding: (widgetHeight - workspaceRow.implicitHeight) / 2
|
||||||
|
|
||||||
function getRealWorkspaces() {
|
function getRealWorkspaces() {
|
||||||
|
|||||||
Reference in New Issue
Block a user