internal: use hyprlandtoplevel
This commit is contained in:
parent
8308060a75
commit
b264ae9888
9 changed files with 53 additions and 130 deletions
|
|
@ -36,7 +36,7 @@ MouseArea {
|
|||
property real sw: Math.abs(sx - ex)
|
||||
property real sh: Math.abs(sy - ey)
|
||||
|
||||
property list<var> clients: Hyprland.clients.filter(c => c.workspace.id === Hyprland.activeWsId)
|
||||
property list<var> clients: Hyprland.toplevels.values.filter(c => c.workspace.id === Hyprland.activeWsId)
|
||||
|
||||
function checkClientRects(x: real, y: real): void {
|
||||
for (const c of clients) {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ Item {
|
|||
anchors.rightMargin: -Config.border.thickness
|
||||
|
||||
onWheel: event => {
|
||||
const activeWs = Hyprland.activeClient?.workspace?.name;
|
||||
const activeWs = Hyprland.activeToplevel?.workspace?.name;
|
||||
if (activeWs?.startsWith("special:"))
|
||||
Hyprland.dispatch(`togglespecialworkspace ${activeWs.slice(8)}`);
|
||||
else if (event.angleDelta.y < 0 || Hyprland.activeWsId > 1)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Item {
|
|||
id: icon
|
||||
|
||||
animate: true
|
||||
text: Icons.getAppCategoryIcon(Hyprland.activeClient?.wmClass, "desktop_windows")
|
||||
text: Icons.getAppCategoryIcon(Hyprland.activeToplevel?.lastIpcObject.class, "desktop_windows")
|
||||
color: root.colour
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
|
@ -77,7 +77,7 @@ Item {
|
|||
TextMetrics {
|
||||
id: metrics
|
||||
|
||||
text: Hyprland.activeClient?.title ?? qsTr("Desktop")
|
||||
text: Hyprland.activeToplevel?.title ?? qsTr("Desktop")
|
||||
font.pointSize: Appearance.font.size.smaller
|
||||
font.family: Appearance.font.family.mono
|
||||
elide: Qt.ElideRight
|
||||
|
|
|
|||
|
|
@ -76,14 +76,14 @@ Item {
|
|||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: Hyprland.clients.filter(c => c.workspace?.id === root.ws)
|
||||
values: Hyprland.toplevels.values.filter(c => c.workspace?.id === root.ws)
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
required property Hyprland.Client modelData
|
||||
required property var modelData
|
||||
|
||||
grade: 0
|
||||
text: Icons.getAppCategoryIcon(modelData.wmClass, "terminal")
|
||||
text: Icons.getAppCategoryIcon(modelData.lastIpcObject.class, "terminal")
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Item {
|
|||
|
||||
required property Item wrapper
|
||||
|
||||
implicitWidth: Hyprland.activeClient ? child.implicitWidth : -Appearance.padding.large * 2
|
||||
implicitWidth: Hyprland.activeToplevel ? child.implicitWidth : -Appearance.padding.large * 2
|
||||
implicitHeight: child.implicitHeight
|
||||
|
||||
Column {
|
||||
|
|
@ -33,7 +33,7 @@ Item {
|
|||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
implicitSize: details.implicitHeight
|
||||
source: Icons.getAppIcon(Hyprland.activeClient?.wmClass ?? "", "image-missing")
|
||||
source: Icons.getAppIcon(Hyprland.activeToplevel?.lastIpcObject.class ?? "", "image-missing")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -44,14 +44,14 @@ Item {
|
|||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: Hyprland.activeClient?.title ?? ""
|
||||
text: Hyprland.activeToplevel?.title ?? ""
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: Hyprland.activeClient?.wmClass ?? ""
|
||||
text: Hyprland.activeToplevel?.lastIpcObject.class ?? ""
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ Item {
|
|||
ScreencopyView {
|
||||
id: preview
|
||||
|
||||
captureSource: Hyprland.activeClient ? ToplevelManager.activeToplevel : null
|
||||
captureSource: Hyprland.activeToplevel?.wayland ?? null
|
||||
live: visible
|
||||
|
||||
constraintSize.width: Config.bar.sizes.windowPreviewSize
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ ColumnLayout {
|
|||
Button {
|
||||
required property int index
|
||||
readonly property int wsId: Math.floor((Hyprland.activeWsId - 1) / 10) * 10 + index + 1
|
||||
readonly property bool isCurrent: Hyprland.activeClient.workspace.id === wsId
|
||||
readonly property bool isCurrent: Hyprland.activeToplevel?.workspace.id === wsId
|
||||
|
||||
color: isCurrent ? Colours.palette.m3surfaceContainerHighest : Colours.palette.m3tertiaryContainer
|
||||
onColor: isCurrent ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
|
||||
|
|
@ -86,7 +86,7 @@ ColumnLayout {
|
|||
disabled: isCurrent
|
||||
|
||||
function onClicked(): void {
|
||||
Hyprland.dispatch(`movetoworkspace ${wsId},address:${Hyprland.activeClient?.address}`);
|
||||
Hyprland.dispatch(`movetoworkspace ${wsId},address:0x${Hyprland.activeToplevel?.address}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -107,20 +107,20 @@ ColumnLayout {
|
|||
Layout.rightMargin: Appearance.padding.large
|
||||
Layout.bottomMargin: Appearance.padding.large
|
||||
|
||||
spacing: Hyprland.activeClient?.floating ? Appearance.spacing.normal : Appearance.spacing.small
|
||||
spacing: Hyprland.activeToplevel?.lastIpcObject.floating ? Appearance.spacing.normal : Appearance.spacing.small
|
||||
|
||||
Button {
|
||||
color: Colours.palette.m3secondaryContainer
|
||||
onColor: Colours.palette.m3onSecondaryContainer
|
||||
text: Hyprland.activeClient?.floating ? qsTr("Tile") : qsTr("Float")
|
||||
text: Hyprland.activeToplevel?.lastIpcObject.floating ? qsTr("Tile") : qsTr("Float")
|
||||
|
||||
function onClicked(): void {
|
||||
Hyprland.dispatch(`togglefloating address:${Hyprland.activeClient?.address}`);
|
||||
Hyprland.dispatch(`togglefloating address:0x${Hyprland.activeToplevel?.address}`);
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: Hyprland.activeClient?.floating
|
||||
active: Hyprland.activeToplevel?.lastIpcObject.floating
|
||||
asynchronous: true
|
||||
Layout.fillWidth: active
|
||||
Layout.leftMargin: active ? 0 : -parent.spacing
|
||||
|
|
@ -129,10 +129,10 @@ ColumnLayout {
|
|||
sourceComponent: Button {
|
||||
color: Colours.palette.m3secondaryContainer
|
||||
onColor: Colours.palette.m3onSecondaryContainer
|
||||
text: Hyprland.activeClient?.lastIpcObject.pinned ? qsTr("Unpin") : qsTr("Pin")
|
||||
text: Hyprland.activeToplevel?.lastIpcObject.pinned ? qsTr("Unpin") : qsTr("Pin")
|
||||
|
||||
function onClicked(): void {
|
||||
Hyprland.dispatch(`pin address:${Hyprland.activeClient?.address}`);
|
||||
Hyprland.dispatch(`pin address:0x${Hyprland.activeToplevel?.address}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ ColumnLayout {
|
|||
text: qsTr("Kill")
|
||||
|
||||
function onClicked(): void {
|
||||
Hyprland.dispatch(`movetoworkspace ${wsId},address:${Hyprland.activeClient?.address}`);
|
||||
Hyprland.dispatch(`movetoworkspace ${wsId},address:0x${Hyprland.activeToplevel?.address}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ ColumnLayout {
|
|||
Label {
|
||||
Layout.topMargin: Appearance.padding.large * 2
|
||||
|
||||
text: Hyprland.activeClient?.title ?? qsTr("No active client")
|
||||
text: Hyprland.activeToplevel?.title ?? qsTr("No active client")
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
|
||||
font.pointSize: Appearance.font.size.large
|
||||
|
|
@ -22,7 +22,7 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
Label {
|
||||
text: Hyprland.activeClient?.wmClass ?? qsTr("No active client")
|
||||
text: Hyprland.activeToplevel?.lastIpcObject.class ?? qsTr("No active client")
|
||||
color: Colours.palette.m3tertiary
|
||||
|
||||
font.pointSize: Appearance.font.size.larger
|
||||
|
|
@ -41,31 +41,31 @@ ColumnLayout {
|
|||
|
||||
Detail {
|
||||
icon: "location_on"
|
||||
text: qsTr("Address: %1").arg(Hyprland.activeClient?.address ?? "unknown")
|
||||
text: qsTr("Address: %1").arg(`0x${Hyprland.activeToplevel?.address}` ?? "unknown")
|
||||
color: Colours.palette.m3primary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "location_searching"
|
||||
text: qsTr("Position: %1, %2").arg(Hyprland.activeClient?.x ?? -1).arg(Hyprland.activeClient?.y ?? -1)
|
||||
text: qsTr("Position: %1, %2").arg(Hyprland.activeToplevel?.lastIpcObject.at[0] ?? -1).arg(Hyprland.activeToplevel?.lastIpcObject.at[1] ?? -1)
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "resize"
|
||||
text: qsTr("Size: %1 x %2").arg(Hyprland.activeClient?.width ?? -1).arg(Hyprland.activeClient?.height ?? -1)
|
||||
text: qsTr("Size: %1 x %2").arg(Hyprland.activeToplevel?.lastIpcObject.size[0] ?? -1).arg(Hyprland.activeToplevel?.lastIpcObject.size[1] ?? -1)
|
||||
color: Colours.palette.m3tertiary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "workspaces"
|
||||
text: qsTr("Workspace: %1 (%2)").arg(Hyprland.activeClient?.workspace.name ?? -1).arg(Hyprland.activeClient?.workspace.id ?? -1)
|
||||
text: qsTr("Workspace: %1 (%2)").arg(Hyprland.activeToplevel?.workspace.name ?? -1).arg(Hyprland.activeToplevel?.workspace.id ?? -1)
|
||||
color: Colours.palette.m3secondary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "desktop_windows"
|
||||
text: {
|
||||
const mon = Hyprland.activeClient?.monitor;
|
||||
const mon = Hyprland.activeToplevel?.monitor;
|
||||
if (mon)
|
||||
return qsTr("Monitor: %1 (%2) at %3, %4").arg(mon.name).arg(mon.id).arg(mon.x).arg(mon.y);
|
||||
return qsTr("Monitor: unknown");
|
||||
|
|
@ -74,42 +74,42 @@ ColumnLayout {
|
|||
|
||||
Detail {
|
||||
icon: "page_header"
|
||||
text: qsTr("Initial title: %1").arg(Hyprland.activeClient?.initialTitle ?? "unknown")
|
||||
text: qsTr("Initial title: %1").arg(Hyprland.activeToplevel?.lastIpcObject.initialTitle ?? "unknown")
|
||||
color: Colours.palette.m3tertiary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "category"
|
||||
text: qsTr("Initial class: %1").arg(Hyprland.activeClient?.initialClass ?? "unknown")
|
||||
text: qsTr("Initial class: %1").arg(Hyprland.activeToplevel?.lastIpcObject.initialClass ?? "unknown")
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "account_tree"
|
||||
text: qsTr("Process id: %1").arg(Hyprland.activeClient?.pid ?? -1)
|
||||
text: qsTr("Process id: %1").arg(Hyprland.activeToplevel?.lastIpcObject.pid ?? -1)
|
||||
color: Colours.palette.m3primary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "picture_in_picture_center"
|
||||
text: qsTr("Floating: %1").arg(Hyprland.activeClient?.floating ? "yes" : "no")
|
||||
text: qsTr("Floating: %1").arg(Hyprland.activeToplevel?.lastIpcObject.floating ? "yes" : "no")
|
||||
color: Colours.palette.m3secondary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "gradient"
|
||||
text: qsTr("Xwayland: %1").arg(Hyprland.activeClient?.lastIpcObject.xwayland ? "yes" : "no")
|
||||
text: qsTr("Xwayland: %1").arg(Hyprland.activeToplevel?.lastIpcObject.xwayland ? "yes" : "no")
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "keep"
|
||||
text: qsTr("Pinned: %1").arg(Hyprland.activeClient?.lastIpcObject.pinned ? "yes" : "no")
|
||||
text: qsTr("Pinned: %1").arg(Hyprland.activeToplevel?.lastIpcObject.pinned ? "yes" : "no")
|
||||
color: Colours.palette.m3secondary
|
||||
}
|
||||
|
||||
Detail {
|
||||
icon: "fullscreen"
|
||||
text: {
|
||||
const fs = Hyprland.activeClient?.fullscreen;
|
||||
const fs = Hyprland.activeToplevel?.lastIpcObject.fullscreen;
|
||||
if (fs)
|
||||
return qsTr("Fullscreen state: %1").arg(fs == 0 ? "off" : fs == 1 ? "maximised" : "on");
|
||||
return qsTr("Fullscreen state: unknown");
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Item {
|
|||
|
||||
Loader {
|
||||
anchors.centerIn: parent
|
||||
active: !Hyprland.activeClient
|
||||
active: !Hyprland.activeToplevel
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: ColumnLayout {
|
||||
|
|
@ -69,10 +69,10 @@ Item {
|
|||
|
||||
anchors.centerIn: parent
|
||||
|
||||
captureSource: Hyprland.activeClient ? ToplevelManager.activeToplevel : null
|
||||
captureSource: Hyprland.activeToplevel?.wayland ?? null
|
||||
live: true
|
||||
|
||||
constraintSize.width: parent.height * Math.min(screen.width / screen.height, Hyprland.activeClient.width / Hyprland.activeClient.height)
|
||||
constraintSize.width: parent.height * Math.min(root.screen.width / root.screen.height, Hyprland.activeToplevel?.lastIpcObject.size[0] / Hyprland.activeToplevel?.lastIpcObject.size[1])
|
||||
constraintSize.height: parent.height
|
||||
}
|
||||
}
|
||||
|
|
@ -86,11 +86,11 @@ Item {
|
|||
|
||||
animate: true
|
||||
text: {
|
||||
const client = Hyprland.activeClient;
|
||||
const client = Hyprland.activeToplevel;
|
||||
if (!client)
|
||||
return qsTr("No active client");
|
||||
|
||||
const mon = Hyprland.monitors.values[Hyprland.activeClient.lastIpcObject.monitor];
|
||||
const mon = client.monitor;
|
||||
return qsTr("%1 on monitor %2 at %3, %4").arg(client.title).arg(mon.name).arg(client.x).arg(client.y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,114 +1,37 @@
|
|||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property list<Client> clients: []
|
||||
readonly property var toplevels: Hyprland.toplevels
|
||||
readonly property var workspaces: Hyprland.workspaces
|
||||
readonly property var monitors: Hyprland.monitors
|
||||
property Client activeClient: null
|
||||
readonly property HyprlandWorkspace activeWorkspace: focusedMonitor?.activeWorkspace ?? null
|
||||
readonly property HyprlandToplevel activeToplevel: Hyprland.activeToplevel
|
||||
readonly property HyprlandWorkspace focusedWorkspace: Hyprland.focusedWorkspace
|
||||
readonly property HyprlandMonitor focusedMonitor: Hyprland.focusedMonitor
|
||||
readonly property int activeWsId: activeWorkspace?.id ?? 1
|
||||
property point cursorPos
|
||||
|
||||
function reload() {
|
||||
Hyprland.refreshWorkspaces();
|
||||
Hyprland.refreshMonitors();
|
||||
getClients.running = true;
|
||||
getActiveClient.running = true;
|
||||
}
|
||||
readonly property int activeWsId: focusedWorkspace?.id ?? 1
|
||||
|
||||
function dispatch(request: string): void {
|
||||
Hyprland.dispatch(request);
|
||||
}
|
||||
|
||||
Component.onCompleted: reload()
|
||||
|
||||
Connections {
|
||||
target: Hyprland
|
||||
|
||||
function onRawEvent(event: HyprlandEvent): void {
|
||||
if (!event.name.endsWith("v2"))
|
||||
root.reload();
|
||||
if (event.name.endsWith("v2"))
|
||||
return;
|
||||
|
||||
if (event.name.includes("mon"))
|
||||
Hyprland.refreshMonitors();
|
||||
else if (event.name.includes("workspace"))
|
||||
Hyprland.refreshWorkspaces();
|
||||
else
|
||||
Hyprland.refreshToplevels();
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: getClients
|
||||
command: ["hyprctl", "-j", "clients"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const clients = JSON.parse(text);
|
||||
const rClients = root.clients;
|
||||
|
||||
const destroyed = rClients.filter(rc => !clients.find(c => c.address === rc.address));
|
||||
for (const client of destroyed)
|
||||
rClients.splice(rClients.indexOf(client), 1).forEach(c => c.destroy());
|
||||
|
||||
for (const client of clients) {
|
||||
const match = rClients.find(c => c.address === client.address);
|
||||
if (match) {
|
||||
match.lastIpcObject = client;
|
||||
} else {
|
||||
rClients.push(clientComp.createObject(root, {
|
||||
lastIpcObject: client
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: getActiveClient
|
||||
command: ["hyprctl", "-j", "activewindow"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const client = JSON.parse(text);
|
||||
const rClient = root.activeClient;
|
||||
if (client.address) {
|
||||
if (rClient)
|
||||
rClient.lastIpcObject = client;
|
||||
else
|
||||
root.activeClient = clientComp.createObject(root, {
|
||||
lastIpcObject: client
|
||||
});
|
||||
} else if (rClient) {
|
||||
rClient.destroy();
|
||||
root.activeClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component Client: QtObject {
|
||||
required property var lastIpcObject
|
||||
readonly property string address: lastIpcObject.address
|
||||
readonly property string wmClass: lastIpcObject.class
|
||||
readonly property string title: lastIpcObject.title
|
||||
readonly property string initialClass: lastIpcObject.initialClass
|
||||
readonly property string initialTitle: lastIpcObject.initialTitle
|
||||
readonly property int x: lastIpcObject.at[0]
|
||||
readonly property int y: lastIpcObject.at[1]
|
||||
readonly property int width: lastIpcObject.size[0]
|
||||
readonly property int height: lastIpcObject.size[1]
|
||||
readonly property HyprlandWorkspace workspace: Hyprland.workspaces.values.find(w => w.id === lastIpcObject.workspace.id) ?? null
|
||||
readonly property HyprlandMonitor monitor: Hyprland.monitors.values.find(m => m.id === lastIpcObject.monitor) ?? null
|
||||
readonly property bool floating: lastIpcObject.floating
|
||||
readonly property bool fullscreen: lastIpcObject.fullscreen
|
||||
readonly property int pid: lastIpcObject.pid
|
||||
readonly property int focusHistoryId: lastIpcObject.focusHistoryID
|
||||
}
|
||||
|
||||
Component {
|
||||
id: clientComp
|
||||
|
||||
Client {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue