1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00

Compare commits

...

6 Commits

Author SHA1 Message Date
bbedward
4a68ce35a3 hyprland: remove focus grab from dankpopout 2025-11-16 11:44:59 -05:00
bbedward
eb4655fcbc rebase woes 2025-11-16 11:37:19 -05:00
bbedward
6eb349c9d4 barmask: fix multi-screen handling 2025-11-16 11:33:47 -05:00
bbedward
0a8a7895b3 hyprland: use FocusGrab for ondemand windows 2025-11-16 11:33:47 -05:00
bbedward
73c82a4dd9 dankbar/mask: extra polish for Hyprland maybe 2025-11-16 11:33:47 -05:00
bbedward
ccf28fc4e7 dankbar: add a mask while popouts are open
- Retains ability to click items on the bar, while another is open
2025-11-16 11:32:47 -05:00
25 changed files with 678 additions and 94 deletions

View File

@@ -12,5 +12,9 @@ Singleton {
if (!modal.allowStacking) {
closeAllModalsExcept(modal)
}
if (!modal.keepPopoutsOpen) {
PopoutManager.closeAllPopouts()
}
TrayMenuManager.closeAllMenus()
}
}

View File

@@ -0,0 +1,162 @@
pragma Singleton
import Quickshell
import QtQuick
Singleton {
id: root
property var currentPopoutsByScreen: ({})
property var currentPopoutTriggers: ({})
function showPopout(popout) {
if (!popout || !popout.screen) return
const screenName = popout.screen.name
for (const otherScreenName in currentPopoutsByScreen) {
const otherPopout = currentPopoutsByScreen[otherScreenName]
if (!otherPopout || otherPopout === popout) continue
if (otherPopout.dashVisible !== undefined) {
otherPopout.dashVisible = false
} else if (otherPopout.notificationHistoryVisible !== undefined) {
otherPopout.notificationHistoryVisible = false
} else {
otherPopout.close()
}
}
currentPopoutsByScreen[screenName] = popout
ModalManager.closeAllModalsExcept(null)
TrayMenuManager.closeAllMenus()
}
function hidePopout(popout) {
if (!popout || !popout.screen) return
const screenName = popout.screen.name
if (currentPopoutsByScreen[screenName] === popout) {
currentPopoutsByScreen[screenName] = null
currentPopoutTriggers[screenName] = null
}
}
function closeAllPopouts() {
for (const screenName in currentPopoutsByScreen) {
const popout = currentPopoutsByScreen[screenName]
if (!popout) continue
if (popout.dashVisible !== undefined) {
popout.dashVisible = false
} else if (popout.notificationHistoryVisible !== undefined) {
popout.notificationHistoryVisible = false
} else {
popout.close()
}
}
currentPopoutsByScreen = {}
}
function getActivePopout(screen) {
if (!screen) return null
return currentPopoutsByScreen[screen.name] || null
}
function requestPopout(popout, tabIndex, triggerSource) {
if (!popout || !popout.screen) return
const screenName = popout.screen.name
const currentPopout = currentPopoutsByScreen[screenName]
const triggerId = triggerSource !== undefined ? triggerSource : tabIndex
let justClosedSamePopout = false
for (const otherScreenName in currentPopoutsByScreen) {
if (otherScreenName === screenName) continue
const otherPopout = currentPopoutsByScreen[otherScreenName]
if (!otherPopout) continue
if (otherPopout === popout) {
justClosedSamePopout = true
}
if (otherPopout.dashVisible !== undefined) {
otherPopout.dashVisible = false
} else if (otherPopout.notificationHistoryVisible !== undefined) {
otherPopout.notificationHistoryVisible = false
} else {
otherPopout.close()
}
}
if (currentPopout && currentPopout !== popout) {
if (currentPopout.dashVisible !== undefined) {
currentPopout.dashVisible = false
} else if (currentPopout.notificationHistoryVisible !== undefined) {
currentPopout.notificationHistoryVisible = false
} else {
currentPopout.close()
}
}
if (currentPopout === popout && popout.shouldBeVisible) {
if (triggerId !== undefined && currentPopoutTriggers[screenName] === triggerId) {
if (popout.dashVisible !== undefined) {
popout.dashVisible = false
} else if (popout.notificationHistoryVisible !== undefined) {
popout.notificationHistoryVisible = false
} else {
popout.close()
}
return
}
if (triggerId === undefined) {
if (popout.dashVisible !== undefined) {
popout.dashVisible = false
} else if (popout.notificationHistoryVisible !== undefined) {
popout.notificationHistoryVisible = false
} else {
popout.close()
}
return
}
if (tabIndex !== undefined && popout.currentTabIndex !== undefined) {
popout.currentTabIndex = tabIndex
}
currentPopoutTriggers[screenName] = triggerId
return
}
currentPopoutTriggers[screenName] = triggerId
currentPopoutsByScreen[screenName] = popout
if (tabIndex !== undefined && popout.currentTabIndex !== undefined) {
popout.currentTabIndex = tabIndex
}
ModalManager.closeAllModalsExcept(null)
TrayMenuManager.closeAllMenus()
if (justClosedSamePopout) {
Qt.callLater(() => {
if (popout.dashVisible !== undefined) {
popout.dashVisible = true
} else if (popout.notificationHistoryVisible !== undefined) {
popout.notificationHistoryVisible = true
} else {
popout.open()
}
})
} else {
if (popout.dashVisible !== undefined) {
popout.dashVisible = true
} else if (popout.notificationHistoryVisible !== undefined) {
popout.notificationHistoryVisible = true
} else {
popout.open()
}
}
}
}

View File

@@ -590,6 +590,53 @@ rm -rf '${home}'/.cache/icon-cache '${home}'/.cache/thumbnails 2>/dev/null || tr
}
}
function getBarBounds(screen, barThickness) {
if (!screen) {
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
const wingRadius = dankBarGothCornerRadiusOverride ? dankBarGothCornerRadiusValue : Theme.cornerRadius
const wingSize = dankBarGothCornersEnabled ? Math.max(0, wingRadius) : 0
const screenWidth = screen.width
const screenHeight = screen.height
if (dankBarPosition === SettingsData.Position.Top) {
return {
"x": 0,
"y": 0,
"width": screenWidth,
"height": barThickness + dankBarSpacing + wingSize,
"wingSize": wingSize
}
} else if (dankBarPosition === SettingsData.Position.Bottom) {
return {
"x": 0,
"y": screenHeight - barThickness - dankBarSpacing - wingSize,
"width": screenWidth,
"height": barThickness + dankBarSpacing + wingSize,
"wingSize": wingSize
}
} else if (dankBarPosition === SettingsData.Position.Left) {
return {
"x": 0,
"y": 0,
"width": barThickness + dankBarSpacing + wingSize,
"height": screenHeight,
"wingSize": wingSize
}
} else if (dankBarPosition === SettingsData.Position.Right) {
return {
"x": screenWidth - barThickness - dankBarSpacing - wingSize,
"y": 0,
"width": barThickness + dankBarSpacing + wingSize,
"height": screenHeight,
"wingSize": wingSize
}
}
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
function getFilteredScreens(componentId) {
var prefs = screenPreferences && screenPreferences[componentId] || ["all"]
if (prefs.includes("all")) {

View File

@@ -0,0 +1,32 @@
pragma Singleton
import Quickshell
import QtQuick
Singleton {
id: root
property var activeTrayBars: ({})
function register(screenName, trayBar) {
if (!screenName || !trayBar) return
activeTrayBars[screenName] = trayBar
}
function unregister(screenName) {
if (!screenName) return
delete activeTrayBars[screenName]
}
function closeAllMenus() {
for (const screenName in activeTrayBars) {
const trayBar = activeTrayBars[screenName]
if (!trayBar) continue
trayBar.menuOpen = false
if (trayBar.currentTrayMenu) {
trayBar.currentTrayMenu.showMenu = false
}
}
}
}

View File

@@ -43,6 +43,7 @@ PanelWindow {
property bool allowFocusOverride: false
property bool allowStacking: false
property bool keepContentLoaded: false
property bool keepPopoutsOpen: false
signal opened
signal dialogClosed
@@ -88,7 +89,17 @@ PanelWindow {
}
}
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: shouldHaveFocus ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: {
if (!shouldHaveFocus) return WlrKeyboardFocus.None
if (CompositorService.isHyprland) return WlrKeyboardFocus.OnDemand
return WlrKeyboardFocus.Exclusive
}
HyprlandFocusGrab {
windows: [root]
active: CompositorService.isHyprland && shouldHaveFocus
}
onVisibleChanged: {
if (root.visible) {
opened()

View File

@@ -33,7 +33,9 @@ DankModal {
parentBounds = bounds
parentScreen = targetScreen
backgroundOpacity = 0
keepPopoutsOpen = true
open()
keepPopoutsOpen = false
}
function updateVisibleActions() {

View File

@@ -17,9 +17,6 @@ DankPopout {
property var triggerScreen: null
// Setting to Exclusive, so virtual keyboards can send input to app drawer
WlrLayershell.keyboardFocus: shouldBeVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
function show() {
open()
}
@@ -40,6 +37,8 @@ DankPopout {
positioning: ""
screen: triggerScreen
onBackgroundClicked: close()
onShouldBeVisibleChanged: {
if (shouldBeVisible) {
appLauncher.searchQuery = ""

View File

@@ -71,7 +71,8 @@ DankPopout {
positioning: ""
screen: triggerScreen
shouldBeVisible: false
visible: shouldBeVisible
onBackgroundClicked: close()
onShouldBeVisibleChanged: {
if (shouldBeVisible) {

View File

@@ -24,6 +24,25 @@ Item {
debounceTimer.restart()
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
z: -999
onClicked: {
const activePopout = PopoutManager.getActivePopout(barWindow.screen)
if (activePopout) {
if (activePopout.dashVisible !== undefined) {
activePopout.dashVisible = false
} else if (activePopout.notificationHistoryVisible !== undefined) {
activePopout.notificationHistoryVisible = false
} else {
activePopout.close()
}
}
TrayMenuManager.closeAllMenus()
}
}
Timer {
id: debounceTimer
interval: 50

View File

@@ -127,10 +127,7 @@ Item {
dankDashPopoutLoader.item.triggerScreen = barWindow.screen
}
if (!dankDashPopoutLoader.item.dashVisible) {
dankDashPopoutLoader.item.currentTabIndex = 2
}
dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible
PopoutManager.requestPopout(dankDashPopoutLoader.item, 2)
}
readonly property var dBarLayer: {
@@ -1061,7 +1058,9 @@ Item {
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barWindow.effectiveBarThickness, launcherButton.visualWidth)
appDrawerLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, launcherButton.section, currentScreen)
}
appDrawerLoader.item?.toggle()
if (appDrawerLoader.item) {
PopoutManager.requestPopout(appDrawerLoader.item, undefined, "appDrawer")
}
}
}
}
@@ -1130,8 +1129,14 @@ Item {
onClockClicked: {
dankDashPopoutLoader.active = true
if (dankDashPopoutLoader.item) {
dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible
dankDashPopoutLoader.item.currentTabIndex = 0
if (dankDashPopoutLoader.item.setTriggerPosition) {
const globalPos = visualContent.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, visualWidth)
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
} else {
dankDashPopoutLoader.item.triggerScreen = barWindow.screen
}
PopoutManager.requestPopout(dankDashPopoutLoader.item, 0)
}
}
}
@@ -1154,8 +1159,14 @@ Item {
onClicked: {
dankDashPopoutLoader.active = true
if (dankDashPopoutLoader.item) {
dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible
dankDashPopoutLoader.item.currentTabIndex = 1
if (dankDashPopoutLoader.item.setTriggerPosition) {
const globalPos = visualContent.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, visualWidth)
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
} else {
dankDashPopoutLoader.item.triggerScreen = barWindow.screen
}
PopoutManager.requestPopout(dankDashPopoutLoader.item, 1)
}
}
}
@@ -1177,8 +1188,14 @@ Item {
onClicked: {
dankDashPopoutLoader.active = true
if (dankDashPopoutLoader.item) {
dankDashPopoutLoader.item.dashVisible = !dankDashPopoutLoader.item.dashVisible
dankDashPopoutLoader.item.currentTabIndex = 3
if (dankDashPopoutLoader.item.setTriggerPosition) {
const globalPos = visualContent.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, visualWidth)
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
} else {
dankDashPopoutLoader.item.triggerScreen = barWindow.screen
}
PopoutManager.requestPopout(dankDashPopoutLoader.item, 3)
}
}
}
@@ -1323,7 +1340,9 @@ Item {
parentScreen: barWindow.screen
onClicked: {
notificationCenterLoader.active = true
notificationCenterLoader.item?.toggle()
if (notificationCenterLoader.item) {
PopoutManager.requestPopout(notificationCenterLoader.item, undefined, "notifications")
}
}
}
}
@@ -1344,7 +1363,9 @@ Item {
parentScreen: barWindow.screen
onToggleBatteryPopup: {
batteryPopoutLoader.active = true
batteryPopoutLoader.item?.toggle()
if (batteryPopoutLoader.item) {
PopoutManager.requestPopout(batteryPopoutLoader.item, undefined, "battery")
}
}
}
}
@@ -1365,7 +1386,9 @@ Item {
parentScreen: barWindow.screen
onToggleLayoutPopup: {
layoutPopoutLoader.active = true
layoutPopoutLoader.item?.toggle()
if (layoutPopoutLoader.item) {
PopoutManager.requestPopout(layoutPopoutLoader.item, undefined, "layout")
}
}
}
}
@@ -1385,7 +1408,9 @@ Item {
parentScreen: barWindow.screen
onToggleVpnPopup: {
vpnPopoutLoader.active = true
vpnPopoutLoader.item?.toggle()
if (vpnPopoutLoader.item) {
PopoutManager.requestPopout(vpnPopoutLoader.item, undefined, "vpn")
}
}
}
}
@@ -1422,7 +1447,7 @@ Item {
return
}
controlCenterLoader.item.triggerScreen = barWindow.screen
controlCenterLoader.item.toggle()
PopoutManager.requestPopout(controlCenterLoader.item, undefined, "controlCenter")
if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) {
NetworkService.scanWifi()
}

View File

@@ -50,8 +50,8 @@ DankPopout {
triggerWidth: 70
positioning: ""
screen: triggerScreen
shouldBeVisible: false
visible: shouldBeVisible
onBackgroundClicked: close()
content: Component {
Rectangle {

View File

@@ -95,7 +95,6 @@ DankPopout {
positioning: ""
screen: triggerScreen
shouldBeVisible: false
visible: shouldBeVisible
content: Component {
Rectangle {

View File

@@ -46,7 +46,8 @@ DankPopout {
positioning: ""
screen: triggerScreen
shouldBeVisible: false
visible: shouldBeVisible
onBackgroundClicked: close()
content: Component {
Rectangle {

View File

@@ -132,8 +132,8 @@ BasePill {
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("cpu");
if (root.toggleProcessList) {
root.toggleProcessList();
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "cpu");
}
}
}

View File

@@ -132,8 +132,8 @@ BasePill {
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("cpu");
if (root.toggleProcessList) {
root.toggleProcessList();
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "cpu_temp");
}
}
}

View File

@@ -196,8 +196,8 @@ BasePill {
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("cpu");
if (root.toggleProcessList) {
root.toggleProcessList();
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "gpu_temp");
}
}
}

View File

@@ -155,8 +155,8 @@ BasePill {
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("memory");
if (root.toggleProcessList) {
root.toggleProcessList();
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "memory");
}
}
}

View File

@@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import Quickshell
import Quickshell.Hyprland
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
@@ -49,7 +50,17 @@ Item {
visible: allTrayItems.length > 0
property bool menuOpen: false
property bool overflowWasOpenBeforeTrayMenu: false
property var currentTrayMenu: null
Component.onCompleted: {
if (!parentScreen) return
TrayMenuManager.register(parentScreen.name, root)
}
Component.onDestruction: {
if (!parentScreen) return
TrayMenuManager.unregister(parentScreen.name)
}
Rectangle {
id: visualBackground
@@ -171,7 +182,7 @@ Item {
if (!delegateRoot.trayItem.hasMenu) return
root.overflowWasOpenBeforeTrayMenu = root.menuOpen
root.menuOpen = false
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
@@ -304,7 +315,7 @@ Item {
if (!delegateRoot.trayItem.hasMenu) return
root.overflowWasOpenBeforeTrayMenu = root.menuOpen
root.menuOpen = false
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
@@ -356,10 +367,19 @@ Item {
screen: root.parentScreen
WlrLayershell.layer: WlrLayershell.Top
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: {
if (!root.menuOpen) return WlrKeyboardFocus.None
if (CompositorService.isHyprland) return WlrKeyboardFocus.OnDemand
return WlrKeyboardFocus.Exclusive
}
WlrLayershell.namespace: "dms:tray-overflow-menu"
color: "transparent"
HyprlandFocusGrab {
windows: [overflowMenu]
active: CompositorService.isHyprland && root.menuOpen
}
anchors {
top: true
left: true
@@ -372,12 +392,108 @@ Item {
: (screen?.devicePixelRatio || 1)
property point anchorPos: Qt.point(screen.width / 2, screen.height / 2)
readonly property var barBounds: {
if (!overflowMenu.screen) {
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
return SettingsData.getBarBounds(overflowMenu.screen, root.barThickness + SettingsData.dankBarSpacing)
}
readonly property real barX: barBounds.x
readonly property real barY: barBounds.y
readonly property real barWidth: barBounds.width
readonly property real barHeight: barBounds.height
readonly property real maskX: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Left:
return barWidth > 0 ? barWidth : 0
case SettingsData.Position.Right:
case SettingsData.Position.Top:
case SettingsData.Position.Bottom:
default:
return 0
}
}
readonly property real maskY: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Top:
return barHeight > 0 ? barHeight : 0
case SettingsData.Position.Bottom:
case SettingsData.Position.Left:
case SettingsData.Position.Right:
default:
return 0
}
}
readonly property real maskWidth: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Left:
return barWidth > 0 ? width - barWidth : width
case SettingsData.Position.Right:
return barWidth > 0 ? width - barWidth : width
case SettingsData.Position.Top:
case SettingsData.Position.Bottom:
default:
return width
}
}
readonly property real maskHeight: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Top:
return barHeight > 0 ? height - barHeight : height
case SettingsData.Position.Bottom:
return barHeight > 0 ? height - barHeight : height
case SettingsData.Position.Left:
case SettingsData.Position.Right:
default:
return height
}
}
mask: Region {
item: Rectangle {
x: overflowMenu.maskX
y: overflowMenu.maskY
width: overflowMenu.maskWidth
height: overflowMenu.maskHeight
}
}
onVisibleChanged: {
if (visible) {
if (currentTrayMenu) {
currentTrayMenu.showMenu = false
}
PopoutManager.closeAllPopouts()
ModalManager.closeAllModalsExcept(null)
updatePosition()
}
}
MouseArea {
x: overflowMenu.maskX
y: overflowMenu.maskY
width: overflowMenu.maskWidth
height: overflowMenu.maskHeight
z: -1
enabled: root.menuOpen
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
onClicked: mouse => {
const clickX = mouse.x + overflowMenu.maskX
const clickY = mouse.y + overflowMenu.maskY
const outsideContent = clickX < menuContainer.x || clickX > menuContainer.x + menuContainer.width ||
clickY < menuContainer.y || clickY > menuContainer.y + menuContainer.height
if (!outsideContent) return
root.menuOpen = false
}
}
FocusScope {
id: overflowFocusScope
anchors.fill: parent
@@ -613,7 +729,6 @@ Item {
if (!trayItem.hasMenu) return
root.overflowWasOpenBeforeTrayMenu = true
root.menuOpen = false
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
@@ -622,12 +737,6 @@ Item {
}
}
}
MouseArea {
anchors.fill: parent
z: -1
onClicked: root.menuOpen = false
}
}
Component {
@@ -674,14 +783,9 @@ Item {
function close() {
showMenu = false
if (root.overflowWasOpenBeforeTrayMenu) {
root.menuOpen = true
}
root.overflowWasOpenBeforeTrayMenu = false
}
function closeWithAction() {
root.overflowWasOpenBeforeTrayMenu = false
close()
}
@@ -715,9 +819,18 @@ Item {
visible: menuRoot.showMenu && (menuRoot.trayItem?.hasMenu ?? false)
WlrLayershell.layer: WlrLayershell.Top
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: {
if (!menuRoot.showMenu) return WlrKeyboardFocus.None
if (CompositorService.isHyprland) return WlrKeyboardFocus.OnDemand
return WlrKeyboardFocus.Exclusive
}
color: "transparent"
HyprlandFocusGrab {
windows: [menuWindow]
active: CompositorService.isHyprland && menuRoot.showMenu
}
anchors {
top: true
left: true
@@ -730,12 +843,106 @@ Item {
: (screen?.devicePixelRatio || 1)
property point anchorPos: Qt.point(screen.width / 2, screen.height / 2)
readonly property var barBounds: {
if (!menuWindow.screen) {
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
return SettingsData.getBarBounds(menuWindow.screen, root.barThickness + SettingsData.dankBarSpacing)
}
readonly property real barX: barBounds.x
readonly property real barY: barBounds.y
readonly property real barWidth: barBounds.width
readonly property real barHeight: barBounds.height
readonly property real maskX: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Left:
return barWidth > 0 ? barWidth : 0
case SettingsData.Position.Right:
case SettingsData.Position.Top:
case SettingsData.Position.Bottom:
default:
return 0
}
}
readonly property real maskY: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Top:
return barHeight > 0 ? barHeight : 0
case SettingsData.Position.Bottom:
case SettingsData.Position.Left:
case SettingsData.Position.Right:
default:
return 0
}
}
readonly property real maskWidth: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Left:
return barWidth > 0 ? width - barWidth : width
case SettingsData.Position.Right:
return barWidth > 0 ? width - barWidth : width
case SettingsData.Position.Top:
case SettingsData.Position.Bottom:
default:
return width
}
}
readonly property real maskHeight: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Top:
return barHeight > 0 ? height - barHeight : height
case SettingsData.Position.Bottom:
return barHeight > 0 ? height - barHeight : height
case SettingsData.Position.Left:
case SettingsData.Position.Right:
default:
return height
}
}
mask: Region {
item: Rectangle {
x: menuWindow.maskX
y: menuWindow.maskY
width: menuWindow.maskWidth
height: menuWindow.maskHeight
}
}
onVisibleChanged: {
if (visible) {
root.menuOpen = false
PopoutManager.closeAllPopouts()
ModalManager.closeAllModalsExcept(null)
updatePosition()
}
}
MouseArea {
x: menuWindow.maskX
y: menuWindow.maskY
width: menuWindow.maskWidth
height: menuWindow.maskHeight
z: -1
enabled: menuRoot.showMenu
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
onClicked: mouse => {
const clickX = mouse.x + menuWindow.maskX
const clickY = mouse.y + menuWindow.maskY
const outsideContent = clickX < menuContainer.x || clickX > menuContainer.x + menuContainer.width ||
clickY < menuContainer.y || clickY > menuContainer.y + menuContainer.height
if (!outsideContent) return
menuRoot.close()
}
}
FocusScope {
id: menuFocusScope
anchors.fill: parent
@@ -1128,40 +1335,23 @@ Item {
}
}
}
MouseArea {
anchors.fill: parent
z: -1
onClicked: menuRoot.close()
}
}
}
}
property var currentTrayMenu: null
Connections {
target: currentTrayMenu
enabled: currentTrayMenu !== null
function onShowMenuChanged() {
if (parentWindow && typeof parentWindow.systemTrayMenuOpen !== "undefined") {
parentWindow.systemTrayMenuOpen = currentTrayMenu.showMenu
}
}
}
function showForTrayItem(item, anchor, screen, atBottom, vertical, axisObj) {
if (parentWindow && typeof parentWindow.systemTrayMenuOpen !== "undefined") {
parentWindow.systemTrayMenuOpen = true
}
if (!screen) return
if (currentTrayMenu) {
currentTrayMenu.showMenu = false
currentTrayMenu.destroy()
currentTrayMenu = null
}
currentTrayMenu = trayMenuComponent.createObject(null)
if (currentTrayMenu) {
if (!currentTrayMenu) return
currentTrayMenu.showForTrayItem(item, anchor, screen, atBottom, vertical ?? false, axisObj)
}
}
}

View File

@@ -18,7 +18,6 @@ DankPopout {
property var triggerScreen: null
property int currentTabIndex: 0
keyboardFocusMode: WlrKeyboardFocus.Exclusive
function setTriggerPosition(x, y, width, section, screen) {
triggerSection = section
@@ -44,8 +43,8 @@ DankPopout {
triggerX: Screen.width - 620 - Theme.spacingL
triggerY: Math.max(26 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding)) + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap - 2
triggerWidth: 80
screen: triggerScreen
shouldBeVisible: dashVisible
visible: shouldBeVisible
property bool __focusArmed: false
property bool __contentReady: false

View File

@@ -35,7 +35,7 @@ Scope {
WlrLayershell.namespace: "dms:workspace-overview"
WlrLayershell.layer: WlrLayer.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
WlrLayershell.keyboardFocus: overviewScope.overviewOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
anchors {
top: true

View File

@@ -42,7 +42,14 @@ DankPopout {
positioning: ""
screen: triggerScreen
shouldBeVisible: notificationHistoryVisible
visible: shouldBeVisible
function toggle() {
notificationHistoryVisible = !notificationHistoryVisible
}
onBackgroundClicked: {
notificationHistoryVisible = false
}
onNotificationHistoryVisibleChanged: {
if (notificationHistoryVisible) {

View File

@@ -8,8 +8,6 @@ DankPopout {
layerNamespace: "dms-plugin:" + layerNamespacePlugin
WlrLayershell.keyboardFocus: shouldBeVisible ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
property var triggerScreen: null
property Component pluginContent: null
property real contentWidth: 400
@@ -27,7 +25,6 @@ DankPopout {
popupHeight: contentHeight
screen: triggerScreen
shouldBeVisible: false
visible: shouldBeVisible
content: Component {
Rectangle {

View File

@@ -45,9 +45,10 @@ DankPopout {
triggerWidth: 55
positioning: ""
screen: triggerScreen
visible: shouldBeVisible
shouldBeVisible: false
onBackgroundClicked: close()
Ref {
service: DgopService
}

View File

@@ -35,9 +35,10 @@ DankPopout {
triggerWidth: 55
positioning: ""
screen: triggerScreen
visible: shouldBeVisible
shouldBeVisible: false
onBackgroundClicked: close()
onShouldBeVisibleChanged: {
if (shouldBeVisible) {
if (SystemUpdateService.updateCount === 0 && !SystemUpdateService.isChecking) {

View File

@@ -28,7 +28,23 @@ PanelWindow {
property list<real> animationEnterCurve: Theme.expressiveCurves.expressiveDefaultSpatial
property list<real> animationExitCurve: Theme.expressiveCurves.emphasized
property bool shouldBeVisible: false
property int keyboardFocusMode: WlrKeyboardFocus.OnDemand
visible: false
readonly property real effectiveBarThickness: Math.max(26 + SettingsData.dankBarInnerPadding * 0.6, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding)) + SettingsData.dankBarSpacing
readonly property var barBounds: {
if (!root.screen) {
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
return SettingsData.getBarBounds(root.screen, effectiveBarThickness)
}
readonly property real barX: barBounds.x
readonly property real barY: barBounds.y
readonly property real barWidth: barBounds.width
readonly property real barHeight: barBounds.height
readonly property real barWingSize: barBounds.wingSize
signal opened
signal popoutClosed
@@ -38,6 +54,7 @@ PanelWindow {
closeTimer.stop()
shouldBeVisible = true
visible = true
PopoutManager.showPopout(root)
opened()
}
@@ -59,6 +76,7 @@ PanelWindow {
onTriggered: {
if (!shouldBeVisible) {
visible = false
PopoutManager.hidePopout(root)
popoutClosed()
}
}
@@ -78,7 +96,11 @@ PanelWindow {
}
}
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: shouldBeVisible ? keyboardFocusMode : WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: {
if (!shouldBeVisible) return WlrKeyboardFocus.None
if (CompositorService.isHyprland) return WlrKeyboardFocus.OnDemand
return WlrKeyboardFocus.Exclusive
}
anchors {
top: true
@@ -114,16 +136,82 @@ PanelWindow {
}
})(), dpr)
readonly property real maskX: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Left:
return root.barWidth > 0 ? root.barWidth : 0
case SettingsData.Position.Right:
case SettingsData.Position.Top:
case SettingsData.Position.Bottom:
default:
return 0
}
}
readonly property real maskY: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Top:
return root.barHeight > 0 ? root.barHeight : 0
case SettingsData.Position.Bottom:
case SettingsData.Position.Left:
case SettingsData.Position.Right:
default:
return 0
}
}
readonly property real maskWidth: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Left:
return root.barWidth > 0 ? root.width - root.barWidth : root.width
case SettingsData.Position.Right:
return root.barWidth > 0 ? root.width - root.barWidth : root.width
case SettingsData.Position.Top:
case SettingsData.Position.Bottom:
default:
return root.width
}
}
readonly property real maskHeight: {
switch (SettingsData.dankBarPosition) {
case SettingsData.Position.Top:
return root.barHeight > 0 ? root.height - root.barHeight : root.height
case SettingsData.Position.Bottom:
return root.barHeight > 0 ? root.height - root.barHeight : root.height
case SettingsData.Position.Left:
case SettingsData.Position.Right:
default:
return root.height
}
}
mask: Region {
item: Rectangle {
x: root.maskX
y: root.maskY
width: root.maskWidth
height: root.maskHeight
}
}
MouseArea {
anchors.fill: parent
enabled: shouldBeVisible && contentLoader.opacity > 0.1
x: maskX
y: maskY
width: maskWidth
height: maskHeight
z: -1
enabled: shouldBeVisible
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
onClicked: mouse => {
if (mouse.x < alignedX || mouse.x > alignedX + alignedWidth ||
mouse.y < alignedY || mouse.y > alignedY + alignedHeight) {
const clickX = mouse.x + maskX
const clickY = mouse.y + maskY
const outsideContent = clickX < alignedX || clickX > alignedX + alignedWidth ||
clickY < alignedY || clickY > alignedY + alignedHeight
if (!outsideContent) return
backgroundClicked()
close()
}
}
}
@@ -253,6 +341,7 @@ PanelWindow {
}
Item {
id: focusHelper
parent: contentContainer
anchors.fill: parent
focus: true
@@ -262,7 +351,5 @@ PanelWindow {
event.accepted = true
}
}
Component.onCompleted: forceActiveFocus()
onVisibleChanged: if (visible) forceActiveFocus()
}
}