mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-06 21:48:30 -04:00
hyprland: scale overview displays relative to their actual scale
port 1.5
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
@@ -80,7 +79,6 @@ Item {
|
|||||||
readonly property int displayWorkspaceCount: displayedWorkspaceIds.length
|
readonly property int displayWorkspaceCount: displayedWorkspaceIds.length
|
||||||
|
|
||||||
readonly property int effectiveColumns: SettingsData.overviewColumns
|
readonly property int effectiveColumns: SettingsData.overviewColumns
|
||||||
readonly property int effectiveRows: Math.max(SettingsData.overviewRows, Math.ceil(displayWorkspaceCount / effectiveColumns))
|
|
||||||
|
|
||||||
function getWorkspaceMonitorName(workspaceId) {
|
function getWorkspaceMonitorName(workspaceId) {
|
||||||
if (!allWorkspaces || !workspaceId)
|
if (!allWorkspaces || !workspaceId)
|
||||||
@@ -107,21 +105,53 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWorkspaceViewportBounds(workspaceId) {
|
function monitorIpcForWorkspace(workspaceId) {
|
||||||
const workspace = allWorkspaces?.find(ws => ws?.id === workspaceId);
|
const workspace = allWorkspaces?.find(ws => ws?.id === workspaceId);
|
||||||
const mon = workspace?.monitor?.lastIpcObject || monitor?.lastIpcObject || {};
|
return workspace?.monitor?.lastIpcObject ?? monitor?.lastIpcObject ?? null;
|
||||||
const reserved = mon.reserved || [0, 0, 0, 0];
|
}
|
||||||
|
|
||||||
const x = (mon.x ?? 0) + (reserved[0] ?? 0);
|
function monitorLogicalSize(ipc) {
|
||||||
const y = (mon.y ?? 0) + (reserved[1] ?? 0);
|
if (!ipc || !ipc.width || !ipc.height)
|
||||||
const width = Math.max((mon.width ?? monitorPhysicalWidth) - (reserved[0] ?? 0) - (reserved[2] ?? 0), 1);
|
return {
|
||||||
const height = Math.max((mon.height ?? monitorPhysicalHeight) - (reserved[1] ?? 0) - (reserved[3] ?? 0), 1);
|
"width": monitorPhysicalWidth,
|
||||||
const scale = Math.min(root.workspaceImplicitWidth / width, root.workspaceImplicitHeight / height);
|
"height": monitorPhysicalHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
const monScale = ipc.scale > 0 ? ipc.scale : 1;
|
||||||
|
const rotated = ((ipc.transform ?? 0) % 2) === 1;
|
||||||
|
return {
|
||||||
|
"width": (rotated ? ipc.height : ipc.width) / monScale,
|
||||||
|
"height": (rotated ? ipc.width : ipc.height) / monScale
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function cellForWorkspace(workspaceId) {
|
||||||
|
const cell = gridLayout.cells.find(c => c.id === workspaceId);
|
||||||
|
if (cell)
|
||||||
|
return cell;
|
||||||
|
return {
|
||||||
|
"id": workspaceId,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": workspaceImplicitWidth,
|
||||||
|
"height": workspaceImplicitHeight
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorkspaceViewportBounds(workspaceId, cellWidth, cellHeight) {
|
||||||
|
const ipc = monitorIpcForWorkspace(workspaceId) ?? {};
|
||||||
|
const logical = monitorLogicalSize(ipc);
|
||||||
|
const reserved = ipc.reserved || [0, 0, 0, 0];
|
||||||
|
|
||||||
|
const x = (ipc.x ?? 0) + (reserved[0] ?? 0);
|
||||||
|
const y = (ipc.y ?? 0) + (reserved[1] ?? 0);
|
||||||
|
const width = Math.max(logical.width - (reserved[0] ?? 0) - (reserved[2] ?? 0), 1);
|
||||||
|
const height = Math.max(logical.height - (reserved[1] ?? 0) - (reserved[3] ?? 0), 1);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"x": x,
|
"x": x,
|
||||||
"y": y,
|
"y": y,
|
||||||
"scale": scale
|
"scale": Math.min(cellWidth / width, cellHeight / height)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,6 +173,56 @@ Item {
|
|||||||
property int draggingFromWorkspace: -1
|
property int draggingFromWorkspace: -1
|
||||||
property int draggingTargetWorkspace: -1
|
property int draggingTargetWorkspace: -1
|
||||||
|
|
||||||
|
readonly property var gridLayout: {
|
||||||
|
const ids = displayedWorkspaceIds;
|
||||||
|
const columns = effectiveColumns;
|
||||||
|
if (!ids || ids.length === 0 || columns < 1)
|
||||||
|
return {
|
||||||
|
"cells": [],
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const rows = [];
|
||||||
|
for (let i = 0; i < ids.length; i += columns) {
|
||||||
|
rows.push(ids.slice(i, i + columns).map(id => {
|
||||||
|
const logical = monitorLogicalSize(monitorIpcForWorkspace(id));
|
||||||
|
return {
|
||||||
|
"id": id,
|
||||||
|
"width": logical.width * scale,
|
||||||
|
"height": logical.height * scale
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const rowWidth = row => row.reduce((acc, cell) => acc + cell.width, 0) + workspaceSpacing * (row.length - 1);
|
||||||
|
const totalWidth = rows.reduce((acc, row) => Math.max(acc, rowWidth(row)), 0);
|
||||||
|
|
||||||
|
const cells = [];
|
||||||
|
let cursorY = 0;
|
||||||
|
for (const row of rows) {
|
||||||
|
const rowHeight = row.reduce((acc, cell) => Math.max(acc, cell.height), 0);
|
||||||
|
let cursorX = (totalWidth - rowWidth(row)) / 2;
|
||||||
|
for (const cell of row) {
|
||||||
|
cells.push({
|
||||||
|
"id": cell.id,
|
||||||
|
"x": cursorX,
|
||||||
|
"y": cursorY + (rowHeight - cell.height) / 2,
|
||||||
|
"width": cell.width,
|
||||||
|
"height": cell.height
|
||||||
|
});
|
||||||
|
cursorX += cell.width + workspaceSpacing;
|
||||||
|
}
|
||||||
|
cursorY += rowHeight + workspaceSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"cells": cells,
|
||||||
|
"width": totalWidth,
|
||||||
|
"height": cursorY - workspaceSpacing
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
implicitWidth: overviewBackground.implicitWidth + Theme.spacingL * 2
|
implicitWidth: overviewBackground.implicitWidth + Theme.spacingL * 2
|
||||||
implicitHeight: overviewBackground.implicitHeight + Theme.spacingL * 2
|
implicitHeight: overviewBackground.implicitHeight + Theme.spacingL * 2
|
||||||
|
|
||||||
@@ -166,8 +246,8 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingL
|
anchors.margins: Theme.spacingL
|
||||||
|
|
||||||
implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2
|
implicitWidth: workspaceGrid.implicitWidth + padding * 2
|
||||||
implicitHeight: workspaceColumnLayout.implicitHeight + padding * 2
|
implicitHeight: workspaceGrid.implicitHeight + padding * 2
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
|
|
||||||
@@ -182,84 +262,78 @@ Item {
|
|||||||
shadowEnabled: Theme.elevationEnabled
|
shadowEnabled: Theme.elevationEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
Item {
|
||||||
id: workspaceColumnLayout
|
id: workspaceGrid
|
||||||
|
|
||||||
z: root.workspaceZ
|
z: root.workspaceZ
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
spacing: workspaceSpacing
|
implicitWidth: root.gridLayout.width
|
||||||
|
implicitHeight: root.gridLayout.height
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.effectiveRows
|
model: root.gridLayout.cells.length
|
||||||
delegate: RowLayout {
|
|
||||||
id: row
|
|
||||||
property int rowIndex: index
|
|
||||||
spacing: workspaceSpacing
|
|
||||||
|
|
||||||
Repeater {
|
Rectangle {
|
||||||
model: root.effectiveColumns
|
id: workspace
|
||||||
Rectangle {
|
required property int index
|
||||||
id: workspace
|
readonly property var cell: root.gridLayout.cells[index] ?? null
|
||||||
property int colIndex: index
|
property int workspaceValue: cell?.id ?? -1
|
||||||
property int workspaceIndex: rowIndex * root.effectiveColumns + colIndex
|
property bool workspaceExists: (root.allWorkspaceIds && workspaceValue > 0) ? root.allWorkspaceIds.includes(workspaceValue) : false
|
||||||
property int workspaceValue: (root.displayedWorkspaceIds && workspaceIndex < root.displayedWorkspaceIds.length) ? root.displayedWorkspaceIds[workspaceIndex] : -1
|
property var workspaceObj: (workspaceExists && Hyprland.workspaces?.values) ? Hyprland.workspaces.values.find(ws => ws?.id === workspaceValue) : null
|
||||||
property bool workspaceExists: (root.allWorkspaceIds && workspaceValue > 0) ? root.allWorkspaceIds.includes(workspaceValue) : false
|
property bool isActive: workspaceObj?.active ?? false
|
||||||
property var workspaceObj: (workspaceExists && Hyprland.workspaces?.values) ? Hyprland.workspaces.values.find(ws => ws?.id === workspaceValue) : null
|
property bool isOnThisMonitor: (workspaceObj && root.monitor) ? (workspaceObj.monitor?.name === root.monitor.name) : true
|
||||||
property bool isActive: workspaceObj?.active ?? false
|
property bool hasWindows: (workspaceValue > 0) ? root.workspaceHasWindows(workspaceValue) : false
|
||||||
property bool isOnThisMonitor: (workspaceObj && root.monitor) ? (workspaceObj.monitor?.name === root.monitor.name) : true
|
property color defaultWorkspaceColor: workspaceExists ? Theme.surfaceContainer : Theme.withAlpha(Theme.surfaceContainer, 0.3)
|
||||||
property bool hasWindows: (workspaceValue > 0) ? root.workspaceHasWindows(workspaceValue) : false
|
property color hoveredWorkspaceColor: Qt.lighter(defaultWorkspaceColor, 1.1)
|
||||||
property string workspaceMonitorName: (workspaceValue > 0) ? root.getWorkspaceMonitorName(workspaceValue) : ""
|
property color hoveredBorderColor: Theme.surfaceVariant
|
||||||
property color defaultWorkspaceColor: workspaceExists ? Theme.surfaceContainer : Theme.withAlpha(Theme.surfaceContainer, 0.3)
|
property bool hoveredWhileDragging: false
|
||||||
property color hoveredWorkspaceColor: Qt.lighter(defaultWorkspaceColor, 1.1)
|
property bool shouldShowActiveIndicator: isActive && isOnThisMonitor && hasWindows
|
||||||
property color hoveredBorderColor: Theme.surfaceVariant
|
|
||||||
property bool hoveredWhileDragging: false
|
|
||||||
property bool shouldShowActiveIndicator: isActive && isOnThisMonitor && hasWindows
|
|
||||||
|
|
||||||
visible: workspaceValue !== -1
|
visible: workspaceValue !== -1
|
||||||
|
|
||||||
implicitWidth: root.workspaceImplicitWidth
|
x: cell?.x ?? 0
|
||||||
implicitHeight: root.workspaceImplicitHeight
|
y: cell?.y ?? 0
|
||||||
color: hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor
|
width: cell?.width ?? 0
|
||||||
radius: Theme.cornerRadius
|
height: cell?.height ?? 0
|
||||||
border.width: 2
|
color: hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor
|
||||||
border.color: hoveredWhileDragging ? hoveredBorderColor : (shouldShowActiveIndicator ? root.activeBorderColor : Theme.withAlpha(root.activeBorderColor, 0))
|
radius: Theme.cornerRadius
|
||||||
|
border.width: 2
|
||||||
|
border.color: hoveredWhileDragging ? hoveredBorderColor : (shouldShowActiveIndicator ? root.activeBorderColor : Theme.withAlpha(root.activeBorderColor, 0))
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: workspaceValue
|
text: workspace.workspaceValue
|
||||||
font.pixelSize: Theme.fontSizeXLarge * 6
|
font.pixelSize: Theme.fontSizeXLarge * 6
|
||||||
font.weight: Font.DemiBold
|
font.weight: Font.DemiBold
|
||||||
color: Theme.withAlpha(Theme.surfaceText, workspaceExists ? 0.2 : 0.1)
|
color: Theme.withAlpha(Theme.surfaceText, workspace.workspaceExists ? 0.2 : 0.1)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: workspaceArea
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
onClicked: {
|
||||||
|
if (root.draggingTargetWorkspace === -1) {
|
||||||
|
root.overviewOpen = false;
|
||||||
|
HyprlandService.focusWorkspace(workspace.workspaceValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
DropArea {
|
||||||
id: workspaceArea
|
anchors.fill: parent
|
||||||
anchors.fill: parent
|
onEntered: {
|
||||||
acceptedButtons: Qt.LeftButton
|
root.draggingTargetWorkspace = workspace.workspaceValue;
|
||||||
onClicked: {
|
if (root.draggingFromWorkspace == root.draggingTargetWorkspace)
|
||||||
if (root.draggingTargetWorkspace === -1) {
|
return;
|
||||||
root.overviewOpen = false;
|
workspace.hoveredWhileDragging = true;
|
||||||
HyprlandService.focusWorkspace(workspaceValue);
|
}
|
||||||
}
|
onExited: {
|
||||||
}
|
workspace.hoveredWhileDragging = false;
|
||||||
}
|
if (root.draggingTargetWorkspace == workspace.workspaceValue)
|
||||||
|
root.draggingTargetWorkspace = -1;
|
||||||
DropArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onEntered: {
|
|
||||||
root.draggingTargetWorkspace = workspaceValue;
|
|
||||||
if (root.draggingFromWorkspace == root.draggingTargetWorkspace)
|
|
||||||
return;
|
|
||||||
hoveredWhileDragging = true;
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
hoveredWhileDragging = false;
|
|
||||||
if (root.draggingTargetWorkspace == workspaceValue)
|
|
||||||
root.draggingTargetWorkspace = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,8 +343,8 @@ Item {
|
|||||||
Item {
|
Item {
|
||||||
id: windowSpace
|
id: windowSpace
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: workspaceColumnLayout.implicitWidth
|
implicitWidth: workspaceGrid.implicitWidth
|
||||||
implicitHeight: workspaceColumnLayout.implicitHeight
|
implicitHeight: workspaceGrid.implicitHeight
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
@@ -306,41 +380,21 @@ Item {
|
|||||||
|
|
||||||
overviewOpen: root.overviewOpen
|
overviewOpen: root.overviewOpen
|
||||||
readonly property int windowWorkspaceId: modelData?.workspace?.id ?? -1
|
readonly property int windowWorkspaceId: modelData?.workspace?.id ?? -1
|
||||||
|
readonly property var workspaceCell: root.cellForWorkspace(windowWorkspaceId)
|
||||||
function getWorkspaceIndex() {
|
readonly property var workspaceBounds: root.getWorkspaceViewportBounds(windowWorkspaceId, workspaceCell.width, workspaceCell.height)
|
||||||
if (!root.displayedWorkspaceIds || root.displayedWorkspaceIds.length === 0)
|
|
||||||
return 0;
|
|
||||||
if (!windowWorkspaceId || windowWorkspaceId < 0)
|
|
||||||
return 0;
|
|
||||||
try {
|
|
||||||
for (let i = 0; i < root.displayedWorkspaceIds.length; i++) {
|
|
||||||
if (root.displayedWorkspaceIds[i] === windowWorkspaceId) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} catch (e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property int workspaceIndex: getWorkspaceIndex()
|
|
||||||
readonly property int workspaceColIndex: workspaceIndex % root.effectiveColumns
|
|
||||||
readonly property int workspaceRowIndex: Math.floor(workspaceIndex / root.effectiveColumns)
|
|
||||||
readonly property var workspaceBounds: root.getWorkspaceViewportBounds(windowWorkspaceId)
|
|
||||||
|
|
||||||
toplevel: modelData
|
toplevel: modelData
|
||||||
scale: root.scale
|
scale: root.scale
|
||||||
monitorDpr: root.dpr
|
monitorDpr: root.dpr
|
||||||
availableWorkspaceWidth: root.workspaceImplicitWidth
|
availableWorkspaceWidth: workspaceCell.width
|
||||||
availableWorkspaceHeight: root.workspaceImplicitHeight
|
availableWorkspaceHeight: workspaceCell.height
|
||||||
contentOriginX: workspaceBounds.x
|
contentOriginX: workspaceBounds.x
|
||||||
contentOriginY: workspaceBounds.y
|
contentOriginY: workspaceBounds.y
|
||||||
contentScale: workspaceBounds.scale
|
contentScale: workspaceBounds.scale
|
||||||
widgetMonitorId: root.monitor.id
|
widgetMonitorId: root.monitor.id
|
||||||
|
|
||||||
xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex
|
xOffset: workspaceCell.x
|
||||||
yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * workspaceRowIndex
|
yOffset: workspaceCell.y
|
||||||
|
|
||||||
z: atInitPosition ? root.windowZ : root.windowDraggingZ
|
z: atInitPosition ? root.windowZ : root.windowDraggingZ
|
||||||
property bool atInitPosition: (initX == x && initY == y)
|
property bool atInitPosition: (initX == x && initY == y)
|
||||||
@@ -409,54 +463,44 @@ Item {
|
|||||||
Item {
|
Item {
|
||||||
id: monitorLabelSpace
|
id: monitorLabelSpace
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
implicitWidth: workspaceColumnLayout.implicitWidth
|
implicitWidth: workspaceGrid.implicitWidth
|
||||||
implicitHeight: workspaceColumnLayout.implicitHeight
|
implicitHeight: workspaceGrid.implicitHeight
|
||||||
z: root.monitorLabelZ
|
z: root.monitorLabelZ
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.effectiveRows
|
model: root.gridLayout.cells.length
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
id: labelRow
|
id: labelItem
|
||||||
property int rowIndex: index
|
required property int index
|
||||||
y: (root.workspaceImplicitHeight + workspaceSpacing) * rowIndex
|
readonly property var cell: root.gridLayout.cells[index] ?? null
|
||||||
width: parent.width
|
property int workspaceValue: cell?.id ?? -1
|
||||||
height: root.workspaceImplicitHeight
|
property bool workspaceExists: (root.allWorkspaceIds && workspaceValue > 0) ? root.allWorkspaceIds.includes(workspaceValue) : false
|
||||||
|
property string workspaceMonitorName: (workspaceValue > 0) ? root.getWorkspaceMonitorName(workspaceValue) : ""
|
||||||
|
|
||||||
Repeater {
|
x: cell?.x ?? 0
|
||||||
model: root.effectiveColumns
|
y: cell?.y ?? 0
|
||||||
delegate: Item {
|
width: cell?.width ?? 0
|
||||||
id: labelItem
|
height: cell?.height ?? 0
|
||||||
property int colIndex: index
|
|
||||||
property int workspaceIndex: labelRow.rowIndex * root.effectiveColumns + colIndex
|
|
||||||
property int workspaceValue: (root.displayedWorkspaceIds && workspaceIndex < root.displayedWorkspaceIds.length) ? root.displayedWorkspaceIds[workspaceIndex] : -1
|
|
||||||
property bool workspaceExists: (root.allWorkspaceIds && workspaceValue > 0) ? root.allWorkspaceIds.includes(workspaceValue) : false
|
|
||||||
property string workspaceMonitorName: (workspaceValue > 0) ? root.getWorkspaceMonitorName(workspaceValue) : ""
|
|
||||||
|
|
||||||
x: (root.workspaceImplicitWidth + workspaceSpacing) * colIndex
|
Rectangle {
|
||||||
width: root.workspaceImplicitWidth
|
anchors.right: parent.right
|
||||||
height: root.workspaceImplicitHeight
|
anchors.top: parent.top
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
|
width: monitorNameText.contentWidth + Theme.spacingS * 2
|
||||||
|
height: monitorNameText.contentHeight + Theme.spacingXS * 2
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.surface
|
||||||
|
visible: labelItem.workspaceExists && labelItem.workspaceMonitorName !== ""
|
||||||
|
|
||||||
Rectangle {
|
StyledText {
|
||||||
anchors.right: parent.right
|
id: monitorNameText
|
||||||
anchors.top: parent.top
|
anchors.centerIn: parent
|
||||||
anchors.margins: Theme.spacingS
|
text: labelItem.workspaceMonitorName
|
||||||
width: monitorNameText.contentWidth + Theme.spacingS * 2
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
height: monitorNameText.contentHeight + Theme.spacingXS * 2
|
font.weight: Font.Medium
|
||||||
radius: Theme.cornerRadius
|
color: Theme.surfaceText
|
||||||
color: Theme.surface
|
horizontalAlignment: Text.AlignHCenter
|
||||||
visible: labelItem.workspaceExists && labelItem.workspaceMonitorName !== ""
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: monitorNameText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: labelItem.workspaceMonitorName
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -942,15 +942,16 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primary detection asks the OS which process owns $WAYLAND_DISPLAY — the
|
// Primary detection asks the kernel which process owns the $WAYLAND_DISPLAY
|
||||||
// compositor quickshell is actually connected to. Env vars like
|
// socket — the compositor quickshell is actually connected to. Env vars like
|
||||||
// HYPRLAND_INSTANCE_SIGNATURE / MANGO_INSTANCE_SIGNATURE can leak into the
|
// HYPRLAND_INSTANCE_SIGNATURE / MANGO_INSTANCE_SIGNATURE can leak into the
|
||||||
// systemd user environment from previous sessions and lie.
|
// systemd user environment from previous sessions and lie. Unset
|
||||||
|
// WAYLAND_DISPLAY falls back to "wayland-0", mirroring wl_display_connect.
|
||||||
|
// /proc/net/unix: field 6 is state (01 = listening), 7 inode, 8 bound path.
|
||||||
function detectCompositor() {
|
function detectCompositor() {
|
||||||
const script = 'sock="$WAYLAND_DISPLAY"; case "$sock" in /*) ;; *) sock="$XDG_RUNTIME_DIR/$sock" ;; esac; ss -xlp 2>/dev/null | grep -F "$sock " | head -n1';
|
const script = 'sock="${WAYLAND_DISPLAY:-wayland-0}"; case "$sock" in /*) ;; *) sock="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/$sock" ;; esac; inode=$(awk -v p="$sock" \'$8 == p && $6 == 1 {print $7; exit}\' /proc/net/unix); [ -n "$inode" ] || exit 1; fd=$(find /proc/[0-9]*/fd/ -mindepth 1 -maxdepth 1 -lname "socket:\\[$inode\\]" 2>/dev/null | head -n1); [ -n "$fd" ] || exit 1; pid="${fd#/proc/}"; cat "/proc/${pid%%/*}/comm"';
|
||||||
Proc.runCommand("waylandSocketOwner", ["sh", "-c", script], (output, exitCode) => {
|
Proc.runCommand("waylandSocketOwner", ["sh", "-c", script], (output, exitCode) => {
|
||||||
const match = output ? output.match(/users:\(\("([^"]+)"/) : null;
|
const comm = (exitCode === 0 && output) ? output.trim().toLowerCase() : "";
|
||||||
const comm = match ? match[1].toLowerCase() : "";
|
|
||||||
const name = _compositorNameFromComm(comm);
|
const name = _compositorNameFromComm(comm);
|
||||||
if (name) {
|
if (name) {
|
||||||
_applyCompositor(name);
|
_applyCompositor(name);
|
||||||
|
|||||||
Reference in New Issue
Block a user