notifications: no selection ring on modal open clipboard: match the notification header and add a settings butto

settings/interface: explicit window radius match option
cc: restore dim in edit mode

fixes #3623
This commit is contained in:
bbedward
2026-09-29 17:44:20 -04:00
parent f025a8d7b4
commit 5cfda4ebe7
9 changed files with 132 additions and 63 deletions
@@ -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()
}
}
}
@@ -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
}
}
@@ -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)
+1 -16
View File
@@ -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
@@ -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 {
@@ -103,6 +103,7 @@ Item {
id: notificationHeader
objectName: "notificationHeader"
historyView: historyList
transientSurfaceTracker: root.host.transientSurfaceTracker ?? null
onHeightChanged: root.cachedHeaderHeight = height
onSettingsRequested: {
@@ -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
}
}
@@ -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
@@ -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",