import Quickshell import QtQuick import qs.Components import ZShell.Config import qs.Helpers import qs.Modules as BarPopouts Item { id: root required property Item bar required property real borderThickness property bool dashboardShortcutActive required property Drawing drawing property bool osdShortcutActive required property Panels panels required property BarPopouts.Wrapper popouts required property ShellScreen screen property bool singleGestureTriggered: false property bool utilitiesShortcutActive required property PersistentProperties visibilities function inBottomPanel(panel: Item, x: real, y: real): bool { return y > root.height - panel.height - Config.bar.border && withinPanelWidth(panel, x, y); } function inLeftPanel(panel: Item, x: real, y: real): bool { return x < panel.x + panel.width + Config.bar.border && withinPanelHeight(panel, x, y); } function inRightPanel(panel: Item, x: real, y: real): bool { return x > panel.x - Config.bar.border && withinPanelHeight(panel, x, y); } function inTopPanel(panel: Item, x: real, y: real): bool { return y < bar.implicitHeight + panel.height && withinPanelWidth(panel, x, y); } function onWheel(event: WheelEvent): void { if (event.x < bar.implicitWidth) { bar.handleWheel(event.y, event.angleDelta); } } function withinPanelHeight(panel: Item, x: real, y: real): bool { const panelY = panel.y + bar.implicitHeight; return y >= panelY && y <= panelY + panel.height; } function withinPanelWidth(panel: Item, x: real, y: real): bool { const panelX = panel.x + root.borderThickness; return x >= panelX && x <= panelX + panel.width; } anchors.fill: parent DragHandler { id: singleHandler cursorShape: (active && centroid.pressPosition.y < root.bar.implicitHeight) ? Qt.ClosedHandCursor : undefined dragThreshold: 0 enabled: !root.visibilities.isDrawing grabPermissions: PointerHandler.CanTakeOverFromHandlersOfSameType | PointerHandler.ApprovesTakeOverByAnything maximumPointCount: 1 minimumPointCount: 1 target: null onActiveChanged: { if (!active) root.singleGestureTriggered = false; } onCentroidChanged: { const x = centroid.position.x; const y = centroid.position.y; const dragX = x - centroid.pressPosition.x; const dragY = y - centroid.pressPosition.y; if (centroid.pressPosition.y >= root.screen.height - Config.bar.border && centroid.pressPosition.x > root.screen.width / 5 && dragY < -Config.launcher.dragThreshold) root.visibilities.launcher = true; if (root.singleGestureTriggered) return; if (centroid.pressPosition.y < root.bar.implicitHeight) { if (dragY > 20) { root.visibilities.settings = true; root.singleGestureTriggered = true; } else if (dragY < -20) { root.visibilities.settings = false; root.singleGestureTriggered = true; } } if (centroid.pressPosition.y > root.screen.height - Config.bar.border && centroid.pressPosition.x < root.screen.width / 5 && dragY < -50) root.visibilities.clipboard = true; if (!Config.dock.hoverToReveal && centroid.pressPosition.y > root.screen.height - root.bar.implicitHeight && centroid.pressPosition.x > root.screen.width / 5 && !root.visibilities.launcher) if (dragY < -10) { root.visibilities.dock = true; root.singleGestureTriggered = true; } if (centroid.pressPosition.x > root.screen.width - Config.bar.border && centroid.pressPosition.y < (root.screen.height / 2) && dragX < -Config.sidebar.dragThreshold) { root.visibilities.sidebar = true; root.singleGestureTriggered = true; } if (centroid.pressPosition.x >= root.screen.width - Config.bar.border && centroid.pressPosition.y > (root.screen.height / 2) && dragX < -20) { Hypr.dispatch(`hl.dsp.focus({ workspace = 'r+1', on_current_monitor = true })`); root.singleGestureTriggered = true; } if (centroid.pressPosition.x <= Config.bar.border && dragX > 20) { Hypr.dispatch(`hl.dsp.focus({ workspace = 'r-1', on_current_monitor = true })`); root.singleGestureTriggered = true; } } } PointHandler { id: drawingHandler property bool setInitialPoint: false acceptedButtons: Qt.LeftButton | Qt.RightButton enabled: root.visibilities.isDrawing && (!root.inLeftPanel(root.panels.drawing, hoverHandler.point.position.x, hoverHandler.point.position.y) || !root.panels.drawing.expanded) onActiveChanged: { if (!active) { setInitialPoint = false; root.drawing.content.endStroke(); } else { root.panels.drawing.collapse(); } } onPointChanged: { if (!active) return; const x = point.position.x; const y = point.position.y; const origX = point.pressPosition.x; const origY = point.pressPosition.y; if (point.pressedButtons & Qt.RightButton) { root.drawing.content.clear(); return; } if (x === 0 && y === 0 && origX === 0 && origY === 0) return; if (!setInitialPoint) { setInitialPoint = true; root.drawing.content.beginStroke(origX, origY); return; } root.drawing.content.appendPoint(x, y); } } HoverHandler { id: hoverHandler cursorShape: root.visibilities.isDrawing && !root.inLeftPanel(root.panels.drawing, point.position.x, point.position.y) ? Qt.BlankCursor : undefined onHoveredChanged: { if (!hovered) { if (!root.osdShortcutActive) { root.visibilities.osd = false; root.panels.osd.hovered = false; } if (!root.popouts.currentName.startsWith("traymenu") || Config.bar.tray.showOnHover) { root.popouts.hasCurrent = false; } if (Config.bar.autoHide) root.bar.isHovered = false; } } onPointChanged: { const x = point.position.x; const y = point.position.y; if (root.visibilities.isDrawing) { if (root.inLeftPanel(root.panels.drawing, x, y) && !(drawingHandler.point.pressedButtons & Qt.LeftButton)) { root.panels.drawing.expand(); root.drawing.content.hideHover(); return; } root.drawing.content.showHover(x, y); return; } if (!root.visibilities.bar && Config.bar.autoHide && y < root.bar.implicitHeight) root.bar.isHovered = true; if (root.panels.sidebar.offsetScale === 1) { const showOsd = root.inRightPanel(root.panels.osdWrapper, x, y); if (showOsd) { root.osdShortcutActive = false; root.panels.osd.hovered = true; } } else { const outOfSidebar = x < root.width - root.panels.sidebar.width * (1 - root.panels.sidebar.offsetScale); const showOsd = outOfSidebar && root.inRightPanel(root.panels.osdWrapper, x, y); if (!root.osdShortcutActive) { root.visibilities.osd = showOsd; root.panels.osd.hovered = showOsd; } else if (showOsd) { root.osdShortcutActive = false; root.panels.osd.hovered = true; } } if (Config.dock.enable && Config.dock.hoverToReveal && !root.visibilities.dock && !root.visibilities.launcher && root.inBottomPanel(root.panels.dock, x, y)) root.visibilities.dock = true; if (y < root.bar.implicitHeight) root.bar.checkPopout(x); } } Connections { function onDashboardChanged() { if (root.visibilities.dashboard) { const inDashboardArea = root.inTopPanel(root.panels.dashboard, root.mouseX, root.mouseY); if (!inDashboardArea) { root.dashboardShortcutActive = true; } if (root.panels.launcher.x + root.panels.launcher.width > root.panels.dashboardWrapper.x) root.visibilities.launcher = false; root.visibilities.settings = false; root.visibilities.sidebar = false; root.popouts.hasCurrent = false; } else { root.dashboardShortcutActive = false; } } function onIsDrawingChanged() { if (!root.visibilities.isDrawing) root.drawing.clear(); } function onLauncherChanged() { if (!root.visibilities.launcher) { root.dashboardShortcutActive = false; root.osdShortcutActive = false; root.utilitiesShortcutActive = false; const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY); if (!inOsdArea) { root.visibilities.osd = false; root.panels.osd.hovered = false; } } if (root.visibilities.launcher) { if (root.panels.dashboardWrapper.x < root.panels.launcher.x + root.panels.launcher.width) { root.visibilities.dashboard = false; } root.visibilities.dock = false; root.visibilities.settings = false; } } function onOsdChanged() { if (root.visibilities.osd) { const inOsdArea = root.inRightPanel(root.panels.osd, root.mouseX, root.mouseY); if (!inOsdArea) { root.osdShortcutActive = true; } } else { root.osdShortcutActive = false; } } function onResourcesChanged() { if (root.visibilities.resources && (root.popouts.currentName.startsWith("audio") || root.popouts.currentName.startsWith("updates"))) { root.popouts.hasCurrent = false; } if (root.visibilities.resources) root.visibilities.settings = false; } function onSettingsChanged() { if (root.visibilities.settings) { root.visibilities.resources = false; root.visibilities.dashboard = false; root.visibilities.sidebar = false; root.panels.popouts.hasCurrent = false; root.visibilities.launcher = false; } else { Config.save(); } } function onSidebarChanged() { if (root.visibilities.sidebar) { root.visibilities.dashboard = false; root.visibilities.settings = false; root.popouts.hasCurrent = false; } } target: root.visibilities } }