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 } } }