1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-07 05:55:37 -05:00
Files
DankMaterialShell/Modules/Dock/DockApps.qml

172 lines
4.5 KiB
QML

import QtQuick
import QtQuick.Controls
import Quickshell
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: root
property var contextMenu: null
property var windowsMenu: null
property bool requestDockShow: false
property int pinnedAppCount: 0
implicitWidth: row.width
implicitHeight: row.height
function movePinnedApp(fromIndex, toIndex) {
if (fromIndex === toIndex)
return
var currentPinned = [...(SessionData.pinnedApps || [])]
if (fromIndex < 0 || fromIndex >= currentPinned.length || toIndex < 0
|| toIndex >= currentPinned.length)
return
var movedApp = currentPinned.splice(fromIndex, 1)[0]
currentPinned.splice(toIndex, 0, movedApp)
SessionData.setPinnedApps(currentPinned)
}
Row {
id: row
spacing: 2
anchors.centerIn: parent
height: 40
Repeater {
id: repeater
model: ListModel {
id: dockModel
Component.onCompleted: updateModel()
function updateModel() {
clear()
var items = []
var pinnedApps = [...(SessionData.pinnedApps || [])]
// First section: Pinned apps (always visible, not representing running windows)
pinnedApps.forEach(appId => {
items.push({
"type": "pinned",
"appId": appId,
"windowId": -1, // Use -1 instead of null to avoid ListModel warnings
"windowTitle": "",
"workspaceId": -1, // Use -1 instead of null
"isPinned": true,
"isRunning": false,
"isFocused": false
})
})
root.pinnedAppCount = pinnedApps.length
// Add separator between pinned and running if both exist
if (pinnedApps.length > 0 && NiriService.windows.length > 0) {
items.push({
"type": "separator",
"appId": "__SEPARATOR__",
"windowId": -1, // Use -1 instead of null
"windowTitle": "",
"workspaceId": -1, // Use -1 instead of null
"isPinned": false,
"isRunning": false,
"isFocused": false
})
}
// Second section: Running windows (sorted by display->workspace->position)
// NiriService.windows is already sorted by sortWindowsByLayout
NiriService.windows.forEach(window => {
// Limit window title length for tooltip
var title = window.title || "(Unnamed)"
if (title.length > 50) {
title = title.substring(0, 47) + "..."
}
// Check if this window is focused - compare as numbers
var isFocused = window.id == NiriService.focusedWindowId
items.push({
"type": "window",
"appId": window.app_id || "",
"windowId": window.id || -1,
"windowTitle": title,
"workspaceId": window.workspace_id || -1,
"isPinned": false,
"isRunning": true,
"isFocused": isFocused
})
})
items.forEach(item => {
append(item)
})
}
}
delegate: Item {
id: delegateItem
property alias dockButton: button
width: model.type === "separator" ? 16 : 40
height: 40
Rectangle {
visible: model.type === "separator"
width: 2
height: 20
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
radius: 1
anchors.centerIn: parent
}
DockAppButton {
id: button
visible: model.type !== "separator"
anchors.centerIn: parent
width: 40
height: 40
appData: model
contextMenu: root.contextMenu
windowsMenu: root.windowsMenu
dockApps: root
index: model.index
// Override tooltip for windows to show window title
showWindowTitle: model.type === "window"
windowTitle: model.windowTitle || ""
}
}
}
}
Connections {
target: NiriService
function onWindowsChanged() {
dockModel.updateModel()
}
function onWindowOpenedOrChanged() {
dockModel.updateModel()
}
function onFocusedWindowIdChanged() {
dockModel.updateModel()
}
}
Connections {
target: SessionData
function onPinnedAppsChanged() {
dockModel.updateModel()
}
}
}