Files
Quickbar/Services/HyprlandService.qml

155 lines
4.9 KiB
QML

pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Wayland
import Quickshell.Io
import qs.Common
Singleton {
id: root
readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")
readonly property var focusedMon: Hyprland.focusedMonitor
property var hasFullscreen: false
property var isScreencasting: false
property var sortedTopLevels: {
if (!ToplevelManager.toplevels || !ToplevelManager.toplevels.values) {
return [];
}
const topLevels = Array.from(Hyprland.toplevels.values);
const sortedHyprland = 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 && b.lastIpcObject && a.lastIpcObject.at && b.lastIpcObject.at) {
const aX = a.lastIpcObject.at[0];
const bX = b.lastIpcObject.at[0];
const aY = a.lastIpcObject.at[1];
const bY = b.lastIpcObject.at[1];
const xCompare = aX - bX;
if (Math.abs(xCompare) > 10) {
return xCompare;
}
return aY - bY;
}
if (a.lastIpcObject && !b.lastIpcObject) {
return -1;
}
if (!a.lastIpcObject && b.lastIpcObject) {
return 1;
}
if (a.title && b.title) {
return a.title.localeCompare(b.title);
}
return 0;
});
return sortedHyprland.filter(tl => tl.wayland !== null);
}
property var topLevelWorkspaces: {
return sortedTopLevels.map(topLevel => topLevel.workspace);
}
property ListModel sortedDesktopApplicationsModel: ListModel {}
onSortedTopLevelsChanged: updateSortedDesktopApplications()
function updateSortedDesktopApplications() {
sortedDesktopApplicationsModel.clear();
for (const topLevel of sortedTopLevels) {
const entry = DesktopEntries.heuristicLookup(topLevel.wayland.appId);
sortedDesktopApplicationsModel.append({
topLevel: topLevel,
desktopEntry: entry
});
}
}
function workspaceApps(workspaceIndexAlign) {
const list = []
const model = sortedDesktopApplicationsModel
for (let i = 0; i < model.count; i++) {
const item = model.get(i)
if (item.topLevel.workspace.id === workspaceIndexAlign)
list.push(item.desktopEntry)
}
return list
}
property var sortedDesktopApplications: {
const sortedWayland = sortedTopLevels.map(topLevel => topLevel.wayland).filter(wayland => wayland !== null);
const desktopEntries = sortedWayland.map(topLevel => {
return DesktopEntries.heuristicLookup(topLevel.appId);
});
const workspace = sortedTopLevels.map(topLevel => {
return topLevel.workspace.id;
});
const workspaceDesktopEntries = new Map();
for (let i = 0; i < workspace.length; i++) {
const key = workspace[i];
const value = desktopEntries[i];
if (workspaceDesktopEntries.has(key)) {
workspaceDesktopEntries.get(key).push(value);
} else {
workspaceDesktopEntries.set(key, [value]);
}
}
return workspaceDesktopEntries;
}
Socket {
path: `${Quickshell.env("XDG_RUNTIME_DIR")}/hypr/${Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")}/.socket2.sock`
connected: true
parser: SplitParser {
property var fullscreenRegex: new RegExp("fullscreen>>.")
property var screencastRegex: new RegExp("screencast>>.*")
onRead: msg => {
let match = fullscreenRegex.exec(msg);
if (match != null) {
if (msg.split(">>")[1] === "1") {
root.hasFullscreen = true;
} else {
root.hasFullscreen = false;
}
}
match = screencastRegex.exec(msg);
if (match != null) {
if (msg.split(">>")[1].split(',')[0] === "1") {
root.isScreencasting = true;
} else {
root.isScreencasting = false;
}
}
}
}
}
}