From 7f4a626a83a9c749e8de9a573320a4482406f965 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:54:05 +0100 Subject: [PATCH 1/5] background: make digital clock quote not italic --- dots/.config/quickshell/ii/modules/background/Background.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/background/Background.qml b/dots/.config/quickshell/ii/modules/background/Background.qml index 9209450be..f36cf3590 100644 --- a/dots/.config/quickshell/ii/modules/background/Background.qml +++ b/dots/.config/quickshell/ii/modules/background/Background.qml @@ -334,7 +334,6 @@ Variants { font { pixelSize: Appearance.font.pixelSize.normal weight: 350 - italic: true } color: bgRoot.colText style: Text.Raised From 83ce5f3fea284f567b89d8584174224bff70396c Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:54:23 +0100 Subject: [PATCH 2/5] refractor animated index pair in workspaces --- .../quickshell/ii/modules/bar/Workspaces.qml | 25 +++++------------- .../common/models/AnimatedTabIndexPair.qml | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/common/models/AnimatedTabIndexPair.qml diff --git a/dots/.config/quickshell/ii/modules/bar/Workspaces.qml b/dots/.config/quickshell/ii/modules/bar/Workspaces.qml index f1da2dab3..f0a61ef23 100644 --- a/dots/.config/quickshell/ii/modules/bar/Workspaces.qml +++ b/dots/.config/quickshell/ii/modules/bar/Workspaces.qml @@ -1,6 +1,7 @@ import qs import qs.services import qs.modules.common +import qs.modules.common.models import qs.modules.common.widgets import qs.modules.common.functions import QtQuick @@ -163,12 +164,12 @@ Item { horizontalCenter: vertical ? parent.horizontalCenter : undefined } - // idx1 is the "leading" indicator position, idx2 is the "following" one - // The former animates faster than the latter, see the NumberAnimations below - property real idx1: workspaceIndexInGroup - property real idx2: workspaceIndexInGroup - property real indicatorPosition: Math.min(idx1, idx2) * workspaceButtonWidth + root.activeWorkspaceMargin - property real indicatorLength: Math.abs(idx1 - idx2) * workspaceButtonWidth + workspaceButtonWidth - root.activeWorkspaceMargin * 2 + AnimatedTabIndexPair { + id: idxPair + index: root.workspaceIndexInGroup + } + property real indicatorPosition: Math.min(idxPair.idx1, idxPair.idx2) * workspaceButtonWidth + root.activeWorkspaceMargin + property real indicatorLength: Math.abs(idxPair.idx1 - idxPair.idx2) * workspaceButtonWidth + workspaceButtonWidth - root.activeWorkspaceMargin * 2 property real indicatorThickness: workspaceButtonWidth - root.activeWorkspaceMargin * 2 x: root.vertical ? null : indicatorPosition @@ -176,18 +177,6 @@ Item { y: root.vertical ? indicatorPosition : null implicitHeight: root.vertical ? indicatorLength : indicatorThickness - Behavior on idx1 { - NumberAnimation { - duration: 100 - easing.type: Easing.OutSine - } - } - Behavior on idx2 { - NumberAnimation { - duration: 300 - easing.type: Easing.OutSine - } - } } // Workspaces - numbers diff --git a/dots/.config/quickshell/ii/modules/common/models/AnimatedTabIndexPair.qml b/dots/.config/quickshell/ii/modules/common/models/AnimatedTabIndexPair.qml new file mode 100644 index 000000000..c18e9ccf2 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/models/AnimatedTabIndexPair.qml @@ -0,0 +1,26 @@ +import QtQuick + +// idx1 is the "leading" indicator position, idx2 is the "following" one +// The former animates faster than the latter, see the NumberAnimations below +QtObject { + id: root + required property int index + + property real idx1: index + property real idx2: index + property int idx1Duration: 100 + property int idx2Duration: 300 + + Behavior on idx1 { + NumberAnimation { + duration: root.idx1Duration + easing.type: Easing.OutSine + } + } + Behavior on idx2 { + NumberAnimation { + duration: root.idx2Duration + easing.type: Easing.OutSine + } + } +} From 4f712116c21ff9484555f582b4b5ddb3b4476bf6 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:54:47 +0100 Subject: [PATCH 3/5] adjust IconAndTextToolbarButton spacing --- .../ii/modules/common/widgets/IconAndTextToolbarButton.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/common/widgets/IconAndTextToolbarButton.qml b/dots/.config/quickshell/ii/modules/common/widgets/IconAndTextToolbarButton.qml index 45f90f8a1..875aec400 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/IconAndTextToolbarButton.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/IconAndTextToolbarButton.qml @@ -13,7 +13,7 @@ ToolbarButton { contentItem: Row { anchors.centerIn: parent - spacing: 6 + spacing: 4 MaterialSymbol { anchors.verticalCenter: parent.verticalCenter From 7c974b7fb4b57d0417cf880a54258a423efa4885 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:55:16 +0100 Subject: [PATCH 4/5] wallpaper selector: adjust quick dir button appearance --- .../ii/modules/wallpaperSelector/WallpaperSelectorContent.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dots/.config/quickshell/ii/modules/wallpaperSelector/WallpaperSelectorContent.qml b/dots/.config/quickshell/ii/modules/wallpaperSelector/WallpaperSelectorContent.qml index a093d38ca..c237a8854 100644 --- a/dots/.config/quickshell/ii/modules/wallpaperSelector/WallpaperSelectorContent.qml +++ b/dots/.config/quickshell/ii/modules/wallpaperSelector/WallpaperSelectorContent.qml @@ -186,6 +186,8 @@ MouseArea { colBackgroundToggled: Appearance.colors.colSecondaryContainer colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover colRippleToggled: Appearance.colors.colSecondaryContainerActive + buttonRadius: height / 2 + implicitHeight: 38 contentItem: RowLayout { MaterialSymbol { From 087a736d1aaee6d75b3445b011b85850ad91aef5 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 3 Nov 2025 17:00:28 +0100 Subject: [PATCH 5/5] left sidebar: toolbar-style tabs --- .../modules/common/widgets/PrimaryTabBar.qml | 11 +- .../ii/modules/common/widgets/Toolbar.qml | 12 +- .../modules/common/widgets/ToolbarTabBar.qml | 103 ++++++++++++++++++ .../common/widgets/ToolbarTabButton.qml | 40 +++++++ .../sidebarLeft/SidebarLeftContent.qml | 39 +++---- 5 files changed, 174 insertions(+), 31 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabBar.qml create mode 100644 dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabButton.qml diff --git a/dots/.config/quickshell/ii/modules/common/widgets/PrimaryTabBar.qml b/dots/.config/quickshell/ii/modules/common/widgets/PrimaryTabBar.qml index 474bdc591..d606c9e17 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/PrimaryTabBar.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/PrimaryTabBar.qml @@ -9,7 +9,7 @@ ColumnLayout { id: root spacing: 0 required property var tabButtonList // Something like [{"icon": "notifications", "name": Translation.tr("Notifications")}, {"icon": "volume_up", "name": Translation.tr("Volume mixer")}] - property int currentIndex + property alias currentIndex: tabBar.currentIndex property bool enableIndicatorAnimation: false property color colIndicator: Appearance?.colors.colPrimary ?? "#65558F" property color colBorder: Appearance?.m3colors.m3outlineVariant ?? "#C6C6D0" @@ -26,17 +26,14 @@ ColumnLayout { TabBar { id: tabBar Layout.fillWidth: true - Synchronizer on currentIndex { - property alias source: root.currentIndex - } background: Item { WheelHandler { onWheel: (event) => { if (event.angleDelta.y < 0) - tabBar.currentIndex = Math.min(tabBar.currentIndex + 1, root.tabButtonList.length - 1) + tabBar.incrementCurrentIndex() else if (event.angleDelta.y > 0) - tabBar.currentIndex = Math.max(tabBar.currentIndex - 1, 0) + tabBar.decrementCurrentIndex() } acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad } @@ -49,7 +46,7 @@ ColumnLayout { buttonText: modelData.name buttonIcon: modelData.icon minimumWidth: 160 - onClicked: root.currentIndex = index + onClicked: tabBar.setCurrentIndex(index) } } } diff --git a/dots/.config/quickshell/ii/modules/common/widgets/Toolbar.qml b/dots/.config/quickshell/ii/modules/common/widgets/Toolbar.qml index 85112160f..51348c4fa 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/Toolbar.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/Toolbar.qml @@ -10,6 +10,7 @@ import qs.modules.common.widgets Item { id: root + property bool enableShadow: true property real padding: 8 property alias colBackground: background.color property alias spacing: toolbarLayout.spacing @@ -18,15 +19,20 @@ Item { implicitHeight: background.implicitHeight property alias radius: background.radius - StyledRectangularShadow { - target: background + Loader { + active: root.enableShadow + anchors.fill: background + sourceComponent: StyledRectangularShadow { + target: background + anchors.fill: undefined + } } Rectangle { id: background anchors.fill: parent color: Appearance.m3colors.m3surfaceContainer - implicitHeight: Math.max(toolbarLayout.implicitHeight + root.padding * 2, 56) + implicitHeight: 56 implicitWidth: toolbarLayout.implicitWidth + root.padding * 2 radius: height / 2 diff --git a/dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabBar.qml b/dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabBar.qml new file mode 100644 index 000000000..c72263a9c --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabBar.qml @@ -0,0 +1,103 @@ +pragma ComponentBehavior: Bound +import qs.modules.common +import qs.modules.common.models +import qs.services +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Qt.labs.synchronizer + +Item { + id: root + property alias currentIndex: tabBar.currentIndex + required property var tabButtonList + + function incrementCurrentIndex() { + tabBar.incrementCurrentIndex() + } + function decrementCurrentIndex() { + tabBar.decrementCurrentIndex() + } + function setCurrentIndex(index) { + tabBar.setCurrentIndex(index) + } + + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + implicitWidth: contentItem.implicitWidth + implicitHeight: 40 + + Row { + id: contentItem + z: 1 + anchors.centerIn: parent + spacing: 4 + + Repeater { + model: root.tabButtonList + delegate: ToolbarTabButton { + required property int index + required property var modelData + current: index == root.currentIndex + text: modelData.name + materialSymbol: modelData.icon + onClicked: { + root.setCurrentIndex(index) + } + } + } + } + + Rectangle { + id: activeIndicator + z: 0 + color: Appearance.colors.colSecondaryContainer + implicitWidth: contentItem.children[root.currentIndex].implicitWidth + implicitHeight: contentItem.children[root.currentIndex].implicitHeight + radius: height / 2 + // Animation + property Item targetItem: contentItem.children[root.currentIndex] + AnimatedTabIndexPair { + id: leftBound + idx1Duration: 50 + idx2Duration: 200 + index: activeIndicator.targetItem.x + } + AnimatedTabIndexPair { + id: rightBound + idx1Duration: 50 + idx2Duration: 200 + index: activeIndicator.targetItem.x + activeIndicator.targetItem.width + } + x: Math.min(leftBound.idx1, leftBound.idx2) + width: Math.max(rightBound.idx1, rightBound.idx2) - x + } + + MouseArea { + anchors.fill: parent + z: 2 + acceptedButtons: Qt.NoButton + cursorShape: Qt.PointingHandCursor + onWheel: (event) => { + if (event.angleDelta.y < 0) { + root.incrementCurrentIndex(); + } + else { + root.decrementCurrentIndex(); + } + } + } + + // TabBar doesn't allow tabs to be of different sizes. Literally unusable. + // We use it only for the logic and draw stuff manually + TabBar { + id: tabBar + z: -1 + background: null + Repeater { // This is to fool the TabBar that it has tabs so it does the indices properly + model: root.tabButtonList.length + delegate: TabButton { + background: null + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabButton.qml b/dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabButton.qml new file mode 100644 index 000000000..e53518875 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/ToolbarTabButton.qml @@ -0,0 +1,40 @@ +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.common.functions +import Qt5Compat.GraphicalEffects +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +RippleButton { + id: root + required property string materialSymbol + required property bool current + horizontalPadding: 10 + + implicitHeight: 40 + implicitWidth: implicitContentWidth + horizontalPadding * 2 + buttonRadius: height / 2 + + colBackground: ColorUtils.transparentize(Appearance.colors.colSurfaceContainer) + colBackgroundHover: ColorUtils.transparentize(Appearance.colors.colOnSurface, current ? 1 : 0.95) + colRipple: ColorUtils.transparentize(Appearance.colors.colOnSurface, 0.95) + + contentItem: Row { + id: contentRow + anchors.centerIn: parent + spacing: 6 + + MaterialSymbol { + id: icon + anchors.verticalCenter: parent.verticalCenter + iconSize: 22 + text: root.materialSymbol + } + StyledText { + id: label + anchors.verticalCenter: parent.verticalCenter + text: root.text + } + } +} diff --git a/dots/.config/quickshell/ii/modules/sidebarLeft/SidebarLeftContent.qml b/dots/.config/quickshell/ii/modules/sidebarLeft/SidebarLeftContent.qml index ff1c34509..063a2866f 100644 --- a/dots/.config/quickshell/ii/modules/sidebarLeft/SidebarLeftContent.qml +++ b/dots/.config/quickshell/ii/modules/sidebarLeft/SidebarLeftContent.qml @@ -21,7 +21,6 @@ Item { ...(root.translatorEnabled ? [{"icon": "translate", "name": Translation.tr("Translator")}] : []), ...((root.animeEnabled && !root.animeCloset) ? [{"icon": "bookmark_heart", "name": Translation.tr("Anime")}] : []) ] - property int selectedTab: 0 property int tabCount: swipeView.count function focusActiveItem() { @@ -31,36 +30,39 @@ Item { Keys.onPressed: (event) => { if (event.modifiers === Qt.ControlModifier) { if (event.key === Qt.Key_PageDown) { - root.selectedTab = Math.min(root.selectedTab + 1, root.tabCount - 1) + swipeView.incrementCurrentIndex() event.accepted = true; - } + } else if (event.key === Qt.Key_PageUp) { - root.selectedTab = Math.max(root.selectedTab - 1, 0) + swipeView.decrementCurrentIndex() event.accepted = true; } else if (event.key === Qt.Key_Tab) { - root.selectedTab = (root.selectedTab + 1) % root.tabCount; + swipeView.setCurrentIndex((swipeView.currentIndex + 1) % swipeView.count); event.accepted = true; } else if (event.key === Qt.Key_Backtab) { - root.selectedTab = (root.selectedTab - 1 + root.tabCount) % root.tabCount; + swipeView.setCurrentIndex((swipeView.currentIndex - 1 + swipeView.count) % swipeView.count); event.accepted = true; } } } ColumnLayout { - anchors.fill: parent - anchors.margins: sidebarPadding - + anchors { + fill: parent + margins: sidebarPadding + } spacing: sidebarPadding - PrimaryTabBar { // Tab strip - id: tabBar - visible: root.tabButtonList.length > 1 - tabButtonList: root.tabButtonList - Synchronizer on currentIndex { - property alias source: root.selectedTab + Toolbar { + Layout.alignment: Qt.AlignHCenter + enableShadow: false + ToolbarTabBar { + id: tabBar + Layout.alignment: Qt.AlignHCenter + tabButtonList: root.tabButtonList + currentIndex: swipeView.currentIndex } } @@ -70,12 +72,7 @@ Item { Layout.fillWidth: true Layout.fillHeight: true spacing: 10 - - currentIndex: root.selectedTab - onCurrentIndexChanged: { - tabBar.enableIndicatorAnimation = true - root.selectedTab = currentIndex - } + currentIndex: tabBar.currentIndex clip: true layer.enabled: true