forked from Shinonome/dots-hyprland
overview
This commit is contained in:
@@ -5,4 +5,5 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
property int sidebarRightOpenCount: 0
|
property int sidebarRightOpenCount: 0
|
||||||
|
property bool overviewOpen: false
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,10 @@ Scope {
|
|||||||
id: hideOsdVolume
|
id: hideOsdVolume
|
||||||
command: ["qs", "ipc", "call", "osdVolume", "hide"]
|
command: ["qs", "ipc", "call", "osdVolume", "hide"]
|
||||||
}
|
}
|
||||||
|
Process {
|
||||||
|
id: toggleOverview
|
||||||
|
command: ["qs", "ipc", "call", "overview", "toggle"]
|
||||||
|
}
|
||||||
|
|
||||||
Variants { // For each monitor
|
Variants { // For each monitor
|
||||||
model: Quickshell.screens
|
model: Quickshell.screens
|
||||||
@@ -220,6 +224,19 @@ Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea { // Middle: right-click to toggle overview
|
||||||
|
id: barMiddleMouseArea
|
||||||
|
anchors.fill: middleSection
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
|
||||||
|
onPressed: (event) => {
|
||||||
|
if (event.button === Qt.RightButton) {
|
||||||
|
toggleOverview.running = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea { // Right side: scroll to change volume
|
MouseArea { // Right side: scroll to change volume
|
||||||
id: barRightSideMouseArea
|
id: barRightSideMouseArea
|
||||||
property bool hovered: false
|
property bool hovered: false
|
||||||
@@ -250,7 +267,7 @@ Scope {
|
|||||||
if (event.angleDelta.y < 0)
|
if (event.angleDelta.y < 0)
|
||||||
Audio.sink.audio.volume -= step;
|
Audio.sink.audio.volume -= step;
|
||||||
else if (event.angleDelta.y > 0)
|
else if (event.angleDelta.y > 0)
|
||||||
Audio.sink.audio.volume += step;
|
Audio.sink.audio.volume = Math.min(1, Audio.sink.audio.volume + step);
|
||||||
// Store the mouse position and start tracking
|
// Store the mouse position and start tracking
|
||||||
barRightSideMouseArea.lastScrollX = event.x;
|
barRightSideMouseArea.lastScrollX = event.x;
|
||||||
barRightSideMouseArea.lastScrollY = event.y;
|
barRightSideMouseArea.lastScrollY = event.y;
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ Singleton {
|
|||||||
property int large: 25
|
property int large: 25
|
||||||
property int full: 9999
|
property int full: 9999
|
||||||
property int screenRounding: large
|
property int screenRounding: large
|
||||||
|
property int windowRounding: 20
|
||||||
}
|
}
|
||||||
|
|
||||||
font: QtObject {
|
font: QtObject {
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ Singleton {
|
|||||||
property int timeout: 1000
|
property int timeout: 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property QtObject overview: QtObject {
|
||||||
|
property real scale: 0.18 // Relative to screen size
|
||||||
|
property real numOfRows: 2
|
||||||
|
property real numOfCols: 5
|
||||||
|
}
|
||||||
|
|
||||||
property QtObject resources: QtObject {
|
property QtObject resources: QtObject {
|
||||||
property int updateInterval: 3000
|
property int updateInterval: 3000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ Item {
|
|||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
copyNotificationBody.running = true
|
copyNotificationBody.running = true
|
||||||
notificationSummaryText.text = `${notificationObject.summary} (copied)`
|
notificationSummaryText.text = `${notificationObject.summary} (copied)`
|
||||||
console.log(notificationSummaryText.text)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onDragStartedChanged: () => {
|
onDragStartedChanged: () => {
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import "root:/"
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: overview
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
property var modelData
|
||||||
|
screen: modelData
|
||||||
|
visible: GlobalStates.overviewOpen
|
||||||
|
|
||||||
|
WlrLayershell.namespace: "quickshell:overview"
|
||||||
|
WlrLayershell.layer: WlrLayer.Overlay
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
mask: Region {
|
||||||
|
item: columnLayout
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
HyprlandFocusGrab {
|
||||||
|
id: grab
|
||||||
|
windows: [ root ]
|
||||||
|
active: false
|
||||||
|
onCleared: () => {
|
||||||
|
if (!active) GlobalStates.overviewOpen = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onVisibleChanged() {
|
||||||
|
delayedGrabTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: delayedGrabTimer
|
||||||
|
interval: ConfigOptions.hacks.arbitraryRaceConditionDelay
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
grab.active = root.visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width: columnLayout.width
|
||||||
|
height: columnLayout.height
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
Keys.onPressed: (event) => {
|
||||||
|
if (event.key === Qt.Key_Escape) {
|
||||||
|
sessionRoot.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
height: 1 // Prevent Wayland protocol error
|
||||||
|
width: 1 // Prevent Wayland protocol error
|
||||||
|
}
|
||||||
|
|
||||||
|
OverviewWidget {
|
||||||
|
bar: root
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "overview"
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
GlobalStates.overviewOpen = !GlobalStates.overviewOpen
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
GlobalStates.overviewOpen = false
|
||||||
|
}
|
||||||
|
function open() {
|
||||||
|
GlobalStates.overviewOpen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import "root:/services/"
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import "./icons.js" as Icons
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
required property var bar
|
||||||
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
|
||||||
|
readonly property var toplevels: ToplevelManager.toplevels
|
||||||
|
readonly property int workspacesShown: ConfigOptions.overview.numOfRows * ConfigOptions.overview.numOfCols
|
||||||
|
readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / workspacesShown)
|
||||||
|
property var windows: HyprlandData.windowList
|
||||||
|
property var windowByAddress: HyprlandData.windowByAddress
|
||||||
|
property var windowAddresses: HyprlandData.addresses
|
||||||
|
property var monitorData: HyprlandData.monitors.find(m => m.id === root.monitor.id)
|
||||||
|
property real scale: ConfigOptions.overview.scale
|
||||||
|
|
||||||
|
property real workspaceNumberMargin: 80
|
||||||
|
property real workspaceNumberSize: 80
|
||||||
|
|
||||||
|
implicitWidth: overviewBackground.implicitWidth + Appearance.sizes.elevationMargin * 2
|
||||||
|
implicitHeight: overviewBackground.implicitHeight + Appearance.sizes.elevationMargin * 2
|
||||||
|
|
||||||
|
property Component windowComponent: OverviewWindow {}
|
||||||
|
property list<OverviewWindow> windowWidgets: []
|
||||||
|
|
||||||
|
// onWindowsChanged: {
|
||||||
|
// console.log("Windows changed")
|
||||||
|
// }
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: overviewBackground
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
implicitWidth: columnLayout.implicitWidth + 5 * 2
|
||||||
|
implicitHeight: columnLayout.implicitHeight + 5 * 2
|
||||||
|
color: Appearance.colors.colLayer0
|
||||||
|
radius: Appearance.rounding.screenRounding * root.scale + 5 * 2
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: columnLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: ConfigOptions.overview.numOfRows
|
||||||
|
delegate: RowLayout {
|
||||||
|
id: row
|
||||||
|
property int rowIndex: index
|
||||||
|
|
||||||
|
Repeater { // Workspace repeater
|
||||||
|
model: ConfigOptions.overview.numOfCols
|
||||||
|
Rectangle { // Workspace
|
||||||
|
id: workspace
|
||||||
|
property int colIndex: index
|
||||||
|
property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * ConfigOptions.overview.numOfCols + colIndex + 1
|
||||||
|
|
||||||
|
implicitWidth: (monitor.width - monitorData?.reserved[0] - monitorData?.reserved[2]) * root.scale
|
||||||
|
implicitHeight: (monitor.height - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale
|
||||||
|
color: Appearance.colors.colLayer1 // TODO: reconsider this color for a cleaner look
|
||||||
|
radius: Appearance.rounding.screenRounding * root.scale
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
z: 9999
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.leftMargin: root.workspaceNumberMargin * root.scale
|
||||||
|
anchors.topMargin: root.workspaceNumberMargin * root.scale
|
||||||
|
font.pixelSize: root.workspaceNumberSize * root.scale
|
||||||
|
color: Appearance.colors.colSubtext
|
||||||
|
text: workspaceValue
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater { // Window repeater
|
||||||
|
model: ScriptModel {
|
||||||
|
values: windowAddresses.filter((address) => {
|
||||||
|
var win = windowByAddress[address]
|
||||||
|
return (win?.workspace?.id === workspace.workspaceValue)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
delegate: OverviewWindow {
|
||||||
|
windowData: windowByAddress[modelData]
|
||||||
|
monitorData: root.monitorData
|
||||||
|
scale: root.scale
|
||||||
|
availableWorkspaceWidth: workspace.implicitWidth
|
||||||
|
availableWorkspaceHeight: workspace.implicitHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DropShadow {
|
||||||
|
anchors.fill: overviewBackground
|
||||||
|
horizontalOffset: 0
|
||||||
|
verticalOffset: 2
|
||||||
|
radius: Appearance.sizes.elevationMargin
|
||||||
|
samples: radius * 2 + 1 // Ideally should be 2 * radius + 1, see qt docs
|
||||||
|
color: Appearance.colors.colShadow
|
||||||
|
source: overviewBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import "root:/services/"
|
||||||
|
import "root:/modules/common"
|
||||||
|
import "root:/modules/common/widgets"
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
import "./icons.js" as Icons
|
||||||
|
|
||||||
|
Rectangle { // Window
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var windowData
|
||||||
|
property var monitorData
|
||||||
|
property var scale
|
||||||
|
property var availableWorkspaceWidth
|
||||||
|
property var availableWorkspaceHeight
|
||||||
|
|
||||||
|
property var iconToWindowRatio: 0.35
|
||||||
|
property var iconToWindowRatioCompact: 0.6
|
||||||
|
property var iconPath: Quickshell.iconPath(Icons.noKnowledgeIconGuess(windowData?.class))
|
||||||
|
property bool compactMode: Appearance.font.pixelSize.smaller * 4 > root.height || Appearance.font.pixelSize.smaller * 4 > root.width
|
||||||
|
|
||||||
|
z: 1
|
||||||
|
x: Math.max((windowData?.at[0] - monitorData?.reserved[0]) * root.scale, 0)
|
||||||
|
y: Math.max((windowData?.at[1] - monitorData?.reserved[1]) * root.scale, 0)
|
||||||
|
width: Math.min(windowData?.size[0] * root.scale, availableWorkspaceWidth - x)
|
||||||
|
height: Math.min(windowData?.size[1] * root.scale, availableWorkspaceHeight - y)
|
||||||
|
|
||||||
|
radius: Appearance.rounding.windowRounding * root.scale
|
||||||
|
color: Appearance.colors.colLayer2
|
||||||
|
border.color : Appearance.transparentize(Appearance.m3colors.m3outline, 0.9)
|
||||||
|
border.pixelAligned : false
|
||||||
|
border.width : 1
|
||||||
|
|
||||||
|
Behavior on x {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.animation.elementDecel.duration
|
||||||
|
easing.type: Appearance.animation.elementDecel.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on y {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.animation.elementDecel.duration
|
||||||
|
easing.type: Appearance.animation.elementDecel.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.animation.elementDecel.duration
|
||||||
|
easing.type: Appearance.animation.elementDecel.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Appearance.animation.elementDecel.duration
|
||||||
|
easing.type: Appearance.animation.elementDecel.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: closeOverview
|
||||||
|
command: ["bash", "-c", "qs ipc call overview close &"] // Somehow has to by async to work?
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (windowData) {
|
||||||
|
closeOverview.running = true
|
||||||
|
Hyprland.dispatch(`focuswindow address:${windowData.address}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: Appearance.font.pixelSize.smaller * 0.5
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
id: windowIcon
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
source: root.iconPath
|
||||||
|
width: root.width * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio)
|
||||||
|
height: root.height * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio)
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
Layout.rightMargin: 10
|
||||||
|
visible: !compactMode
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||||
|
elide: Text.ElideRight
|
||||||
|
// wrapMode: Text.Wrap
|
||||||
|
text: windowData?.title ?? ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
const substitutions = {
|
||||||
|
"code-url-handler": "visual-studio-code",
|
||||||
|
"Code": "visual-studio-code",
|
||||||
|
"GitHub Desktop": "github-desktop",
|
||||||
|
"Minecraft* 1.20.1": "minecraft",
|
||||||
|
"gnome-tweaks": "org.gnome.tweaks",
|
||||||
|
"pavucontrol-qt": "pavucontrol",
|
||||||
|
"wps": "wps-office2019-kprometheus",
|
||||||
|
"wpsoffice": "wps-office2019-kprometheus",
|
||||||
|
"footclient": "foot",
|
||||||
|
"": "image-missing"
|
||||||
|
}
|
||||||
|
const regexSubstitutions = [
|
||||||
|
{
|
||||||
|
"regex": "/^steam_app_(\\d+)$/",
|
||||||
|
"replace": "steam_icon_$1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
function iconExists(iconName) {
|
||||||
|
return false; // TODO: Make this work without Gtk
|
||||||
|
}
|
||||||
|
|
||||||
|
function substitute(str) {
|
||||||
|
// Normal substitutions
|
||||||
|
if (substitutions[str])
|
||||||
|
return substitutions[str];
|
||||||
|
|
||||||
|
// Regex substitutions
|
||||||
|
for (let i = 0; i < regexSubstitutions.length; i++) {
|
||||||
|
const substitution = regexSubstitutions[i];
|
||||||
|
const replacedName = str.replace(
|
||||||
|
substitution.regex,
|
||||||
|
substitution.replace,
|
||||||
|
);
|
||||||
|
if (replacedName != str) return replacedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess: convert to kebab case
|
||||||
|
if (!iconExists(str)) str = str.toLowerCase().replace(/\s+/g, "-");
|
||||||
|
|
||||||
|
// Original string
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function noKnowledgeIconGuess(str) {
|
||||||
|
if (!str) return "image-missing";
|
||||||
|
|
||||||
|
// Normal substitutions
|
||||||
|
if (substitutions[str])
|
||||||
|
return substitutions[str];
|
||||||
|
|
||||||
|
// Regex substitutions
|
||||||
|
for (let i = 0; i < regexSubstitutions.length; i++) {
|
||||||
|
const substitution = regexSubstitutions[i];
|
||||||
|
const replacedName = str.replace(
|
||||||
|
substitution.regex,
|
||||||
|
substitution.replace,
|
||||||
|
);
|
||||||
|
if (replacedName != str) return replacedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess: convert to kebab case if it's not reverse domain name notation
|
||||||
|
if (!str.includes('.')) {
|
||||||
|
str = str.toLowerCase().replace(/\s+/g, "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original string
|
||||||
|
return str;
|
||||||
|
}
|
||||||
@@ -187,7 +187,7 @@ Scope {
|
|||||||
SessionActionButton {
|
SessionActionButton {
|
||||||
id: sessionFirmwareReboot
|
id: sessionFirmwareReboot
|
||||||
focus: sessionRoot.visible
|
focus: sessionRoot.visible
|
||||||
buttonIcon: "reset_wrench"
|
buttonIcon: "settings_applications"
|
||||||
buttonText: "Reboot to firmware settings"
|
buttonText: "Reboot to firmware settings"
|
||||||
onClicked: { firmwareReboot.running = true; sessionRoot.visible = false }
|
onClicked: { firmwareReboot.running = true; sessionRoot.visible = false }
|
||||||
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
|
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ Button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
console.log("Button clicked:", buttonText)
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Appearance.rounding.full
|
radius: Appearance.rounding.full
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
property var windowList: []
|
||||||
|
property var addresses: []
|
||||||
|
property var windowByAddress: {}
|
||||||
|
property var monitors: []
|
||||||
|
|
||||||
|
function updateWindowList() {
|
||||||
|
getClients.running = true
|
||||||
|
getMonitors.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updateWindowList()
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Hyprland
|
||||||
|
|
||||||
|
function onRawEvent(event) {
|
||||||
|
// Filter out redundant old v1 events for the same thing
|
||||||
|
if(event in [
|
||||||
|
"activewindow", "focusedmon", "monitoradded",
|
||||||
|
"createworkspace", "destroyworkspace", "moveworkspace",
|
||||||
|
"activespecial", "movewindow", "windowtitle"
|
||||||
|
]) return ;
|
||||||
|
updateWindowList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: getClients
|
||||||
|
command: ["bash", "-c", "hyprctl clients -j | jq -c"]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: (data) => {
|
||||||
|
root.windowList = JSON.parse(data)
|
||||||
|
root.windowByAddress = {}
|
||||||
|
for (var i = 0; i < root.windowList.length; ++i) {
|
||||||
|
var win = root.windowList[i]
|
||||||
|
root.windowByAddress[win.address] = win
|
||||||
|
}
|
||||||
|
root.addresses = root.windowList.map((win) => win.address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Process {
|
||||||
|
id: getMonitors
|
||||||
|
command: ["bash", "-c", "hyprctl monitors -j | jq -c"]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: (data) => {
|
||||||
|
root.monitors = JSON.parse(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
import "./modules/bar/"
|
import "./modules/bar/"
|
||||||
import "./modules/notificationPopup/"
|
import "./modules/notificationPopup/"
|
||||||
import "./modules/onScreenDisplay/"
|
import "./modules/onScreenDisplay/"
|
||||||
|
import "./modules/overview/"
|
||||||
import "./modules/screenCorners/"
|
import "./modules/screenCorners/"
|
||||||
import "./modules/session/"
|
import "./modules/session/"
|
||||||
import "./modules/sidebarRight/"
|
import "./modules/sidebarRight/"
|
||||||
@@ -17,6 +18,7 @@ ShellRoot {
|
|||||||
NotificationPopup {}
|
NotificationPopup {}
|
||||||
OnScreenDisplayBrightness {}
|
OnScreenDisplayBrightness {}
|
||||||
OnScreenDisplayVolume {}
|
OnScreenDisplayVolume {}
|
||||||
|
Overview {}
|
||||||
ReloadPopup {}
|
ReloadPopup {}
|
||||||
ScreenCorners {}
|
ScreenCorners {}
|
||||||
Session {}
|
Session {}
|
||||||
|
|||||||
Reference in New Issue
Block a user