import QtQuick import qs.Services import Quickshell import Quickshell.Widgets Item { id: activeWindowDisplay required property int maxWidth required property var screen property var activeWindow: { let currWindowId = Array.from(NiriService.workspaces).find(ws => { return ws.output === screen.name && ws.is_active; })?.active_window_id; return currWindowId ? Array.from(NiriService.windows).find(win => win.id == currWindowId) : null; } property var windowEntry: activeWindow ? DesktopEntries.heuristicLookup(activeWindow.app_id) : null anchors.verticalCenter: parent.verticalCenter width: activeWindowDisplayContent.width height: parent.height WrapperMouseArea { id: widgetMouseArea anchors.fill: parent hoverEnabled: true Item { anchors.fill: parent Row { id: activeWindowDisplayContent width: childrenRect.width height: parent.height anchors.verticalCenter: parent.verticalCenter spacing: 8 IconImage { id: activeWindowIcon implicitSize: 14 anchors.verticalCenter: parent.verticalCenter source: { let icon = activeWindowDisplay.windowEntry?.icon if (typeof icon === 'string' || icon instanceof String) { if (icon.includes("?path=")) { const split = icon.split("?path=") if (split.length !== 2) return icon const name = split[0] const path = split[1] const fileName = name.substring( name.lastIndexOf("/") + 1) return `file://${path}/${fileName}` } else icon = Quickshell.iconPath(icon); return icon } return "" } asynchronous: true smooth: true mipmap: true } Text { id: windowTitle width: Math.min(implicitWidth, activeWindowDisplay.maxWidth - activeWindowIcon.width - activeWindowDisplayContent.spacing) property var appAliases: { "Firefox": "Mozilla Firefox", "mpv Media Player": "mpv", "Thunderbird": "Mozilla Thunderbird", "Thunderbird (LMU)": "Mozilla Thunderbird" } elide: Text.ElideRight maximumLineCount: 1 color: "white" anchors.verticalCenter: parent.verticalCenter text: { if (!activeWindowDisplay.activeWindow) return ""; var title = activeWindowDisplay.activeWindow.title; var appName = activeWindowDisplay.windowEntry?.name; if (appAliases[appName]) appName = appAliases[appName]; if (appName && title.endsWith(appName)) { const oldTitle = title; title = title.substring(0, title.length - appName.length); title = title.replace(/\s*(—|-)\s*$/, ""); if (!title) title = oldTitle; } return title; } } } } } Loader { id: tooltipLoader active: false Connections { target: widgetMouseArea function onContainsMouseChanged() { if (widgetMouseArea.containsMouse) tooltipLoader.active = true; } } PopupWindow { id: tooltip property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse anchor { item: widgetMouseArea edges: Edges.Bottom | Edges.Left } visible: false onNextVisibleChanged: hangTimer.restart() Timer { id: hangTimer interval: tooltip.visible ? 100 : 500 onTriggered: { tooltip.visible = tooltip.nextVisible; if (!tooltip.visible) tooltipLoader.active = false; } } implicitWidth: widgetTooltipText.contentWidth + 16 implicitHeight: widgetTooltipText.contentHeight + 16 color: "black" WrapperMouseArea { id: tooltipMouseArea hoverEnabled: true enabled: true anchors.centerIn: parent Text { id: widgetTooltipText font.pointSize: 10 font.family: "Fira Mono" color: "white" text: JSON.stringify(Object.assign({}, activeWindowDisplay.activeWindow), null, 2) } } } } }