pragma Singleton import QtQuick import QtQuick.Layouts // Workspaces.qml import Quickshell import Quickshell.Widgets import qs.Common import qs.Services Singleton { function start(component, type) { HoverMediator.component = component; HoverMediator.type = type; hoverPopUp.anchor.updateAnchor(); hoverTimer.start(); } function exit() { hoverTimer.stop(); hoverPopUp.visible = false; } PopupWindow { id: hoverPopUp anchor.item: HoverMediator.component property bool initialized: false anchor.rect.y: HoverMediator.y anchor.rect.x: (HoverMediator.x - this.implicitWidth) / 2 implicitHeight: wsPopUp.implicitHeight implicitWidth: wsPopUp.implicitWidth color: "transparent" Component { id: stub Text { text: "stub" font.bold: true font.pixelSize: Theme.pixelSize font.family: Theme.fontFamily color: Theme.textColor } } Component { id: systray Text { text: { if (!HoverMediator.component.model) return ""; if (HoverMediator.component.model.tooltipTitle) return HoverMediator.component.model.tooltipTitle; if (HoverMediator.component.model.title) return HoverMediator.component.model.title; else return ""; } font.bold: true font.pixelSize: Theme.pixelSize font.family: Theme.fontFamily color: Theme.textColor } } Component { id: time Text { property string calendar: (HoverMediator.component.calendar) ? HoverMediator.component.calendar : "" text: calendar font.bold: true font.pixelSize: Theme.pixelSize font.family: Theme.fontFamilyMono color: Theme.textColor } } Component { id: audio Text { property string sinkDescription: (HoverMediator.component.sink) ? HoverMediator.component.sink.description : "" text: sinkDescription font.bold: true font.pixelSize: Theme.pixelSize font.family: Theme.fontFamily color: Theme.textColor } } Component { id: workspaceComponent RowLayout { id: wsPopUpRow property int workspaceIndexAlign: HoverMediator.component.workspaceIndexAlign || 0 Repeater { property var modelo: HyprlandService.sortedDesktopApplications.get(parent.workspaceIndexAlign) model: modelo delegate: IconImage { required property var modelData width: 30 height: 30 source: (modelData && modelData.icon) ? Quickshell.iconPath(modelData.icon, 1) : "" } } } } WrapperRectangle { id: wsPopUp leftMargin: (Theme.gaps * 2) rightMargin: (Theme.gaps * 2) topMargin: Theme.gaps bottomMargin: Theme.gaps color: Theme.backgroudColor radius: 25 opacity: 1 Behavior on opacity { NumberAnimation { property: "opacity" duration: Theme.animationDuration } } Loader { id: hoverLoader sourceComponent: { if (!HoverMediator.type) return stub; if (HoverMediator.type === "workspace") return workspaceComponent; if (HoverMediator.type === "audio") return audio; if (HoverMediator.type === "time") return time; if (HoverMediator.type === "systray") return systray; } } } } Timer { id: hoverTimer interval: 300 onTriggered: { // wsPopUp.opacity = 1 hoverPopUp.visible = true; } } }