diff --git a/dots/.config/hypr/hyprland/rules.conf b/dots/.config/hypr/hyprland/rules.conf index 9cb877f7c..4891ee854 100644 --- a/dots/.config/hypr/hyprland/rules.conf +++ b/dots/.config/hypr/hyprland/rules.conf @@ -141,6 +141,9 @@ layerrule = noanim, quickshell:lockWindowPusher layerrule = animation fade, quickshell:notificationPopup layerrule = noanim, quickshell:overview layerrule = animation slide bottom, quickshell:osk +layerrule = noanim, quickshell:polkit +layerrule = xray 0, quickshell:popup # No weird color for bar tooltips (this in theory should suffice) +layerrule = ignorealpha 1, quickshell:popup # No weird color for bar tooltips (but somehow this is necessary) layerrule = noanim, quickshell:regionSelector layerrule = noanim, quickshell:screenshot layerrule = blur, quickshell:session diff --git a/dots/.config/quickshell/ii/modules/bar/StyledPopup.qml b/dots/.config/quickshell/ii/modules/bar/StyledPopup.qml index 9b030685f..650d770b6 100644 --- a/dots/.config/quickshell/ii/modules/bar/StyledPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/StyledPopup.qml @@ -70,7 +70,7 @@ LazyLoader { } implicitWidth: root.contentItem.implicitWidth + margin * 2 implicitHeight: root.contentItem.implicitHeight + margin * 2 - color: ColorUtils.applyAlpha(Appearance.colors.colSurfaceContainer, 1 - Appearance.backgroundTransparency) + color: Appearance.m3colors.m3surfaceContainer radius: Appearance.rounding.small children: [root.contentItem] diff --git a/dots/.config/quickshell/ii/modules/common/widgets/NotificationAppIcon.qml b/dots/.config/quickshell/ii/modules/common/widgets/NotificationAppIcon.qml index 795a708be..b590f22ac 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/NotificationAppIcon.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/NotificationAppIcon.qml @@ -27,7 +27,7 @@ MaterialShape { // App icon ] shape: isUrgent ? urgentShapes[Math.floor(Math.random() * urgentShapes.length)] : MaterialShape.Shape.Circle - color: isUrgent ? Appearance.colors.colPrimary : Appearance.colors.colSecondaryContainer + color: isUrgent ? Appearance.colors.colPrimaryContainer : Appearance.colors.colSecondaryContainer Loader { id: materialSymbolLoader active: root.appIcon == "" @@ -40,7 +40,7 @@ MaterialShape { // App icon "priority_high" : guessedIcon } anchors.fill: parent - color: isUrgent ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer + color: isUrgent ? Appearance.colors.colOnPrimaryContainer : Appearance.colors.colOnSecondaryContainer iconSize: root.materialIconSize horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter diff --git a/dots/.config/quickshell/ii/modules/overview/OverviewWidget.qml b/dots/.config/quickshell/ii/modules/overview/OverviewWidget.qml index 0eff4b53e..50e3a8ee1 100644 --- a/dots/.config/quickshell/ii/modules/overview/OverviewWidget.qml +++ b/dots/.config/quickshell/ii/modules/overview/OverviewWidget.qml @@ -1,8 +1,10 @@ +pragma ComponentBehavior: Bound import qs import qs.services import qs.modules.common import qs.modules.common.widgets import qs.modules.common.functions +import Qt5Compat.GraphicalEffects import QtQuick import QtQuick.Layouts import Quickshell @@ -30,6 +32,8 @@ Item { property real workspaceImplicitHeight: (monitorData?.transform % 2 === 1) ? ((monitor.width - 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 workspaceNumberSize: 250 * monitor.scale @@ -58,10 +62,8 @@ Item { implicitWidth: workspaceColumnLayout.implicitWidth + padding * 2 implicitHeight: workspaceColumnLayout.implicitHeight + padding * 2 - radius: Appearance.rounding.screenRounding * root.scale + padding - color: Appearance.colors.colLayer0 - border.width: 1 - border.color: Appearance.colors.colLayer0Border + radius: root.largeWorkspaceRadius + padding + color: Appearance.colors.colBackgroundSurfaceContainer Column { // Workspaces id: workspaceColumnLayout @@ -69,20 +71,22 @@ Item { z: root.workspaceZ anchors.centerIn: parent spacing: workspaceSpacing + Repeater { model: Config.options.overview.rows delegate: Row { id: row - property int rowIndex: index + required property int index spacing: workspaceSpacing Repeater { // Workspace repeater model: Config.options.overview.columns Rectangle { // Workspace id: workspace + required property int index property int colIndex: index - property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * Config.options.overview.columns + colIndex + 1 - property color defaultWorkspaceColor: Appearance.colors.colLayer1 // TODO: reconsider this color for a cleaner look + property int workspaceValue: root.workspaceGroup * root.workspacesShown + row.index * Config.options.overview.columns + colIndex + 1 + 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 hoveredBorderColor: Appearance.colors.colLayer2Hover property bool hoveredWhileDragging: false @@ -90,13 +94,20 @@ Item { implicitWidth: root.workspaceImplicitWidth implicitHeight: root.workspaceImplicitHeight 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.color: hoveredWhileDragging ? hoveredBorderColor : "transparent" StyledText { anchors.centerIn: parent - text: workspaceValue + text: workspace.workspaceValue font { pixelSize: root.workspaceNumberSize * root.scale weight: Font.DemiBold @@ -114,7 +125,7 @@ Item { onPressed: { if (root.draggingTargetWorkspace === -1) { GlobalStates.overviewOpen = false - Hyprland.dispatch(`workspace ${workspaceValue}`) + Hyprland.dispatch(`workspace ${workspace.workspaceValue}`) } } } @@ -122,13 +133,13 @@ Item { DropArea { anchors.fill: parent onEntered: { - root.draggingTargetWorkspace = workspaceValue + root.draggingTargetWorkspace = workspace.workspaceValue if (root.draggingFromWorkspace == root.draggingTargetWorkspace) return; hoveredWhileDragging = true } onExited: { hoveredWhileDragging = false - if (root.draggingTargetWorkspace == workspaceValue) root.draggingTargetWorkspace = -1 + if (root.draggingTargetWorkspace == workspace.workspaceValue) root.draggingTargetWorkspace = -1 } } @@ -165,17 +176,41 @@ Item { toplevel: modelData monitorData: this.monitor scale: root.scale - availableWorkspaceWidth: root.workspaceImplicitWidth - availableWorkspaceHeight: root.workspaceImplicitHeight widgetMonitor: HyprlandData.monitors.find(m => m.id == root.monitor.id) windowData: windowByAddress[address] property bool atInitPosition: (initX == x && initY == y) + // Offset on the canvas 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) xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex 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 { id: updateWindowPosition @@ -183,8 +218,8 @@ Item { repeat: false running: false onTriggered: { - window.x = Math.round(Math.max((windowData?.at[0] - (monitor?.x ?? 0) - monitorData?.reserved[0]) * root.scale, 0) + xOffset) - window.y = Math.round(Math.max((windowData?.at[1] - (monitor?.y ?? 0) - monitorData?.reserved[1]) * root.scale, 0) + yOffset) + window.x = Math.round(xWithinWorkspaceWidget + xOffset) + window.y = Math.round(yWithinWorkspaceWidget + yOffset) } } @@ -252,15 +287,22 @@ Item { Rectangle { // Focused workspace indicator id: focusedWorkspaceIndicator property int activeWorkspaceInGroup: monitor.activeWorkspace?.id - (root.workspaceGroup * root.workspacesShown) - property int activeWorkspaceRowIndex: Math.floor((activeWorkspaceInGroup - 1) / Config.options.overview.columns) - property int activeWorkspaceColIndex: (activeWorkspaceInGroup - 1) % Config.options.overview.columns - x: (root.workspaceImplicitWidth + workspaceSpacing) * activeWorkspaceColIndex - y: (root.workspaceImplicitHeight + workspaceSpacing) * activeWorkspaceRowIndex + property int rowIndex: Math.floor((activeWorkspaceInGroup - 1) / Config.options.overview.columns) + property int colIndex: (activeWorkspaceInGroup - 1) % Config.options.overview.columns + x: (root.workspaceImplicitWidth + workspaceSpacing) * colIndex + y: (root.workspaceImplicitHeight + workspaceSpacing) * rowIndex z: root.windowZ width: root.workspaceImplicitWidth height: root.workspaceImplicitHeight 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.color: root.activeBorderColor Behavior on x { @@ -269,6 +311,18 @@ Item { Behavior on y { 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) + } } } } diff --git a/dots/.config/quickshell/ii/modules/overview/OverviewWindow.qml b/dots/.config/quickshell/ii/modules/overview/OverviewWindow.qml index d55eeedf7..e531c4b8c 100644 --- a/dots/.config/quickshell/ii/modules/overview/OverviewWindow.qml +++ b/dots/.config/quickshell/ii/modules/overview/OverviewWindow.qml @@ -1,3 +1,4 @@ +pragma ComponentBehavior: Bound import qs import qs.services import qs.modules.common @@ -14,25 +15,23 @@ Item { // Window property var windowData property var monitorData property var scale - property var availableWorkspaceWidth - property var availableWorkspaceHeight property bool restrictToWorkspace: true property real widthRatio: { const widgetWidth = widgetMonitor.transform & 1 ? widgetMonitor.height : widgetMonitor.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: { const widgetHeight = widgetMonitor.transform & 1 ? widgetMonitor.width : widgetMonitor.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: { - 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: { - 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 yOffset: 0 @@ -58,12 +57,20 @@ Item { // Window height: targetWindowHeight opacity: windowData.monitor == widgetMonitorId ? 1 : 0.4 + property real topLeftRadius + property real topRightRadius + property real bottomLeftRadius + property real bottomRightRadius + layer.enabled: true layer.effect: OpacityMask { maskSource: Rectangle { width: root.width 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 Rectangle { 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) : hovered ? ColorUtils.transparentize(Appearance.colors.colLayer2Hover, 0.7) : 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 } @@ -106,7 +116,7 @@ Item { // Window // console.log("Icon ratio:", root.compactMode ? root.iconToWindowRatioCompact : root.iconToWindowRatio) // console.log("Scale:", 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 Layout.alignment: Qt.AlignHCenter diff --git a/dots/.config/quickshell/ii/modules/overview/SearchBar.qml b/dots/.config/quickshell/ii/modules/overview/SearchBar.qml index 653e3d3f0..a0abd54c8 100644 --- a/dots/.config/quickshell/ii/modules/overview/SearchBar.qml +++ b/dots/.config/quickshell/ii/modules/overview/SearchBar.qml @@ -18,7 +18,7 @@ RowLayout { property alias searchInput: searchInput property string searchingText - function focus() { + function forceFocus() { searchInput.forceActiveFocus(); } diff --git a/dots/.config/quickshell/ii/modules/overview/SearchItem.qml b/dots/.config/quickshell/ii/modules/overview/SearchItem.qml index 9b6ca28d9..8f72db56a 100644 --- a/dots/.config/quickshell/ii/modules/overview/SearchItem.qml +++ b/dots/.config/quickshell/ii/modules/overview/SearchItem.qml @@ -36,11 +36,11 @@ RippleButton { implicitHeight: rowLayout.implicitHeight + root.buttonVerticalPadding * 2 implicitWidth: rowLayout.implicitWidth + root.buttonHorizontalPadding * 2 buttonRadius: Appearance.rounding.normal - colBackground: (root.down || root.keyboardDown) ? Appearance.colors.colSecondaryContainerActive : - ((root.hovered || root.focus) ? Appearance.colors.colSecondaryContainer : - ColorUtils.transparentize(Appearance.colors.colSecondaryContainer, 1)) - colBackgroundHover: Appearance.colors.colSecondaryContainer - colRipple: Appearance.colors.colSecondaryContainerActive + colBackground: (root.down || root.keyboardDown) ? Appearance.colors.colPrimaryContainerActive : + ((root.hovered || root.focus) ? Appearance.colors.colPrimaryContainer : + ColorUtils.transparentize(Appearance.colors.colPrimaryContainer, 1)) + colBackgroundHover: Appearance.colors.colPrimaryContainer + colRipple: Appearance.colors.colPrimaryContainerActive property string highlightPrefix: `` property string highlightSuffix: `` @@ -228,7 +228,7 @@ RippleButton { visible: (root.hovered || root.focus) id: clickAction font.pixelSize: Appearance.font.pixelSize.normal - color: Appearance.colors.colSubtext + color: Appearance.colors.colOnPrimaryContainer horizontalAlignment: Text.AlignRight text: root.itemClickActionName } diff --git a/dots/.config/quickshell/ii/modules/overview/SearchWidget.qml b/dots/.config/quickshell/ii/modules/overview/SearchWidget.qml index 5286d0697..03ebfce1b 100644 --- a/dots/.config/quickshell/ii/modules/overview/SearchWidget.qml +++ b/dots/.config/quickshell/ii/modules/overview/SearchWidget.qml @@ -17,7 +17,7 @@ Item { // Wrapper property string searchingText: "" property bool showResults: searchingText != "" implicitWidth: searchWidgetContent.implicitWidth + Appearance.sizes.elevationMargin * 2 - implicitHeight: searchWidgetContent.implicitHeight + Appearance.sizes.elevationMargin * 2 + implicitHeight: searchBar.implicitHeight + searchBar.verticalPadding * 2 + Appearance.sizes.elevationMargin * 2 property string mathResult: "" property bool clipboardWorkSafetyActive: { @@ -94,7 +94,7 @@ Item { // Wrapper } function focusSearchInput() { - searchBar.focus(); + searchBar.forceFocus(); } function disableExpandAnimation() { @@ -201,15 +201,29 @@ Item { // Wrapper } Rectangle { // Background id: searchWidgetContent - anchors.centerIn: parent + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + topMargin: Appearance.sizes.elevationMargin + } + clip: true implicitWidth: columnLayout.implicitWidth implicitHeight: columnLayout.implicitHeight radius: searchBar.height / 2 + searchBar.verticalPadding color: Appearance.colors.colBackgroundSurfaceContainer + Behavior on implicitHeight { + id: searchHeightBehavior + enabled: GlobalStates.overviewOpen && root.showResults + animation: Appearance.animation.elementMove.numberAnimation.createObject(this) + } + ColumnLayout { id: columnLayout - anchors.centerIn: parent + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + } spacing: 0 // clip: true diff --git a/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml b/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml index 2c5b9f3e2..baef7f0b5 100644 --- a/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml +++ b/dots/.config/quickshell/ii/modules/polkit/PolkitContent.qml @@ -52,7 +52,7 @@ Item { MaterialSymbol { Layout.alignment: Qt.AlignHCenter iconSize: 26 - text: "shield_locked" + text: "security" color: Appearance.colors.colSecondary }