summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml
diff options
context:
space:
mode:
authorNippy <nippy@rp1.hu>2026-05-08 19:50:49 +0200
committerNippy <nippy@rp1.hu>2026-05-08 19:50:49 +0200
commit3462bcc46ecf74f576ea4397f16492c16bd75b10 (patch)
treec5ab7aef4498647e057bda8d49c11e5f9dda74c9 /raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml
parent56616f693b4f263cbf0d47da43b67424efa6022d (diff)
downloadRaveOS-PKGBUILD-3462bcc46ecf74f576ea4397f16492c16bd75b10.tar.gz
RaveOS-PKGBUILD-3462bcc46ecf74f576ea4397f16492c16bd75b10.zip
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml')
-rw-r--r--raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml1459
1 files changed, 1459 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml b/raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml
new file mode 100644
index 0000000..0c977bf
--- /dev/null
+++ b/raveos-hyprland-theme/theme-data/dms/Modules/DankBar/DankBarContent.qml
@@ -0,0 +1,1459 @@
+import QtQuick
+import Quickshell.Hyprland
+import Quickshell.I3
+import Quickshell.Services.SystemTray
+import Quickshell.Wayland
+import qs.Common
+import qs.Modules.DankBar.Widgets
+import qs.Services
+
+Item {
+ id: topBarContent
+
+ required property var barWindow
+ required property var rootWindow
+ required property var barConfig
+
+ readonly property var blurBarWindow: barWindow
+
+ property var leftWidgetsModel
+ property var centerWidgetsModel
+ property var rightWidgetsModel
+
+ readonly property real innerPadding: barConfig?.innerPadding ?? 4
+ readonly property real outlineThickness: (barConfig?.widgetOutlineEnabled ?? false) ? (barConfig?.widgetOutlineThickness ?? 1) : 0
+
+ property alias hLeftSection: hLeftSection
+ property alias hCenterSection: hCenterSection
+ property alias hRightSection: hRightSection
+ property alias vLeftSection: vLeftSection
+ property alias vCenterSection: vCenterSection
+ property alias vRightSection: vRightSection
+
+ anchors.fill: parent
+ anchors.leftMargin: Math.max(Theme.spacingXS, innerPadding * 0.8)
+ anchors.rightMargin: Math.max(Theme.spacingXS, innerPadding * 0.8)
+ anchors.topMargin: barWindow.isVertical ? (barWindow.hasAdjacentTopBar ? outlineThickness : Theme.spacingXS) : 0
+ anchors.bottomMargin: barWindow.isVertical ? (barWindow.hasAdjacentBottomBar ? outlineThickness : Theme.spacingXS) : 0
+ clip: false
+
+ property int componentMapRevision: 0
+
+ function updateComponentMap() {
+ componentMapRevision++;
+ }
+
+ readonly property var sortedToplevels: {
+ return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, barWindow.screenName);
+ }
+
+ function getRealWorkspaces() {
+ if (CompositorService.isNiri) {
+ const fallbackWorkspaces = [
+ {
+ "id": 1,
+ "idx": 0,
+ "name": ""
+ },
+ {
+ "id": 2,
+ "idx": 1,
+ "name": ""
+ }
+ ];
+ if (!barWindow.screenName || SettingsData.workspaceFollowFocus) {
+ const currentWorkspaces = NiriService.getCurrentOutputWorkspaces();
+ return currentWorkspaces.length > 0 ? currentWorkspaces : fallbackWorkspaces;
+ }
+ const workspaces = NiriService.allWorkspaces.filter(ws => ws.output === barWindow.screenName);
+ return workspaces.length > 0 ? workspaces : fallbackWorkspaces;
+ } else if (CompositorService.isHyprland) {
+ const workspaces = Hyprland.workspaces?.values || [];
+
+ if (!barWindow.screenName || SettingsData.workspaceFollowFocus) {
+ const sorted = workspaces.slice().sort((a, b) => a.id - b.id);
+ const filtered = sorted.filter(ws => ws.id > -1);
+ return filtered.length > 0 ? filtered : [
+ {
+ "id": 1,
+ "name": "1"
+ }
+ ];
+ }
+
+ const monitorWorkspaces = workspaces.filter(ws => {
+ return ws.lastIpcObject && ws.lastIpcObject.monitor === barWindow.screenName && ws.id > -1;
+ });
+
+ if (monitorWorkspaces.length === 0) {
+ return [
+ {
+ "id": 1,
+ "name": "1"
+ }
+ ];
+ }
+
+ return monitorWorkspaces.sort((a, b) => a.id - b.id);
+ } else if (CompositorService.isDwl) {
+ if (!DwlService.dwlAvailable) {
+ return [0];
+ }
+ if (SettingsData.dwlShowAllTags) {
+ return Array.from({
+ length: DwlService.tagCount
+ }, (_, i) => i);
+ }
+ return DwlService.getVisibleTags(barWindow.screenName);
+ } else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
+ const workspaces = I3.workspaces?.values || [];
+ if (workspaces.length === 0)
+ return [
+ {
+ "num": 1
+ }
+ ];
+
+ if (!barWindow.screenName || SettingsData.workspaceFollowFocus) {
+ return workspaces.slice().sort((a, b) => a.num - b.num);
+ }
+
+ const monitorWorkspaces = workspaces.filter(ws => ws.monitor?.name === barWindow.screenName);
+ return monitorWorkspaces.length > 0 ? monitorWorkspaces.sort((a, b) => a.num - b.num) : [
+ {
+ "num": 1
+ }
+ ];
+ }
+ return [1];
+ }
+
+ function getCurrentWorkspace() {
+ if (CompositorService.isNiri) {
+ if (!barWindow.screenName || SettingsData.workspaceFollowFocus) {
+ return NiriService.getCurrentWorkspaceNumber();
+ }
+ const activeWs = NiriService.allWorkspaces.find(ws => ws.output === barWindow.screenName && ws.is_active);
+ return activeWs ? activeWs.idx : 1;
+ } else if (CompositorService.isHyprland) {
+ const monitors = Hyprland.monitors?.values || [];
+ const currentMonitor = monitors.find(monitor => monitor.name === barWindow.screenName);
+ return currentMonitor?.activeWorkspace?.id ?? 1;
+ } else if (CompositorService.isDwl) {
+ if (!DwlService.dwlAvailable)
+ return 0;
+ const outputState = DwlService.getOutputState(barWindow.screenName);
+ if (!outputState || !outputState.tags)
+ return 0;
+ const activeTags = DwlService.getActiveTags(barWindow.screenName);
+ return activeTags.length > 0 ? activeTags[0] : 0;
+ } else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
+ if (!barWindow.screenName || SettingsData.workspaceFollowFocus) {
+ const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
+ return focusedWs ? focusedWs.num : 1;
+ }
+
+ const focusedWs = I3.workspaces?.values?.find(ws => ws.monitor?.name === barWindow.screenName && ws.focused === true);
+ return focusedWs ? focusedWs.num : 1;
+ }
+ return 1;
+ }
+
+ function switchWorkspace(direction) {
+ const realWorkspaces = getRealWorkspaces();
+ if (realWorkspaces.length < 2) {
+ return;
+ }
+
+ if (CompositorService.isNiri) {
+ const currentWs = getCurrentWorkspace();
+ const currentIndex = realWorkspaces.findIndex(ws => ws && ws.idx === currentWs);
+ const validIndex = currentIndex === -1 ? 0 : currentIndex;
+ const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0);
+
+ if (nextIndex !== validIndex) {
+ const nextWorkspace = realWorkspaces[nextIndex];
+ if (!nextWorkspace || nextWorkspace.idx === undefined) {
+ return;
+ }
+ NiriService.switchToWorkspace(nextWorkspace.idx);
+ }
+ } else if (CompositorService.isHyprland) {
+ const currentWs = getCurrentWorkspace();
+ const currentIndex = realWorkspaces.findIndex(ws => ws.id === currentWs);
+ const validIndex = currentIndex === -1 ? 0 : currentIndex;
+ const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0);
+
+ if (nextIndex !== validIndex) {
+ Hyprland.dispatch(`workspace ${realWorkspaces[nextIndex].id}`);
+ }
+ } else if (CompositorService.isDwl) {
+ const currentTag = getCurrentWorkspace();
+ const currentIndex = realWorkspaces.findIndex(tag => tag === currentTag);
+ const validIndex = currentIndex === -1 ? 0 : currentIndex;
+ const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0);
+
+ if (nextIndex !== validIndex) {
+ DwlService.switchToTag(barWindow.screenName, realWorkspaces[nextIndex]);
+ }
+ } else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
+ const currentWs = getCurrentWorkspace();
+ const currentIndex = realWorkspaces.findIndex(ws => ws.num === currentWs);
+ const validIndex = currentIndex === -1 ? 0 : currentIndex;
+ const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0);
+
+ if (nextIndex !== validIndex) {
+ try {
+ I3.dispatch(`workspace number ${realWorkspaces[nextIndex].num}`);
+ } catch (_) {}
+ }
+ }
+ }
+
+ function switchApp(deltaY) {
+ const windows = sortedToplevels;
+ if (windows.length < 2) {
+ return;
+ }
+ let currentIndex = -1;
+ for (let i = 0; i < windows.length; i++) {
+ if (windows[i].activated) {
+ currentIndex = i;
+ break;
+ }
+ }
+ let nextIndex;
+ if (deltaY < 0) {
+ if (currentIndex === -1) {
+ nextIndex = 0;
+ } else {
+ nextIndex = currentIndex + 1;
+ }
+ } else {
+ if (currentIndex === -1) {
+ nextIndex = windows.length - 1;
+ } else {
+ nextIndex = currentIndex - 1;
+ }
+ }
+ const nextWindow = windows[nextIndex];
+ if (nextWindow) {
+ nextWindow.activate();
+ }
+ }
+
+ 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") {
+ return "left";
+ }
+ if (current.objectName === "centerSection") {
+ return "center";
+ }
+ if (current.objectName === "rightSection") {
+ return "right";
+ }
+ current = current.parent;
+ }
+ return "left";
+ }
+
+ 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: {
+ componentMapRevision;
+
+ let baseMap = {
+ "launcherButton": launcherButtonComponent,
+ "workspaceSwitcher": workspaceSwitcherComponent,
+ "focusedWindow": focusedWindowComponent,
+ "runningApps": runningAppsComponent,
+ "appsDock": appsDockComponent,
+ "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,
+ "layout": layoutComponent,
+ "controlCenterButton": controlCenterButtonComponent,
+ "capsLockIndicator": capsLockIndicatorComponent,
+ "idleInhibitor": idleInhibitorComponent,
+ "spacer": spacerComponent,
+ "separator": separatorComponent,
+ "network_speed_monitor": networkComponent,
+ "keyboard_layout_name": keyboardLayoutNameComponent,
+ "vpn": vpnComponent,
+ "notepadButton": notepadButtonComponent,
+ "colorPicker": colorPickerComponent,
+ "systemUpdate": systemUpdateComponent,
+ "powerMenuButton": powerMenuButtonComponent
+ };
+
+ let pluginMap = PluginService.getWidgetComponents();
+ return Object.assign(baseMap, pluginMap);
+ }
+
+ function getWidgetComponent(widgetId) {
+ return componentMap[widgetId] || null;
+ }
+
+ readonly property var allComponents: ({
+ "launcherButtonComponent": launcherButtonComponent,
+ "workspaceSwitcherComponent": workspaceSwitcherComponent,
+ "focusedWindowComponent": focusedWindowComponent,
+ "runningAppsComponent": runningAppsComponent,
+ "appsDockComponent": appsDockComponent,
+ "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,
+ "layoutComponent": layoutComponent,
+ "controlCenterButtonComponent": controlCenterButtonComponent,
+ "capsLockIndicatorComponent": capsLockIndicatorComponent,
+ "idleInhibitorComponent": idleInhibitorComponent,
+ "spacerComponent": spacerComponent,
+ "separatorComponent": separatorComponent,
+ "networkComponent": networkComponent,
+ "keyboardLayoutNameComponent": keyboardLayoutNameComponent,
+ "vpnComponent": vpnComponent,
+ "notepadButtonComponent": notepadButtonComponent,
+ "colorPickerComponent": colorPickerComponent,
+ "systemUpdateComponent": systemUpdateComponent,
+ "powerMenuButtonComponent": powerMenuButtonComponent
+ })
+
+ Item {
+ id: stackContainer
+ anchors.fill: parent
+
+ Item {
+ id: horizontalStack
+ anchors.fill: parent
+ visible: !barWindow.axis.isVertical
+
+ LeftSection {
+ id: hLeftSection
+ objectName: "leftSection"
+ overrideAxisLayout: true
+ forceVerticalLayout: false
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ axis: barWindow.axis
+ widgetsModel: topBarContent.leftWidgetsModel
+ components: topBarContent.allComponents
+ noBackground: barConfig?.noBackground ?? false
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ }
+
+ Binding {
+ target: hLeftSection
+ property: "barConfig"
+ value: topBarContent.barConfig
+ restoreMode: Binding.RestoreNone
+ }
+ Binding {
+ target: hLeftSection
+ property: "blurBarWindow"
+ value: topBarContent.blurBarWindow
+ restoreMode: Binding.RestoreNone
+ }
+
+ RightSection {
+ id: hRightSection
+ objectName: "rightSection"
+ overrideAxisLayout: true
+ forceVerticalLayout: false
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ axis: barWindow.axis
+ widgetsModel: topBarContent.rightWidgetsModel
+ components: topBarContent.allComponents
+ noBackground: barConfig?.noBackground ?? false
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ }
+
+ Binding {
+ target: hRightSection
+ property: "barConfig"
+ value: topBarContent.barConfig
+ restoreMode: Binding.RestoreNone
+ }
+ Binding {
+ target: hRightSection
+ property: "blurBarWindow"
+ value: topBarContent.blurBarWindow
+ restoreMode: Binding.RestoreNone
+ }
+
+ CenterSection {
+ id: hCenterSection
+ objectName: "centerSection"
+ overrideAxisLayout: true
+ forceVerticalLayout: false
+ anchors {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ axis: barWindow.axis
+ widgetsModel: topBarContent.centerWidgetsModel
+ components: topBarContent.allComponents
+ noBackground: barConfig?.noBackground ?? false
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ }
+
+ Binding {
+ target: hCenterSection
+ property: "barConfig"
+ value: topBarContent.barConfig
+ restoreMode: Binding.RestoreNone
+ }
+ Binding {
+ target: hCenterSection
+ property: "blurBarWindow"
+ value: topBarContent.blurBarWindow
+ restoreMode: Binding.RestoreNone
+ }
+ }
+
+ Item {
+ id: verticalStack
+ anchors.fill: parent
+ visible: barWindow.axis.isVertical
+
+ LeftSection {
+ id: vLeftSection
+ objectName: "leftSection"
+ overrideAxisLayout: true
+ forceVerticalLayout: true
+ width: parent.width
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ }
+ axis: barWindow.axis
+ widgetsModel: topBarContent.leftWidgetsModel
+ components: topBarContent.allComponents
+ noBackground: barConfig?.noBackground ?? false
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ }
+
+ Binding {
+ target: vLeftSection
+ property: "barConfig"
+ value: topBarContent.barConfig
+ restoreMode: Binding.RestoreNone
+ }
+ Binding {
+ target: vLeftSection
+ property: "blurBarWindow"
+ value: topBarContent.blurBarWindow
+ restoreMode: Binding.RestoreNone
+ }
+
+ CenterSection {
+ id: vCenterSection
+ objectName: "centerSection"
+ overrideAxisLayout: true
+ forceVerticalLayout: true
+ width: parent.width
+ anchors {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ axis: barWindow.axis
+ widgetsModel: topBarContent.centerWidgetsModel
+ components: topBarContent.allComponents
+ noBackground: barConfig?.noBackground ?? false
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ }
+
+ Binding {
+ target: vCenterSection
+ property: "barConfig"
+ value: topBarContent.barConfig
+ restoreMode: Binding.RestoreNone
+ }
+ Binding {
+ target: vCenterSection
+ property: "blurBarWindow"
+ value: topBarContent.blurBarWindow
+ restoreMode: Binding.RestoreNone
+ }
+
+ RightSection {
+ id: vRightSection
+ objectName: "rightSection"
+ overrideAxisLayout: true
+ forceVerticalLayout: true
+ width: parent.width
+ height: implicitHeight
+ anchors {
+ bottom: parent.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ axis: barWindow.axis
+ widgetsModel: topBarContent.rightWidgetsModel
+ components: topBarContent.allComponents
+ noBackground: barConfig?.noBackground ?? false
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ }
+
+ Binding {
+ target: vRightSection
+ property: "barConfig"
+ value: topBarContent.barConfig
+ restoreMode: Binding.RestoreNone
+ }
+ Binding {
+ target: vRightSection
+ property: "blurBarWindow"
+ value: topBarContent.blurBarWindow
+ restoreMode: Binding.RestoreNone
+ }
+ }
+ }
+
+ Component {
+ id: clipboardComponent
+
+ ClipboardButton {
+ id: clipboardWidget
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent)
+ parentScreen: barWindow.screen
+ popoutTarget: clipboardHistoryPopoutLoader.item ?? null
+
+ function openClipboardPopout(initialTab) {
+ clipboardHistoryPopoutLoader.active = true;
+ if (!clipboardHistoryPopoutLoader.item) {
+ return;
+ }
+ const popout = clipboardHistoryPopoutLoader.item;
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (popout.setBarContext) {
+ popout.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (popout.setTriggerPosition) {
+ const globalPos = clipboardWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, clipboardWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ popout.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ if (initialTab) {
+ popout.activeTab = initialTab;
+ }
+ PopoutManager.requestPopout(popout, undefined, "clipboard");
+ }
+
+ onClipboardClicked: openClipboardPopout("recents")
+
+ onShowSavedItemsRequested: openClipboardPopout("saved")
+
+ onClearAllRequested: {
+ clipboardHistoryPopoutLoader.active = true;
+ const popout = clipboardHistoryPopoutLoader.item;
+ if (!popout?.confirmDialog) {
+ return;
+ }
+ const hasPinned = popout.pinnedCount > 0;
+ const message = hasPinned ? I18n.tr("This will delete all unpinned entries. %1 pinned entries will be kept.").arg(popout.pinnedCount) : I18n.tr("This will permanently delete all clipboard history.");
+ popout.confirmDialog.show(I18n.tr("Clear History?"), message, function () {
+ if (popout && typeof popout.clearAll === "function") {
+ popout.clearAll();
+ }
+ }, function () {});
+ }
+ }
+ }
+
+ Component {
+ id: powerMenuButtonComponent
+
+ PowerMenuButton {
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent)
+ parentScreen: barWindow.screen
+ onClicked: {
+ if (powerMenuModalLoader) {
+ powerMenuModalLoader.active = true;
+ if (powerMenuModalLoader.item) {
+ powerMenuModalLoader.item.openCentered();
+ }
+ }
+ }
+ }
+ }
+
+ Component {
+ id: launcherButtonComponent
+
+ LauncherButton {
+ id: launcherButton
+ isActive: false
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ section: topBarContent.getWidgetSection(parent)
+ popoutTarget: appDrawerLoader.item
+ parentScreen: barWindow.screen
+ hyprlandOverviewLoader: barWindow ? barWindow.hyprlandOverviewLoader : null
+
+ function _preparePopout() {
+ appDrawerLoader.active = true;
+ if (!appDrawerLoader.item)
+ return false;
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (appDrawerLoader.item.setBarContext)
+ appDrawerLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ if (appDrawerLoader.item.setTriggerPosition) {
+ const globalPos = launcherButton.visualContent.mapToItem(null, 0, 0);
+ const currentScreen = barWindow.screen;
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barWindow.effectiveBarThickness, launcherButton.visualWidth, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ appDrawerLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, launcherButton.section, currentScreen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ return true;
+ }
+
+ function openWithMode(mode) {
+ if (!_preparePopout())
+ return;
+ appDrawerLoader.item.openWithMode(mode);
+ }
+
+ function toggleWithMode(mode) {
+ if (!_preparePopout())
+ return;
+ appDrawerLoader.item.toggleWithMode(mode);
+ }
+
+ function openWithQuery(query) {
+ if (!_preparePopout())
+ return;
+ appDrawerLoader.item.openWithQuery(query);
+ }
+
+ function toggleWithQuery(query) {
+ if (!_preparePopout())
+ return;
+ appDrawerLoader.item.toggleWithQuery(query);
+ }
+
+ onClicked: {
+ if (!_preparePopout())
+ return;
+ PopoutManager.requestPopout(appDrawerLoader.item, undefined, "appDrawer");
+ }
+ }
+ }
+
+ Component {
+ id: workspaceSwitcherComponent
+
+ WorkspaceSwitcher {
+ axis: barWindow.axis
+ screenName: barWindow.screenName
+ widgetHeight: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ parentScreen: barWindow.screen
+ hyprlandOverviewLoader: barWindow ? barWindow.hyprlandOverviewLoader : null
+ }
+ }
+
+ Component {
+ id: focusedWindowComponent
+
+ FocusedApp {
+ axis: barWindow.axis
+ availableWidth: topBarContent.leftToMediaGap
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ barConfig: topBarContent.barConfig
+ isAutoHideBar: topBarContent.barConfig?.autoHide ?? false
+ parentScreen: barWindow.screen
+ }
+ }
+
+ Component {
+ id: runningAppsComponent
+
+ RunningApps {
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ section: topBarContent.getWidgetSection(parent)
+ parentScreen: barWindow.screen
+ topBar: topBarContent
+ barConfig: topBarContent.barConfig
+ isAutoHideBar: topBarContent.barConfig?.autoHide ?? false
+ }
+ }
+
+ Component {
+ id: appsDockComponent
+
+ AppsDock {
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ barSpacing: barConfig?.spacing ?? 4
+ section: topBarContent.getWidgetSection(parent)
+ parentScreen: barWindow.screen
+ topBar: topBarContent
+ barConfig: topBarContent.barConfig
+ isAutoHideBar: topBarContent.barConfig?.autoHide ?? false
+ }
+ }
+
+ Component {
+ id: clockComponent
+
+ Clock {
+ axis: barWindow.axis
+ compactMode: topBarContent.overlapping
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ section: topBarContent.getWidgetSection(parent) || "center"
+ popoutTarget: dankDashPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+
+ Component.onCompleted: {
+ barWindow.clockButtonRef = this;
+ }
+
+ Component.onDestruction: {
+ if (barWindow.clockButtonRef === this) {
+ barWindow.clockButtonRef = null;
+ }
+ }
+
+ onClockClicked: {
+ dankDashPopoutLoader.active = true;
+ if (dankDashPopoutLoader.item) {
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (dankDashPopoutLoader.item.setBarContext) {
+ dankDashPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (dankDashPopoutLoader.item.setTriggerPosition) {
+ let triggerPos, triggerWidth;
+ if (section === "center") {
+ const centerSection = barWindow.isVertical ? (barWindow.axis?.edge === "left" ? vCenterSection : vCenterSection) : hCenterSection;
+ if (centerSection) {
+ if (barWindow.isVertical) {
+ const centerY = centerSection.height / 2;
+ const centerGlobalPos = centerSection.mapToItem(null, 0, centerY);
+ triggerPos = centerGlobalPos;
+ triggerWidth = centerSection.height;
+ } else {
+ const centerGlobalPos = centerSection.mapToItem(null, 0, 0);
+ triggerPos = centerGlobalPos;
+ triggerWidth = centerSection.width;
+ }
+ } else {
+ triggerPos = visualContent.mapToItem(null, 0, 0);
+ triggerWidth = visualWidth;
+ }
+ } else {
+ triggerPos = visualContent.mapToItem(null, 0, 0);
+ triggerWidth = visualWidth;
+ }
+ const pos = SettingsData.getPopupTriggerPosition(triggerPos, barWindow.screen, barWindow.effectiveBarThickness, triggerWidth, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ } else {
+ dankDashPopoutLoader.item.triggerScreen = barWindow.screen;
+ }
+ PopoutManager.requestPopout(dankDashPopoutLoader.item, 0, (effectiveBarConfig?.id ?? "default") + "-" + section + "-0");
+ }
+ }
+ }
+ }
+
+ Component {
+ id: mediaComponent
+
+ Media {
+ axis: barWindow.axis
+ compactMode: topBarContent.spacingTight || topBarContent.overlapping
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ section: topBarContent.getWidgetSection(parent) || "center"
+ popoutTarget: dankDashPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ onClicked: {
+ dankDashPopoutLoader.active = true;
+ if (dankDashPopoutLoader.item) {
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (dankDashPopoutLoader.item.setBarContext) {
+ dankDashPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (dankDashPopoutLoader.item.setTriggerPosition) {
+ let triggerPos, triggerWidth;
+ if (section === "center") {
+ const centerSection = barWindow.isVertical ? (barWindow.axis?.edge === "left" ? vCenterSection : vCenterSection) : hCenterSection;
+ if (centerSection) {
+ if (barWindow.isVertical) {
+ const centerY = centerSection.height / 2;
+ const centerGlobalPos = centerSection.mapToItem(null, 0, centerY);
+ triggerPos = centerGlobalPos;
+ triggerWidth = centerSection.height;
+ } else {
+ const centerGlobalPos = centerSection.mapToItem(null, 0, 0);
+ triggerPos = centerGlobalPos;
+ triggerWidth = centerSection.width;
+ }
+ } else {
+ triggerPos = visualContent.mapToItem(null, 0, 0);
+ triggerWidth = visualWidth;
+ }
+ } else {
+ triggerPos = visualContent.mapToItem(null, 0, 0);
+ triggerWidth = visualWidth;
+ }
+ const pos = SettingsData.getPopupTriggerPosition(triggerPos, barWindow.screen, barWindow.effectiveBarThickness, triggerWidth, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ } else {
+ dankDashPopoutLoader.item.triggerScreen = barWindow.screen;
+ }
+ PopoutManager.requestPopout(dankDashPopoutLoader.item, 1, (effectiveBarConfig?.id ?? "default") + "-" + section + "-1");
+ }
+ }
+ }
+ }
+
+ Component {
+ id: weatherComponent
+
+ Weather {
+ axis: barWindow.axis
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ section: topBarContent.getWidgetSection(parent) || "center"
+ popoutTarget: dankDashPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ onClicked: {
+ dankDashPopoutLoader.active = true;
+ if (dankDashPopoutLoader.item) {
+ const effectiveBarConfig = topBarContent.barConfig;
+ // Calculate barPosition from axis.edge
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (dankDashPopoutLoader.item.setBarContext) {
+ dankDashPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (dankDashPopoutLoader.item.setTriggerPosition) {
+ // For center section widgets, use center section bounds for DankDash centering
+ let triggerPos, triggerWidth;
+ if (section === "center") {
+ const centerSection = barWindow.isVertical ? (barWindow.axis?.edge === "left" ? vCenterSection : vCenterSection) : hCenterSection;
+ if (centerSection) {
+ // For vertical bars, use center Y of section; for horizontal, use left edge
+ if (barWindow.isVertical) {
+ const centerY = centerSection.height / 2;
+ const centerGlobalPos = centerSection.mapToItem(null, 0, centerY);
+ triggerPos = centerGlobalPos;
+ triggerWidth = centerSection.height;
+ } else {
+ // For horizontal bars, use left edge (DankPopout will center it)
+ const centerGlobalPos = centerSection.mapToItem(null, 0, 0);
+ triggerPos = centerGlobalPos;
+ triggerWidth = centerSection.width;
+ }
+ } else {
+ triggerPos = visualContent.mapToItem(null, 0, 0);
+ triggerWidth = visualWidth;
+ }
+ } else {
+ triggerPos = visualContent.mapToItem(null, 0, 0);
+ triggerWidth = visualWidth;
+ }
+ const pos = SettingsData.getPopupTriggerPosition(triggerPos, barWindow.screen, barWindow.effectiveBarThickness, triggerWidth, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ } else {
+ dankDashPopoutLoader.item.triggerScreen = barWindow.screen;
+ }
+ PopoutManager.requestPopout(dankDashPopoutLoader.item, 3, (effectiveBarConfig?.id ?? "default") + "-" + section + "-3");
+ }
+ }
+ }
+ }
+
+ Component {
+ id: systemTrayComponent
+
+ SystemTrayBar {
+ parentWindow: barWindow
+ parentScreen: barWindow.screen
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ barSpacing: barConfig?.spacing ?? 4
+ barConfig: topBarContent.barConfig
+ widgetData: parent.widgetData
+ isAutoHideBar: topBarContent.barConfig?.autoHide ?? false
+ isAtBottom: barWindow.axis?.edge === "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 {
+ id: cpuWidget
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: processListPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ widgetData: parent.widgetData
+ onCpuClicked: {
+ processListPopoutLoader.active = true;
+ if (!processListPopoutLoader.item) {
+ return;
+ }
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (processListPopoutLoader.item.setBarContext) {
+ processListPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (processListPopoutLoader.item.setTriggerPosition) {
+ const globalPos = cpuWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, cpuWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ processListPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(processListPopoutLoader.item, undefined, "cpu");
+ }
+ }
+ }
+
+ Component {
+ id: memUsageComponent
+
+ RamMonitor {
+ id: ramWidget
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: processListPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ widgetData: parent.widgetData
+ onRamClicked: {
+ processListPopoutLoader.active = true;
+ if (!processListPopoutLoader.item) {
+ return;
+ }
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (processListPopoutLoader.item.setBarContext) {
+ processListPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (processListPopoutLoader.item.setTriggerPosition) {
+ const globalPos = ramWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, ramWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ processListPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(processListPopoutLoader.item, undefined, "memory");
+ }
+ }
+ }
+
+ Component {
+ id: diskUsageComponent
+
+ DiskUsage {
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ widgetData: parent.widgetData
+ parentScreen: barWindow.screen
+ barConfig: topBarContent.barConfig
+ isAutoHideBar: topBarContent.barConfig?.autoHide ?? false
+ }
+ }
+
+ Component {
+ id: cpuTempComponent
+
+ CpuTemperature {
+ id: cpuTempWidget
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: processListPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ widgetData: parent.widgetData
+ onCpuTempClicked: {
+ processListPopoutLoader.active = true;
+ if (!processListPopoutLoader.item) {
+ return;
+ }
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (processListPopoutLoader.item.setBarContext) {
+ processListPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (processListPopoutLoader.item.setTriggerPosition) {
+ const globalPos = cpuTempWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, cpuTempWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ processListPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(processListPopoutLoader.item, undefined, "cpu_temp");
+ }
+ }
+ }
+
+ Component {
+ id: gpuTempComponent
+
+ GpuTemperature {
+ id: gpuTempWidget
+ barThickness: barWindow.effectiveBarThickness
+ widgetThickness: barWindow.widgetThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: processListPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ widgetData: parent.widgetData
+ onGpuTempClicked: {
+ processListPopoutLoader.active = true;
+ if (!processListPopoutLoader.item) {
+ return;
+ }
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (processListPopoutLoader.item.setBarContext) {
+ processListPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (processListPopoutLoader.item.setTriggerPosition) {
+ const globalPos = gpuTempWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, gpuTempWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ processListPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(processListPopoutLoader.item, undefined, "gpu_temp");
+ }
+ }
+ }
+
+ Component {
+ id: networkComponent
+
+ NetworkMonitor {}
+ }
+
+ Component {
+ id: notificationButtonComponent
+
+ NotificationCenterButton {
+ id: notificationButton
+ hasUnread: barWindow.notificationCount > 0
+ isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: notificationCenterLoader.item ?? null
+ parentScreen: barWindow.screen
+ onClicked: {
+ notificationCenterLoader.active = true;
+ if (!notificationCenterLoader.item) {
+ return;
+ }
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (notificationCenterLoader.item.setBarContext) {
+ notificationCenterLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (notificationCenterLoader.item.setTriggerPosition) {
+ const globalPos = notificationButton.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, notificationButton.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ notificationCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(notificationCenterLoader.item, undefined, "notifications");
+ }
+ }
+ }
+
+ Component {
+ id: batteryComponent
+
+ Battery {
+ id: batteryWidget
+ batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ barSpacing: barConfig?.spacing ?? 4
+ barConfig: topBarContent.barConfig
+ popoutTarget: batteryPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ onToggleBatteryPopup: {
+ batteryPopoutLoader.active = true;
+ if (!batteryPopoutLoader.item) {
+ return;
+ }
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (batteryPopoutLoader.item.setBarContext) {
+ batteryPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (batteryPopoutLoader.item.setTriggerPosition) {
+ const globalPos = batteryWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, batteryWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ batteryPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(batteryPopoutLoader.item, undefined, "battery");
+ }
+ }
+ }
+
+ Component {
+ id: layoutComponent
+
+ DWLLayout {
+ id: layoutWidget
+ layoutPopupVisible: layoutPopoutLoader.item ? layoutPopoutLoader.item.shouldBeVisible : false
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "center"
+ popoutTarget: layoutPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ onToggleLayoutPopup: {
+ layoutPopoutLoader.active = true;
+ if (!layoutPopoutLoader.item)
+ return;
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+
+ if (layoutPopoutLoader.item.setTriggerPosition) {
+ const globalPos = layoutWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, layoutWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "center";
+ layoutPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+
+ PopoutManager.requestPopout(layoutPopoutLoader.item, undefined, "layout");
+ }
+ }
+ }
+
+ Component {
+ id: vpnComponent
+
+ Vpn {
+ id: vpnWidget
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ barSpacing: barConfig?.spacing ?? 4
+ barConfig: topBarContent.barConfig
+ isAutoHideBar: topBarContent.barConfig?.autoHide ?? false
+ popoutTarget: vpnPopoutLoader.item ?? null
+ parentScreen: barWindow.screen
+ onToggleVpnPopup: {
+ vpnPopoutLoader.active = true;
+ if (!vpnPopoutLoader.item)
+ return;
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+
+ if (vpnPopoutLoader.item.setBarContext) {
+ vpnPopoutLoader.item.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+
+ if (vpnPopoutLoader.item.setTriggerPosition) {
+ const globalPos = vpnWidget.mapToItem(null, 0, 0);
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, vpnWidget.width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const widgetSection = topBarContent.getWidgetSection(parent) || "right";
+ vpnPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+
+ PopoutManager.requestPopout(vpnPopoutLoader.item, undefined, "vpn");
+ }
+ }
+ }
+
+ Component {
+ id: controlCenterButtonComponent
+
+ ControlCenterButton {
+ isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: controlCenterLoader.item ?? null
+ parentScreen: barWindow.screen
+ screenName: barWindow.screen?.name || ""
+ screenModel: barWindow.screen?.model || ""
+ 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;
+ if (controlCenterLoader.item.setTriggerPosition) {
+ const globalPos = mapToItem(null, 0, 0);
+ // Use topBarContent.barConfig directly
+ const effectiveBarConfig = topBarContent.barConfig;
+ // Calculate barPosition from axis.edge like Battery widget does
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, width, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ const section = topBarContent.getWidgetSection(parent) || "right";
+ controlCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(controlCenterLoader.item, undefined, "controlCenter");
+ if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) {
+ NetworkService.scanWifi();
+ }
+ }
+ }
+ }
+
+ Component {
+ id: capsLockIndicatorComponent
+
+ CapsLockIndicator {
+ widgetThickness: barWindow.widgetThickness
+ section: topBarContent.getWidgetSection(parent) || "right"
+ parentScreen: barWindow.screen
+ }
+ }
+
+ 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
+ propagateComposedEvents: true
+ cursorShape: Qt.ArrowCursor
+ onEntered: parent.visible = true
+ onExited: parent.visible = false
+ }
+ }
+ }
+ }
+
+ Component {
+ id: separatorComponent
+
+ Item {
+ width: barWindow.isVertical ? parent.barThickness : 1
+ height: barWindow.isVertical ? 1 : parent.barThickness
+ implicitWidth: width
+ implicitHeight: height
+
+ Rectangle {
+ width: barWindow.isVertical ? parent.width * 0.6 : 1
+ height: barWindow.isVertical ? 1 : parent.height * 0.6
+ anchors.centerIn: parent
+ color: Theme.outline
+ opacity: 0.3
+ }
+ }
+ }
+
+ Component {
+ id: keyboardLayoutNameComponent
+
+ KeyboardLayoutName {}
+ }
+
+ Component {
+ id: notepadButtonComponent
+
+ NotepadButton {
+ widgetThickness: barWindow.widgetThickness
+ barThickness: barWindow.effectiveBarThickness
+ axis: barWindow.axis
+ 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
+ axis: barWindow.axis
+ section: topBarContent.getWidgetSection(parent) || "right"
+ popoutTarget: systemUpdateLoader.item ?? null
+ parentScreen: barWindow.screen
+ onClicked: {
+ systemUpdateLoader.active = true;
+ if (!systemUpdateLoader.item)
+ return;
+ const popout = systemUpdateLoader.item;
+ const effectiveBarConfig = topBarContent.barConfig;
+ const barPosition = barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
+ if (popout.setBarContext) {
+ popout.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
+ }
+ if (popout.setTriggerPosition) {
+ const globalPos = visualContent.mapToItem(null, 0, 0);
+ const currentScreen = parentScreen || Screen;
+ const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barWindow.effectiveBarThickness, visualWidth, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
+ popout.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
+ }
+ PopoutManager.requestPopout(popout, undefined, "systemUpdate");
+ }
+ }
+ }
+}