Files
Quickbar/Services/HyprlandService.qml

111 lines
3.5 KiB
QML

pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
Singleton {
id: root
readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")
readonly property var focusedMon: Hyprland.focusedMonitor
property bool hasFullscreen: false
property bool isScreencasting: false
property ListModel sortedDesktopApplicationsModel: ListModel {}
// Derived property of sorted toplevels
property var sortedTopLevels: {
const topLevels = Array.from(Hyprland.toplevels?.values ?? []);
const sorted = topLevels.sort((a, b) => {
if (a.monitor && b.monitor) {
const monitorCompare = a.monitor.name.localeCompare(b.monitor.name);
if (monitorCompare !== 0)
return monitorCompare;
}
if (a.workspace && b.workspace) {
const workspaceCompare = a.workspace.id - b.workspace.id;
if (workspaceCompare !== 0)
return workspaceCompare;
}
if (a.lastIpcObject?.at && b.lastIpcObject?.at) {
const xCompare = a.lastIpcObject.at[0] - b.lastIpcObject.at[0];
if (Math.abs(xCompare) > 10)
return xCompare;
return a.lastIpcObject.at[1] - b.lastIpcObject.at[1];
}
if (a.title && b.title)
return a.title.localeCompare(b.title);
return 0;
});
return sorted.filter(tl => tl.wayland !== null);
}
property var topLevelWorkspaces: {
return sortedTopLevels.map(toplevel => toplevel.workspace);
}
onSortedTopLevelsChanged: refreshSortedDesktopApplications()
Timer {
id: retryTimer
interval: 300
repeat: false
onTriggered: root.refreshSortedDesktopApplications()
}
function refreshSortedDesktopApplications() {
if (!Hyprland.toplevels)
return;
try {
sortedDesktopApplicationsModel.clear();
for (const topLevel of sortedTopLevels) {
const entry = DesktopEntries.heuristicLookup(topLevel.wayland.appId);
if (!entry) {
retryTimer.restart();
return;
}
sortedDesktopApplicationsModel.append({
topLevel: topLevel,
desktopEntry: entry
});
}
} catch (err) {
retryTimer.restart();
}
}
function workspaceApps(workspaceIndexAlign) {
const list = [];
for (let i = 0; i < sortedDesktopApplicationsModel.count; i++) {
const item = sortedDesktopApplicationsModel.get(i);
if (item.topLevel.workspace.id === workspaceIndexAlign)
list.push(item.desktopEntry);
}
return list;
}
// Hyprland socket listener
Socket {
path: `${Quickshell.env("XDG_RUNTIME_DIR")}/hypr/${root.hyprlandSignature}/.socket2.sock`
connected: true
parser: SplitParser {
property var fullscreenRegex: /fullscreen>>./
property var screencastRegex: /screencast>>.*/
onRead: msg => {
if (fullscreenRegex.test(msg)) {
root.hasFullscreen = msg.split(">>")[1] === "1";
}
if (screencastRegex.test(msg)) {
root.isScreencasting = msg.split(">>")[1].split(',')[0] === "1";
}
}
}
}
}