1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

dankbar: support multiple bars and per-display bars

- Migrate settings to v2
  - Up to 4 bars
  - Per-bar settings instead of global
This commit is contained in:
bbedward
2025-11-22 15:28:06 -05:00
parent 4f32376f22
commit a3a27e07fa
69 changed files with 5567 additions and 3846 deletions

View File

@@ -1,86 +1,113 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Shapes
import Quickshell
import Quickshell.Hyprland
import Quickshell.I3
import Quickshell.Io
import Quickshell.Services.Mpris
import Quickshell.Services.Notifications
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Modules
import qs.Modules.DankBar.Widgets
import qs.Modules.DankBar.Popouts
import qs.Services
import qs.Widgets
PanelWindow {
id: barWindow
required property var rootWindow
required property var barConfig
property var modelData: item
property var hyprlandOverviewLoader: rootWindow ? rootWindow.hyprlandOverviewLoader : null
property var leftWidgetsModel
property var centerWidgetsModel
property var rightWidgetsModel
property var controlCenterButtonRef: null
property var clockButtonRef: null
function triggerControlCenter() {
controlCenterLoader.active = true
controlCenterLoader.active = true;
if (!controlCenterLoader.item) {
return
return;
}
if (controlCenterButtonRef && controlCenterLoader.item.setTriggerPosition) {
const globalPos = controlCenterButtonRef.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, controlCenterButtonRef.width)
const section = controlCenterButtonRef.section || "right"
controlCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
const globalPos = controlCenterButtonRef.mapToGlobal(0, 0);
// Calculate barPosition from axis.edge
const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, controlCenterButtonRef.width, barConfig?.spacing ?? 4, barPosition, barConfig);
const section = controlCenterButtonRef.section || "right";
controlCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, barConfig?.spacing ?? 4, barConfig);
} else {
controlCenterLoader.item.triggerScreen = barWindow.screen
controlCenterLoader.item.triggerScreen = barWindow.screen;
}
controlCenterLoader.item.toggle()
controlCenterLoader.item.toggle();
if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) {
NetworkService.scanWifi()
NetworkService.scanWifi();
}
}
function triggerWallpaperBrowser() {
dankDashPopoutLoader.active = true
dankDashPopoutLoader.active = true;
if (!dankDashPopoutLoader.item) {
return
return;
}
if (clockButtonRef && clockButtonRef.visualContent && dankDashPopoutLoader.item.setTriggerPosition) {
const globalPos = clockButtonRef.visualContent.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, clockButtonRef.visualWidth)
const section = clockButtonRef.section || "center"
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
// Calculate barPosition from axis.edge
const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
const section = clockButtonRef.section || "center";
// 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" ? topBarContent.vCenterSection : topBarContent.vCenterSection) : topBarContent.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.mapToGlobal(0, centerY);
triggerPos = centerGlobalPos;
triggerWidth = centerSection.height;
} else {
// For horizontal bars, use left edge (DankPopout will center it)
const centerGlobalPos = centerSection.mapToGlobal(0, 0);
triggerPos = centerGlobalPos;
triggerWidth = centerSection.width;
}
} else {
triggerPos = clockButtonRef.visualContent.mapToGlobal(0, 0);
triggerWidth = clockButtonRef.visualWidth;
}
} else {
triggerPos = clockButtonRef.visualContent.mapToGlobal(0, 0);
triggerWidth = clockButtonRef.visualWidth;
}
const pos = SettingsData.getPopupTriggerPosition(triggerPos, barWindow.screen, barWindow.effectiveBarThickness, triggerWidth, barConfig?.spacing ?? 4, barPosition, barConfig);
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, barConfig?.spacing ?? 4, barConfig);
} else {
dankDashPopoutLoader.item.triggerScreen = barWindow.screen
dankDashPopoutLoader.item.triggerScreen = barWindow.screen;
}
PopoutManager.requestPopout(dankDashPopoutLoader.item, 2)
PopoutManager.requestPopout(dankDashPopoutLoader.item, 2, (barConfig?.id ?? "default") + "-2");
}
readonly property var dBarLayer: {
switch (Quickshell.env("DMS_DANKBAR_LAYER")) {
case "bottom":
return WlrLayer.Bottom
return WlrLayer.Bottom;
case "overlay":
return WlrLayer.Overlay
return WlrLayer.Overlay;
case "background":
return WlrLayer.background
return WlrLayer.background;
default:
return WlrLayer.Top
return WlrLayer.Top;
}
}
WlrLayershell.layer: dBarLayer
WlrLayershell.layer: {
if ((barConfig?.autoHide ?? false) && topBarCore.reveal) {
return WlrLayer.Overlay;
}
return dBarLayer;
}
WlrLayershell.namespace: "dms:bar"
signal colorPickerRequested
@@ -92,39 +119,134 @@ PanelWindow {
AxisContext {
id: axis
edge: {
switch (SettingsData.dankBarPosition) {
switch (barConfig?.position ?? 0) {
case SettingsData.Position.Top:
return "top"
return "top";
case SettingsData.Position.Bottom:
return "bottom"
return "bottom";
case SettingsData.Position.Left:
return "left"
return "left";
case SettingsData.Position.Right:
return "right"
return "right";
default:
return "top"
return "top";
}
}
}
readonly property bool isVertical: axis.isVertical
property bool gothCornersEnabled: SettingsData.dankBarGothCornersEnabled
property real wingtipsRadius: SettingsData.dankBarGothCornerRadiusOverride ? SettingsData.dankBarGothCornerRadiusValue : Theme.cornerRadius
property bool gothCornersEnabled: barConfig?.gothCornersEnabled ?? false
property real wingtipsRadius: barConfig?.gothCornerRadiusOverride ? (barConfig?.gothCornerRadiusValue ?? 12) : Theme.cornerRadius
readonly property real _wingR: Math.max(0, wingtipsRadius)
readonly property color _surfaceContainer: Theme.surfaceContainer
readonly property real _backgroundAlpha: topBarCore?.backgroundTransparency ?? SettingsData.dankBarTransparency
readonly property real _backgroundAlpha: topBarCore?.backgroundTransparency ?? (barConfig?.transparency ?? 1.0)
readonly property color _bgColor: Theme.withAlpha(_surfaceContainer, _backgroundAlpha)
readonly property real _dpr: CompositorService.getScreenScale(barWindow.screen)
property string screenName: modelData.name
readonly property int notificationCount: NotificationService.notifications.length
readonly property real effectiveBarThickness: Math.max(barWindow.widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
readonly property real widgetThickness: Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
readonly property real effectiveBarThickness: Math.max(barWindow.widgetThickness + (barConfig?.innerPadding ?? 4) + 4, Theme.barHeight - 4 - (8 - (barConfig?.innerPadding ?? 4)))
readonly property real widgetThickness: Math.max(20, 26 + (barConfig?.innerPadding ?? 4) * 0.6)
readonly property bool hasAdjacentTopBar: {
if (barConfig?.autoHide ?? false)
return false;
if (!isVertical)
return false;
return SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Top && bc.position !== 0)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
}
readonly property bool hasAdjacentBottomBar: {
if (barConfig?.autoHide ?? false)
return false;
if (!isVertical)
return false;
const result = SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Bottom && bc.position !== 1)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
return result;
}
readonly property bool hasAdjacentLeftBar: {
if (barConfig?.autoHide ?? false)
return false;
if (isVertical)
return false;
const result = SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Left && bc.position !== 2)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
return result;
}
readonly property bool hasAdjacentRightBar: {
if (barConfig?.autoHide ?? false)
return false;
if (isVertical)
return false;
const result = SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Right && bc.position !== 3)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
return result;
}
screen: modelData
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0), _dpr) : 0
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0), _dpr) : 0
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + (barConfig?.spacing ?? 4) + ((barConfig?.gothCornersEnabled ?? false) ? _wingR : 0), _dpr) : 0
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + (barConfig?.spacing ?? 4) + ((barConfig?.gothCornersEnabled ?? false) ? _wingR : 0), _dpr) : 0
color: "transparent"
property var nativeInhibitor: null
@@ -132,18 +254,18 @@ PanelWindow {
Component.onCompleted: {
if (SettingsData.forceStatusBarLayoutRefresh) {
SettingsData.forceStatusBarLayoutRefresh.connect(() => {
Qt.callLater(() => {
stackContainer.visible = false
Qt.callLater(() => {
stackContainer.visible = true
})
})
})
Qt.callLater(() => {
stackContainer.visible = false;
Qt.callLater(() => {
stackContainer.visible = true;
});
});
});
}
updateGpuTempConfig()
updateGpuTempConfig();
inhibitorInitTimer.start()
inhibitorInitTimer.start();
}
Timer {
@@ -152,7 +274,7 @@ PanelWindow {
repeat: false
onTriggered: {
if (SessionService.nativeInhibitorAvailable) {
createNativeInhibitor()
createNativeInhibitor();
}
}
}
@@ -160,32 +282,35 @@ PanelWindow {
Connections {
target: PluginService
function onPluginLoaded(pluginId) {
console.info("DankBar: Plugin loaded:", pluginId)
SettingsData.widgetDataChanged()
console.info("DankBar: Plugin loaded:", pluginId);
SettingsData.widgetDataChanged();
}
function onPluginUnloaded(pluginId) {
console.info("DankBar: Plugin unloaded:", pluginId)
SettingsData.widgetDataChanged()
console.info("DankBar: Plugin unloaded:", pluginId);
SettingsData.widgetDataChanged();
}
}
function updateGpuTempConfig() {
const allWidgets = [...(SettingsData.dankBarLeftWidgets || []), ...(SettingsData.dankBarCenterWidgets || []), ...(SettingsData.dankBarRightWidgets || [])]
const leftWidgets = barConfig?.leftWidgets || [];
const centerWidgets = barConfig?.centerWidgets || [];
const rightWidgets = barConfig?.rightWidgets || [];
const allWidgets = [...leftWidgets, ...centerWidgets, ...rightWidgets];
const hasGpuTempWidget = allWidgets.some(widget => {
const widgetId = typeof widget === "string" ? widget : widget.id
const widgetEnabled = typeof widget === "string" ? true : (widget.enabled !== false)
return widgetId === "gpuTemp" && widgetEnabled
})
const widgetId = typeof widget === "string" ? widget : widget.id;
const widgetEnabled = typeof widget === "string" ? true : (widget.enabled !== false);
return widgetId === "gpuTemp" && widgetEnabled;
});
DgopService.gpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled || SessionData.nonNvidiaGpuTempEnabled
DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled
DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nonNvidiaGpuTempEnabled
DgopService.gpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled || SessionData.nonNvidiaGpuTempEnabled;
DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled;
DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nonNvidiaGpuTempEnabled;
}
function createNativeInhibitor() {
if (!SessionService.nativeInhibitorAvailable) {
return
return;
}
try {
@@ -196,121 +321,88 @@ PanelWindow {
IdleInhibitor {
enabled: false
}
`
`;
nativeInhibitor = Qt.createQmlObject(qmlString, barWindow, "DankBar.NativeInhibitor")
nativeInhibitor.window = barWindow
nativeInhibitor.enabled = Qt.binding(() => SessionService.idleInhibited)
nativeInhibitor = Qt.createQmlObject(qmlString, barWindow, "DankBar.NativeInhibitor");
nativeInhibitor.window = barWindow;
nativeInhibitor.enabled = Qt.binding(() => SessionService.idleInhibited);
nativeInhibitor.enabledChanged.connect(function () {
console.log("DankBar: Native inhibitor enabled changed to:", nativeInhibitor.enabled)
if (SessionService.idleInhibited !== nativeInhibitor.enabled) {
SessionService.idleInhibited = nativeInhibitor.enabled
SessionService.inhibitorChanged()
SessionService.idleInhibited = nativeInhibitor.enabled;
SessionService.inhibitorChanged();
}
})
console.log("DankBar: Created native Wayland IdleInhibitor for", barWindow.screenName)
});
} catch (e) {
console.warn("DankBar: Failed to create native IdleInhibitor:", e)
nativeInhibitor = null
nativeInhibitor = null;
}
}
Connections {
function onDankBarLeftWidgetsChanged() {
barWindow.updateGpuTempConfig()
function onBarConfigChanged() {
barWindow.updateGpuTempConfig();
}
function onDankBarCenterWidgetsChanged() {
barWindow.updateGpuTempConfig()
}
function onDankBarRightWidgetsChanged() {
barWindow.updateGpuTempConfig()
}
target: SettingsData
target: rootWindow
}
Connections {
function onNvidiaGpuTempEnabledChanged() {
barWindow.updateGpuTempConfig()
barWindow.updateGpuTempConfig();
}
function onNonNvidiaGpuTempEnabledChanged() {
barWindow.updateGpuTempConfig()
barWindow.updateGpuTempConfig();
}
target: SessionData
}
Connections {
target: barWindow.screen
function onGeometryChanged() {
Qt.callLater(forceWidgetRefresh)
}
}
Timer {
id: refreshTimer
interval: 0
running: false
repeat: false
onTriggered: {
forceWidgetRefresh()
}
}
readonly property int barPos: barConfig?.position ?? 0
Connections {
target: axis
function onChanged() {
Qt.application.active
refreshTimer.restart()
}
}
anchors.top: !isVertical ? (barPos === SettingsData.Position.Top) : true
anchors.bottom: !isVertical ? (barPos === SettingsData.Position.Bottom) : true
anchors.left: !isVertical ? true : (barPos === SettingsData.Position.Left)
anchors.right: !isVertical ? true : (barPos === SettingsData.Position.Right)
anchors.top: !isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Top) : true
anchors.bottom: !isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom) : true
anchors.left: !isVertical ? true : (SettingsData.dankBarPosition === SettingsData.Position.Left)
anchors.right: !isVertical ? true : (SettingsData.dankBarPosition === SettingsData.Position.Right)
exclusiveZone: (!SettingsData.dankBarVisible || topBarCore.autoHide) ? -1 : (barWindow.effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap)
exclusiveZone: (!(barConfig?.visible ?? true) || topBarCore.autoHide) ? -1 : (barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4) + (barConfig?.bottomGap ?? 0))
Item {
id: inputMask
readonly property int barThickness: Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr)
readonly property int barThickness: Theme.px(barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4), barWindow._dpr)
readonly property bool inOverviewWithShow: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview
readonly property bool effectiveVisible: SettingsData.dankBarVisible || inOverviewWithShow
readonly property bool inOverviewWithShow: CompositorService.isNiri && NiriService.inOverview && (barConfig?.openOnOverview ?? false)
readonly property bool effectiveVisible: (barConfig?.visible ?? true) || inOverviewWithShow
readonly property bool showing: effectiveVisible && (topBarCore.reveal || inOverviewWithShow || !topBarCore.autoHide)
readonly property int maskThickness: showing ? barThickness : 1
x: {
if (!axis.isVertical) {
return 0
return 0;
} else {
switch (SettingsData.dankBarPosition) {
switch (barPos) {
case SettingsData.Position.Left:
return 0
return 0;
case SettingsData.Position.Right:
return parent.width - maskThickness
return parent.width - maskThickness;
default:
return 0
return 0;
}
}
}
y: {
if (axis.isVertical) {
return 0
return 0;
} else {
switch (SettingsData.dankBarPosition) {
switch (barPos) {
case SettingsData.Position.Top:
return 0
return 0;
case SettingsData.Position.Bottom:
return parent.height - maskThickness
return parent.height - maskThickness;
default:
return 0
return 0;
}
}
}
@@ -327,112 +419,97 @@ PanelWindow {
anchors.fill: parent
layer.enabled: true
property real backgroundTransparency: SettingsData.dankBarTransparency
property bool autoHide: SettingsData.dankBarAutoHide
property real backgroundTransparency: barConfig?.transparency ?? 1.0
property bool autoHide: barConfig?.autoHide ?? false
property bool revealSticky: false
Timer {
id: revealHold
interval: SettingsData.dankBarAutoHideDelay
interval: barConfig?.autoHideDelay ?? 250
repeat: false
onTriggered: topBarCore.revealSticky = false
onTriggered: {
if (!topBarMouseArea.containsMouse && !topBarCore.hasActivePopout) {
topBarCore.revealSticky = false;
}
}
}
property bool reveal: {
if (CompositorService.isNiri && NiriService.inOverview) {
return SettingsData.dankBarOpenOnOverview || topBarMouseArea.containsMouse || hasActivePopout || revealSticky
return (barConfig?.openOnOverview ?? false) || topBarMouseArea.containsMouse || hasActivePopout || revealSticky;
}
return SettingsData.dankBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky)
return (barConfig?.visible ?? true) && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky);
}
readonly property bool hasActivePopout: {
const loaders = [{
"loader": appDrawerLoader,
"prop": "shouldBeVisible"
}, {
"loader": dankDashPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": processListPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": notificationCenterLoader,
"prop": "shouldBeVisible"
}, {
"loader": batteryPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": layoutPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": vpnPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": controlCenterLoader,
"prop": "shouldBeVisible"
}, {
"loader": clipboardHistoryModalPopup,
"prop": "visible"
}, {
"loader": systemUpdateLoader,
"prop": "shouldBeVisible"
}]
return loaders.some(item => {
if (item.loader && item.loader.item) {
return item.loader.item[item.prop]
}
return false
}) || rootWindow.systemTrayMenuOpen
property bool hasActivePopout: false
onHasActivePopoutChanged: evaluateReveal()
Connections {
target: PopoutManager
function onPopoutChanged() {
const screenName = barWindow.screen.name;
const activePopout = PopoutManager.currentPopoutsByScreen[screenName];
const activeTrayMenu = TrayMenuManager.activeTrayMenus[screenName];
const trayOpen = rootWindow.systemTrayMenuOpen;
topBarCore.hasActivePopout = !!(activePopout || activeTrayMenu || trayOpen);
}
}
Connections {
function onDankBarTransparencyChanged() {
topBarCore.backgroundTransparency = SettingsData.dankBarTransparency
function onBarConfigChanged() {
topBarCore.backgroundTransparency = barConfig?.transparency ?? 1.0;
topBarCore.autoHide = barConfig?.autoHide ?? false;
revealHold.interval = barConfig?.autoHideDelay ?? 250;
}
target: SettingsData
target: rootWindow
}
function evaluateReveal() {
if (!autoHide)
return;
if (topBarMouseArea.containsMouse || hasActivePopout) {
revealSticky = true;
revealHold.stop();
return;
}
revealHold.restart();
}
Connections {
target: topBarMouseArea
function onContainsMouseChanged() {
if (topBarMouseArea.containsMouse) {
topBarCore.revealSticky = true
revealHold.stop()
} else {
if (topBarCore.autoHide && !topBarCore.hasActivePopout) {
revealHold.restart()
}
}
topBarCore.evaluateReveal();
}
}
onHasActivePopoutChanged: {
if (hasActivePopout) {
revealSticky = true
revealHold.stop()
} else if (autoHide && !topBarMouseArea.containsMouse) {
revealSticky = true
revealHold.restart()
Connections {
target: PopoutManager
function onPopoutOpening() {
topBarCore.evaluateReveal();
}
}
MouseArea {
id: topBarMouseArea
y: !barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? parent.height - height : 0) : 0
x: barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.width - width : 0) : 0
height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined
width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined
y: !barWindow.isVertical ? (barPos === SettingsData.Position.Bottom ? parent.height - height : 0) : 0
x: barWindow.isVertical ? (barPos === SettingsData.Position.Right ? parent.width - width : 0) : 0
height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4), barWindow._dpr) : undefined
width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4), barWindow._dpr) : undefined
anchors {
left: !barWindow.isVertical ? parent.left : (SettingsData.dankBarPosition === SettingsData.Position.Left ? parent.left : undefined)
right: !barWindow.isVertical ? parent.right : (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.right : undefined)
left: !barWindow.isVertical ? parent.left : (barPos === SettingsData.Position.Left ? parent.left : undefined)
right: !barWindow.isVertical ? parent.right : (barPos === SettingsData.Position.Right ? parent.right : undefined)
top: barWindow.isVertical ? parent.top : undefined
bottom: barWindow.isVertical ? parent.bottom : undefined
}
readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview
hoverEnabled: SettingsData.dankBarAutoHide && !inOverview
readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && (barConfig?.openOnOverview ?? false)
hoverEnabled: (barConfig?.autoHide ?? false) && !inOverview && !topBarCore.hasActivePopout
acceptedButtons: Qt.NoButton
enabled: SettingsData.dankBarAutoHide && !inOverview
enabled: (barConfig?.autoHide ?? false) && !inOverview
Item {
id: topBarContainer
@@ -440,8 +517,8 @@ PanelWindow {
transform: Translate {
id: topBarSlide
x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0
y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0
x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (barPos === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0
y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (barPos === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0
Behavior on x {
NumberAnimation {
@@ -460,16 +537,18 @@ PanelWindow {
Item {
id: barUnitInset
property int spacingPx: Theme.px(barConfig?.spacing ?? 4, barWindow._dpr)
anchors.fill: parent
anchors.leftMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "left" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.rightMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "right" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.topMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? 0 : Theme.px(SettingsData.dankBarSpacing, barWindow._dpr))
anchors.bottomMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.leftMargin: !barWindow.isVertical ? spacingPx : (axis.edge === "left" ? spacingPx : 0)
anchors.rightMargin: !barWindow.isVertical ? spacingPx : (axis.edge === "right" ? spacingPx : 0)
anchors.topMargin: barWindow.isVertical ? (barWindow.hasAdjacentTopBar ? 0 : spacingPx) : (axis.outerVisualEdge() === "bottom" ? 0 : spacingPx)
anchors.bottomMargin: barWindow.isVertical ? (barWindow.hasAdjacentBottomBar ? 0 : spacingPx) : (axis.outerVisualEdge() === "bottom" ? spacingPx : 0)
BarCanvas {
id: barBackground
barWindow: barWindow
axis: axis
barConfig: barWindow.barConfig
}
MouseArea {
@@ -491,39 +570,39 @@ PanelWindow {
onWheel: wheel => {
if (actionInProgress) {
wheel.accepted = false
return
wheel.accepted = false;
return;
}
const deltaY = wheel.angleDelta.y
const deltaX = wheel.angleDelta.x
const deltaY = wheel.angleDelta.y;
const deltaX = wheel.angleDelta.x;
if (CompositorService.isNiri && Math.abs(deltaX) > Math.abs(deltaY)) {
topBarContent.switchApp(deltaX)
wheel.accepted = false
return
topBarContent.switchApp(deltaX);
wheel.accepted = false;
return;
}
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0
const direction = deltaY < 0 ? 1 : -1
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0;
const direction = deltaY < 0 ? 1 : -1;
if (isMouseWheel) {
topBarContent.switchWorkspace(direction)
actionInProgress = true
cooldownTimer.restart()
topBarContent.switchWorkspace(direction);
actionInProgress = true;
cooldownTimer.restart();
} else {
scrollAccumulator += deltaY
scrollAccumulator += deltaY;
if (Math.abs(scrollAccumulator) >= touchpadThreshold) {
const touchDirection = scrollAccumulator < 0 ? 1 : -1
topBarContent.switchWorkspace(touchDirection)
scrollAccumulator = 0
actionInProgress = true
cooldownTimer.restart()
const touchDirection = scrollAccumulator < 0 ? 1 : -1;
topBarContent.switchWorkspace(touchDirection);
scrollAccumulator = 0;
actionInProgress = true;
cooldownTimer.restart();
}
}
wheel.accepted = false
wheel.accepted = false;
}
}
@@ -531,6 +610,10 @@ PanelWindow {
id: topBarContent
barWindow: barWindow
rootWindow: rootWindow
barConfig: barWindow.barConfig
leftWidgetsModel: barWindow.leftWidgetsModel
centerWidgetsModel: barWindow.centerWidgetsModel
rightWidgetsModel: barWindow.rightWidgetsModel
}
}
}