overview: more rounding

This commit is contained in:
end-4
2025-11-01 18:28:25 +01:00
parent 816d2b8a76
commit 77d9b93887
2 changed files with 95 additions and 31 deletions
@@ -1,8 +1,10 @@
pragma ComponentBehavior: Bound
import qs import qs
import qs.services import qs.services
import qs.modules.common import qs.modules.common
import qs.modules.common.widgets import qs.modules.common.widgets
import qs.modules.common.functions import qs.modules.common.functions
import Qt5Compat.GraphicalEffects
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Quickshell import Quickshell
@@ -30,6 +32,8 @@ Item {
property real workspaceImplicitHeight: (monitorData?.transform % 2 === 1) ? property real workspaceImplicitHeight: (monitorData?.transform % 2 === 1) ?
((monitor.width - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale) : ((monitor.width - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale) :
((monitor.height - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale) ((monitor.height - monitorData?.reserved[1] - monitorData?.reserved[3]) * root.scale / monitor.scale)
property real largeWorkspaceRadius: Appearance.rounding.large
property real smallWorkspaceRadius: Appearance.rounding.verysmall
property real workspaceNumberMargin: 80 property real workspaceNumberMargin: 80
property real workspaceNumberSize: 250 * monitor.scale property real workspaceNumberSize: 250 * monitor.scale
@@ -58,10 +62,8 @@ Item {
implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2 implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2
implicitHeight: workspaceColumnLayout.implicitHeight + padding * 2 implicitHeight: workspaceColumnLayout.implicitHeight + padding * 2
radius: Appearance.rounding.screenRounding * root.scale + padding radius: root.largeWorkspaceRadius + padding
color: Appearance.colors.colLayer0 color: Appearance.colors.colBackgroundSurfaceContainer
border.width: 1
border.color: Appearance.colors.colLayer0Border
Column { // Workspaces Column { // Workspaces
id: workspaceColumnLayout id: workspaceColumnLayout
@@ -69,20 +71,22 @@ Item {
z: root.workspaceZ z: root.workspaceZ
anchors.centerIn: parent anchors.centerIn: parent
spacing: workspaceSpacing spacing: workspaceSpacing
Repeater { Repeater {
model: Config.options.overview.rows model: Config.options.overview.rows
delegate: Row { delegate: Row {
id: row id: row
property int rowIndex: index required property int index
spacing: workspaceSpacing spacing: workspaceSpacing
Repeater { // Workspace repeater Repeater { // Workspace repeater
model: Config.options.overview.columns model: Config.options.overview.columns
Rectangle { // Workspace Rectangle { // Workspace
id: workspace id: workspace
required property int index
property int colIndex: index property int colIndex: index
property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * Config.options.overview.columns + colIndex + 1 property int workspaceValue: root.workspaceGroup * root.workspacesShown + row.index * Config.options.overview.columns + colIndex + 1
property color defaultWorkspaceColor: Appearance.colors.colLayer1 // TODO: reconsider this color for a cleaner look property color defaultWorkspaceColor: ColorUtils.mix(Appearance.colors.colBackgroundSurfaceContainer, Appearance.colors.colSurfaceContainerHigh, 0.8)
property color hoveredWorkspaceColor: ColorUtils.mix(defaultWorkspaceColor, Appearance.colors.colLayer1Hover, 0.1) property color hoveredWorkspaceColor: ColorUtils.mix(defaultWorkspaceColor, Appearance.colors.colLayer1Hover, 0.1)
property color hoveredBorderColor: Appearance.colors.colLayer2Hover property color hoveredBorderColor: Appearance.colors.colLayer2Hover
property bool hoveredWhileDragging: false property bool hoveredWhileDragging: false
@@ -90,13 +94,20 @@ Item {
implicitWidth: root.workspaceImplicitWidth implicitWidth: root.workspaceImplicitWidth
implicitHeight: root.workspaceImplicitHeight implicitHeight: root.workspaceImplicitHeight
color: hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor color: hoveredWhileDragging ? hoveredWorkspaceColor : defaultWorkspaceColor
radius: Appearance.rounding.screenRounding * root.scale property bool workspaceAtLeft: colIndex === 0
property bool workspaceAtRight: colIndex === Config.options.overview.columns - 1
property bool workspaceAtTop: row.index === 0
property bool workspaceAtBottom: row.index === Config.options.overview.rows - 1
topLeftRadius: (workspaceAtLeft && workspaceAtTop) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
topRightRadius: (workspaceAtRight && workspaceAtTop) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
bottomLeftRadius: (workspaceAtLeft && workspaceAtBottom) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
bottomRightRadius: (workspaceAtRight && workspaceAtBottom) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
border.width: 2 border.width: 2
border.color: hoveredWhileDragging ? hoveredBorderColor : "transparent" border.color: hoveredWhileDragging ? hoveredBorderColor : "transparent"
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: workspaceValue text: workspace.workspaceValue
font { font {
pixelSize: root.workspaceNumberSize * root.scale pixelSize: root.workspaceNumberSize * root.scale
weight: Font.DemiBold weight: Font.DemiBold
@@ -114,7 +125,7 @@ Item {
onPressed: { onPressed: {
if (root.draggingTargetWorkspace === -1) { if (root.draggingTargetWorkspace === -1) {
GlobalStates.overviewOpen = false GlobalStates.overviewOpen = false
Hyprland.dispatch(`workspace ${workspaceValue}`) Hyprland.dispatch(`workspace ${workspace.workspaceValue}`)
} }
} }
} }
@@ -122,13 +133,13 @@ Item {
DropArea { DropArea {
anchors.fill: parent anchors.fill: parent
onEntered: { onEntered: {
root.draggingTargetWorkspace = workspaceValue root.draggingTargetWorkspace = workspace.workspaceValue
if (root.draggingFromWorkspace == root.draggingTargetWorkspace) return; if (root.draggingFromWorkspace == root.draggingTargetWorkspace) return;
hoveredWhileDragging = true hoveredWhileDragging = true
} }
onExited: { onExited: {
hoveredWhileDragging = false hoveredWhileDragging = false
if (root.draggingTargetWorkspace == workspaceValue) root.draggingTargetWorkspace = -1 if (root.draggingTargetWorkspace == workspace.workspaceValue) root.draggingTargetWorkspace = -1
} }
} }
@@ -165,17 +176,41 @@ Item {
toplevel: modelData toplevel: modelData
monitorData: this.monitor monitorData: this.monitor
scale: root.scale scale: root.scale
availableWorkspaceWidth: root.workspaceImplicitWidth
availableWorkspaceHeight: root.workspaceImplicitHeight
widgetMonitor: HyprlandData.monitors.find(m => m.id == root.monitor.id) widgetMonitor: HyprlandData.monitors.find(m => m.id == root.monitor.id)
windowData: windowByAddress[address] windowData: windowByAddress[address]
property bool atInitPosition: (initX == x && initY == y) property bool atInitPosition: (initX == x && initY == y)
// Offset on the canvas
property int workspaceColIndex: (windowData?.workspace.id - 1) % Config.options.overview.columns property int workspaceColIndex: (windowData?.workspace.id - 1) % Config.options.overview.columns
property int workspaceRowIndex: Math.floor((windowData?.workspace.id - 1) % root.workspacesShown / Config.options.overview.columns) property int workspaceRowIndex: Math.floor((windowData?.workspace.id - 1) % root.workspacesShown / Config.options.overview.columns)
xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex
yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * workspaceRowIndex yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * workspaceRowIndex
property real xWithinWorkspaceWidget: Math.max((windowData?.at[0] - (monitor?.x ?? 0) - monitorData?.reserved[0]) * root.scale, 0)
property real yWithinWorkspaceWidget: Math.max((windowData?.at[1] - (monitor?.y ?? 0) - monitorData?.reserved[1]) * root.scale, 0)
// Radius
property real minRadius: Appearance.rounding.small
property bool workspaceAtLeft: workspaceColIndex === 0
property bool workspaceAtRight: workspaceColIndex === Config.options.overview.columns - 1
property bool workspaceAtTop: workspaceRowIndex === 0
property bool workspaceAtBottom: workspaceRowIndex === Config.options.overview.rows - 1
property bool workspaceAtTopLeft: (workspaceAtLeft && workspaceAtTop)
property bool workspaceAtTopRight: (workspaceAtRight && workspaceAtTop)
property bool workspaceAtBottomLeft: (workspaceAtLeft && workspaceAtBottom)
property bool workspaceAtBottomRight: (workspaceAtRight && workspaceAtBottom)
property real distanceFromLeftEdge: xWithinWorkspaceWidget
property real distanceFromRightEdge: root.workspaceImplicitWidth - (xWithinWorkspaceWidget + targetWindowWidth)
property real distanceFromTopEdge: yWithinWorkspaceWidget
property real distanceFromBottomEdge: root.workspaceImplicitHeight - (yWithinWorkspaceWidget + targetWindowHeight)
property real distanceFromTopLeftCorner: Math.max(distanceFromLeftEdge, distanceFromTopEdge)
property real distanceFromTopRightCorner: Math.max(distanceFromRightEdge, distanceFromTopEdge)
property real distanceFromBottomLeftCorner: Math.max(distanceFromLeftEdge, distanceFromBottomEdge)
property real distanceFromBottomRightCorner: Math.max(distanceFromRightEdge, distanceFromBottomEdge)
topLeftRadius: Math.max((workspaceAtTopLeft ? root.largeWorkspaceRadius : root.smallWorkspaceRadius) - distanceFromTopLeftCorner, minRadius)
topRightRadius: Math.max((workspaceAtTopRight ? root.largeWorkspaceRadius : root.smallWorkspaceRadius) - distanceFromTopRightCorner, minRadius)
bottomLeftRadius: Math.max((workspaceAtBottomLeft ? root.largeWorkspaceRadius : root.smallWorkspaceRadius) - distanceFromBottomLeftCorner, minRadius)
bottomRightRadius: Math.max((workspaceAtBottomRight ? root.largeWorkspaceRadius : root.smallWorkspaceRadius) - distanceFromBottomRightCorner, minRadius)
Timer { Timer {
id: updateWindowPosition id: updateWindowPosition
@@ -183,8 +218,8 @@ Item {
repeat: false repeat: false
running: false running: false
onTriggered: { onTriggered: {
window.x = Math.round(Math.max((windowData?.at[0] - (monitor?.x ?? 0) - monitorData?.reserved[0]) * root.scale, 0) + xOffset) window.x = Math.round(xWithinWorkspaceWidget + xOffset)
window.y = Math.round(Math.max((windowData?.at[1] - (monitor?.y ?? 0) - monitorData?.reserved[1]) * root.scale, 0) + yOffset) window.y = Math.round(yWithinWorkspaceWidget + yOffset)
} }
} }
@@ -252,15 +287,22 @@ Item {
Rectangle { // Focused workspace indicator Rectangle { // Focused workspace indicator
id: focusedWorkspaceIndicator id: focusedWorkspaceIndicator
property int activeWorkspaceInGroup: monitor.activeWorkspace?.id - (root.workspaceGroup * root.workspacesShown) property int activeWorkspaceInGroup: monitor.activeWorkspace?.id - (root.workspaceGroup * root.workspacesShown)
property int activeWorkspaceRowIndex: Math.floor((activeWorkspaceInGroup - 1) / Config.options.overview.columns) property int rowIndex: Math.floor((activeWorkspaceInGroup - 1) / Config.options.overview.columns)
property int activeWorkspaceColIndex: (activeWorkspaceInGroup - 1) % Config.options.overview.columns property int colIndex: (activeWorkspaceInGroup - 1) % Config.options.overview.columns
x: (root.workspaceImplicitWidth + workspaceSpacing) * activeWorkspaceColIndex x: (root.workspaceImplicitWidth + workspaceSpacing) * colIndex
y: (root.workspaceImplicitHeight + workspaceSpacing) * activeWorkspaceRowIndex y: (root.workspaceImplicitHeight + workspaceSpacing) * rowIndex
z: root.windowZ z: root.windowZ
width: root.workspaceImplicitWidth width: root.workspaceImplicitWidth
height: root.workspaceImplicitHeight height: root.workspaceImplicitHeight
color: "transparent" color: "transparent"
radius: Appearance.rounding.screenRounding * root.scale property bool workspaceAtLeft: colIndex === 0
property bool workspaceAtRight: colIndex === Config.options.overview.columns - 1
property bool workspaceAtTop: rowIndex === 0
property bool workspaceAtBottom: rowIndex === Config.options.overview.rows - 1
topLeftRadius: (workspaceAtLeft && workspaceAtTop) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
topRightRadius: (workspaceAtRight && workspaceAtTop) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
bottomLeftRadius: (workspaceAtLeft && workspaceAtBottom) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
bottomRightRadius: (workspaceAtRight && workspaceAtBottom) ? root.largeWorkspaceRadius : root.smallWorkspaceRadius
border.width: 2 border.width: 2
border.color: root.activeBorderColor border.color: root.activeBorderColor
Behavior on x { Behavior on x {
@@ -269,6 +311,18 @@ Item {
Behavior on y { Behavior on y {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
} }
Behavior on topLeftRadius {
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
}
Behavior on topRightRadius {
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
}
Behavior on bottomLeftRadius {
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
}
Behavior on bottomRightRadius {
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
}
} }
} }
} }
@@ -1,3 +1,4 @@
pragma ComponentBehavior: Bound
import qs import qs
import qs.services import qs.services
import qs.modules.common import qs.modules.common
@@ -14,25 +15,23 @@ Item { // Window
property var windowData property var windowData
property var monitorData property var monitorData
property var scale property var scale
property var availableWorkspaceWidth
property var availableWorkspaceHeight
property bool restrictToWorkspace: true property bool restrictToWorkspace: true
property real widthRatio: { property real widthRatio: {
const widgetWidth = widgetMonitor.transform & 1 ? widgetMonitor.height : widgetMonitor.width; const widgetWidth = widgetMonitor.transform & 1 ? widgetMonitor.height : widgetMonitor.width;
const monitorWidth = monitorData.transform & 1 ? monitorData.height : monitorData.width; const monitorWidth = monitorData.transform & 1 ? monitorData.height : monitorData.width;
(widgetWidth * monitorData.scale) / (monitorWidth * widgetMonitor.scale); return (widgetWidth * monitorData.scale) / (monitorWidth * widgetMonitor.scale);
} }
property real heightRatio: { property real heightRatio: {
const widgetHeight = widgetMonitor.transform & 1 ? widgetMonitor.width : widgetMonitor.height; const widgetHeight = widgetMonitor.transform & 1 ? widgetMonitor.width : widgetMonitor.height;
const monitorHeight = monitorData.transform & 1 ? monitorData.width : monitorData.height; const monitorHeight = monitorData.transform & 1 ? monitorData.width : monitorData.height;
(widgetHeight * monitorData.scale) / (monitorHeight * widgetMonitor.scale); return (widgetHeight * monitorData.scale) / (monitorHeight * widgetMonitor.scale);
} }
property real initX: { property real initX: {
Math.max((windowData?.at[0] - (monitorData?.x ?? 0) - monitorData?.reserved[0]) * widthRatio * root.scale, 0) + xOffset; return Math.max((windowData?.at[0] - (monitorData?.x ?? 0) - monitorData?.reserved[0]) * widthRatio * root.scale, 0) + xOffset;
} }
property real initY: { property real initY: {
Math.max((windowData?.at[1] - (monitorData?.y ?? 0) - monitorData?.reserved[1]) * heightRatio * root.scale, 0) + yOffset; return Math.max((windowData?.at[1] - (monitorData?.y ?? 0) - monitorData?.reserved[1]) * heightRatio * root.scale, 0) + yOffset;
} }
property real xOffset: 0 property real xOffset: 0
property real yOffset: 0 property real yOffset: 0
@@ -58,12 +57,20 @@ Item { // Window
height: targetWindowHeight height: targetWindowHeight
opacity: windowData.monitor == widgetMonitorId ? 1 : 0.4 opacity: windowData.monitor == widgetMonitorId ? 1 : 0.4
property real topLeftRadius
property real topRightRadius
property real bottomLeftRadius
property real bottomRightRadius
layer.enabled: true layer.enabled: true
layer.effect: OpacityMask { layer.effect: OpacityMask {
maskSource: Rectangle { maskSource: Rectangle {
width: root.width width: root.width
height: root.height height: root.height
radius: Appearance.rounding.windowRounding * root.scale topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomRightRadius: root.bottomRightRadius
bottomLeftRadius: root.bottomLeftRadius
} }
} }
@@ -89,11 +96,14 @@ Item { // Window
// Color overlay for interactions // Color overlay for interactions
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
radius: Appearance.rounding.windowRounding * root.scale topLeftRadius: root.topLeftRadius
topRightRadius: root.topRightRadius
bottomRightRadius: root.bottomRightRadius
bottomLeftRadius: root.bottomLeftRadius
color: pressed ? ColorUtils.transparentize(Appearance.colors.colLayer2Active, 0.5) : color: pressed ? ColorUtils.transparentize(Appearance.colors.colLayer2Active, 0.5) :
hovered ? ColorUtils.transparentize(Appearance.colors.colLayer2Hover, 0.7) : hovered ? ColorUtils.transparentize(Appearance.colors.colLayer2Hover, 0.7) :
ColorUtils.transparentize(Appearance.colors.colLayer2) ColorUtils.transparentize(Appearance.colors.colLayer2)
border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.7) border.color : ColorUtils.transparentize(Appearance.m3colors.m3outline, 0.88)
border.width : 1 border.width : 1
} }
@@ -106,7 +116,7 @@ Item { // Window
// console.log("Icon ratio:", root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) // console.log("Icon ratio:", root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio)
// console.log("Scale:", root.monitorData.scale) // console.log("Scale:", root.monitorData.scale)
// console.log("Final:", Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / root.monitorData.scale) // console.log("Final:", Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) / root.monitorData.scale)
return Math.min(targetWindowWidth, targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio); return Math.min(root.targetWindowWidth, root.targetWindowHeight) * (root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio);
} }
// mipmap: true // mipmap: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter