1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-14 23:25:23 -04:00
Files
DankMaterialShell/quickshell/Modules/DankBar/DankBarContent.qml
T

2038 lines
75 KiB
QML

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
property bool _animateFrameInsets: false
readonly property real innerPadding: barConfig?.innerPadding ?? 4
readonly property real outlineThickness: (barConfig?.widgetOutlineEnabled ?? false) ? (barConfig?.widgetOutlineThickness ?? 1) : 0
readonly property real _edgeBaseMargin: Math.max(Theme.spacingXS, innerPadding * 0.8)
readonly property bool _hasBarWindow: barWindow !== undefined && barWindow !== null
readonly property bool _usesFrameBarChrome: _hasBarWindow && (barWindow.usesFrameBarChrome ?? false)
readonly property real _frameEdgeFloorInset: (SettingsData.frameEnabled && _usesFrameBarChrome) ? Math.max(0, SettingsData.frameThickness - _edgeBaseMargin) : 0
readonly property bool _barIsVertical: _hasBarWindow ? barWindow.isVertical : false
readonly property string _barScreenName: _hasBarWindow ? (barWindow.screenName || "") : ""
readonly property bool hasAdjacentTopBarLive: _hasBarWindow && barWindow.hasAdjacentTopBar
readonly property bool hasAdjacentBottomBarLive: _hasBarWindow && barWindow.hasAdjacentBottomBar
readonly property bool hasAdjacentLeftBarLive: _hasBarWindow && barWindow.hasAdjacentLeftBar
readonly property bool hasAdjacentRightBarLive: _hasBarWindow && barWindow.hasAdjacentRightBar
property bool _hadAdjacentTopBar: false
property bool _hadAdjacentBottomBar: false
property bool _hadAdjacentLeftBar: false
property bool _hadAdjacentRightBar: false
onHasAdjacentTopBarLiveChanged: if (hasAdjacentTopBarLive)
_hadAdjacentTopBar = true
onHasAdjacentBottomBarLiveChanged: if (hasAdjacentBottomBarLive)
_hadAdjacentBottomBar = true
onHasAdjacentLeftBarLiveChanged: if (hasAdjacentLeftBarLive)
_hadAdjacentLeftBar = true
onHasAdjacentRightBarLiveChanged: if (hasAdjacentRightBarLive)
_hadAdjacentRightBar = true
readonly property real _frameLeftInset: {
if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || _barIsVertical)
return 0;
return hasAdjacentLeftBarLive ? SettingsData.frameBarSize : (_hadAdjacentLeftBar ? _frameEdgeFloorInset : 0);
}
readonly property real _frameRightInset: {
if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || _barIsVertical)
return 0;
return hasAdjacentRightBarLive ? SettingsData.frameBarSize : (_hadAdjacentRightBar ? _frameEdgeFloorInset : 0);
}
readonly property real _frameTopInset: {
if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || !_barIsVertical)
return 0;
return hasAdjacentTopBarLive ? SettingsData.frameThickness : (_hadAdjacentTopBar ? _frameEdgeFloorInset : 0);
}
readonly property real _frameBottomInset: {
if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || !_barIsVertical)
return 0;
return hasAdjacentBottomBarLive ? SettingsData.frameThickness : (_hadAdjacentBottomBar ? _frameEdgeFloorInset : 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: _edgeBaseMargin + _frameLeftInset
anchors.rightMargin: _edgeBaseMargin + _frameRightInset
anchors.topMargin: (_barIsVertical ? (hasAdjacentTopBarLive ? outlineThickness : Theme.spacingXS) : 0) + _frameTopInset
anchors.bottomMargin: (_barIsVertical ? (hasAdjacentBottomBarLive ? outlineThickness : Theme.spacingXS) : 0) + _frameBottomInset
clip: false
DeferredAction {
id: enableFrameInsetAnimation
onTriggered: topBarContent._animateFrameInsets = true
}
Component.onCompleted: {
_hadAdjacentTopBar = hasAdjacentTopBarLive;
_hadAdjacentBottomBar = hasAdjacentBottomBarLive;
_hadAdjacentLeftBar = hasAdjacentLeftBarLive;
_hadAdjacentRightBar = hasAdjacentRightBarLive;
enableFrameInsetAnimation.schedule();
}
Behavior on anchors.leftMargin {
enabled: _animateFrameInsets && _usesFrameBarChrome
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
Behavior on anchors.rightMargin {
enabled: _animateFrameInsets && _usesFrameBarChrome
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
Behavior on anchors.topMargin {
enabled: _animateFrameInsets && _usesFrameBarChrome
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
Behavior on anchors.bottomMargin {
enabled: _animateFrameInsets && _usesFrameBarChrome
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
property int componentMapRevision: 0
function updateComponentMap() {
componentMapRevision++;
}
readonly property var sortedToplevels: {
if (!_hasBarWindow) {
return [];
}
return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, _barScreenName);
}
function getRealWorkspaces() {
const screenName = _barScreenName;
if (CompositorService.isNiri) {
const fallbackWorkspaces = [
{
"id": 1,
"idx": 0,
"name": ""
},
{
"id": 2,
"idx": 1,
"name": ""
}
];
if (!screenName || SettingsData.workspaceFollowFocus) {
const currentWorkspaces = NiriService.getCurrentOutputWorkspaces();
return currentWorkspaces.length > 0 ? currentWorkspaces : fallbackWorkspaces;
}
const workspaces = NiriService.allWorkspaces.filter(ws => ws.output === screenName);
return workspaces.length > 0 ? workspaces : fallbackWorkspaces;
} else if (CompositorService.isHyprland) {
const workspaces = Hyprland.workspaces?.values || [];
if (!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 === 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.isMango) {
if (!MangoService.available) {
return [0];
}
if (SettingsData.dwlShowAllTags) {
return Array.from({
length: MangoService.tagCount
}, (_, i) => i);
}
return MangoService.getVisibleTags(screenName);
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const workspaces = I3.workspaces?.values || [];
if (workspaces.length === 0)
return [
{
"num": 1
}
];
if (!screenName || SettingsData.workspaceFollowFocus) {
return workspaces.slice().sort((a, b) => a.num - b.num);
}
const monitorWorkspaces = workspaces.filter(ws => ws.monitor?.name === screenName);
return monitorWorkspaces.length > 0 ? monitorWorkspaces.sort((a, b) => a.num - b.num) : [
{
"num": 1
}
];
}
return [1];
}
function getCurrentWorkspace() {
const screenName = _barScreenName;
if (CompositorService.isNiri) {
if (!screenName || SettingsData.workspaceFollowFocus) {
return NiriService.getCurrentWorkspaceNumber();
}
const activeWs = NiriService.allWorkspaces.find(ws => ws.output === 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 === screenName);
return currentMonitor?.activeWorkspace?.id ?? 1;
} else if (CompositorService.isMango) {
if (!MangoService.available)
return 0;
const outputState = MangoService.getOutputState(screenName);
if (!outputState || !outputState.tags)
return 0;
const activeTags = MangoService.getActiveTags(screenName);
return activeTags.length > 0 ? activeTags[0] : 0;
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
if (!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 === 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.id === undefined) {
return;
}
NiriService.switchToWorkspace(nextWorkspace.id);
}
} 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) {
HyprlandService.focusWorkspace(realWorkspaces[nextIndex].id);
}
} else if (CompositorService.isMango) {
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) {
MangoService.switchToTag(_barScreenName, 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: !_barIsVertical && validLayout && (leftToMediaGap < 150 || clockToRightGap < 100)
readonly property bool overlapping: !_barIsVertical && 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";
}
property string activeHoverTrigger: ""
property real _lastHoverGlobalX: 0
property real _lastHoverGlobalY: 0
readonly property bool hoverPopoutsEnabled: barConfig?.hoverPopouts ?? false
function getBarPosition() {
return barWindow.axis?.edge === "left" ? 2 : (barWindow.axis?.edge === "right" ? 3 : (barWindow.axis?.edge === "top" ? 0 : 1));
}
function resolveWidgetTriggerGeometry(widgetItem, section, opts) {
opts = opts || {};
if (opts.useCenterSection && section === "center") {
const centerSection = barWindow.isVertical ? vCenterSection : hCenterSection;
if (centerSection) {
if (barWindow.isVertical) {
const centerY = centerSection.height / 2;
return {
triggerPos: centerSection.mapToItem(null, 0, centerY),
triggerWidth: centerSection.height
};
}
return {
triggerPos: centerSection.mapToItem(null, 0, 0),
triggerWidth: centerSection.width
};
}
}
const ref = opts.visualItem || widgetItem.visualContent || widgetItem;
const w = opts.triggerWidth !== undefined ? opts.triggerWidth : (widgetItem.visualWidth !== undefined ? widgetItem.visualWidth : widgetItem.width);
return {
triggerPos: ref.mapToItem(null, 0, 0),
triggerWidth: w
};
}
function openWidgetPopout(spec) {
if (!spec?.loader)
return false;
spec.loader.active = true;
let popout = _resolvePopoutFromLoader(spec.loader);
if (!popout) {
_queuePopoutLoaderOpen(spec);
return false;
}
return _finishWidgetPopoutOpen(spec, popout);
}
function _resolvePopoutFromLoader(loader) {
if (!loader)
return null;
if (loader.item)
return loader.item;
const pairs = [
[PopoutService.appDrawerLoader, PopoutService.appDrawerPopout],
[PopoutService.batteryPopoutLoader, PopoutService.batteryPopout],
[PopoutService.clipboardHistoryPopoutLoader, PopoutService.clipboardHistoryPopout],
[PopoutService.controlCenterLoader, PopoutService.controlCenterPopout],
[PopoutService.dankDashPopoutLoader, PopoutService.dankDashPopout],
[PopoutService.layoutPopoutLoader, PopoutService.layoutPopout],
[PopoutService.notificationCenterLoader, PopoutService.notificationCenterPopout],
[PopoutService.processListPopoutLoader, PopoutService.processListPopout],
[PopoutService.systemUpdateLoader, PopoutService.systemUpdatePopout],
[PopoutService.vpnPopoutLoader, PopoutService.vpnPopout]
];
for (let i = 0; i < pairs.length; i++) {
if (loader === pairs[i][0] && pairs[i][1])
return pairs[i][1];
}
return null;
}
property var _pendingPopoutOpenSpec: null
function _queuePopoutLoaderOpen(spec) {
if (_pendingPopoutOpenSpec && _pendingPopoutOpenSpec.loader === spec.loader)
return;
_pendingPopoutOpenSpec = spec;
const loader = spec.loader;
const onLoaded = function () {
if (!loader.item)
return;
if (loader.loaded)
loader.loaded.disconnect(onLoaded);
const pending = topBarContent._pendingPopoutOpenSpec;
if (!pending || pending.loader !== loader)
return;
topBarContent._pendingPopoutOpenSpec = null;
topBarContent._finishWidgetPopoutOpen(pending, loader.item);
if (pending.mode === "hover")
topBarContent.checkHoverPopout(topBarContent._lastHoverGlobalX, topBarContent._lastHoverGlobalY);
};
if (loader.item) {
onLoaded();
return;
}
if (loader.loaded)
loader.loaded.connect(onLoaded);
}
function _finishWidgetPopoutOpen(spec, popout) {
const effectiveBarConfig = barConfig;
const barPosition = getBarPosition();
const widgetSection = spec.section || "right";
const mode = spec.mode || "click";
if (popout.setBarContext)
popout.setBarContext(barPosition, effectiveBarConfig?.bottomGap ?? 0);
if (spec.setTriggerScreen)
popout.triggerScreen = barWindow.screen;
if (popout.setTriggerPosition && spec.widgetItem) {
const geom = resolveWidgetTriggerGeometry(spec.widgetItem, widgetSection, {
useCenterSection: spec.useCenterSection,
visualItem: spec.visualItem,
triggerWidth: spec.triggerWidth
});
if (geom.triggerPos) {
const pos = SettingsData.getPopupTriggerPosition(geom.triggerPos, barWindow.screen, barWindow.effectiveBarThickness, geom.triggerWidth, effectiveBarConfig?.spacing ?? 4, barPosition, effectiveBarConfig);
popout.setTriggerPosition(pos.x, pos.y, pos.width, widgetSection, barWindow.screen, barPosition, barWindow.effectiveBarThickness, effectiveBarConfig?.spacing ?? 4, effectiveBarConfig);
}
}
if (spec.prepare)
spec.prepare(popout);
const request = mode === "hover" ? PopoutManager.requestHoverPopout : PopoutManager.requestPopout;
request(popout, spec.tabIndex, spec.triggerSource);
return true;
}
function _getBarSections() {
if (barWindow.isVertical) {
return [
{
section: vLeftSection,
name: "left"
},
{
section: vCenterSection,
name: "center"
},
{
section: vRightSection,
name: "right"
}
];
}
return [
{
section: hLeftSection,
name: "left"
},
{
section: hCenterSection,
name: "center"
},
{
section: hRightSection,
name: "right"
}
];
}
function _findWidgetHostInWrapper(wrapper) {
if (wrapper.widgetId !== undefined)
return wrapper;
const children = wrapper.children || [];
for (let i = 0; i < children.length; i++) {
if (children[i].widgetId !== undefined)
return children[i];
}
return null;
}
function _collectSectionWrappers(section) {
const layout = section.layoutLoader?.item;
if (layout)
return layout.children || [];
const children = section.children || [];
const wrappers = [];
for (let i = 0; i < children.length; i++) {
const child = children[i];
if (!child || child === section.layoutLoader)
continue;
if (child.itemData !== undefined || child.widgetId !== undefined || _findWidgetHostInWrapper(child))
wrappers.push(child);
}
return wrappers;
}
function _widgetSupportsHoverPopout(widgetId, widgetItem) {
if (!widgetId || !widgetItem)
return false;
if (typeof widgetItem.triggerHoverPopout === "function")
return true;
if (widgetId === "systemTray" && typeof widgetItem.openHoverAtGlobalPoint === "function")
return true;
switch (widgetId) {
case "launcherButton":
case "clipboard":
case "clock":
case "music":
case "weather":
case "cpuUsage":
case "memUsage":
case "cpuTemp":
case "gpuTemp":
case "notificationButton":
case "battery":
case "layout":
case "vpn":
case "controlCenterButton":
case "systemUpdate":
case "notepadButton":
case "systemTray":
return true;
default:
return false;
}
}
function _enumerateWidgetHosts() {
const hosts = [];
const sections = _getBarSections();
for (let s = 0; s < sections.length; s++) {
const sectionEntry = sections[s];
const section = sectionEntry.section;
if (!section)
continue;
const wrappers = _collectSectionWrappers(section);
for (let i = 0; i < wrappers.length; i++) {
const wrapper = wrappers[i];
const host = _findWidgetHostInWrapper(wrapper);
if (!host?.widgetId)
continue;
hosts.push({
host,
wrapper,
section: sectionEntry.name
});
}
}
return hosts;
}
function _collectHoverCandidates() {
const screenName = barWindow.screen?.name;
const candidates = [];
const seen = new Set();
function addCandidate(widgetId, widgetItem, sectionHint) {
if (!widgetId || !widgetItem || seen.has(widgetItem))
return;
if (!_widgetSupportsHoverPopout(widgetId, widgetItem))
return;
if (!getWidgetVisible(widgetId))
return;
seen.add(widgetItem);
candidates.push({
widgetId,
widgetItem,
section: widgetItem.section || sectionHint || "right",
wrapper: null
});
}
if (screenName) {
const registry = BarWidgetService.widgetRegistry;
if (registry && typeof registry === "object") {
for (const widgetId in registry) {
const screenMap = registry[widgetId];
if (!screenMap || typeof screenMap !== "object")
continue;
const widgetItem = screenMap[screenName];
if (widgetItem)
addCandidate(widgetId, widgetItem, widgetItem.section);
}
}
}
const hosts = _enumerateWidgetHosts();
for (let i = 0; i < hosts.length; i++) {
const entry = hosts[i];
if (!entry.host?.item)
continue;
const existing = candidates.find(c => c.widgetItem === entry.host.item);
if (existing) {
existing.wrapper = entry.wrapper;
if (!existing.section)
existing.section = entry.section;
continue;
}
candidates.push({
widgetId: entry.host.widgetId,
widgetItem: entry.host.item,
section: entry.host.item.section || entry.section,
wrapper: entry.wrapper
});
}
return candidates;
}
function _globalItemBounds(item) {
const topLeft = item.mapToItem(null, 0, 0);
return {
x: topLeft.x,
y: topLeft.y,
width: item.width,
height: item.height
};
}
function _hitBoundsForWidget(widgetItem, wrapper) {
if (!widgetItem?.visible)
return null;
if (widgetItem.visualContent !== undefined) {
const visual = widgetItem.visualContent;
if (visual.width > 0 && visual.height > 0)
return _globalItemBounds(visual);
}
if (widgetItem.width > 0 && widgetItem.height > 0)
return _globalItemBounds(widgetItem);
if (wrapper && wrapper.width > 0 && wrapper.height > 0)
return _globalItemBounds(wrapper);
return null;
}
function _pointInBounds(gx, gy, bounds) {
return gx >= bounds.x && gx < bounds.x + bounds.width && gy >= bounds.y && gy < bounds.y + bounds.height;
}
function findWidgetAtGlobalPoint(gx, gy) {
const candidates = _collectHoverCandidates();
let best = null;
let bestArea = Infinity;
for (let i = 0; i < candidates.length; i++) {
const entry = candidates[i];
const bounds = _hitBoundsForWidget(entry.widgetItem, entry.wrapper);
if (!bounds || bounds.width <= 0 || bounds.height <= 0)
continue;
if (!_pointInBounds(gx, gy, bounds))
continue;
const area = bounds.width * bounds.height;
if (area < bestArea) {
bestArea = area;
best = {
widgetId: entry.widgetId,
widgetItem: entry.widgetItem,
section: entry.section
};
}
}
return best;
}
function _dashTriggerSource(section, tabIndex) {
return (barConfig?.id ?? "default") + "-" + section + "-" + tabIndex;
}
function _notepadWidgetForScreen() {
const screenName = barWindow?.screen?.name;
const fromRegistry = screenName ? BarWidgetService.getWidget("notepadButton", screenName) : null;
if (fromRegistry)
return fromRegistry;
const candidates = _collectHoverCandidates();
for (let i = 0; i < candidates.length; i++) {
if (candidates[i].widgetId === "notepadButton")
return candidates[i].widgetItem;
}
return null;
}
function notepadContainsGlobalPoint(gx, gy) {
const instance = _notepadWidgetForScreen()?.notepadInstance;
if (!instance?.isVisible || typeof instance.containsGlobalPoint !== "function")
return false;
return instance.containsGlobalPoint(gx, gy);
}
function cursorOverHoverChain(gx, gy) {
if (PopoutManager.cursorOverBar(gx, gy))
return true;
const popout = PopoutManager.getActivePopout(barWindow?.screen);
if (popout?.containsGlobalPoint?.(gx, gy))
return true;
if (notepadContainsGlobalPoint(gx, gy))
return true;
const screenName = barWindow.screen?.name;
if (screenName && TrayMenuManager.activeTrayMenus[screenName])
return true;
return false;
}
function _closeHoverNotepad() {
if (activeHoverTrigger !== "notepadButton")
return;
const instance = _notepadWidgetForScreen()?.notepadInstance;
if (!instance)
return;
if (instance.hoverDismissEnabled !== undefined)
instance.hoverDismissEnabled = false;
if (typeof instance.hideFromHoverDismiss === "function")
instance.hideFromHoverDismiss();
else if (typeof instance.hide === "function")
instance.hide();
}
function closeHoverSurfaces() {
_closeHoverNotepad();
activeHoverTrigger = "";
PopoutManager.closePopoutForScreen(barWindow?.screen);
TrayMenuManager.closeAllMenus();
}
function openNotepadHover(widgetItem) {
const instance = widgetItem.prepareNotepadInstance?.(widgetItem.notepadInstance) ?? widgetItem.notepadInstance;
if (!instance || typeof instance.show !== "function")
return false;
if (instance.hoverDismissEnabled !== undefined)
instance.hoverDismissEnabled = true;
instance.show();
return true;
}
function _syncHoverTriggerState() {
if (activeHoverTrigger === "notepadButton") {
const inst = _notepadWidgetForScreen()?.notepadInstance;
if (!inst?.isVisible)
activeHoverTrigger = "";
return;
}
if (activeHoverTrigger === "")
return;
if (!hasOpenHoverSurface())
activeHoverTrigger = "";
}
function hasOpenHoverSurface() {
if (activeHoverTrigger === "")
return false;
if (activeHoverTrigger === "notepadButton") {
const inst = _notepadWidgetForScreen()?.notepadInstance;
return inst?.isVisible ?? false;
}
const popout = PopoutManager.getActivePopout(barWindow?.screen);
if (!popout)
return false;
if (popout.dashVisible !== undefined)
return !!popout.dashVisible || !!popout.isClosing;
if (popout.notificationHistoryVisible !== undefined)
return !!popout.notificationHistoryVisible || !!popout.isClosing;
return !!(popout.shouldBeVisible || popout.isClosing);
}
function openHoverPopoutForHit(hit) {
if (!hit?.widgetItem)
return false;
const widgetId = hit.widgetId;
const widgetItem = hit.widgetItem;
const section = hit.section;
const mode = "hover";
const base = {
widgetItem,
section,
mode
};
if (widgetId === "systemTray") {
if (typeof widgetItem.openHoverAtGlobalPoint !== "function")
return false;
return !!widgetItem.openHoverAtGlobalPoint(hit.globalX, hit.globalY);
}
if (typeof widgetItem.triggerHoverPopout === "function") {
widgetItem.triggerHoverPopout(hit.widgetId);
return true;
}
switch (widgetId) {
case "launcherButton":
return openWidgetPopout(Object.assign({}, base, {
loader: appDrawerLoader,
triggerSource: "appDrawer",
visualItem: widgetItem
}));
case "clipboard":
return openWidgetPopout(Object.assign({}, base, {
loader: clipboardHistoryPopoutLoader,
triggerSource: "clipboard",
prepare: popout => {
popout.activeTab = "recents";
}
}));
case "clock":
return openWidgetPopout(Object.assign({}, base, {
loader: dankDashPopoutLoader,
tabIndex: 0,
triggerSource: _dashTriggerSource(section, 0),
useCenterSection: true,
setTriggerScreen: true
}));
case "music":
return openWidgetPopout(Object.assign({}, base, {
loader: dankDashPopoutLoader,
tabIndex: 1,
triggerSource: _dashTriggerSource(section, 1),
useCenterSection: true,
setTriggerScreen: true
}));
case "weather":
return openWidgetPopout(Object.assign({}, base, {
loader: dankDashPopoutLoader,
tabIndex: 3,
triggerSource: _dashTriggerSource(section, 3),
useCenterSection: true,
setTriggerScreen: true
}));
case "cpuUsage":
return openWidgetPopout(Object.assign({}, base, {
loader: processListPopoutLoader,
triggerSource: "cpu"
}));
case "memUsage":
return openWidgetPopout(Object.assign({}, base, {
loader: processListPopoutLoader,
triggerSource: "memory"
}));
case "cpuTemp":
return openWidgetPopout(Object.assign({}, base, {
loader: processListPopoutLoader,
triggerSource: "cpu_temp"
}));
case "gpuTemp":
return openWidgetPopout(Object.assign({}, base, {
loader: processListPopoutLoader,
triggerSource: "gpu_temp"
}));
case "notificationButton":
return openWidgetPopout(Object.assign({}, base, {
loader: notificationCenterLoader,
triggerSource: "notifications",
setTriggerScreen: true
}));
case "battery":
return openWidgetPopout(Object.assign({}, base, {
loader: batteryPopoutLoader,
triggerSource: "battery"
}));
case "layout":
return openWidgetPopout(Object.assign({}, base, {
loader: layoutPopoutLoader,
triggerSource: "layout"
}));
case "vpn":
return openWidgetPopout(Object.assign({}, base, {
loader: vpnPopoutLoader,
triggerSource: "vpn"
}));
case "controlCenterButton":
if (openWidgetPopout(Object.assign({}, base, {
loader: controlCenterLoader,
triggerSource: "controlCenter",
setTriggerScreen: true
}))) {
if (controlCenterLoader.item?.shouldBeVisible && NetworkService.wifiEnabled)
NetworkService.scanWifi();
return true;
}
return false;
case "systemUpdate":
return openWidgetPopout(Object.assign({}, base, {
loader: systemUpdateLoader,
triggerSource: "systemUpdate",
visualItem: widgetItem
}));
case "notepadButton":
return openNotepadHover(widgetItem);
default:
return false;
}
}
function checkHoverPopout(gx, gy) {
if (!hoverPopoutsEnabled)
return;
_lastHoverGlobalX = gx;
_lastHoverGlobalY = gy;
PopoutManager.updateHoverCursor(gx, gy);
_syncHoverTriggerState();
const hit = findWidgetAtGlobalPoint(gx, gy);
if (!hit) {
if (!cursorOverHoverChain(gx, gy))
closeHoverSurfaces();
return;
}
hit.globalX = gx;
hit.globalY = gy;
let triggerKey = hit.widgetId;
if (hit.widgetId === "systemTray")
triggerKey = hit.widgetItem.hoverTriggerAtGlobalPoint?.(gx, gy) || "";
else if (hit.widgetId === "clock")
triggerKey = _dashTriggerSource(hit.section, 0);
else if (hit.widgetId === "music")
triggerKey = _dashTriggerSource(hit.section, 1);
else if (hit.widgetId === "weather")
triggerKey = _dashTriggerSource(hit.section, 3);
if (!triggerKey) {
if (!cursorOverHoverChain(gx, gy))
closeHoverSurfaces();
return;
}
if (triggerKey === activeHoverTrigger && hasOpenHoverSurface())
return;
if (triggerKey !== activeHoverTrigger && activeHoverTrigger !== "")
closeHoverSurfaces();
if (!openHoverPopoutForHit(hit)) {
if (activeHoverTrigger !== "")
closeHoverSurfaces();
return;
}
activeHoverTrigger = triggerKey;
}
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, mode) {
openWidgetPopout({
loader: clipboardHistoryPopoutLoader,
widgetItem: clipboardWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "clipboard",
mode: mode || "click",
prepare: popout => {
if (initialTab)
popout.activeTab = initialTab;
}
});
}
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: {
topBarContent.openWidgetPopout({
loader: appDrawerLoader,
widgetItem: launcherButton,
section: launcherButton.section,
triggerSource: "appDrawer",
mode: "click",
visualItem: launcherButton
});
}
}
}
Component {
id: workspaceSwitcherComponent
WorkspaceSwitcher {
axis: barWindow.axis
screenName: _barScreenName
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 {
id: clockWidget
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: {
const section = topBarContent.getWidgetSection(parent) || "center";
topBarContent.openWidgetPopout({
loader: dankDashPopoutLoader,
widgetItem: clockWidget,
section,
tabIndex: 0,
triggerSource: topBarContent._dashTriggerSource(section, 0),
mode: "click",
useCenterSection: true,
setTriggerScreen: true
});
}
}
}
Component {
id: mediaComponent
Media {
id: mediaWidget
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: {
const section = topBarContent.getWidgetSection(parent) || "center";
topBarContent.openWidgetPopout({
loader: dankDashPopoutLoader,
widgetItem: mediaWidget,
section,
tabIndex: 1,
triggerSource: topBarContent._dashTriggerSource(section, 1),
mode: "click",
useCenterSection: true,
setTriggerScreen: true
});
}
}
}
Component {
id: weatherComponent
Weather {
id: weatherWidget
axis: barWindow.axis
barThickness: barWindow.effectiveBarThickness
widgetThickness: barWindow.widgetThickness
section: topBarContent.getWidgetSection(parent) || "center"
popoutTarget: dankDashPopoutLoader.item ?? null
parentScreen: barWindow.screen
onClicked: {
const section = topBarContent.getWidgetSection(parent) || "center";
topBarContent.openWidgetPopout({
loader: dankDashPopoutLoader,
widgetItem: weatherWidget,
section,
tabIndex: 3,
triggerSource: topBarContent._dashTriggerSource(section, 3),
mode: "click",
useCenterSection: true,
setTriggerScreen: true
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: processListPopoutLoader,
widgetItem: cpuWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "cpu",
mode: "click"
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: processListPopoutLoader,
widgetItem: ramWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "memory",
mode: "click"
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: processListPopoutLoader,
widgetItem: cpuTempWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "cpu_temp",
mode: "click"
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: processListPopoutLoader,
widgetItem: gpuTempWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "gpu_temp",
mode: "click"
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: notificationCenterLoader,
widgetItem: notificationButton,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "notifications",
mode: "click",
setTriggerScreen: true
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: batteryPopoutLoader,
widgetItem: batteryWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "battery",
mode: "click"
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: layoutPopoutLoader,
widgetItem: layoutWidget,
section: topBarContent.getWidgetSection(parent) || "center",
triggerSource: "layout",
mode: "click"
});
}
}
}
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: {
topBarContent.openWidgetPopout({
loader: vpnPopoutLoader,
widgetItem: vpnWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "vpn",
mode: "click"
});
}
}
}
Component {
id: controlCenterButtonComponent
ControlCenterButton {
id: 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: {
topBarContent.openWidgetPopout({
loader: controlCenterLoader,
widgetItem: controlCenterButton,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "controlCenter",
mode: "click",
setTriggerScreen: true
});
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: _barIsVertical ? barWindow.widgetThickness : (parent.spacerSize || 20)
height: _barIsVertical ? (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: _barIsVertical ? parent.barThickness : 1
height: _barIsVertical ? 1 : parent.barThickness
implicitWidth: width
implicitHeight: height
Rectangle {
width: _barIsVertical ? parent.width * 0.6 : 1
height: _barIsVertical ? 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 {
id: systemUpdateWidget
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
Component.onCompleted: {
barWindow.systemUpdateButtonRef = this;
}
Component.onDestruction: {
if (barWindow.systemUpdateButtonRef === this)
barWindow.systemUpdateButtonRef = null;
}
onClicked: {
topBarContent.openWidgetPopout({
loader: systemUpdateLoader,
widgetItem: systemUpdateWidget,
section: topBarContent.getWidgetSection(parent) || "right",
triggerSource: "systemUpdate",
mode: "click",
visualItem: systemUpdateWidget
});
}
}
}
}