diff --git a/quickshell/Modals/Clipboard/ClipboardActions.qml b/quickshell/Modals/Clipboard/ClipboardActions.qml index ea8eeebc8..c0d36df23 100644 --- a/quickshell/Modals/Clipboard/ClipboardActions.qml +++ b/quickshell/Modals/Clipboard/ClipboardActions.qml @@ -2,43 +2,70 @@ import QtQuick import qs.Common import qs.Widgets -Row { +Item { id: actions required property var modal + readonly property real sideWidth: Math.max(leading.width, trailing.width) - spacing: Theme.spacingS + implicitWidth: leading.width + Theme.spacingXS + trailing.width + implicitHeight: Theme.buttonHeightXS - DankActionButton { - Keys.forwardTo: [actions.modal.modalFocusScope] - iconName: "push_pin" - buttonSize: Theme.buttonHeightXXS - iconSize: Theme.iconSizeSmall - iconColor: actions.modal.activeTab === "saved" ? Theme.onPrimary : Theme.onSurfaceVariant - backgroundColor: actions.modal.activeTab === "saved" ? Theme.primary : "transparent" - visible: actions.modal.pinnedCount > 0 || actions.modal.activeTab === "saved" - tooltipText: actions.modal.activeTab === "saved" ? I18n.tr("Recent", "clipboard button tooltip, switches to recent entries") : I18n.tr("Saved", "clipboard button tooltip, switches to saved entries") - onClicked: actions.modal.activeTab = actions.modal.activeTab === "saved" ? "recents" : "saved" + Row { + id: leading + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingXS + + DankActionButton { + Keys.forwardTo: [actions.modal.modalFocusScope] + iconName: "push_pin" + iconColor: actions.modal.activeTab === "saved" ? Theme.onPrimary : Theme.onSurfaceVariant + backgroundColor: actions.modal.activeTab === "saved" ? Theme.primary : "transparent" + visible: actions.modal.pinnedCount > 0 || actions.modal.activeTab === "saved" + tooltipText: actions.modal.activeTab === "saved" ? I18n.tr("Recent", "clipboard button tooltip, switches to recent entries") : I18n.tr("Saved", "clipboard button tooltip, switches to saved entries") + onClicked: actions.modal.activeTab = actions.modal.activeTab === "saved" ? "recents" : "saved" + } + + DankActionButton { + Keys.forwardTo: [actions.modal.modalFocusScope] + objectName: "keyboardHints" + iconName: "info" + iconColor: actions.modal.showKeyboardHints ? Theme.onSecondaryContainer : Theme.onSurfaceVariant + backgroundColor: actions.modal.showKeyboardHints ? Theme.secondaryContainer : "transparent" + tooltipText: I18n.tr("Keyboard shortcuts") + onClicked: actions.modal.showKeyboardHints = !actions.modal.showKeyboardHints + } } - DankActionButton { - Keys.forwardTo: [actions.modal.modalFocusScope] - objectName: "keyboardHints" - iconName: "info" - buttonSize: Theme.buttonHeightXXS - iconSize: Theme.iconSizeSmall - iconColor: actions.modal.showKeyboardHints ? Theme.onSecondaryContainer : Theme.onSurfaceVariant - backgroundColor: actions.modal.showKeyboardHints ? Theme.secondaryContainer : "transparent" - tooltipText: I18n.tr("Keyboard shortcuts") - onClicked: actions.modal.showKeyboardHints = !actions.modal.showKeyboardHints - } + Row { + id: trailing + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingXS - DankActionButton { - Keys.forwardTo: [actions.modal.modalFocusScope] - iconName: "delete_sweep" - buttonSize: Theme.buttonHeightXXS - iconSize: Theme.iconSizeSmall - tooltipText: actions.modal.clearsFilteredOnly ? I18n.tr("Clear Filtered", "clipboard modal: clear button tooltip while a search filter is active") : I18n.tr("Clear All") - onClicked: actions.modal.confirmClearAll() + DankActionButton { + Keys.forwardTo: [actions.modal.modalFocusScope] + iconName: "settings" + tooltipText: I18n.tr("Settings") + onClicked: actions.modal.openSettings() + } + + DankActionButton { + Keys.forwardTo: [actions.modal.modalFocusScope] + iconName: "delete_sweep" + iconColor: Theme.onSecondaryContainer + backgroundColor: Theme.secondaryContainer + tooltipText: actions.modal.clearsFilteredOnly ? I18n.tr("Clear Filtered", "clipboard modal: clear button tooltip while a search filter is active") : I18n.tr("Clear All") + onClicked: actions.modal.confirmClearAll() + } + + DankActionButton { + Keys.forwardTo: [actions.modal.modalFocusScope] + visible: !actions.modal.popout + iconName: "close" + tooltipText: I18n.tr("Close") + onClicked: actions.modal.hide() + } } } diff --git a/quickshell/Modals/Clipboard/ClipboardHeader.qml b/quickshell/Modals/Clipboard/ClipboardHeader.qml index c053a7a2c..e029f6bcc 100644 --- a/quickshell/Modals/Clipboard/ClipboardHeader.qml +++ b/quickshell/Modals/Clipboard/ClipboardHeader.qml @@ -2,19 +2,28 @@ import QtQuick import qs.Common import qs.Widgets -DankWindowHeader { +Item { id: header required property var modal + readonly property bool savedTab: modal.activeTab === "saved" - controls: null - horizontalPadding: 0 - verticalPadding: 0 - showDivider: false - title: (modal.activeTab === "saved" ? I18n.tr("Clipboard Saved") : I18n.tr("Clipboard History")) + ` (${modal.activeTab === "saved" ? modal.pinnedEntries.length : modal.unpinnedEntries.length})` - onCloseRequested: modal.hide() + implicitHeight: actions.implicitHeight ClipboardActions { + id: actions + anchors.fill: parent modal: header.modal } + + StyledText { + anchors.centerIn: parent + width: Math.max(0, parent.width - 2 * (actions.sideWidth + Theme.spacingM)) + text: (header.savedTab ? I18n.tr("Clipboard Saved") : I18n.tr("Clipboard History")) + ` (${header.savedTab ? header.modal.pinnedEntries.length : header.modal.unpinnedEntries.length})` + font.pixelSize: Theme.fontSizeMedium + font.weight: Theme.fontWeightMedium + color: Theme.surfaceText + horizontalAlignment: Text.AlignHCenter + elide: Text.ElideRight + } } diff --git a/quickshell/Modals/Clipboard/ClipboardHistoryContent.qml b/quickshell/Modals/Clipboard/ClipboardHistoryContent.qml index d616c2e06..32a445fc1 100644 --- a/quickshell/Modals/Clipboard/ClipboardHistoryContent.qml +++ b/quickshell/Modals/Clipboard/ClipboardHistoryContent.qml @@ -100,6 +100,12 @@ FocusScope { requestClose(false); } + function openSettings() { + const host = surfaceHost; + requestClose(false); + PopoutService.openSettingsWithTab("clipboard", host, () => host?.show()); + } + function pasteSelected() { const entry = selectedEntry(); if (!entry) diff --git a/quickshell/Modals/NotificationModal.qml b/quickshell/Modals/NotificationModal.qml index 8a59c3f57..496c331fd 100644 --- a/quickshell/Modals/NotificationModal.qml +++ b/quickshell/Modals/NotificationModal.qml @@ -24,22 +24,6 @@ DankModal { NotificationService.onOverlayOpen(); open(); modalKeyboardController.reset(); - if (modalKeyboardController && notificationListRef) { - modalKeyboardController.listView = notificationListRef; - modalKeyboardController.rebuildFlatNavigation(); - - Qt.callLater(() => { - modalKeyboardController.keyboardNavigationActive = true; - modalKeyboardController.selectedFlatIndex = 0; - modalKeyboardController.updateSelectedIdFromIndex(); - if (notificationListRef) { - notificationListRef.keyboardActive = true; - notificationListRef.currentIndex = 0; - } - modalKeyboardController.selectionVersion++; - modalKeyboardController.ensureVisible(); - }); - } } function hide() { @@ -227,6 +211,7 @@ DankModal { id: notificationHeader modal: true keyboardController: modalKeyboardController + historyView: historyList transientSurfaceTracker: notificationModal.transientSurfaceTracker onCloseRequested: notificationModal.hide() onCurrentTabChanged: notificationModal.currentTab = currentTab diff --git a/quickshell/Modules/ControlCenter/Widgets/CcTile.qml b/quickshell/Modules/ControlCenter/Widgets/CcTile.qml index 4ef18da32..2024065ed 100644 --- a/quickshell/Modules/ControlCenter/Widgets/CcTile.qml +++ b/quickshell/Modules/ControlCenter/Widgets/CcTile.qml @@ -47,13 +47,14 @@ Item { readonly property bool tall: height >= CcMetrics.gridRowUnit * 2 readonly property bool hasIconBox: (showExpand || opensPage || expanded) && !compact + readonly property bool showsActive: active && interactive readonly property real restRadius: { - if (active) + if (showsActive) return Math.min(CcMetrics.tileActiveRadius, width / 2, height / 2); return tall ? Math.min(CcMetrics.tallTileRadius, width / 2, height / 2) : Theme.fullRadius(width, height); } readonly property bool acceptsInput: interactive && enabled - readonly property bool bodyActive: active && !hasIconBox + readonly property bool bodyActive: showsActive && !hasIconBox readonly property color bodyColor: { if (!enabled) return Theme.onSurface_12; @@ -73,20 +74,20 @@ Item { if (!enabled) return Theme.onSurface_38; if (hasIconBox) - return active ? CcMetrics.tileActiveContent : CcMetrics.tileInactiveContent; + return showsActive ? CcMetrics.tileActiveContent : CcMetrics.tileInactiveContent; return bodyActive ? CcMetrics.tileActiveContent : root.restIconColor; } readonly property color iconBoxColor: { if (!enabled) return Theme.onSurface_12; - return active ? CcMetrics.tileActiveColor : CcMetrics.iconBoxInactiveColor; + return showsActive ? CcMetrics.tileActiveColor : CcMetrics.iconBoxInactiveColor; } property real bodyRadius: bodyLayer.pressed ? Math.min(Theme.cornerRadiusM, width / 2, height / 2) : restRadius property real iconBoxRadius: { if (boxLayer.pressed) return Math.min(Theme.cornerRadiusS, CcMetrics.iconBoxSize / 2); - if (active) + if (showsActive) return Math.min(CcMetrics.iconBoxActiveRadius, CcMetrics.iconBoxSize / 2); return Theme.fullRadius(CcMetrics.iconBoxSize, CcMetrics.iconBoxSize); } @@ -198,7 +199,7 @@ Item { name: root.iconName size: CcMetrics.tileIconSize color: root.iconColor - filled: root.active + filled: root.showsActive rotation: root.iconRotation visible: root.compact @@ -260,7 +261,7 @@ Item { name: root.iconName size: root.hasIconBox ? CcMetrics.iconBoxIconSize : CcMetrics.tileIconSize color: root.iconColor - filled: root.active + filled: root.showsActive rotation: root.iconRotation DankBlink { diff --git a/quickshell/Modules/Notifications/Center/NotificationCenterContent.qml b/quickshell/Modules/Notifications/Center/NotificationCenterContent.qml index 634dd8aac..9f8581a72 100644 --- a/quickshell/Modules/Notifications/Center/NotificationCenterContent.qml +++ b/quickshell/Modules/Notifications/Center/NotificationCenterContent.qml @@ -103,6 +103,7 @@ Item { id: notificationHeader objectName: "notificationHeader" + historyView: historyList transientSurfaceTracker: root.host.transientSurfaceTracker ?? null onHeightChanged: root.cachedHeaderHeight = height onSettingsRequested: { diff --git a/quickshell/Modules/Notifications/Center/NotificationHeader.qml b/quickshell/Modules/Notifications/Center/NotificationHeader.qml index cbb2f4bd2..db47ac8e0 100644 --- a/quickshell/Modules/Notifications/Center/NotificationHeader.qml +++ b/quickshell/Modules/Notifications/Center/NotificationHeader.qml @@ -8,9 +8,11 @@ Item { id: root property var keyboardController: null + property var historyView: null property int currentTab: 0 property var transientSurfaceTracker: null property bool modal: false + readonly property var hintsOwner: currentTab === 1 && historyView ? historyView : keyboardController readonly property string currentLabel: { const count = NotificationService.notifications.length; if (count === 0) @@ -75,11 +77,15 @@ Item { } DankActionButton { - visible: root.keyboardController !== null + readonly property bool hintsShown: root.hintsOwner?.showKeyboardHints ?? false + + visible: root.hintsOwner !== null iconName: "info" buttonSize: Theme.buttonHeightXS + backgroundColor: hintsShown ? Theme.secondaryContainer : "transparent" + iconColor: hintsShown ? Theme.onSecondaryContainer : Theme.onSurfaceVariant tooltipText: I18n.tr("Keyboard shortcuts") - onClicked: root.keyboardController.showKeyboardHints = !root.keyboardController.showKeyboardHints + onClicked: root.hintsOwner.showKeyboardHints = !hintsShown } } diff --git a/quickshell/Modules/Settings/ThemeSurfacesTab.qml b/quickshell/Modules/Settings/ThemeSurfacesTab.qml index e65c3b8c5..f27272588 100644 --- a/quickshell/Modules/Settings/ThemeSurfacesTab.qml +++ b/quickshell/Modules/Settings/ThemeSurfacesTab.qml @@ -257,13 +257,25 @@ Column { onSliderValueChanged: newValue => SettingsData.set("fixedRadius", newValue) } + SettingsToggleRow { + tab: "theme" + tags: ["window", "corner", "radius", "match", "follow", "link", "strength", "compositor"] + settingKey: "windowRadiusMatch" + text: I18n.tr("Match corner style", "toggle: window radius follows the corner style setting") + visible: root.windowRadiusKey !== "" + resetKeys: root.windowRadiusKey !== "" ? [root.windowRadiusKey] : [] + checked: Theme.compositorRadiusOverride < 0 + onToggled: checked => SettingsData.set(root.windowRadiusKey, checked ? -1 : Math.round(Theme.windowRadius)) + } + SettingsSliderRow { tab: "theme" tags: ["window", "corner", "radius", "rounded", "popout", "menu", "modal", "compositor", "niri", "hyprland", "mango"] settingKey: "windowRadius" text: I18n.tr("Window radius") visible: root.windowRadiusKey !== "" - resetKeys: root.windowRadiusKey !== "" ? [root.windowRadiusKey] : [] + enabled: Theme.compositorRadiusOverride >= 0 + resetKeys: [] value: Theme.windowRadius minimum: 0 maximum: 64 diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index bf37c9d01..90cfed5b0 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -1527,6 +1527,28 @@ ], "page": "notifications" }, + { + "section": "windowRadiusMatch", + "label": "Match corner style", + "tabIndex": -1, + "category": "Interface style", + "keywords": [ + "compositor", + "corner", + "corners", + "follow", + "interface", + "link", + "match", + "radius", + "round", + "rounded", + "strength", + "style", + "window" + ], + "page": "theme_surfaces" + }, { "section": "matugenTargetMonitor", "label": "Matugen source display",