diff --git a/DMSShell.qml b/DMSShell.qml index b18f1d22..12dbb982 100644 --- a/DMSShell.qml +++ b/DMSShell.qml @@ -25,515 +25,517 @@ import qs.Modules.DankBar.Popouts import qs.Modules.Plugins import qs.Services - Item { - id: root + id: root - Instantiator { - id: daemonPluginInstantiator - asynchronous: true - model: Object.keys(PluginService.pluginDaemonComponents) + Instantiator { + id: daemonPluginInstantiator + asynchronous: true + model: Object.keys(PluginService.pluginDaemonComponents) - delegate: Loader { - id: daemonLoader - property string pluginId: modelData - sourceComponent: PluginService.pluginDaemonComponents[pluginId] + delegate: Loader { + id: daemonLoader + property string pluginId: modelData + sourceComponent: PluginService.pluginDaemonComponents[pluginId] - onLoaded: { - if (item) { - item.pluginService = PluginService - if (item.popoutService !== undefined) { - item.popoutService = PopoutService - } - item.pluginId = pluginId - console.log("Daemon plugin loaded:", pluginId) - } - } - } - } - - WallpaperBackground {} - - Lock { - id: lock - } - - Loader { - id: dankBarLoader - asynchronous: false - - property var currentPosition: SettingsData.dankBarPosition - property bool initialized: false - - sourceComponent: DankBar { - onColorPickerRequested: { - if (colorPickerModal.shouldBeVisible) { - colorPickerModal.close() - } else { - colorPickerModal.show() - } - } - } - - Component.onCompleted: { - initialized = true - } - - onCurrentPositionChanged: { - if (!initialized) return - - const component = sourceComponent - sourceComponent = null - sourceComponent = component - } - } - - Loader { - id: dockLoader - active: true - asynchronous: false - - property var currentPosition: SettingsData.dockPosition - property bool initialized: false - - sourceComponent: Dock { - contextMenu: dockContextMenuLoader.item ? dockContextMenuLoader.item : null - } - - onLoaded: { - if (item) { - dockContextMenuLoader.active = true - } - } - - Component.onCompleted: { - initialized = true - } - - onCurrentPositionChanged: { - if (!initialized) return - - console.log("DEBUG: Dock position changed to:", currentPosition, "- recreating dock") - const comp = sourceComponent - sourceComponent = null - sourceComponent = comp - } - } - - Loader { - id: dankDashPopoutLoader - - active: false - asynchronous: true - - sourceComponent: Component { - DankDashPopout { - id: dankDashPopout - - Component.onCompleted: { - PopoutService.dankDashPopout = dankDashPopout - } - } - } - } - - LazyLoader { - id: dockContextMenuLoader - - active: false - - DockContextMenu { - id: dockContextMenu - } - } - - LazyLoader { - id: notificationCenterLoader - - active: false - - NotificationCenterPopout { - id: notificationCenter - - Component.onCompleted: { - PopoutService.notificationCenterPopout = notificationCenter - } - } - } - - Variants { - model: SettingsData.getFilteredScreens("notifications") - - delegate: NotificationPopupManager { - modelData: item - } - } - - LazyLoader { - id: controlCenterLoader - - active: false - - property var modalRef: colorPickerModal - property LazyLoader powerModalLoaderRef: powerMenuModalLoader - - ControlCenterPopout { - id: controlCenterPopout - colorPickerModal: controlCenterLoader.modalRef - powerMenuModalLoader: controlCenterLoader.powerModalLoaderRef - - onLockRequested: { - lock.activate() - } - - Component.onCompleted: { - PopoutService.controlCenterPopout = controlCenterPopout - } - } - } - - LazyLoader { - id: wifiPasswordModalLoader - - active: false - - WifiPasswordModal { - id: wifiPasswordModal - - Component.onCompleted: { - PopoutService.wifiPasswordModal = wifiPasswordModal - } - } - } - - LazyLoader { - id: networkInfoModalLoader - - active: false - - NetworkInfoModal { - id: networkInfoModal - - Component.onCompleted: { - PopoutService.networkInfoModal = networkInfoModal - } - } - } - - LazyLoader { - id: batteryPopoutLoader - - active: false - - BatteryPopout { - id: batteryPopout - - Component.onCompleted: { - PopoutService.batteryPopout = batteryPopout - } - } - } - - LazyLoader { - id: vpnPopoutLoader - - active: false - - VpnPopout { - id: vpnPopout - - Component.onCompleted: { - PopoutService.vpnPopout = vpnPopout - } - } - } - - LazyLoader { - id: powerMenuLoader - - active: false - - PowerMenu { - id: powerMenu - - onPowerActionRequested: (action, title, message) => { - if (SettingsData.powerActionConfirm) { - powerConfirmModalLoader.active = true - if (powerConfirmModalLoader.item) { - powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary - powerConfirmModalLoader.item.show(title, message, () => actionApply(action), function () {}) + onLoaded: { + if (item) { + item.pluginService = PluginService + if (item.popoutService !== undefined) { + item.popoutService = PopoutService + } + item.pluginId = pluginId + console.log("Daemon plugin loaded:", pluginId) } - } else { - actionApply(action) - } - } - - function actionApply(action) { - switch (action) { - case "logout": - SessionService.logout() - break - case "suspend": - SessionService.suspend() - break - case "hibernate": - SessionService.hibernate() - break - case "reboot": - SessionService.reboot() - break - case "poweroff": - SessionService.poweroff() - break } } } - } - LazyLoader { - id: powerConfirmModalLoader + WallpaperBackground {} - active: false + Lock { + id: lock + } - ConfirmModal { - id: powerConfirmModal - } - } + Loader { + id: dankBarLoader + asynchronous: false - LazyLoader { - id: processListPopoutLoader + property var currentPosition: SettingsData.dankBarPosition + property bool initialized: false - active: false - - ProcessListPopout { - id: processListPopout - - Component.onCompleted: { - PopoutService.processListPopout = processListPopout - } - } - } - - SettingsModal { - id: settingsModal - - Component.onCompleted: { - PopoutService.settingsModal = settingsModal - } - } - - LazyLoader { - id: appDrawerLoader - - active: false - - AppDrawerPopout { - id: appDrawerPopout - - Component.onCompleted: { - PopoutService.appDrawerPopout = appDrawerPopout - } - } - } - - SpotlightModal { - id: spotlightModal - - Component.onCompleted: { - PopoutService.spotlightModal = spotlightModal - } - } - - ClipboardHistoryModal { - id: clipboardHistoryModalPopup - - Component.onCompleted: { - PopoutService.clipboardHistoryModal = clipboardHistoryModalPopup - } - } - - NotificationModal { - id: notificationModal - - Component.onCompleted: { - PopoutService.notificationModal = notificationModal - } - } - - DankColorPickerModal { - id: colorPickerModal - - Component.onCompleted: { - PopoutService.colorPickerModal = colorPickerModal - } - } - - LazyLoader { - id: processListModalLoader - - active: false - - ProcessListModal { - id: processListModal - - Component.onCompleted: { - PopoutService.processListModal = processListModal - } - } - } - - LazyLoader { - id: systemUpdateLoader - - active: false - - SystemUpdatePopout { - id: systemUpdatePopout - - Component.onCompleted: { - PopoutService.systemUpdatePopout = systemUpdatePopout - } - } - } - - Variants { - id: notepadSlideoutVariants - model: SettingsData.getFilteredScreens("notepad") - - delegate: DankSlideout { - id: notepadSlideout - modelData: item - title: I18n.tr("Notepad") - slideoutWidth: 480 - expandable: true - expandedWidthValue: 960 - customTransparency: SettingsData.notepadTransparencyOverride - - content: Component { - Notepad { - onHideRequested: { - notepadSlideout.hide() - } - } - } - - function toggle() { - if (isVisible) { - hide() - } else { - show() - } - } - } - } - - LazyLoader { - id: powerMenuModalLoader - - active: false - - PowerMenuModal { - id: powerMenuModal - - onPowerActionRequested: (action, title, message) => { - if (SettingsData.powerActionConfirm) { - powerConfirmModalLoader.active = true - if (powerConfirmModalLoader.item) { - powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary - powerConfirmModalLoader.item.show(title, message, () => actionApply(action), function () {}) + sourceComponent: DankBar { + onColorPickerRequested: { + if (colorPickerModal.shouldBeVisible) { + colorPickerModal.close() + } else { + colorPickerModal.show() } - } else { - actionApply(action) - } - } - - function actionApply(action) { - switch (action) { - case "logout": - SessionService.logout() - break - case "suspend": - SessionService.suspend() - break - case "hibernate": - SessionService.hibernate() - break - case "reboot": - SessionService.reboot() - break - case "poweroff": - SessionService.poweroff() - break } } Component.onCompleted: { - PopoutService.powerMenuModal = powerMenuModal + initialized = true + } + + onCurrentPositionChanged: { + if (!initialized) + return + + const component = sourceComponent + sourceComponent = null + sourceComponent = component } } - } - LazyLoader { - id: hyprKeybindsModalLoader + Loader { + id: dockLoader + active: true + asynchronous: false - active: false + property var currentPosition: SettingsData.dockPosition + property bool initialized: false - HyprKeybindsModal { - id: hyprKeybindsModal + sourceComponent: Dock { + contextMenu: dockContextMenuLoader.item ? dockContextMenuLoader.item : null + } - Component.onCompleted: { - PopoutService.hyprKeybindsModal = hyprKeybindsModal - } - } - } + onLoaded: { + if (item) { + dockContextMenuLoader.active = true + } + } - DMSShellIPC { - powerMenuModalLoader: powerMenuModalLoader - processListModalLoader: processListModalLoader - controlCenterLoader: controlCenterLoader - dankDashPopoutLoader: dankDashPopoutLoader - notepadSlideoutVariants: notepadSlideoutVariants - hyprKeybindsModalLoader: hyprKeybindsModalLoader - } + Component.onCompleted: { + initialized = true + } - Variants { - model: SettingsData.getFilteredScreens("toast") + onCurrentPositionChanged: { + if (!initialized) + return - delegate: Toast { - modelData: item - visible: ToastService.toastVisible - } - } + console.log("DEBUG: Dock position changed to:", currentPosition, "- recreating dock") + const comp = sourceComponent + sourceComponent = null + sourceComponent = comp + } + } - Variants { - model: SettingsData.getFilteredScreens("osd") + Loader { + id: dankDashPopoutLoader - delegate: VolumeOSD { - modelData: item - } - } + active: false + asynchronous: true - Variants { - model: SettingsData.getFilteredScreens("osd") + sourceComponent: Component { + DankDashPopout { + id: dankDashPopout - delegate: MicMuteOSD { - modelData: item - } - } + Component.onCompleted: { + PopoutService.dankDashPopout = dankDashPopout + } + } + } + } - Variants { - model: SettingsData.getFilteredScreens("osd") + LazyLoader { + id: dockContextMenuLoader - delegate: BrightnessOSD { - modelData: item - } - } + active: false - Variants { - model: SettingsData.getFilteredScreens("osd") + DockContextMenu { + id: dockContextMenu + } + } - delegate: IdleInhibitorOSD { - modelData: item - } - } + LazyLoader { + id: notificationCenterLoader + + active: false + + NotificationCenterPopout { + id: notificationCenter + + Component.onCompleted: { + PopoutService.notificationCenterPopout = notificationCenter + } + } + } + + Variants { + model: SettingsData.getFilteredScreens("notifications") + + delegate: NotificationPopupManager { + modelData: item + } + } + + LazyLoader { + id: controlCenterLoader + + active: false + + property var modalRef: colorPickerModal + property LazyLoader powerModalLoaderRef: powerMenuModalLoader + + ControlCenterPopout { + id: controlCenterPopout + colorPickerModal: controlCenterLoader.modalRef + powerMenuModalLoader: controlCenterLoader.powerModalLoaderRef + + onLockRequested: { + lock.activate() + } + + Component.onCompleted: { + PopoutService.controlCenterPopout = controlCenterPopout + } + } + } + + LazyLoader { + id: wifiPasswordModalLoader + + active: false + + WifiPasswordModal { + id: wifiPasswordModal + + Component.onCompleted: { + PopoutService.wifiPasswordModal = wifiPasswordModal + } + } + } + + LazyLoader { + id: networkInfoModalLoader + + active: false + + NetworkInfoModal { + id: networkInfoModal + + Component.onCompleted: { + PopoutService.networkInfoModal = networkInfoModal + } + } + } + + LazyLoader { + id: batteryPopoutLoader + + active: false + + BatteryPopout { + id: batteryPopout + + Component.onCompleted: { + PopoutService.batteryPopout = batteryPopout + } + } + } + + LazyLoader { + id: vpnPopoutLoader + + active: false + + VpnPopout { + id: vpnPopout + + Component.onCompleted: { + PopoutService.vpnPopout = vpnPopout + } + } + } + + LazyLoader { + id: powerMenuLoader + + active: false + + PowerMenu { + id: powerMenu + + onPowerActionRequested: (action, title, message) => { + if (SettingsData.powerActionConfirm) { + powerConfirmModalLoader.active = true + if (powerConfirmModalLoader.item) { + powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary + powerConfirmModalLoader.item.show(title, message, () => actionApply(action), function () {}) + } + } else { + actionApply(action) + } + } + + function actionApply(action) { + switch (action) { + case "logout": + SessionService.logout() + break + case "suspend": + SessionService.suspend() + break + case "hibernate": + SessionService.hibernate() + break + case "reboot": + SessionService.reboot() + break + case "poweroff": + SessionService.poweroff() + break + } + } + } + } + + LazyLoader { + id: powerConfirmModalLoader + + active: false + + ConfirmModal { + id: powerConfirmModal + } + } + + LazyLoader { + id: processListPopoutLoader + + active: false + + ProcessListPopout { + id: processListPopout + + Component.onCompleted: { + PopoutService.processListPopout = processListPopout + } + } + } + + SettingsModal { + id: settingsModal + + Component.onCompleted: { + PopoutService.settingsModal = settingsModal + } + } + + LazyLoader { + id: appDrawerLoader + + active: false + + AppDrawerPopout { + id: appDrawerPopout + + Component.onCompleted: { + PopoutService.appDrawerPopout = appDrawerPopout + } + } + } + + SpotlightModal { + id: spotlightModal + + Component.onCompleted: { + PopoutService.spotlightModal = spotlightModal + } + } + + ClipboardHistoryModal { + id: clipboardHistoryModalPopup + + Component.onCompleted: { + PopoutService.clipboardHistoryModal = clipboardHistoryModalPopup + } + } + + NotificationModal { + id: notificationModal + + Component.onCompleted: { + PopoutService.notificationModal = notificationModal + } + } + + DankColorPickerModal { + id: colorPickerModal + + Component.onCompleted: { + PopoutService.colorPickerModal = colorPickerModal + } + } + + LazyLoader { + id: processListModalLoader + + active: false + + ProcessListModal { + id: processListModal + + Component.onCompleted: { + PopoutService.processListModal = processListModal + } + } + } + + LazyLoader { + id: systemUpdateLoader + + active: false + + SystemUpdatePopout { + id: systemUpdatePopout + + Component.onCompleted: { + PopoutService.systemUpdatePopout = systemUpdatePopout + } + } + } + + Variants { + id: notepadSlideoutVariants + model: SettingsData.getFilteredScreens("notepad") + + delegate: DankSlideout { + id: notepadSlideout + modelData: item + title: I18n.tr("Notepad") + slideoutWidth: 480 + expandable: true + expandedWidthValue: 960 + customTransparency: SettingsData.notepadTransparencyOverride + + content: Component { + Notepad { + onHideRequested: { + notepadSlideout.hide() + } + } + } + + function toggle() { + if (isVisible) { + hide() + } else { + show() + } + } + } + } + + LazyLoader { + id: powerMenuModalLoader + + active: false + + PowerMenuModal { + id: powerMenuModal + + onPowerActionRequested: (action, title, message) => { + if (SettingsData.powerActionConfirm) { + powerConfirmModalLoader.active = true + if (powerConfirmModalLoader.item) { + powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary + powerConfirmModalLoader.item.show(title, message, () => actionApply(action), function () {}) + } + } else { + actionApply(action) + } + } + + function actionApply(action) { + switch (action) { + case "logout": + SessionService.logout() + break + case "suspend": + SessionService.suspend() + break + case "hibernate": + SessionService.hibernate() + break + case "reboot": + SessionService.reboot() + break + case "poweroff": + SessionService.poweroff() + break + } + } + + Component.onCompleted: { + PopoutService.powerMenuModal = powerMenuModal + } + } + } + + LazyLoader { + id: hyprKeybindsModalLoader + + active: false + + HyprKeybindsModal { + id: hyprKeybindsModal + + Component.onCompleted: { + PopoutService.hyprKeybindsModal = hyprKeybindsModal + } + } + } + + DMSShellIPC { + powerMenuModalLoader: powerMenuModalLoader + processListModalLoader: processListModalLoader + controlCenterLoader: controlCenterLoader + dankDashPopoutLoader: dankDashPopoutLoader + notepadSlideoutVariants: notepadSlideoutVariants + hyprKeybindsModalLoader: hyprKeybindsModalLoader + dankBarLoader: dankBarLoader + } + + Variants { + model: SettingsData.getFilteredScreens("toast") + + delegate: Toast { + modelData: item + visible: ToastService.toastVisible + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: VolumeOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: MicMuteOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: BrightnessOSD { + modelData: item + } + } + + Variants { + model: SettingsData.getFilteredScreens("osd") + + delegate: IdleInhibitorOSD { + modelData: item + } + } } diff --git a/DMSShellIPC.qml b/DMSShellIPC.qml index fbf71898..16cff3de 100644 --- a/DMSShellIPC.qml +++ b/DMSShellIPC.qml @@ -14,6 +14,7 @@ Item { required property var dankDashPopoutLoader required property var notepadSlideoutVariants required property var hyprKeybindsModalLoader + required property var dankBarLoader IpcHandler { function open() { @@ -76,9 +77,8 @@ Item { IpcHandler { function open(): string { - root.controlCenterLoader.active = true - if (root.controlCenterLoader.item) { - root.controlCenterLoader.item.open() + if (root.dankBarLoader.item) { + root.dankBarLoader.item.triggerControlCenterOnFocusedScreen() return "CONTROL_CENTER_OPEN_SUCCESS" } return "CONTROL_CENTER_OPEN_FAILED" @@ -93,9 +93,8 @@ Item { } function toggle(): string { - root.controlCenterLoader.active = true - if (root.controlCenterLoader.item) { - root.controlCenterLoader.item.toggle() + if (root.dankBarLoader.item) { + root.dankBarLoader.item.triggerControlCenterOnFocusedScreen() return "CONTROL_CENTER_TOGGLE_SUCCESS" } return "CONTROL_CENTER_TOGGLE_FAILED" diff --git a/Modules/ControlCenter/ControlCenterPopout.qml b/Modules/ControlCenter/ControlCenterPopout.qml index 3b2681c5..353c6d17 100644 --- a/Modules/ControlCenter/ControlCenterPopout.qml +++ b/Modules/ControlCenter/ControlCenterPopout.qml @@ -73,21 +73,21 @@ DankPopout { onShouldBeVisibleChanged: { if (shouldBeVisible) { Qt.callLater(() => { - if (NetworkService.activeService) { - NetworkService.activeService.autoRefreshEnabled = NetworkService.wifiEnabled - } - if (UserInfoService) - UserInfoService.getUptime() - }) + if (NetworkService.activeService) { + NetworkService.activeService.autoRefreshEnabled = NetworkService.wifiEnabled + } + if (UserInfoService) + UserInfoService.getUptime() + }) } else { Qt.callLater(() => { - if (NetworkService.activeService) { - NetworkService.activeService.autoRefreshEnabled = false - } - if (BluetoothService.adapter && BluetoothService.adapter.discovering) - BluetoothService.adapter.discovering = false - editMode = false - }) + if (NetworkService.activeService) { + NetworkService.activeService.autoRefreshEnabled = false + } + if (BluetoothService.adapter && BluetoothService.adapter.discovering) + BluetoothService.adapter.discovering = false + editMode = false + }) } } @@ -108,8 +108,7 @@ DankPopout { return Qt.rgba(surface.r, surface.g, surface.b, transparency) } radius: Theme.cornerRadius - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.08) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.width: 0 antialiasing: true smooth: true @@ -156,19 +155,19 @@ DankPopout { bluetoothCodecSelector: bluetoothCodecSelector colorPickerModal: root.colorPickerModal onExpandClicked: (widgetData, globalIndex) => { - root.expandedWidgetIndex = globalIndex - root.expandedWidgetData = widgetData - if (widgetData.id === "diskUsage") { - root.toggleSection("diskUsage_" + (widgetData.instanceId || "default")) - } else if (widgetData.id === "brightnessSlider") { - root.toggleSection("brightnessSlider_" + (widgetData.instanceId || "default")) - } else { - root.toggleSection(widgetData.id) - } - } - onRemoveWidget: (index) => widgetModel.removeWidget(index) + root.expandedWidgetIndex = globalIndex + root.expandedWidgetData = widgetData + if (widgetData.id === "diskUsage") { + root.toggleSection("diskUsage_" + (widgetData.instanceId || "default")) + } else if (widgetData.id === "brightnessSlider") { + root.toggleSection("brightnessSlider_" + (widgetData.instanceId || "default")) + } else { + root.toggleSection(widgetData.id) + } + } + onRemoveWidget: index => widgetModel.removeWidget(index) onMoveWidget: (fromIndex, toIndex) => widgetModel.moveWidget(fromIndex, toIndex) - onToggleWidgetSize: (index) => widgetModel.toggleWidgetSize(index) + onToggleWidgetSize: index => widgetModel.toggleWidgetSize(index) onCollapseRequested: root.collapseAll() } @@ -177,12 +176,13 @@ DankPopout { visible: editMode popoutContent: controlContent availableWidgets: { - if (!editMode) return [] + if (!editMode) + return [] const existingIds = (SettingsData.controlCenterWidgets || []).map(w => w.id) const allWidgets = widgetModel.baseWidgetDefinitions.concat(widgetModel.getPluginWidgets()) return allWidgets.filter(w => w.allowMultiple || !existingIds.includes(w.id)) } - onAddWidget: (widgetId) => widgetModel.addWidget(widgetId) + onAddWidget: widgetId => widgetModel.addWidget(widgetId) onResetToDefault: () => widgetModel.resetToDefault() onClearAll: () => widgetModel.clearAll() } @@ -205,10 +205,10 @@ DankPopout { id: bluetoothDetailComponent BluetoothDetail { id: bluetoothDetail - onShowCodecSelector: function(device) { + onShowCodecSelector: function (device) { if (contentLoader.item && contentLoader.item.bluetoothCodecSelector) { contentLoader.item.bluetoothCodecSelector.show(device) - contentLoader.item.bluetoothCodecSelector.codecSelected.connect(function(deviceAddress, codecName) { + contentLoader.item.bluetoothCodecSelector.codecSelected.connect(function (deviceAddress, codecName) { bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName) }) } @@ -233,4 +233,4 @@ DankPopout { property var colorPickerModal: null property var powerMenuModalLoader: null -} \ No newline at end of file +} diff --git a/Modules/DankBar/DankBar.qml b/Modules/DankBar/DankBar.qml index 556362c1..6a45a165 100644 --- a/Modules/DankBar/DankBar.qml +++ b/Modules/DankBar/DankBar.qml @@ -20,24 +20,74 @@ import qs.Widgets Item { id: root - signal colorPickerRequested() + signal colorPickerRequested + + property alias barVariants: barVariants + + function triggerControlCenterOnFocusedScreen() { + let focusedScreenName = "" + if (CompositorService.isHyprland && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor) { + focusedScreenName = Hyprland.focusedWorkspace.monitor.name + } else if (CompositorService.isNiri && NiriService.currentOutput) { + focusedScreenName = NiriService.currentOutput + } + + if (!focusedScreenName && barVariants.instances.length > 0) { + const firstBar = barVariants.instances[0] + firstBar.triggerControlCenter() + return true + } + + for (var i = 0; i < barVariants.instances.length; i++) { + const barInstance = barVariants.instances[i] + if (barInstance.modelData && barInstance.modelData.name === focusedScreenName) { + barInstance.triggerControlCenter() + return true + } + } + return false + } Variants { + id: barVariants model: SettingsData.getFilteredScreens("dankBar") delegate: PanelWindow { id: barWindow + property var controlCenterButtonRef: null + + function triggerControlCenter() { + controlCenterLoader.active = true + if (!controlCenterLoader.item) { + return + } + + if (controlCenterButtonRef && controlCenterLoader.item.setTriggerPosition) { + const globalPos = controlCenterButtonRef.mapToGlobal(0, 0) + const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, controlCenterButtonRef.width) + const section = controlCenterButtonRef.section || "right" + controlCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen) + } else { + controlCenterLoader.item.triggerScreen = barWindow.screen + } + + controlCenterLoader.item.toggle() + if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) { + NetworkService.scanWifi() + } + } + readonly property var dBarLayer: { switch (Quickshell.env("DMS_DANKBAR_LAYER")) { - case "bottom": - return WlrLayer.Bottom - case "overlay": - return WlrLayer.Overlay - case "background": - return WlrLayer.background - default: - return WlrLayer.Top + case "bottom": + return WlrLayer.Bottom + case "overlay": + return WlrLayer.Overlay + case "background": + return WlrLayer.background + default: + return WlrLayer.Top } } @@ -46,32 +96,30 @@ Item { property var modelData: item - signal colorPickerRequested() + signal colorPickerRequested onColorPickerRequested: root.colorPickerRequested() - AxisContext { id: axis edge: { switch (SettingsData.dankBarPosition) { - case SettingsData.Position.Top: - return "top"; - case SettingsData.Position.Bottom: - return "bottom"; - case SettingsData.Position.Left: - return "left"; - case SettingsData.Position.Right: - return "right"; - default: - return "top"; + case SettingsData.Position.Top: + return "top" + case SettingsData.Position.Bottom: + return "bottom" + case SettingsData.Position.Left: + return "left" + case SettingsData.Position.Right: + return "right" + default: + return "top" } } } readonly property bool isVertical: axis.isVertical - property bool gothCornersEnabled: SettingsData.dankBarGothCornersEnabled property real wingtipsRadius: Theme.cornerRadius readonly property real _wingR: Math.max(0, wingtipsRadius) @@ -81,11 +129,13 @@ Item { readonly property real _dpr: { if (CompositorService.isNiri && barWindow.screen) { const niriScale = NiriService.displayScales[barWindow.screen.name] - if (niriScale !== undefined) return niriScale + if (niriScale !== undefined) + return niriScale } if (CompositorService.isHyprland && barWindow.screen) { const hyprlandMonitor = Hyprland.monitors.values.find(m => m.name === barWindow.screen.name) - if (hyprlandMonitor?.scale !== undefined) return hyprlandMonitor.scale + if (hyprlandMonitor?.scale !== undefined) + return hyprlandMonitor.scale } return (barWindow.screen?.devicePixelRatio) || 1 } @@ -110,13 +160,13 @@ Item { if (SettingsData.forceStatusBarLayoutRefresh) { SettingsData.forceStatusBarLayoutRefresh.connect(() => { - Qt.callLater(() => { - stackContainer.visible = false - Qt.callLater(() => { - stackContainer.visible = true - }) - }) - }) + Qt.callLater(() => { + stackContainer.visible = false + Qt.callLater(() => { + stackContainer.visible = true + }) + }) + }) } updateGpuTempConfig() @@ -168,18 +218,18 @@ Item { try { const qmlString = ` - import QtQuick - import Quickshell.Wayland + import QtQuick + import Quickshell.Wayland - IdleInhibitor { - enabled: false - } + IdleInhibitor { + enabled: false + } ` nativeInhibitor = Qt.createQmlObject(qmlString, barWindow, "DankBar.NativeInhibitor") nativeInhibitor.window = barWindow nativeInhibitor.enabled = Qt.binding(() => SessionService.idleInhibited) - nativeInhibitor.enabledChanged.connect(function() { + nativeInhibitor.enabledChanged.connect(function () { console.log("DankBar: Native inhibitor enabled changed to:", nativeInhibitor.enabled) if (SessionService.idleInhibited !== nativeInhibitor.enabled) { SessionService.idleInhibited = nativeInhibitor.enabled @@ -260,9 +310,7 @@ Item { readonly property bool inOverviewWithShow: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview readonly property bool effectiveVisible: SettingsData.dankBarVisible || inOverviewWithShow - readonly property bool showing: effectiveVisible && (topBarCore.reveal - || inOverviewWithShow - || !topBarCore.autoHide) + readonly property bool showing: effectiveVisible && (topBarCore.reveal || inOverviewWithShow || !topBarCore.autoHide) readonly property int maskThickness: showing ? barThickness : 1 @@ -271,9 +319,12 @@ Item { return 0 } else { switch (SettingsData.dankBarPosition) { - case SettingsData.Position.Left: return 0 - case SettingsData.Position.Right: return parent.width - maskThickness - default: return 0 + case SettingsData.Position.Left: + return 0 + case SettingsData.Position.Right: + return parent.width - maskThickness + default: + return 0 } } } @@ -282,9 +333,12 @@ Item { return 0 } else { switch (SettingsData.dankBarPosition) { - case SettingsData.Position.Top: return 0 - case SettingsData.Position.Bottom: return parent.height - maskThickness - default: return 0 + case SettingsData.Position.Top: + return 0 + case SettingsData.Position.Bottom: + return parent.height - maskThickness + default: + return 0 } } } @@ -305,842 +359,850 @@ Item { property bool autoHide: SettingsData.dankBarAutoHide property bool revealSticky: false - Timer { - id: revealHold - interval: 250 - repeat: false - onTriggered: topBarCore.revealSticky = false - } - - property bool reveal: { - if (CompositorService.isNiri && NiriService.inOverview) { - return SettingsData.dankBarOpenOnOverview || topBarMouseArea.containsMouse || hasActivePopout || revealSticky - } - return SettingsData.dankBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky) - } - - readonly property bool hasActivePopout: { - const loaders = [{ - "loader": appDrawerLoader, - "prop": "shouldBeVisible" - }, { - "loader": dankDashPopoutLoader, - "prop": "shouldBeVisible" - }, { - "loader": processListPopoutLoader, - "prop": "shouldBeVisible" - }, { - "loader": notificationCenterLoader, - "prop": "shouldBeVisible" - }, { - "loader": batteryPopoutLoader, - "prop": "shouldBeVisible" - }, { - "loader": vpnPopoutLoader, - "prop": "shouldBeVisible" - }, { - "loader": controlCenterLoader, - "prop": "shouldBeVisible" - }, { - "loader": clipboardHistoryModalPopup, - "prop": "visible" - }, { - "loader": systemUpdateLoader, - "prop": "shouldBeVisible" - }] - return loaders.some(item => { - if (item.loader) { - return item.loader?.item?.[item.prop] + Timer { + id: revealHold + interval: 250 + repeat: false + onTriggered: topBarCore.revealSticky = false } - return false - }) - } - Connections { - function onDankBarTransparencyChanged() { - topBarCore.backgroundTransparency = SettingsData.dankBarTransparency - } + property bool reveal: { + if (CompositorService.isNiri && NiriService.inOverview) { + return SettingsData.dankBarOpenOnOverview || topBarMouseArea.containsMouse || hasActivePopout || revealSticky + } + return SettingsData.dankBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky) + } - target: SettingsData - } + readonly property bool hasActivePopout: { + const loaders = [{ + "loader": appDrawerLoader, + "prop": "shouldBeVisible" + }, { + "loader": dankDashPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": processListPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": notificationCenterLoader, + "prop": "shouldBeVisible" + }, { + "loader": batteryPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": vpnPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": controlCenterLoader, + "prop": "shouldBeVisible" + }, { + "loader": clipboardHistoryModalPopup, + "prop": "visible" + }, { + "loader": systemUpdateLoader, + "prop": "shouldBeVisible" + }] + return loaders.some(item => { + if (item.loader && item.loader.item) { + return item.loader.item[item.prop] + } + return false + }) + } - Connections { - target: topBarMouseArea - function onContainsMouseChanged() { - if (topBarMouseArea.containsMouse) { - topBarCore.revealSticky = true - revealHold.stop() - } else { - if (topBarCore.autoHide && !topBarCore.hasActivePopout) { + Connections { + function onDankBarTransparencyChanged() { + topBarCore.backgroundTransparency = SettingsData.dankBarTransparency + } + + target: SettingsData + } + + Connections { + target: topBarMouseArea + function onContainsMouseChanged() { + if (topBarMouseArea.containsMouse) { + topBarCore.revealSticky = true + revealHold.stop() + } else { + if (topBarCore.autoHide && !topBarCore.hasActivePopout) { + revealHold.restart() + } + } + } + } + + onHasActivePopoutChanged: { + if (!hasActivePopout && autoHide && !topBarMouseArea.containsMouse) { + revealSticky = true revealHold.restart() } } - } - } - onHasActivePopoutChanged: { - if (!hasActivePopout && autoHide && !topBarMouseArea.containsMouse) { - revealSticky = true - revealHold.restart() - } - } - - MouseArea { - id: topBarMouseArea - y: !barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? parent.height - height : 0) : 0 - x: barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.width - width : 0) : 0 - height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined - width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined - anchors { - left: !barWindow.isVertical ? parent.left : (SettingsData.dankBarPosition === SettingsData.Position.Left ? parent.left : undefined) - right: !barWindow.isVertical ? parent.right : (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.right : undefined) - top: barWindow.isVertical ? parent.top : undefined - bottom: barWindow.isVertical ? parent.bottom : undefined - } - readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview - hoverEnabled: SettingsData.dankBarAutoHide && !topBarCore.reveal && !inOverview - acceptedButtons: Qt.NoButton - enabled: SettingsData.dankBarAutoHide && !topBarCore.reveal && !inOverview - - Item { - id: topBarContainer - anchors.fill: parent - - transform: Translate { - id: topBarSlide - x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0 - y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0 - - Behavior on x { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Easing.OutCubic - } - } - - Behavior on y { - NumberAnimation { - duration: Theme.shortDuration - easing.type: Easing.OutCubic - } - } - } - - Item { - id: barUnitInset - anchors.fill: parent - anchors.leftMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "left" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0) - anchors.rightMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "right" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0) - anchors.topMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? 0 : Theme.px(SettingsData.dankBarSpacing, barWindow._dpr)) - anchors.bottomMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0) - - BarCanvas { - id: barBackground - barWindow: barWindow - axis: axis + MouseArea { + id: topBarMouseArea + y: !barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? parent.height - height : 0) : 0 + x: barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.width - width : 0) : 0 + height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined + width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined + anchors { + left: !barWindow.isVertical ? parent.left : (SettingsData.dankBarPosition === SettingsData.Position.Left ? parent.left : undefined) + right: !barWindow.isVertical ? parent.right : (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.right : undefined) + top: barWindow.isVertical ? parent.top : undefined + bottom: barWindow.isVertical ? parent.bottom : undefined } + readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview + hoverEnabled: SettingsData.dankBarAutoHide && !topBarCore.reveal && !inOverview + acceptedButtons: Qt.NoButton + enabled: SettingsData.dankBarAutoHide && !topBarCore.reveal && !inOverview Item { - id: topBarContent + id: topBarContainer anchors.fill: parent - anchors.leftMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2 - anchors.rightMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2 - anchors.topMargin: !barWindow.isVertical ? SettingsData.dankBarInnerPadding / 2 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) - anchors.bottomMargin: !barWindow.isVertical ? SettingsData.dankBarInnerPadding / 2 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) - clip: true - property int componentMapRevision: 0 + transform: Translate { + id: topBarSlide + x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0 + y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0 - function updateComponentMap() { - componentMapRevision++ - } - - readonly property int availableWidth: width - readonly property int launcherButtonWidth: 40 - readonly property int workspaceSwitcherWidth: 120 - readonly property int focusedAppMaxWidth: 456 - readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth + focusedAppMaxWidth + (Theme.spacingXS * 2) - readonly property int rightSectionWidth: 200 - readonly property int clockWidth: 120 - readonly property int mediaMaxWidth: 280 - readonly property int weatherWidth: 80 - readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0 - readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2 - readonly property int clockRightEdge: clockLeftEdge + clockWidth - readonly property int leftSectionRightEdge: estimatedLeftSectionWidth - readonly property int mediaLeftEdge: clockLeftEdge - mediaMaxWidth - Theme.spacingS - readonly property int rightSectionLeftEdge: availableWidth - rightSectionWidth - readonly property int leftToClockGap: Math.max(0, clockLeftEdge - leftSectionRightEdge) - readonly property int leftToMediaGap: mediaMaxWidth > 0 ? Math.max(0, mediaLeftEdge - leftSectionRightEdge) : leftToClockGap - readonly property int mediaToClockGap: mediaMaxWidth > 0 ? Theme.spacingS : 0 - readonly property int clockToRightGap: validLayout ? Math.max(0, rightSectionLeftEdge - clockRightEdge) : 1000 - readonly property bool spacingTight: !barWindow.isVertical && validLayout && (leftToMediaGap < 150 || clockToRightGap < 100) - readonly property bool overlapping: !barWindow.isVertical && validLayout && (leftToMediaGap < 100 || clockToRightGap < 50) - - function getWidgetEnabled(enabled) { - return enabled !== false - } - - function getWidgetSection(parentItem) { - let current = parentItem - while (current) { - if (current.objectName === "leftSection" || current === hLeftSection || current === vLeftSection) { - return "left" + Behavior on x { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Easing.OutCubic } - if (current.objectName === "centerSection" || current === hCenterSection || current === vCenterSection) { - return "center" - } - if (current.objectName === "rightSection" || current === hRightSection || current === vRightSection) { - return "right" - } - current = current.parent - } - return "left" // fallback - } - - readonly property var widgetVisibility: ({ - "cpuUsage": DgopService.dgopAvailable, - "memUsage": DgopService.dgopAvailable, - "cpuTemp": DgopService.dgopAvailable, - "gpuTemp": DgopService.dgopAvailable, - "network_speed_monitor": DgopService.dgopAvailable - }) - - function getWidgetVisible(widgetId) { - return widgetVisibility[widgetId] ?? true - } - - readonly property var componentMap: { - // This property depends on componentMapRevision to ensure it updates when plugins change - componentMapRevision; - - let baseMap = { - "launcherButton": launcherButtonComponent, - "workspaceSwitcher": workspaceSwitcherComponent, - "focusedWindow": focusedWindowComponent, - "runningApps": runningAppsComponent, - "clock": clockComponent, - "music": mediaComponent, - "weather": weatherComponent, - "systemTray": systemTrayComponent, - "privacyIndicator": privacyIndicatorComponent, - "clipboard": clipboardComponent, - "cpuUsage": cpuUsageComponent, - "memUsage": memUsageComponent, - "diskUsage": diskUsageComponent, - "cpuTemp": cpuTempComponent, - "gpuTemp": gpuTempComponent, - "notificationButton": notificationButtonComponent, - "battery": batteryComponent, - "controlCenterButton": controlCenterButtonComponent, - "idleInhibitor": idleInhibitorComponent, - "spacer": spacerComponent, - "separator": separatorComponent, - "network_speed_monitor": networkComponent, - "keyboard_layout_name": keyboardLayoutNameComponent, - "vpn": vpnComponent, - "notepadButton": notepadButtonComponent, - "colorPicker": colorPickerComponent, - "systemUpdate": systemUpdateComponent } - // Merge with plugin widgets - let pluginMap = PluginService.getWidgetComponents() - return Object.assign(baseMap, pluginMap) + Behavior on y { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Easing.OutCubic + } + } } - function getWidgetComponent(widgetId) { - return componentMap[widgetId] || null - } - - readonly property var allComponents: ({ - launcherButtonComponent: launcherButtonComponent, - workspaceSwitcherComponent: workspaceSwitcherComponent, - focusedWindowComponent: focusedWindowComponent, - runningAppsComponent: runningAppsComponent, - clockComponent: clockComponent, - mediaComponent: mediaComponent, - weatherComponent: weatherComponent, - systemTrayComponent: systemTrayComponent, - privacyIndicatorComponent: privacyIndicatorComponent, - clipboardComponent: clipboardComponent, - cpuUsageComponent: cpuUsageComponent, - memUsageComponent: memUsageComponent, - diskUsageComponent: diskUsageComponent, - cpuTempComponent: cpuTempComponent, - gpuTempComponent: gpuTempComponent, - notificationButtonComponent: notificationButtonComponent, - batteryComponent: batteryComponent, - controlCenterButtonComponent: controlCenterButtonComponent, - idleInhibitorComponent: idleInhibitorComponent, - spacerComponent: spacerComponent, - separatorComponent: separatorComponent, - networkComponent: networkComponent, - keyboardLayoutNameComponent: keyboardLayoutNameComponent, - vpnComponent: vpnComponent, - notepadButtonComponent: notepadButtonComponent, - colorPickerComponent: colorPickerComponent, - systemUpdateComponent: systemUpdateComponent - }) - Item { - id: stackContainer + id: barUnitInset anchors.fill: parent + anchors.leftMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "left" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0) + anchors.rightMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "right" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0) + anchors.topMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? 0 : Theme.px(SettingsData.dankBarSpacing, barWindow._dpr)) + anchors.bottomMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0) + + BarCanvas { + id: barBackground + barWindow: barWindow + axis: axis + } Item { - id: horizontalStack + id: topBarContent anchors.fill: parent - visible: !axis.isVertical + anchors.leftMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2 + anchors.rightMargin: !barWindow.isVertical ? Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) : SettingsData.dankBarInnerPadding / 2 + anchors.topMargin: !barWindow.isVertical ? SettingsData.dankBarInnerPadding / 2 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) + anchors.bottomMargin: !barWindow.isVertical ? SettingsData.dankBarInnerPadding / 2 : Math.max(Theme.spacingXS, SettingsData.dankBarInnerPadding * 0.8) + clip: true - LeftSection { - id: hLeftSection - anchors { - left: parent.left - verticalCenter: parent.verticalCenter + property int componentMapRevision: 0 + + function updateComponentMap() { + componentMapRevision++ + } + + readonly property int availableWidth: width + readonly property int launcherButtonWidth: 40 + readonly property int workspaceSwitcherWidth: 120 + readonly property int focusedAppMaxWidth: 456 + readonly property int estimatedLeftSectionWidth: launcherButtonWidth + workspaceSwitcherWidth + focusedAppMaxWidth + (Theme.spacingXS * 2) + readonly property int rightSectionWidth: 200 + readonly property int clockWidth: 120 + readonly property int mediaMaxWidth: 280 + readonly property int weatherWidth: 80 + readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0 + readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2 + readonly property int clockRightEdge: clockLeftEdge + clockWidth + readonly property int leftSectionRightEdge: estimatedLeftSectionWidth + readonly property int mediaLeftEdge: clockLeftEdge - mediaMaxWidth - Theme.spacingS + readonly property int rightSectionLeftEdge: availableWidth - rightSectionWidth + readonly property int leftToClockGap: Math.max(0, clockLeftEdge - leftSectionRightEdge) + readonly property int leftToMediaGap: mediaMaxWidth > 0 ? Math.max(0, mediaLeftEdge - leftSectionRightEdge) : leftToClockGap + readonly property int mediaToClockGap: mediaMaxWidth > 0 ? Theme.spacingS : 0 + readonly property int clockToRightGap: validLayout ? Math.max(0, rightSectionLeftEdge - clockRightEdge) : 1000 + readonly property bool spacingTight: !barWindow.isVertical && validLayout && (leftToMediaGap < 150 || clockToRightGap < 100) + readonly property bool overlapping: !barWindow.isVertical && validLayout && (leftToMediaGap < 100 || clockToRightGap < 50) + + function getWidgetEnabled(enabled) { + return enabled !== false + } + + function getWidgetSection(parentItem) { + let current = parentItem + while (current) { + if (current.objectName === "leftSection" || current === hLeftSection || current === vLeftSection) { + return "left" + } + if (current.objectName === "centerSection" || current === hCenterSection || current === vCenterSection) { + return "center" + } + if (current.objectName === "rightSection" || current === hRightSection || current === vRightSection) { + return "right" + } + current = current.parent } - axis: axis - widgetsModel: SettingsData.dankBarLeftWidgetsModel - components: topBarContent.allComponents - noBackground: SettingsData.dankBarNoBackground - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness + return "left" // fallback } - RightSection { - id: hRightSection - anchors { - right: parent.right - verticalCenter: parent.verticalCenter + readonly property var widgetVisibility: ({ + "cpuUsage": DgopService.dgopAvailable, + "memUsage": DgopService.dgopAvailable, + "cpuTemp": DgopService.dgopAvailable, + "gpuTemp": DgopService.dgopAvailable, + "network_speed_monitor": DgopService.dgopAvailable + }) + + function getWidgetVisible(widgetId) { + return widgetVisibility[widgetId] ?? true + } + + readonly property var componentMap: { + // This property depends on componentMapRevision to ensure it updates when plugins change + componentMapRevision + + let baseMap = { + "launcherButton": launcherButtonComponent, + "workspaceSwitcher": workspaceSwitcherComponent, + "focusedWindow": focusedWindowComponent, + "runningApps": runningAppsComponent, + "clock": clockComponent, + "music": mediaComponent, + "weather": weatherComponent, + "systemTray": systemTrayComponent, + "privacyIndicator": privacyIndicatorComponent, + "clipboard": clipboardComponent, + "cpuUsage": cpuUsageComponent, + "memUsage": memUsageComponent, + "diskUsage": diskUsageComponent, + "cpuTemp": cpuTempComponent, + "gpuTemp": gpuTempComponent, + "notificationButton": notificationButtonComponent, + "battery": batteryComponent, + "controlCenterButton": controlCenterButtonComponent, + "idleInhibitor": idleInhibitorComponent, + "spacer": spacerComponent, + "separator": separatorComponent, + "network_speed_monitor": networkComponent, + "keyboard_layout_name": keyboardLayoutNameComponent, + "vpn": vpnComponent, + "notepadButton": notepadButtonComponent, + "colorPicker": colorPickerComponent, + "systemUpdate": systemUpdateComponent } - axis: axis - widgetsModel: SettingsData.dankBarRightWidgetsModel - components: topBarContent.allComponents - noBackground: SettingsData.dankBarNoBackground - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness + + // Merge with plugin widgets + let pluginMap = PluginService.getWidgetComponents() + return Object.assign(baseMap, pluginMap) } - CenterSection { - id: hCenterSection - anchors { - verticalCenter: parent.verticalCenter - horizontalCenter: parent.horizontalCenter - } - axis: axis - widgetsModel: SettingsData.dankBarCenterWidgetsModel - components: topBarContent.allComponents - noBackground: SettingsData.dankBarNoBackground - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - } - } - - Item { - id: verticalStack - anchors.fill: parent - visible: axis.isVertical - - LeftSection { - id: vLeftSection - width: parent.width - anchors { - top: parent.top - horizontalCenter: parent.horizontalCenter - } - axis: axis - widgetsModel: SettingsData.dankBarLeftWidgetsModel - components: topBarContent.allComponents - noBackground: SettingsData.dankBarNoBackground - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness + function getWidgetComponent(widgetId) { + return componentMap[widgetId] || null } - CenterSection { - id: vCenterSection - width: parent.width - anchors { - verticalCenter: parent.verticalCenter - horizontalCenter: parent.horizontalCenter - } - axis: axis - widgetsModel: SettingsData.dankBarCenterWidgetsModel - components: topBarContent.allComponents - noBackground: SettingsData.dankBarNoBackground - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - } + readonly property var allComponents: ({ + "launcherButtonComponent": launcherButtonComponent, + "workspaceSwitcherComponent": workspaceSwitcherComponent, + "focusedWindowComponent": focusedWindowComponent, + "runningAppsComponent": runningAppsComponent, + "clockComponent": clockComponent, + "mediaComponent": mediaComponent, + "weatherComponent": weatherComponent, + "systemTrayComponent": systemTrayComponent, + "privacyIndicatorComponent": privacyIndicatorComponent, + "clipboardComponent": clipboardComponent, + "cpuUsageComponent": cpuUsageComponent, + "memUsageComponent": memUsageComponent, + "diskUsageComponent": diskUsageComponent, + "cpuTempComponent": cpuTempComponent, + "gpuTempComponent": gpuTempComponent, + "notificationButtonComponent": notificationButtonComponent, + "batteryComponent": batteryComponent, + "controlCenterButtonComponent": controlCenterButtonComponent, + "idleInhibitorComponent": idleInhibitorComponent, + "spacerComponent": spacerComponent, + "separatorComponent": separatorComponent, + "networkComponent": networkComponent, + "keyboardLayoutNameComponent": keyboardLayoutNameComponent, + "vpnComponent": vpnComponent, + "notepadButtonComponent": notepadButtonComponent, + "colorPickerComponent": colorPickerComponent, + "systemUpdateComponent": systemUpdateComponent + }) - RightSection { - id: vRightSection - width: parent.width - height: implicitHeight - anchors { - bottom: parent.bottom - horizontalCenter: parent.horizontalCenter - } - axis: axis - widgetsModel: SettingsData.dankBarRightWidgetsModel - components: topBarContent.allComponents - noBackground: SettingsData.dankBarNoBackground - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - } - } - } - - - - Component { - id: clipboardComponent - - ClipboardButton { - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) - parentScreen: barWindow.screen - onClicked: { - clipboardHistoryModalPopup.toggle() - } - } - } - - Component { - id: launcherButtonComponent - - LauncherButton { - isActive: false - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) - popupTarget: appDrawerLoader.item - parentScreen: barWindow.screen - onClicked: { - appDrawerLoader.active = true - appDrawerLoader.item?.toggle() - } - } - } - - Component { - id: workspaceSwitcherComponent - - WorkspaceSwitcher { - screenName: barWindow.screenName - widgetHeight: barWindow.widgetThickness - } - } - - Component { - id: focusedWindowComponent - - FocusedApp { - availableWidth: topBarContent.leftToMediaGap - widgetThickness: barWindow.widgetThickness - parentScreen: barWindow.screen - } - } - - Component { - id: runningAppsComponent - - RunningApps { - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) - parentScreen: barWindow.screen - topBar: topBarContent - } - } - - Component { - id: clockComponent - - Clock { - compactMode: topBarContent.overlapping - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "center" - popupTarget: { - dankDashPopoutLoader.active = true - return dankDashPopoutLoader.item - } - parentScreen: barWindow.screen - onClockClicked: { - dankDashPopoutLoader.active = true - if (dankDashPopoutLoader.item) { - dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible - dankDashPopoutLoader.item.currentTabIndex = 0 - } - } - } - } - - Component { - id: mediaComponent - - Media { - compactMode: topBarContent.spacingTight || topBarContent.overlapping - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "center" - popupTarget: { - dankDashPopoutLoader.active = true - return dankDashPopoutLoader.item - } - parentScreen: barWindow.screen - onClicked: { - dankDashPopoutLoader.active = true - if (dankDashPopoutLoader.item) { - dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible - dankDashPopoutLoader.item.currentTabIndex = 1 - } - } - } - } - - Component { - id: weatherComponent - - Weather { - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "center" - popupTarget: { - dankDashPopoutLoader.active = true - return dankDashPopoutLoader.item - } - parentScreen: barWindow.screen - onClicked: { - dankDashPopoutLoader.active = true - if (dankDashPopoutLoader.item) { - dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible - dankDashPopoutLoader.item.currentTabIndex = 2 - } - } - } - } - - Component { - id: systemTrayComponent - - SystemTrayBar { - parentWindow: root - parentScreen: barWindow.screen - widgetThickness: barWindow.widgetThickness - isAtBottom: SettingsData.dankBarPosition === SettingsData.Position.Bottom - visible: SettingsData.getFilteredScreens("systemTray").includes(barWindow.screen) && SystemTray.items.values.length > 0 - } - } - - Component { - id: privacyIndicatorComponent - - PrivacyIndicator { - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "right" - parentScreen: barWindow.screen - } - } - - Component { - id: cpuUsageComponent - - CpuMonitor { - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - processListPopoutLoader.active = true - return processListPopoutLoader.item - } - parentScreen: barWindow.screen - widgetData: parent.widgetData - toggleProcessList: () => { - processListPopoutLoader.active = true - return processListPopoutLoader.item?.toggle() - } - } - } - - Component { - id: memUsageComponent - - RamMonitor { - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - processListPopoutLoader.active = true - return processListPopoutLoader.item - } - parentScreen: barWindow.screen - widgetData: parent.widgetData - toggleProcessList: () => { - processListPopoutLoader.active = true - return processListPopoutLoader.item?.toggle() - } - } - } - - Component { - id: diskUsageComponent - - DiskUsage { - widgetThickness: barWindow.widgetThickness - widgetData: parent.widgetData - parentScreen: barWindow.screen - } - } - - Component { - id: cpuTempComponent - - CpuTemperature { - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - processListPopoutLoader.active = true - return processListPopoutLoader.item - } - parentScreen: barWindow.screen - widgetData: parent.widgetData - toggleProcessList: () => { - processListPopoutLoader.active = true - return processListPopoutLoader.item?.toggle() - } - } - } - - Component { - id: gpuTempComponent - - GpuTemperature { - barThickness: barWindow.effectiveBarThickness - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - processListPopoutLoader.active = true - return processListPopoutLoader.item - } - parentScreen: barWindow.screen - widgetData: parent.widgetData - toggleProcessList: () => { - processListPopoutLoader.active = true - return processListPopoutLoader.item?.toggle() - } - } - } - - Component { - id: networkComponent - - NetworkMonitor {} - } - - Component { - id: notificationButtonComponent - - NotificationCenterButton { - hasUnread: barWindow.notificationCount > 0 - isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - notificationCenterLoader.active = true - return notificationCenterLoader.item - } - parentScreen: barWindow.screen - onClicked: { - notificationCenterLoader.active = true - notificationCenterLoader.item?.toggle() - } - } - } - - Component { - id: batteryComponent - - Battery { - batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - batteryPopoutLoader.active = true - return batteryPopoutLoader.item - } - parentScreen: barWindow.screen - onToggleBatteryPopup: { - batteryPopoutLoader.active = true - batteryPopoutLoader.item?.toggle() - } - } - } - - Component { - id: vpnComponent - - Vpn { - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - vpnPopoutLoader.active = true - return vpnPopoutLoader.item - } - parentScreen: barWindow.screen - onToggleVpnPopup: { - vpnPopoutLoader.active = true - vpnPopoutLoader.item?.toggle() - } - } - } - - Component { - id: controlCenterButtonComponent - - ControlCenterButton { - isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - controlCenterLoader.active = true - return controlCenterLoader.item - } - parentScreen: barWindow.screen - widgetData: parent.widgetData - onClicked: { - controlCenterLoader.active = true - if (!controlCenterLoader.item) { - return - } - controlCenterLoader.item.triggerScreen = barWindow.screen - controlCenterLoader.item.toggle() - if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) { - NetworkService.scanWifi() - } - } - } - } - - Component { - id: idleInhibitorComponent - - IdleInhibitor { - widgetThickness: barWindow.widgetThickness - section: topBarContent.getWidgetSection(parent) || "right" - parentScreen: barWindow.screen - } - } - - Component { - id: spacerComponent - - Item { - width: barWindow.isVertical ? barWindow.widgetThickness : (parent.spacerSize || 20) - height: barWindow.isVertical ? (parent.spacerSize || 20) : barWindow.widgetThickness - implicitWidth: width - implicitHeight: height - - Rectangle { + Item { + id: stackContainer anchors.fill: parent - color: "transparent" - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) - border.width: 1 - radius: 2 - visible: false - MouseArea { + Item { + id: horizontalStack anchors.fill: parent - hoverEnabled: true - acceptedButtons: Qt.NoButton // do not consume clicks - propagateComposedEvents: true // let events pass through - cursorShape: Qt.ArrowCursor // don't override widget cursors - onEntered: parent.visible = true - onExited: parent.visible = false + visible: !axis.isVertical + + LeftSection { + id: hLeftSection + anchors { + left: parent.left + verticalCenter: parent.verticalCenter + } + axis: axis + widgetsModel: SettingsData.dankBarLeftWidgetsModel + components: topBarContent.allComponents + noBackground: SettingsData.dankBarNoBackground + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + } + + RightSection { + id: hRightSection + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + } + axis: axis + widgetsModel: SettingsData.dankBarRightWidgetsModel + components: topBarContent.allComponents + noBackground: SettingsData.dankBarNoBackground + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + } + + CenterSection { + id: hCenterSection + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + axis: axis + widgetsModel: SettingsData.dankBarCenterWidgetsModel + components: topBarContent.allComponents + noBackground: SettingsData.dankBarNoBackground + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + } + } + + Item { + id: verticalStack + anchors.fill: parent + visible: axis.isVertical + + LeftSection { + id: vLeftSection + width: parent.width + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + } + axis: axis + widgetsModel: SettingsData.dankBarLeftWidgetsModel + components: topBarContent.allComponents + noBackground: SettingsData.dankBarNoBackground + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + } + + CenterSection { + id: vCenterSection + width: parent.width + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + axis: axis + widgetsModel: SettingsData.dankBarCenterWidgetsModel + components: topBarContent.allComponents + noBackground: SettingsData.dankBarNoBackground + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + } + + RightSection { + id: vRightSection + width: parent.width + height: implicitHeight + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + axis: axis + widgetsModel: SettingsData.dankBarRightWidgetsModel + components: topBarContent.allComponents + noBackground: SettingsData.dankBarNoBackground + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + } + } + } + + Component { + id: clipboardComponent + + ClipboardButton { + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) + parentScreen: barWindow.screen + onClicked: { + clipboardHistoryModalPopup.toggle() + } + } + } + + Component { + id: launcherButtonComponent + + LauncherButton { + isActive: false + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) + popupTarget: appDrawerLoader.item + parentScreen: barWindow.screen + onClicked: { + appDrawerLoader.active = true + appDrawerLoader.item?.toggle() + } + } + } + + Component { + id: workspaceSwitcherComponent + + WorkspaceSwitcher { + screenName: barWindow.screenName + widgetHeight: barWindow.widgetThickness + } + } + + Component { + id: focusedWindowComponent + + FocusedApp { + availableWidth: topBarContent.leftToMediaGap + widgetThickness: barWindow.widgetThickness + parentScreen: barWindow.screen + } + } + + Component { + id: runningAppsComponent + + RunningApps { + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) + parentScreen: barWindow.screen + topBar: topBarContent + } + } + + Component { + id: clockComponent + + Clock { + compactMode: topBarContent.overlapping + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "center" + popupTarget: { + dankDashPopoutLoader.active = true + return dankDashPopoutLoader.item + } + parentScreen: barWindow.screen + onClockClicked: { + dankDashPopoutLoader.active = true + if (dankDashPopoutLoader.item) { + dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible + dankDashPopoutLoader.item.currentTabIndex = 0 + } + } + } + } + + Component { + id: mediaComponent + + Media { + compactMode: topBarContent.spacingTight || topBarContent.overlapping + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "center" + popupTarget: { + dankDashPopoutLoader.active = true + return dankDashPopoutLoader.item + } + parentScreen: barWindow.screen + onClicked: { + dankDashPopoutLoader.active = true + if (dankDashPopoutLoader.item) { + dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible + dankDashPopoutLoader.item.currentTabIndex = 1 + } + } + } + } + + Component { + id: weatherComponent + + Weather { + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "center" + popupTarget: { + dankDashPopoutLoader.active = true + return dankDashPopoutLoader.item + } + parentScreen: barWindow.screen + onClicked: { + dankDashPopoutLoader.active = true + if (dankDashPopoutLoader.item) { + dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible + dankDashPopoutLoader.item.currentTabIndex = 2 + } + } + } + } + + Component { + id: systemTrayComponent + + SystemTrayBar { + parentWindow: root + parentScreen: barWindow.screen + widgetThickness: barWindow.widgetThickness + isAtBottom: SettingsData.dankBarPosition === SettingsData.Position.Bottom + visible: SettingsData.getFilteredScreens("systemTray").includes(barWindow.screen) && SystemTray.items.values.length > 0 + } + } + + Component { + id: privacyIndicatorComponent + + PrivacyIndicator { + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "right" + parentScreen: barWindow.screen + } + } + + Component { + id: cpuUsageComponent + + CpuMonitor { + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + processListPopoutLoader.active = true + return processListPopoutLoader.item + } + parentScreen: barWindow.screen + widgetData: parent.widgetData + toggleProcessList: () => { + processListPopoutLoader.active = true + return processListPopoutLoader.item?.toggle() + } + } + } + + Component { + id: memUsageComponent + + RamMonitor { + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + processListPopoutLoader.active = true + return processListPopoutLoader.item + } + parentScreen: barWindow.screen + widgetData: parent.widgetData + toggleProcessList: () => { + processListPopoutLoader.active = true + return processListPopoutLoader.item?.toggle() + } + } + } + + Component { + id: diskUsageComponent + + DiskUsage { + widgetThickness: barWindow.widgetThickness + widgetData: parent.widgetData + parentScreen: barWindow.screen + } + } + + Component { + id: cpuTempComponent + + CpuTemperature { + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + processListPopoutLoader.active = true + return processListPopoutLoader.item + } + parentScreen: barWindow.screen + widgetData: parent.widgetData + toggleProcessList: () => { + processListPopoutLoader.active = true + return processListPopoutLoader.item?.toggle() + } + } + } + + Component { + id: gpuTempComponent + + GpuTemperature { + barThickness: barWindow.effectiveBarThickness + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + processListPopoutLoader.active = true + return processListPopoutLoader.item + } + parentScreen: barWindow.screen + widgetData: parent.widgetData + toggleProcessList: () => { + processListPopoutLoader.active = true + return processListPopoutLoader.item?.toggle() + } + } + } + + Component { + id: networkComponent + + NetworkMonitor {} + } + + Component { + id: notificationButtonComponent + + NotificationCenterButton { + hasUnread: barWindow.notificationCount > 0 + isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + notificationCenterLoader.active = true + return notificationCenterLoader.item + } + parentScreen: barWindow.screen + onClicked: { + notificationCenterLoader.active = true + notificationCenterLoader.item?.toggle() + } + } + } + + Component { + id: batteryComponent + + Battery { + batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + batteryPopoutLoader.active = true + return batteryPopoutLoader.item + } + parentScreen: barWindow.screen + onToggleBatteryPopup: { + batteryPopoutLoader.active = true + batteryPopoutLoader.item?.toggle() + } + } + } + + Component { + id: vpnComponent + + Vpn { + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + vpnPopoutLoader.active = true + return vpnPopoutLoader.item + } + parentScreen: barWindow.screen + onToggleVpnPopup: { + vpnPopoutLoader.active = true + vpnPopoutLoader.item?.toggle() + } + } + } + + Component { + id: controlCenterButtonComponent + + ControlCenterButton { + isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + controlCenterLoader.active = true + return controlCenterLoader.item + } + parentScreen: barWindow.screen + widgetData: parent.widgetData + + Component.onCompleted: { + barWindow.controlCenterButtonRef = this + } + + Component.onDestruction: { + if (barWindow.controlCenterButtonRef === this) { + barWindow.controlCenterButtonRef = null + } + } + + onClicked: { + controlCenterLoader.active = true + if (!controlCenterLoader.item) { + return + } + controlCenterLoader.item.triggerScreen = barWindow.screen + controlCenterLoader.item.toggle() + if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) { + NetworkService.scanWifi() + } + } + } + } + + Component { + id: idleInhibitorComponent + + IdleInhibitor { + widgetThickness: barWindow.widgetThickness + section: topBarContent.getWidgetSection(parent) || "right" + parentScreen: barWindow.screen + } + } + + Component { + id: spacerComponent + + Item { + width: barWindow.isVertical ? barWindow.widgetThickness : (parent.spacerSize || 20) + height: barWindow.isVertical ? (parent.spacerSize || 20) : barWindow.widgetThickness + implicitWidth: width + implicitHeight: height + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) + border.width: 1 + radius: 2 + visible: false + + MouseArea { + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.NoButton // do not consume clicks + propagateComposedEvents: true // let events pass through + cursorShape: Qt.ArrowCursor // don't override widget cursors + onEntered: parent.visible = true + onExited: parent.visible = false + } + } + } + } + + Component { + id: separatorComponent + + Rectangle { + width: barWindow.isVertical ? barWindow.widgetThickness * 0.67 : 1 + height: barWindow.isVertical ? 1 : barWindow.widgetThickness * 0.67 + implicitWidth: width + implicitHeight: height + color: Theme.outline + opacity: 0.3 + } + } + + Component { + id: keyboardLayoutNameComponent + + KeyboardLayoutName {} + } + + Component { + id: notepadButtonComponent + + NotepadButton { + isVertical: barWindow.isVertical + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + parentScreen: barWindow.screen + } + } + + Component { + id: colorPickerComponent + + ColorPicker { + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + parentScreen: barWindow.screen + onColorPickerRequested: { + barWindow.colorPickerRequested() + } + } + } + + Component { + id: systemUpdateComponent + + SystemUpdate { + isActive: systemUpdateLoader.item ? systemUpdateLoader.item.shouldBeVisible : false + widgetThickness: barWindow.widgetThickness + barThickness: barWindow.effectiveBarThickness + section: topBarContent.getWidgetSection(parent) || "right" + popupTarget: { + systemUpdateLoader.active = true + return systemUpdateLoader.item + } + parentScreen: barWindow.screen + onClicked: { + systemUpdateLoader.active = true + systemUpdateLoader.item?.toggle() + } } } } } - - Component { - id: separatorComponent - - Rectangle { - width: barWindow.isVertical ? barWindow.widgetThickness * 0.67 : 1 - height: barWindow.isVertical ? 1 : barWindow.widgetThickness * 0.67 - implicitWidth: width - implicitHeight: height - color: Theme.outline - opacity: 0.3 - } - } - - Component { - id: keyboardLayoutNameComponent - - KeyboardLayoutName {} - } - - Component { - id: notepadButtonComponent - - NotepadButton { - isVertical: barWindow.isVertical - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - parentScreen: barWindow.screen - } - } - - Component { - id: colorPickerComponent - - ColorPicker { - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - parentScreen: barWindow.screen - onColorPickerRequested: { - barWindow.colorPickerRequested() - } - } - } - - Component { - id: systemUpdateComponent - - SystemUpdate { - isActive: systemUpdateLoader.item ? systemUpdateLoader.item.shouldBeVisible : false - widgetThickness: barWindow.widgetThickness - barThickness: barWindow.effectiveBarThickness - section: topBarContent.getWidgetSection(parent) || "right" - popupTarget: { - systemUpdateLoader.active = true - return systemUpdateLoader.item - } - parentScreen: barWindow.screen - onClicked: { - systemUpdateLoader.active = true - systemUpdateLoader.item?.toggle() - } - } - } - } } } } - } - } } }