diff --git a/docs/widgets.md b/docs/widgets.md index db2c8e9..e2681bb 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -70,7 +70,9 @@ or the Blob menu's Display layout row. A scaled picture of the desktop, one draggable rectangle per monitor. Dropping one applies the new position immediately. Edges snap to a neighbour's edge within 60 logical pixels, so monitors end up touching exactly. Per-monitor -controls: mode, scale, enable or disable, and mirror. +controls: mode, scale, enable or disable, and mirror. The panel +shrinks to fit the screen, and when a monitor reports more modes than fit, the +controls scroll while the canvas and the apply buttons stay in view. **Scale options are filtered, not free.** Hyprland steps fractional scaling in 1/120 and rejects a scale that does not land on a whole number of physical diff --git a/shell/Ui/StatRow.qml b/shell/Ui/StatRow.qml index ff069b1..88a5461 100644 --- a/shell/Ui/StatRow.qml +++ b/shell/Ui/StatRow.qml @@ -35,8 +35,12 @@ Item { } Text { + anchors.left: labelText.right + anchors.leftMargin: Style.spaceReal(8) anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter + horizontalAlignment: Text.AlignRight + elide: Text.ElideRight text: root.value textFormat: Text.PlainText color: Color.foreground diff --git a/shell/plugins/panels/display-layout/DisplayLayout.qml b/shell/plugins/panels/display-layout/DisplayLayout.qml index 9c92873..f4cbeeb 100644 --- a/shell/plugins/panels/display-layout/DisplayLayout.qml +++ b/shell/plugins/panels/display-layout/DisplayLayout.qml @@ -130,6 +130,7 @@ Item { onOpenedChanged: if (root.opened) root.refresh() PanelWindow { + id: panelWindow visible: root.opened anchors { top: true; bottom: true; left: true; right: true } color: "transparent" @@ -144,22 +145,32 @@ Item { } Card { + id: layoutCard + + readonly property real screenMargin: Style.spaceReal(20) + readonly property real maxHeight: panelWindow.height - screenMargin * 2 + readonly property real fixedContentHeight: header.height + hint.height + canvas.height + + actions.height + spacing * 4 + padding * 2 + anchors.centerIn: parent - implicitWidth: Style.spaceReal(720) - implicitHeight: Style.spaceReal(540) + implicitWidth: Math.min(Style.spaceReal(720), panelWindow.width - screenMargin * 2) fillColor: Util.alpha(Color.background, Style.panelFillAlpha) spacing: Style.spaceReal(10) Item { + id: header width: parent.width implicitHeight: Math.max(title.implicitHeight, closeButton.implicitHeight) Text { id: title anchors.left: parent.left + anchors.right: closeButton.left + anchors.rightMargin: Style.spaceReal(8) anchors.verticalCenter: parent.verticalCenter text: "Display layout" textFormat: Text.PlainText + elide: Text.ElideRight color: Color.foreground font.family: Style.font.family font.pixelSize: Style.font.body @@ -170,12 +181,13 @@ Item { id: closeButton anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - icon: "" + icon: "\uf00d" onActivated: root.dismiss() } } Text { + id: hint width: parent.width wrapMode: Text.WordWrap text: "Drag a monitor to move it. Edges snap to a neighbour. Changes apply as you drop and last until the session ends." @@ -186,6 +198,7 @@ Item { } MonitorCanvas { + id: canvas width: parent.width height: Style.spaceReal(220) monitors: root.monitors @@ -195,29 +208,42 @@ Item { onLayoutSettled: root.applyMonitor(root.selectedName) } - MonitorControls { + Flickable { + id: controlsScroll width: parent.width - monitor: root.selectedMonitor - monitors: root.monitors - onScaleRequested: function(scale) { - root.replaceMonitor(root.selectedName, { scale: scale }) - root.applyMonitor(root.selectedName) - } - onModeRequested: function(mode) { - root.replaceMonitor(root.selectedName, { mode: mode }) - root.applyMonitor(root.selectedName) - } - onEnabledRequested: function(enabled) { - root.replaceMonitor(root.selectedName, { disabled: !enabled }) - root.applyMonitor(root.selectedName) - } - onMirrorRequested: function(target) { - root.replaceMonitor(root.selectedName, { mirrorOf: target }) - root.applyMonitor(root.selectedName) + height: Math.max(0, Math.min(controls.implicitHeight, layoutCard.maxHeight - layoutCard.fixedContentHeight)) + contentWidth: width + contentHeight: controls.implicitHeight + clip: true + boundsBehavior: Flickable.StopAtBounds + interactive: contentHeight > height + + MonitorControls { + id: controls + width: controlsScroll.width + monitor: root.selectedMonitor + monitors: root.monitors + onScaleRequested: function(scale) { + root.replaceMonitor(root.selectedName, { scale: scale }) + root.applyMonitor(root.selectedName) + } + onModeRequested: function(mode) { + root.replaceMonitor(root.selectedName, { mode: mode }) + root.applyMonitor(root.selectedName) + } + onEnabledRequested: function(enabled) { + root.replaceMonitor(root.selectedName, { disabled: !enabled }) + root.applyMonitor(root.selectedName) + } + onMirrorRequested: function(target) { + root.replaceMonitor(root.selectedName, { mirrorOf: target }) + root.applyMonitor(root.selectedName) + } } } - Row { + Flow { + id: actions width: parent.width spacing: Style.spaceReal(6) diff --git a/shell/plugins/panels/display-layout/MonitorCard.qml b/shell/plugins/panels/display-layout/MonitorCard.qml index 8054425..31f9c35 100644 --- a/shell/plugins/panels/display-layout/MonitorCard.qml +++ b/shell/plugins/panels/display-layout/MonitorCard.qml @@ -29,13 +29,17 @@ Rectangle { : Util.alpha(Color.background, Style.cardFillAlpha) border.width: Style.cardBorderWidth border.color: root.selected ? Color.accent : Util.alpha(Color.blue, Style.cardBorderAlpha) + clip: true Column { anchors.centerIn: parent + width: Math.max(0, root.width - Style.spaceReal(8)) spacing: Style.spaceReal(2) Text { - anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight text: root.name textFormat: Text.PlainText color: Color.foreground @@ -45,7 +49,9 @@ Rectangle { } Text { - anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight visible: root.height > Style.spaceReal(44) text: root.monitor ? root.monitor.width + "x" + root.monitor.height : "" textFormat: Text.PlainText @@ -55,7 +61,9 @@ Rectangle { } Text { - anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight visible: root.monitor && root.monitor.focused && root.height > Style.spaceReal(58) text: "focused" textFormat: Text.PlainText diff --git a/shell/plugins/panels/display-layout/MonitorControls.qml b/shell/plugins/panels/display-layout/MonitorControls.qml index 566e893..e117afa 100644 --- a/shell/plugins/panels/display-layout/MonitorControls.qml +++ b/shell/plugins/panels/display-layout/MonitorControls.qml @@ -20,8 +20,10 @@ Column { visible: !!monitor Text { + width: parent.width text: root.monitor ? root.monitor.name : "" textFormat: Text.PlainText + elide: Text.ElideRight color: Color.foreground font.family: Style.font.family font.pixelSize: Style.font.body @@ -40,14 +42,14 @@ Column { StatRow { width: parent.width - icon: "" + icon: "\uf047" label: "Position" value: root.monitor ? root.monitor.x + ", " + root.monitor.y : "" } StatRow { width: parent.width - icon: "" + icon: "\uf108" label: "Logical size" value: root.monitor ? root.monitor.width + "x" + root.monitor.height : "" } @@ -110,7 +112,8 @@ Column { font.pixelSize: Style.font.bodySmall } - Row { + Flow { + width: parent.width spacing: Style.spaceReal(6) Chip {