import qs.config import qs.custom import qs.services import qs.modules.bar.popouts as BarPopouts import qs.modules.osd as Osd import Quickshell import QtQuick CustomMouseArea { id: root required property ShellScreen screen required property PersistentProperties uiState required property Panels panels required property Item bar readonly property BarPopouts.Wrapper popouts: panels.popouts property bool osdHovered property bool osdShortcutActive property bool dashboardShortcutActive anchors.fill: parent // HACK: Fixes weird pixel alignment issues that drop mouse events anchors.rightMargin: -1 anchors.bottomMargin: -1 hoverEnabled: true function withinPanelWidth(panel: Item, x: real): bool { const panelX = panel.x + Config.border.thickness; return x >= panelX - Config.border.rounding && x <= panelX + panel.width + Config.border.rounding; } function withinPanelHeight(panel: Item, y: real): bool { const panelY = panel.y + Config.bar.height; return y >= panelY - Config.border.rounding && y <= panelY + panel.height + Config.border.rounding; } function inBottomPanel(panel: Item, x: real, y: real): bool { return y > panel.y + Config.bar.height && withinPanelWidth(panel, x); } function inLeftPanel(panel: Item, x: real, y: real): bool { return x < panel.x + panel.width + Config.border.thickness && withinPanelHeight(panel, y); } function inRightPanel(panel: Item, x: real, y: real): bool { return x > panel.x + Config.border.thickness && withinPanelHeight(panel, y); } // Handling Mouse Input property point dragStart onPressed: event => dragStart = Qt.point(event.x, event.y) onPositionChanged: event => { const x = event.x; const y = event.y; // Show bar popouts on hover if (y < Config.bar.height && !popoutsSuppressed && !popouts.persistent) { bar.checkPopout(x); } // Show osd on hover const showOsd = inRightPanel(panels.osd, x, y); // Always update visibility based on hover if not in shortcut mode if (!osdShortcutActive) { uiState.osd = showOsd && !osdSuppressed; osdHovered = showOsd && !osdSuppressed; } else if (showOsd) { // If hovering over OSD area while in shortcut mode, transition to hover control osdShortcutActive = false; osdHovered = true; } // Show dashboard on hover const showDashboard = !dashboardSuppressed && inLeftPanel(panels.dashboard, x, y); // Always update visibility based on hover if not in shortcut mode if (!dashboardShortcutActive) { uiState.dashboard = showDashboard; } else if (showDashboard) { // If hovering over dashboard area while in shortcut mode, transition to hover control dashboardShortcutActive = false; } // Show launcher on drag if (pressed && inBottomPanel(panels.launcher, dragStart.x, dragStart.y) && withinPanelWidth(panels.launcher, x, y)) { const dragY = y - dragStart.y; if (dragY < -Config.launcher.dragThreshold && !launcherSuppressed) uiState.launcher = true; else if (dragY > Config.launcher.dragThreshold) uiState.launcher = false; } } Connections { target: root.uiState function onOsdChanged() { if (root.uiState.osd) { // OSD became visible, immediately check if this should be shortcut mode const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY); if (!inOsdArea) { root.osdShortcutActive = true; } } else { // OSD hidden, clear shortcut flag root.osdShortcutActive = false; } } } Osd.Interactions { uiState: root.uiState screen: root.screen hovered: root.osdHovered suppressed: root.osdSuppressed } onContainsMouseChanged: { if (!containsMouse) { if (!popouts.persistent) popouts.hasCurrent = false; if(!osdShortcutActive) { uiState.osd = false; osdHovered = false; } if (!dashboardShortcutActive) uiState.dashboard = false; } } // Suppressing Panels property bool popoutsSuppressed: uiState.dashboard || uiState.session property bool dashboardSuppressed: uiState.launcher property bool launcherSuppressed: uiState.dashboard property bool osdSuppressed: popouts.hasCurrent onPopoutsSuppressedChanged: { if (popoutsSuppressed && popouts.hasCurrent) { popouts.hasCurrent = false; } } onDashboardSuppressed: { if (dashboardSuppressed && uiState.dashboard) { uiState.dashboard = false; } } onLauncherSuppressedChanged: { if (launcherSuppressed && uiState.launcher) { uiState.launcher = false; } } onOsdSuppressedChanged: { if (osdSuppressed && uiState.osd) { uiState.osd = false; } } }