feat: window info panel
Also disable reload popup
This commit is contained in:
parent
97c0c387f1
commit
4a86b66d06
13 changed files with 477 additions and 51 deletions
|
|
@ -14,6 +14,7 @@ Singleton {
|
||||||
property alias notifs: adapter.notifs
|
property alias notifs: adapter.notifs
|
||||||
property alias osd: adapter.osd
|
property alias osd: adapter.osd
|
||||||
property alias session: adapter.session
|
property alias session: adapter.session
|
||||||
|
property alias winfo: adapter.winfo
|
||||||
property alias paths: adapter.paths
|
property alias paths: adapter.paths
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
|
|
@ -32,6 +33,7 @@ Singleton {
|
||||||
property JsonObject notifs: NotifsConfig {}
|
property JsonObject notifs: NotifsConfig {}
|
||||||
property JsonObject osd: OsdConfig {}
|
property JsonObject osd: OsdConfig {}
|
||||||
property JsonObject session: SessionConfig {}
|
property JsonObject session: SessionConfig {}
|
||||||
|
property JsonObject winfo: WInfoConfig {}
|
||||||
property JsonObject paths: UserPaths {}
|
property JsonObject paths: UserPaths {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
config/WInfoConfig.qml
Normal file
8
config/WInfoConfig.qml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
JsonObject {
|
||||||
|
property JsonObject sizes: JsonObject {
|
||||||
|
property real heightMult: 0.7
|
||||||
|
property real detailsWidth: 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ import QtQuick.Layouts
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
required property Item wrapper
|
||||||
|
|
||||||
implicitWidth: Hyprland.activeClient ? child.implicitWidth : -Appearance.padding.large * 2
|
implicitWidth: Hyprland.activeClient ? child.implicitWidth : -Appearance.padding.large * 2
|
||||||
implicitHeight: child.implicitHeight
|
implicitHeight: child.implicitHeight
|
||||||
|
|
||||||
|
|
@ -65,7 +67,7 @@ Item {
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
|
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
// TODO
|
root.wrapper.detach("winfo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,17 @@ ShapePath {
|
||||||
readonly property real roundingX: flatten ? wrapper.width / 2 : rounding
|
readonly property real roundingX: flatten ? wrapper.width / 2 : rounding
|
||||||
property real ibr: invertBottomRounding ? -1 : 1
|
property real ibr: invertBottomRounding ? -1 : 1
|
||||||
|
|
||||||
|
property real sideRounding: startX > 0 ? -1 : 1
|
||||||
|
|
||||||
strokeWidth: -1
|
strokeWidth: -1
|
||||||
fillColor: Config.border.colour
|
fillColor: Config.border.colour
|
||||||
|
|
||||||
PathArc {
|
PathArc {
|
||||||
relativeX: root.roundingX
|
relativeX: root.roundingX
|
||||||
relativeY: root.rounding
|
relativeY: root.rounding * root.sideRounding
|
||||||
radiusX: Math.min(root.rounding, root.wrapper.width)
|
radiusX: Math.min(root.rounding, root.wrapper.width)
|
||||||
radiusY: root.rounding
|
radiusY: root.rounding
|
||||||
direction: PathArc.Counterclockwise
|
direction: root.sideRounding < 0 ? PathArc.Clockwise : PathArc.Counterclockwise
|
||||||
}
|
}
|
||||||
PathLine {
|
PathLine {
|
||||||
relativeX: root.wrapper.width - root.roundingX * 2
|
relativeX: root.wrapper.width - root.roundingX * 2
|
||||||
|
|
@ -50,10 +52,10 @@ ShapePath {
|
||||||
}
|
}
|
||||||
PathArc {
|
PathArc {
|
||||||
relativeX: -root.roundingX
|
relativeX: -root.roundingX
|
||||||
relativeY: root.rounding
|
relativeY: root.rounding * root.sideRounding
|
||||||
radiusX: Math.min(root.rounding, root.wrapper.width)
|
radiusX: Math.min(root.rounding, root.wrapper.width)
|
||||||
radiusY: root.rounding
|
radiusY: root.rounding
|
||||||
direction: PathArc.Counterclockwise
|
direction: root.sideRounding < 0 ? PathArc.Clockwise : PathArc.Counterclockwise
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on fillColor {
|
Behavior on fillColor {
|
||||||
|
|
@ -71,4 +73,12 @@ ShapePath {
|
||||||
easing.bezierCurve: Appearance.anim.curves.standard
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on sideRounding {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,15 @@ import QtQuick
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
required property Item wrapper
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
|
required property string currentName
|
||||||
property string currentName
|
required property real currentCenter
|
||||||
property real currentCenter
|
required property bool hasCurrent
|
||||||
property bool hasCurrent
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
implicitWidth: hasCurrent ? (content.children.find(c => c.shouldBeActive)?.implicitWidth ?? 0) + Appearance.padding.large * 2 : 0
|
implicitWidth: (content.children.find(c => c.shouldBeActive)?.implicitWidth ?? 0) + Appearance.padding.large * 2
|
||||||
implicitHeight: (content.children.find(c => c.shouldBeActive)?.implicitHeight ?? 0) + Appearance.padding.large * 2
|
implicitHeight: (content.children.find(c => c.shouldBeActive)?.implicitHeight ?? 0) + Appearance.padding.large * 2
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -26,11 +26,11 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.large
|
anchors.margins: Appearance.padding.large
|
||||||
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Popout {
|
Popout {
|
||||||
name: "activewindow"
|
name: "activewindow"
|
||||||
source: "ActiveWindow.qml"
|
sourceComponent: ActiveWindow {
|
||||||
|
wrapper: root.wrapper
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Popout {
|
Popout {
|
||||||
|
|
@ -85,30 +85,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on implicitWidth {
|
|
||||||
Anim {
|
|
||||||
easing.bezierCurve: Appearance.anim.curves.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on implicitHeight {
|
|
||||||
enabled: root.implicitWidth > 0
|
|
||||||
|
|
||||||
Anim {
|
|
||||||
easing.bezierCurve: Appearance.anim.curves.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on currentCenter {
|
|
||||||
enabled: root.implicitWidth > 0
|
|
||||||
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Appearance.anim.durations.normal
|
|
||||||
easing.type: Easing.BezierSpline
|
|
||||||
easing.bezierCurve: Appearance.anim.curves.emphasized
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component Popout: Loader {
|
component Popout: Loader {
|
||||||
id: popout
|
id: popout
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import "root:/services"
|
import "root:/services"
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
|
import "root:/modules/windowinfo"
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -8,18 +13,168 @@ Item {
|
||||||
|
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
|
|
||||||
property alias currentName: content.currentName
|
readonly property real nonAnimWidth: x > 0 || hasCurrent ? children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth : 0
|
||||||
property alias currentCenter: content.currentCenter
|
readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight
|
||||||
property alias hasCurrent: content.hasCurrent
|
|
||||||
|
property string currentName
|
||||||
|
property real currentCenter
|
||||||
|
property bool hasCurrent
|
||||||
|
|
||||||
|
property string detachedMode
|
||||||
|
readonly property bool isDetached: detachedMode.length > 0
|
||||||
|
|
||||||
|
property int animLength: Appearance.anim.durations.normal
|
||||||
|
property list<real> animCurve: Appearance.anim.curves.emphasized
|
||||||
|
|
||||||
|
function detach(mode: string): void {
|
||||||
|
animLength = Appearance.anim.durations.large;
|
||||||
|
detachedMode = mode;
|
||||||
|
focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): void {
|
||||||
|
hasCurrent = false;
|
||||||
|
animCurve = Appearance.anim.curves.emphasizedAccel;
|
||||||
|
animLength = Appearance.anim.durations.normal;
|
||||||
|
detachedMode = "";
|
||||||
|
animCurve = Appearance.anim.curves.emphasized;
|
||||||
|
}
|
||||||
|
|
||||||
visible: width > 0 && height > 0
|
visible: width > 0 && height > 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth
|
implicitWidth: nonAnimWidth
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: nonAnimHeight
|
||||||
|
|
||||||
Content {
|
Keys.onEscapePressed: close()
|
||||||
|
|
||||||
|
HyprlandFocusGrab {
|
||||||
|
active: root.isDetached
|
||||||
|
windows: [QsWindow.window]
|
||||||
|
onCleared: root.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
when: root.isDetached
|
||||||
|
|
||||||
|
target: QsWindow.window
|
||||||
|
property: "WlrLayershell.keyboardFocus"
|
||||||
|
value: WlrKeyboardFocus.OnDemand
|
||||||
|
}
|
||||||
|
|
||||||
|
Comp {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
screen: root.screen
|
shouldBeActive: !root.detachedMode
|
||||||
|
asynchronous: true
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
sourceComponent: Content {
|
||||||
|
wrapper: root
|
||||||
|
screen: root.screen
|
||||||
|
currentName: root.currentName
|
||||||
|
currentCenter: root.currentCenter
|
||||||
|
hasCurrent: root.hasCurrent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Comp {
|
||||||
|
shouldBeActive: root.detachedMode === "winfo"
|
||||||
|
asynchronous: true
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
sourceComponent: WindowInfo {
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
Anim {
|
||||||
|
duration: root.animLength
|
||||||
|
easing.bezierCurve: root.animCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on y {
|
||||||
|
enabled: root.implicitWidth > 0
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: root.animLength
|
||||||
|
easing.bezierCurve: root.animCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
Anim {
|
||||||
|
duration: root.animLength
|
||||||
|
easing.bezierCurve: root.animCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
enabled: root.implicitWidth > 0
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
duration: root.animLength
|
||||||
|
easing.bezierCurve: root.animCurve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Comp: Loader {
|
||||||
|
id: comp
|
||||||
|
|
||||||
|
property bool shouldBeActive
|
||||||
|
|
||||||
|
asynchronous: true
|
||||||
|
active: false
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "active"
|
||||||
|
when: comp.shouldBeActive
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
comp.opacity: 1
|
||||||
|
comp.active: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
from: ""
|
||||||
|
to: "active"
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
PropertyAction {
|
||||||
|
property: "active"
|
||||||
|
}
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
from: "active"
|
||||||
|
to: ""
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
Anim {
|
||||||
|
property: "opacity"
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.standard
|
||||||
|
}
|
||||||
|
PropertyAction {
|
||||||
|
property: "active"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
component Anim: NumberAnimation {
|
||||||
|
duration: Appearance.anim.durations.normal
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
easing.bezierCurve: Appearance.anim.curves.emphasized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ Shape {
|
||||||
wrapper: panels.popouts
|
wrapper: panels.popouts
|
||||||
invertBottomRounding: wrapper.y + wrapper.height + 1 >= root.height
|
invertBottomRounding: wrapper.y + wrapper.height + 1 >= root.height
|
||||||
|
|
||||||
startX: 0
|
startX: wrapper.x
|
||||||
startY: wrapper.y - rounding
|
startY: wrapper.y - rounding * sideRounding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,13 @@ Item {
|
||||||
|
|
||||||
screen: root.screen
|
screen: root.screen
|
||||||
|
|
||||||
anchors.left: parent.left
|
x: isDetached ? (root.width - nonAnimWidth) / 2 : 0
|
||||||
anchors.verticalCenter: parent.top
|
y: {
|
||||||
anchors.verticalCenterOffset: {
|
if (isDetached)
|
||||||
const off = root.popouts.currentCenter - Config.border.thickness;
|
return (root.height - nonAnimHeight) / 2;
|
||||||
const diff = root.height - Math.floor(off + implicitHeight / 2);
|
|
||||||
|
const off = currentCenter - Config.border.thickness - nonAnimHeight / 2;
|
||||||
|
const diff = root.height - Math.floor(off + nonAnimHeight);
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
return off + diff;
|
return off + diff;
|
||||||
return off;
|
return off;
|
||||||
|
|
|
||||||
158
modules/windowinfo/Details.qml
Normal file
158
modules/windowinfo/Details.qml
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
import "root:/widgets"
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Appearance.spacing.small
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.topMargin: Appearance.padding.large * 2
|
||||||
|
|
||||||
|
text: Hyprland.activeClient.title
|
||||||
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
|
|
||||||
|
font.pointSize: Appearance.font.size.large
|
||||||
|
font.weight: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: Hyprland.activeClient.wmClass
|
||||||
|
color: Colours.palette.m3tertiary
|
||||||
|
|
||||||
|
font.pointSize: Appearance.font.size.larger
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.leftMargin: Appearance.padding.large * 2
|
||||||
|
Layout.rightMargin: Appearance.padding.large * 2
|
||||||
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
|
Layout.bottomMargin: Appearance.spacing.large
|
||||||
|
|
||||||
|
color: Colours.palette.m3secondary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "location_on"
|
||||||
|
text: qsTr("Address: %1").arg(Hyprland.activeClient.address)
|
||||||
|
color: Colours.palette.m3primary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "location_searching"
|
||||||
|
text: qsTr("Position: %1, %2").arg(Hyprland.activeClient.x).arg(Hyprland.activeClient.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "resize"
|
||||||
|
text: qsTr("Size: %1 x %2").arg(Hyprland.activeClient.width).arg(Hyprland.activeClient.height)
|
||||||
|
color: Colours.palette.m3tertiary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "workspaces"
|
||||||
|
text: qsTr("Workspace: %1 (%2)").arg(Hyprland.activeClient.workspace.name).arg(Hyprland.activeClient.workspace.id)
|
||||||
|
color: Colours.palette.m3secondary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "desktop_windows"
|
||||||
|
text: {
|
||||||
|
const mon = Hyprland.activeClient.monitor;
|
||||||
|
return qsTr("Monitor: %1 (%2) at %3, %4").arg(mon.name).arg(mon.id).arg(mon.x).arg(mon.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "page_header"
|
||||||
|
text: qsTr("Initial title: %1").arg(Hyprland.activeClient.initialTitle)
|
||||||
|
color: Colours.palette.m3tertiary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "category"
|
||||||
|
text: qsTr("Initial class: %1").arg(Hyprland.activeClient.initialClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "account_tree"
|
||||||
|
text: qsTr("Process id: %1").arg(Hyprland.activeClient.pid)
|
||||||
|
color: Colours.palette.m3primary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "picture_in_picture_center"
|
||||||
|
text: qsTr("Floating: %1").arg(Hyprland.activeClient.floating ? "yes" : "no")
|
||||||
|
color: Colours.palette.m3secondary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "gradient"
|
||||||
|
text: qsTr("Xwayland: %1").arg(Hyprland.activeClient.lastIpcObject.xwayland ? "yes" : "no")
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "keep"
|
||||||
|
text: qsTr("Pinned: %1").arg(Hyprland.activeClient.pinned ? "yes" : "no")
|
||||||
|
color: Colours.palette.m3secondary
|
||||||
|
}
|
||||||
|
|
||||||
|
Detail {
|
||||||
|
icon: "fullscreen"
|
||||||
|
text: {
|
||||||
|
const fs = Hyprland.activeClient.fullscreen;
|
||||||
|
return qsTr("Fullscreen state: %1").arg(fs == 0 ? "off" : fs == 1 ? "maximised" : "on");
|
||||||
|
}
|
||||||
|
color: Colours.palette.m3tertiary
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
|
component Detail: RowLayout {
|
||||||
|
id: detail
|
||||||
|
|
||||||
|
required property string icon
|
||||||
|
required property string text
|
||||||
|
property alias color: icon.color
|
||||||
|
|
||||||
|
Layout.leftMargin: Appearance.padding.large
|
||||||
|
Layout.rightMargin: Appearance.padding.large
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
text: detail.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
text: detail.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pointSize: Appearance.font.size.normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Label: StyledText {
|
||||||
|
Layout.leftMargin: Appearance.padding.large
|
||||||
|
Layout.rightMargin: Appearance.padding.large
|
||||||
|
Layout.fillWidth: true
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
animate: true
|
||||||
|
}
|
||||||
|
}
|
||||||
65
modules/windowinfo/Preview.qml
Normal file
65
modules/windowinfo/Preview.qml
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import "root:/widgets"
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
Layout.preferredWidth: preview.implicitWidth + Appearance.padding.large * 2
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
ClippingRectangle {
|
||||||
|
id: preview
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: label.top
|
||||||
|
anchors.topMargin: Appearance.padding.large
|
||||||
|
anchors.bottomMargin: Appearance.spacing.normal
|
||||||
|
|
||||||
|
implicitWidth: view.implicitWidth
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
radius: Appearance.rounding.small
|
||||||
|
|
||||||
|
ScreencopyView {
|
||||||
|
id: view
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
captureSource: Hyprland.activeClient ? ToplevelManager.activeToplevel : null
|
||||||
|
live: true
|
||||||
|
|
||||||
|
constraintSize.width: parent.height * Math.min(screen.width / screen.height, Hyprland.activeClient.width / Hyprland.activeClient.height)
|
||||||
|
constraintSize.height: parent.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: label
|
||||||
|
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: Appearance.padding.large
|
||||||
|
|
||||||
|
animate: true
|
||||||
|
text: {
|
||||||
|
const client = Hyprland.activeClient;
|
||||||
|
if (!client)
|
||||||
|
return qsTr("No active client");
|
||||||
|
|
||||||
|
const mon = Hyprland.monitors.values[Hyprland.activeClient.lastIpcObject.monitor];
|
||||||
|
return qsTr("%1 on monitor %2 at %3, %4").arg(client.title).arg(mon.name).arg(client.x).arg(client.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
modules/windowinfo/WindowInfo.qml
Normal file
45
modules/windowinfo/WindowInfo.qml
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import "root:/widgets"
|
||||||
|
import "root:/services"
|
||||||
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
implicitWidth: child.implicitWidth
|
||||||
|
implicitHeight: screen.height * Config.winfo.sizes.heightMult
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: child
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Appearance.padding.large
|
||||||
|
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
Preview {
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
Layout.preferredWidth: Config.winfo.sizes.detailsWidth
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
color: Colours.palette.m3surfaceContainer
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
|
||||||
|
Details {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -99,6 +99,7 @@ Singleton {
|
||||||
readonly property int width: lastIpcObject.size[0]
|
readonly property int width: lastIpcObject.size[0]
|
||||||
readonly property int height: lastIpcObject.size[1]
|
readonly property int height: lastIpcObject.size[1]
|
||||||
readonly property HyprlandWorkspace workspace: Hyprland.workspaces.values.find(w => w.id === lastIpcObject.workspace.id) ?? null
|
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 floating: lastIpcObject.floating
|
||||||
readonly property bool fullscreen: lastIpcObject.fullscreen
|
readonly property bool fullscreen: lastIpcObject.fullscreen
|
||||||
readonly property int pid: lastIpcObject.pid
|
readonly property int pid: lastIpcObject.pid
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
//@ pragma Env QS_NO_RELOAD_POPUP=1
|
||||||
|
|
||||||
import "modules"
|
import "modules"
|
||||||
import "modules/drawers"
|
import "modules/drawers"
|
||||||
import "modules/background"
|
import "modules/background"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue