mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-20 01:55:20 -04:00
Compare commits
11 Commits
8d94117a69
..
hover
| Author | SHA1 | Date | |
|---|---|---|---|
| fc72b6d779 | |||
| 3701b3d7a3 | |||
| bae98daa5c | |||
| b34a04f723 | |||
| 1c0245f2db | |||
| 7777e87dc8 | |||
| 820fa07846 | |||
| 66794582c9 | |||
| 73eb471ae3 | |||
| 0f2f4b96c4 | |||
| d53809cf2b |
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
@@ -16,8 +17,76 @@ Singleton {
|
|||||||
signal popoutOpening
|
signal popoutOpening
|
||||||
signal popoutChanged
|
signal popoutChanged
|
||||||
|
|
||||||
|
property real hoverCursorGlobalX: 0
|
||||||
|
property real hoverCursorGlobalY: 0
|
||||||
|
|
||||||
|
function updateHoverCursor(gx, gy) {
|
||||||
|
hoverCursorGlobalX = gx;
|
||||||
|
hoverCursorGlobalY = gy;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cursorOverBar(gx, gy, padding) {
|
||||||
|
const pad = padding !== undefined ? padding : 16;
|
||||||
|
const bars = KeyboardFocus.barWindows || [];
|
||||||
|
for (let i = 0; i < bars.length; i++) {
|
||||||
|
const w = bars[i];
|
||||||
|
if (!w?.visible)
|
||||||
|
continue;
|
||||||
|
if (typeof w.containsGlobalPoint === "function") {
|
||||||
|
if (w.containsGlobalPoint(gx, gy, pad))
|
||||||
|
return true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const item = w.contentItem;
|
||||||
|
if (!item || typeof item.mapToItem !== "function")
|
||||||
|
continue;
|
||||||
|
const topLeft = item.mapToItem(null, 0, 0);
|
||||||
|
if (!topLeft)
|
||||||
|
continue;
|
||||||
|
if (gx >= topLeft.x - pad && gx < topLeft.x + item.width + pad && gy >= topLeft.y - pad && gy < topLeft.y + item.height + pad)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isPopoutPresented(popout) {
|
||||||
|
if (!popout)
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
if (popout.dashVisible !== undefined)
|
||||||
|
return !!popout.dashVisible;
|
||||||
|
if (popout.notificationHistoryVisible !== undefined)
|
||||||
|
return !!popout.notificationHistoryVisible;
|
||||||
|
return !!(popout.shouldBeVisible || popout.isClosing);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _openPopout(popout) {
|
||||||
|
if (popout.dashVisible !== undefined) {
|
||||||
|
if (popout.dashVisible && !popout.shouldBeVisible && !popout.isClosing)
|
||||||
|
popout.dashVisible = false;
|
||||||
|
popout.dashVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (popout.notificationHistoryVisible !== undefined) {
|
||||||
|
popout.notificationHistoryVisible = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
popout.open();
|
||||||
|
}
|
||||||
|
|
||||||
function _closePopout(popout) {
|
function _closePopout(popout) {
|
||||||
try {
|
try {
|
||||||
|
if (popout?.hoverDismissEnabled) {
|
||||||
|
if (typeof popout.closeFromHoverDismiss === "function") {
|
||||||
|
popout.closeFromHoverDismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (popout.hoverDismissEnabled !== undefined)
|
||||||
|
popout.hoverDismissEnabled = false;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case popout.dashVisible !== undefined:
|
case popout.dashVisible !== undefined:
|
||||||
popout.dashVisible = false;
|
popout.dashVisible = false;
|
||||||
@@ -89,7 +158,26 @@ Singleton {
|
|||||||
continue;
|
continue;
|
||||||
_closePopout(popout);
|
_closePopout(popout);
|
||||||
}
|
}
|
||||||
currentPopoutsByScreen = {};
|
// Keep map entries until each popout's close animation finishes (hidePopout).
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopoutForScreen(screen) {
|
||||||
|
if (!screen)
|
||||||
|
return;
|
||||||
|
const screenName = screen.name;
|
||||||
|
const popout = currentPopoutsByScreen[screenName];
|
||||||
|
if (!popout || _isStale(popout)) {
|
||||||
|
currentPopoutsByScreen[screenName] = null;
|
||||||
|
currentPopoutTriggers[screenName] = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_closePopout(popout);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelHoverDismiss(screen) {
|
||||||
|
const popout = getActivePopout(screen);
|
||||||
|
if (popout?.cancelHoverDismiss)
|
||||||
|
popout.cancelHoverDismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActivePopout(screen) {
|
function getActivePopout(screen) {
|
||||||
@@ -106,6 +194,8 @@ Singleton {
|
|||||||
function requestPopout(popout, tabIndex, triggerSource) {
|
function requestPopout(popout, tabIndex, triggerSource) {
|
||||||
if (!popout || !popout.screen)
|
if (!popout || !popout.screen)
|
||||||
return;
|
return;
|
||||||
|
if (popout.hoverDismissEnabled !== undefined)
|
||||||
|
popout.hoverDismissEnabled = false;
|
||||||
screenshotActive = false;
|
screenshotActive = false;
|
||||||
const screenName = popout.screen.name;
|
const screenName = popout.screen.name;
|
||||||
const currentPopout = currentPopoutsByScreen[screenName];
|
const currentPopout = currentPopoutsByScreen[screenName];
|
||||||
@@ -181,16 +271,81 @@ Singleton {
|
|||||||
ModalManager.closeAllModalsExcept(null);
|
ModalManager.closeAllModalsExcept(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movedFromOtherScreen) {
|
_openPopout(popout);
|
||||||
popout.open();
|
}
|
||||||
} else {
|
|
||||||
if (popout.dashVisible !== undefined) {
|
function requestHoverPopout(popout, tabIndex, triggerSource) {
|
||||||
popout.dashVisible = true;
|
if (!popout || !popout.screen)
|
||||||
} else if (popout.notificationHistoryVisible !== undefined) {
|
return;
|
||||||
popout.notificationHistoryVisible = true;
|
screenshotActive = false;
|
||||||
|
const screenName = popout.screen.name;
|
||||||
|
const currentPopout = currentPopoutsByScreen[screenName];
|
||||||
|
const triggerId = triggerSource !== undefined ? triggerSource : tabIndex;
|
||||||
|
|
||||||
|
const willOpen = !(currentPopout === popout && _isPopoutPresented(popout) && triggerId !== undefined && currentPopoutTriggers[screenName] === triggerId);
|
||||||
|
if (willOpen)
|
||||||
|
popoutOpening();
|
||||||
|
|
||||||
|
let movedFromOtherScreen = false;
|
||||||
|
for (const otherScreenName in currentPopoutsByScreen) {
|
||||||
|
if (otherScreenName === screenName)
|
||||||
|
continue;
|
||||||
|
const otherPopout = currentPopoutsByScreen[otherScreenName];
|
||||||
|
if (!otherPopout)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_isStale(otherPopout)) {
|
||||||
|
currentPopoutsByScreen[otherScreenName] = null;
|
||||||
|
currentPopoutTriggers[otherScreenName] = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otherPopout === popout) {
|
||||||
|
movedFromOtherScreen = true;
|
||||||
|
currentPopoutsByScreen[otherScreenName] = null;
|
||||||
|
currentPopoutTriggers[otherScreenName] = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_closePopout(otherPopout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPopout && currentPopout !== popout) {
|
||||||
|
if (_isStale(currentPopout)) {
|
||||||
|
currentPopoutsByScreen[screenName] = null;
|
||||||
|
currentPopoutTriggers[screenName] = null;
|
||||||
} else {
|
} else {
|
||||||
popout.open();
|
_closePopout(currentPopout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentPopout === popout && _isPopoutPresented(popout) && !movedFromOtherScreen) {
|
||||||
|
if (triggerId !== undefined && currentPopoutTriggers[screenName] === triggerId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tabIndex !== undefined && popout.currentTabIndex !== undefined)
|
||||||
|
popout.currentTabIndex = tabIndex;
|
||||||
|
if (popout.updateSurfacePosition)
|
||||||
|
popout.updateSurfacePosition();
|
||||||
|
currentPopoutTriggers[screenName] = triggerId;
|
||||||
|
if (popout.hoverDismissEnabled !== undefined)
|
||||||
|
popout.hoverDismissEnabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPopoutTriggers[screenName] = triggerId;
|
||||||
|
currentPopoutsByScreen[screenName] = popout;
|
||||||
|
popoutChanged();
|
||||||
|
|
||||||
|
if (tabIndex !== undefined && popout.currentTabIndex !== undefined)
|
||||||
|
popout.currentTabIndex = tabIndex;
|
||||||
|
|
||||||
|
if (currentPopout !== popout)
|
||||||
|
ModalManager.closeAllModalsExcept(null);
|
||||||
|
|
||||||
|
if (popout.hoverDismissEnabled !== undefined)
|
||||||
|
popout.hoverDismissEnabled = true;
|
||||||
|
|
||||||
|
_openPopout(popout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property bool clipboardEnterToPaste: false
|
property bool clipboardEnterToPaste: false
|
||||||
|
property var clipboardVisibleEntryActions: ["pin", "edit", "delete"]
|
||||||
|
|
||||||
property var launcherPluginVisibility: ({})
|
property var launcherPluginVisibility: ({})
|
||||||
|
|
||||||
@@ -809,7 +810,8 @@ Singleton {
|
|||||||
"shadowOpacity": 60,
|
"shadowOpacity": 60,
|
||||||
"shadowColorMode": "default",
|
"shadowColorMode": "default",
|
||||||
"shadowCustomColor": "#000000",
|
"shadowCustomColor": "#000000",
|
||||||
"clickThrough": false
|
"clickThrough": false,
|
||||||
|
"hoverPopouts": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1650,6 +1652,15 @@ Singleton {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function effectiveBarConfigForRender(config, usesFrameBarChrome) {
|
||||||
|
if (!config || !connectedFrameModeActive || usesFrameBarChrome)
|
||||||
|
return config;
|
||||||
|
const backup = connectedFrameBarStyleBackups[config.id];
|
||||||
|
if (!backup)
|
||||||
|
return config;
|
||||||
|
return Object.assign({}, config, backup);
|
||||||
|
}
|
||||||
|
|
||||||
// Single entry point for connected-mode settings state.
|
// Single entry point for connected-mode settings state.
|
||||||
// !active → restore backups
|
// !active → restore backups
|
||||||
function _reconcileConnectedFrameBarStyles() {
|
function _reconcileConnectedFrameBarStyles() {
|
||||||
|
|||||||
@@ -572,6 +572,7 @@ var SPEC = {
|
|||||||
|
|
||||||
builtInPluginSettings: { def: {} },
|
builtInPluginSettings: { def: {} },
|
||||||
clipboardEnterToPaste: { def: false },
|
clipboardEnterToPaste: { def: false },
|
||||||
|
clipboardVisibleEntryActions: { def: ["pin", "edit", "delete"] },
|
||||||
|
|
||||||
launcherPluginVisibility: { def: {} },
|
launcherPluginVisibility: { def: {} },
|
||||||
launcherPluginOrder: { def: [] },
|
launcherPluginOrder: { def: [] },
|
||||||
|
|||||||
+2
-19
@@ -64,27 +64,15 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool wallpaperSurfacesLoaded: true
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: blurredWallpaperBackgroundLoader
|
id: blurredWallpaperBackgroundLoader
|
||||||
active: root.wallpaperSurfacesLoaded && SettingsData.blurredWallpaperLayer && CompositorService.isNiri
|
active: SettingsData.blurredWallpaperLayer && CompositorService.isNiri
|
||||||
asynchronous: false
|
asynchronous: false
|
||||||
|
|
||||||
sourceComponent: BlurredWallpaperBackground {}
|
sourceComponent: BlurredWallpaperBackground {}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeferredAction {
|
WallpaperBackground {}
|
||||||
id: wallpaperSurfaceReloadAction
|
|
||||||
onTriggered: root.wallpaperSurfacesLoaded = true
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: wallpaperBackgroundLoader
|
|
||||||
active: root.wallpaperSurfacesLoaded
|
|
||||||
asynchronous: false
|
|
||||||
sourceComponent: WallpaperBackground {}
|
|
||||||
}
|
|
||||||
|
|
||||||
DesktopWidgetLayer {}
|
DesktopWidgetLayer {}
|
||||||
|
|
||||||
@@ -398,11 +386,6 @@ Item {
|
|||||||
frameSurfaceReloadAction.schedule();
|
frameSurfaceReloadAction.schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.wallpaperSurfacesLoaded) {
|
|
||||||
root.wallpaperSurfacesLoaded = false;
|
|
||||||
wallpaperSurfaceReloadAction.schedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
root.dockEnabled = false;
|
root.dockEnabled = false;
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
root.dockEnabled = true;
|
root.dockEnabled = true;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Item {
|
|||||||
id: clipboardContent
|
id: clipboardContent
|
||||||
|
|
||||||
required property var modal
|
required property var modal
|
||||||
required property var clearConfirmDialog
|
|
||||||
|
|
||||||
property alias searchField: searchField
|
property alias searchField: searchField
|
||||||
property alias clipboardListView: clipboardListView
|
property alias clipboardListView: clipboardListView
|
||||||
@@ -33,14 +32,7 @@ Item {
|
|||||||
pinnedCount: modal.pinnedCount
|
pinnedCount: modal.pinnedCount
|
||||||
onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints
|
onKeyboardHintsToggled: modal.showKeyboardHints = !modal.showKeyboardHints
|
||||||
onTabChanged: tabName => modal.activeTab = tabName
|
onTabChanged: tabName => modal.activeTab = tabName
|
||||||
onClearAllClicked: {
|
onClearAllClicked: modal.confirmClearAll()
|
||||||
const hasPinned = modal.pinnedCount > 0;
|
|
||||||
const message = hasPinned ? I18n.tr("This will delete all unpinned entries. %1 pinned entries will be kept.").arg(modal.pinnedCount) : I18n.tr("This will permanently delete all clipboard history.");
|
|
||||||
clearConfirmDialog.show(I18n.tr("Clear History?"), message, function () {
|
|
||||||
modal.clearAll();
|
|
||||||
modal.hide();
|
|
||||||
}, function () {});
|
|
||||||
}
|
|
||||||
onCloseClicked: modal.hide()
|
onCloseClicked: modal.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,14 @@ Rectangle {
|
|||||||
readonly property string entryType: modal ? modal.getEntryType(entry) : "text"
|
readonly property string entryType: modal ? modal.getEntryType(entry) : "text"
|
||||||
readonly property string entryPreview: modal ? modal.getEntryPreview(entry) : ""
|
readonly property string entryPreview: modal ? modal.getEntryPreview(entry) : ""
|
||||||
readonly property var pinnedDuplicateEntry: !entry.pinned ? ClipboardService.getPinnedEntryByHash(entry.hash) : null
|
readonly property var pinnedDuplicateEntry: !entry.pinned ? ClipboardService.getPinnedEntryByHash(entry.hash) : null
|
||||||
readonly property bool effectivePinned: entry.pinned || pinnedDuplicateEntry !== null
|
readonly property bool hasPinnedDuplicate: pinnedDuplicateEntry !== null
|
||||||
|
readonly property bool effectivePinned: entry.pinned || hasPinnedDuplicate
|
||||||
|
readonly property var visibleEntryActions: SettingsData.clipboardVisibleEntryActions || ["pin", "edit", "delete"]
|
||||||
|
readonly property bool showPinAction: visibleEntryActions.includes("pin")
|
||||||
|
readonly property bool showEditAction: visibleEntryActions.includes("edit")
|
||||||
|
readonly property bool showDeleteAction: visibleEntryActions.includes("delete")
|
||||||
|
readonly property bool showPinnedIndicator: hasPinnedDuplicate && !showPinAction
|
||||||
|
readonly property bool showAnyAction: showPinAction || showEditAction || showDeleteAction || showPinnedIndicator
|
||||||
|
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
@@ -63,12 +70,28 @@ Rectangle {
|
|||||||
anchors.rightMargin: Theme.spacingS
|
anchors.rightMargin: Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingXS
|
spacing: Theme.spacingXS
|
||||||
|
visible: root.showAnyAction
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
visible: root.showPinnedIndicator
|
||||||
|
|
||||||
|
// Status indicator only; the Pin action remains hidden.
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "push_pin"
|
||||||
|
size: Theme.iconSize - 6
|
||||||
|
color: Theme.primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DankActionButton {
|
DankActionButton {
|
||||||
iconName: "push_pin"
|
iconName: "push_pin"
|
||||||
iconSize: Theme.iconSize - 6
|
iconSize: Theme.iconSize - 6
|
||||||
iconColor: effectivePinned ? Theme.primary : Theme.surfaceText
|
iconColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primary : Theme.surfaceText
|
||||||
backgroundColor: effectivePinned ? Theme.primarySelected : "transparent"
|
backgroundColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primarySelected : "transparent"
|
||||||
|
visible: root.showPinAction
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (entry.pinned) {
|
if (entry.pinned) {
|
||||||
unpinRequested(entry);
|
unpinRequested(entry);
|
||||||
@@ -86,6 +109,7 @@ Rectangle {
|
|||||||
iconName: "edit"
|
iconName: "edit"
|
||||||
iconSize: Theme.iconSize - 6
|
iconSize: Theme.iconSize - 6
|
||||||
iconColor: Theme.surfaceText
|
iconColor: Theme.surfaceText
|
||||||
|
visible: root.showEditAction
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (entryType === "image") {
|
if (entryType === "image") {
|
||||||
@@ -99,6 +123,7 @@ Rectangle {
|
|||||||
iconName: "close"
|
iconName: "close"
|
||||||
iconSize: Theme.iconSize - 6
|
iconSize: Theme.iconSize - 6
|
||||||
iconColor: Theme.surfaceText
|
iconColor: Theme.surfaceText
|
||||||
|
visible: root.showDeleteAction
|
||||||
onClicked: deleteRequested()
|
onClicked: deleteRequested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,8 +131,8 @@ Rectangle {
|
|||||||
Item {
|
Item {
|
||||||
anchors.left: indexBadge.right
|
anchors.left: indexBadge.right
|
||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
anchors.right: actionButtons.left
|
anchors.right: root.showAnyAction ? actionButtons.left : parent.right
|
||||||
anchors.rightMargin: Theme.spacingM
|
anchors.rightMargin: root.showAnyAction ? Theme.spacingM : Theme.spacingS
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
// height: contentColumn.implicitHeight
|
// height: contentColumn.implicitHeight
|
||||||
height: ClipboardConstants.itemHeight
|
height: ClipboardConstants.itemHeight
|
||||||
@@ -168,8 +193,8 @@ Rectangle {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: actionButtons.left
|
anchors.right: root.showAnyAction ? actionButtons.left : parent.right
|
||||||
anchors.rightMargin: Theme.spacingS
|
anchors.rightMargin: root.showAnyAction ? Theme.spacingS : 0
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|||||||
@@ -82,6 +82,15 @@ FocusScope {
|
|||||||
ClipboardService.clearAll();
|
ClipboardService.clearAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function confirmClearAll() {
|
||||||
|
const hasPinned = pinnedCount > 0;
|
||||||
|
const message = hasPinned ? I18n.tr("This will delete all unpinned entries. %1 pinned entries will be kept.").arg(pinnedCount) : I18n.tr("This will permanently delete all clipboard history.");
|
||||||
|
clearConfirmDialog.show(I18n.tr("Clear History?"), message, function () {
|
||||||
|
clearAll();
|
||||||
|
hide();
|
||||||
|
}, function () {});
|
||||||
|
}
|
||||||
|
|
||||||
function getEntryPreview(entry) {
|
function getEntryPreview(entry) {
|
||||||
return ClipboardService.getEntryPreview(entry);
|
return ClipboardService.getEntryPreview(entry);
|
||||||
}
|
}
|
||||||
@@ -135,7 +144,6 @@ FocusScope {
|
|||||||
id: historyContent
|
id: historyContent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
modal: root
|
modal: root
|
||||||
clearConfirmDialog: root.clearConfirmDialog
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,22 +77,35 @@ DankModal {
|
|||||||
id: clearConfirmDialog
|
id: clearConfirmDialog
|
||||||
confirmButtonText: I18n.tr("Clear All")
|
confirmButtonText: I18n.tr("Clear All")
|
||||||
confirmButtonColor: Theme.primary
|
confirmButtonColor: Theme.primary
|
||||||
onVisibleChanged: {
|
onShouldBeVisibleChanged: {
|
||||||
if (visible) {
|
if (shouldBeVisible) {
|
||||||
clipboardHistoryModal.shouldHaveFocus = false;
|
clipboardHistoryModal.shouldHaveFocus = false;
|
||||||
|
selectedButton = 0;
|
||||||
|
keyboardNavigation = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
if (!clipboardHistoryModal.shouldBeVisible) {
|
if (!clipboardHistoryModal.shouldBeVisible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clipboardHistoryModal.shouldHaveFocus = true;
|
clipboardHistoryModal.shouldHaveFocus = Qt.binding(() => clipboardHistoryModal.shouldBeVisible);
|
||||||
clipboardHistoryModal.modalFocusScope.forceActiveFocus();
|
clipboardHistoryModal.modalFocusScope.forceActiveFocus();
|
||||||
if (clipboardHistoryModal.contentLoader.item?.searchField) {
|
if (clipboardHistoryModal.contentLoader.item?.searchField) {
|
||||||
clipboardHistoryModal.contentLoader.item.searchField.forceActiveFocus();
|
clipboardHistoryModal.contentLoader.item.searchField.forceActiveFocus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Connections {
|
||||||
|
target: clearConfirmDialog.modalFocusScope.Keys
|
||||||
|
function onPressed(event) {
|
||||||
|
if (!clearConfirmDialog.shouldBeVisible || event.key !== Qt.Key_Backtab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearConfirmDialog.selectedButton = clearConfirmDialog.selectedButton === -1 ? 1 : (clearConfirmDialog.selectedButton - 1 + 2) % 2;
|
||||||
|
clearConfirmDialog.keyboardNavigation = true;
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Modals.Clipboard
|
import qs.Modals.Clipboard
|
||||||
import qs.Modals.Common
|
import qs.Modals.Common
|
||||||
@@ -95,6 +96,35 @@ DankPopout {
|
|||||||
id: clearConfirmDialog
|
id: clearConfirmDialog
|
||||||
confirmButtonText: I18n.tr("Clear All")
|
confirmButtonText: I18n.tr("Clear All")
|
||||||
confirmButtonColor: Theme.primary
|
confirmButtonColor: Theme.primary
|
||||||
|
onShouldBeVisibleChanged: {
|
||||||
|
if (shouldBeVisible) {
|
||||||
|
root.customKeyboardFocus = WlrKeyboardFocus.None;
|
||||||
|
selectedButton = 0;
|
||||||
|
keyboardNavigation = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
root.customKeyboardFocus = null;
|
||||||
|
Qt.callLater(function () {
|
||||||
|
if (!root.shouldBeVisible || !root.contentLoader.item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
root.contentLoader.item.forceActiveFocus();
|
||||||
|
if (root.contentLoader.item.searchField) {
|
||||||
|
root.contentLoader.item.searchField.forceActiveFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: clearConfirmDialog.modalFocusScope.Keys
|
||||||
|
function onPressed(event) {
|
||||||
|
if (!clearConfirmDialog.shouldBeVisible || event.key !== Qt.Key_Backtab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearConfirmDialog.selectedButton = clearConfirmDialog.selectedButton === -1 ? 1 : (clearConfirmDialog.selectedButton - 1 + 2) % 2;
|
||||||
|
clearConfirmDialog.keyboardNavigation = true;
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
|
|||||||
@@ -125,8 +125,6 @@ QtObject {
|
|||||||
if (!ClipboardService.keyboardNavigationActive) {
|
if (!ClipboardService.keyboardNavigationActive) {
|
||||||
ClipboardService.keyboardNavigationActive = true;
|
ClipboardService.keyboardNavigationActive = true;
|
||||||
ClipboardService.selectedIndex = 0;
|
ClipboardService.selectedIndex = 0;
|
||||||
} else if (ClipboardService.selectedIndex === 0) {
|
|
||||||
ClipboardService.keyboardNavigationActive = false;
|
|
||||||
} else {
|
} else {
|
||||||
selectPrevious();
|
selectPrevious();
|
||||||
}
|
}
|
||||||
@@ -155,8 +153,6 @@ QtObject {
|
|||||||
if (!ClipboardService.keyboardNavigationActive) {
|
if (!ClipboardService.keyboardNavigationActive) {
|
||||||
ClipboardService.keyboardNavigationActive = true;
|
ClipboardService.keyboardNavigationActive = true;
|
||||||
ClipboardService.selectedIndex = 0;
|
ClipboardService.selectedIndex = 0;
|
||||||
} else if (ClipboardService.selectedIndex === 0) {
|
|
||||||
ClipboardService.keyboardNavigationActive = false;
|
|
||||||
} else {
|
} else {
|
||||||
selectPrevious();
|
selectPrevious();
|
||||||
}
|
}
|
||||||
@@ -184,8 +180,7 @@ QtObject {
|
|||||||
if (event.modifiers & Qt.ShiftModifier) {
|
if (event.modifiers & Qt.ShiftModifier) {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case Qt.Key_Delete:
|
case Qt.Key_Delete:
|
||||||
modal.clearAll();
|
modal.confirmClearAll();
|
||||||
modal.hide();
|
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
return;
|
return;
|
||||||
case Qt.Key_Return:
|
case Qt.Key_Return:
|
||||||
|
|||||||
@@ -105,8 +105,8 @@ Rectangle {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "compositor_layout",
|
"id": "compositor_layout",
|
||||||
"text": CompositorService.isNiri ? "niri" : (CompositorService.isHyprland ? "Hyprland" : "MangoWC"),
|
"text": CompositorService.isNiri ? "Niri" : (CompositorService.isHyprland ? "Hyprland" : "MangoWC"),
|
||||||
"icon": "crop_square",
|
"icon": "layers",
|
||||||
"tabIndex": 37,
|
"tabIndex": 37,
|
||||||
"layoutCapable": true
|
"layoutCapable": true
|
||||||
}
|
}
|
||||||
@@ -117,18 +117,18 @@ Rectangle {
|
|||||||
"text": I18n.tr("Dank Bar"),
|
"text": I18n.tr("Dank Bar"),
|
||||||
"icon": "toolbar",
|
"icon": "toolbar",
|
||||||
"children": [
|
"children": [
|
||||||
{
|
|
||||||
"id": "dankbar_settings",
|
|
||||||
"text": I18n.tr("Settings"),
|
|
||||||
"icon": "tune",
|
|
||||||
"tabIndex": 3
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "dankbar_appearance",
|
"id": "dankbar_appearance",
|
||||||
"text": I18n.tr("Appearance"),
|
"text": I18n.tr("Appearance"),
|
||||||
"icon": "palette",
|
"icon": "palette",
|
||||||
"tabIndex": 6
|
"tabIndex": 6
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "dankbar_settings",
|
||||||
|
"text": I18n.tr("Settings"),
|
||||||
|
"icon": "tune",
|
||||||
|
"tabIndex": 3
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "dankbar_widgets",
|
"id": "dankbar_widgets",
|
||||||
"text": I18n.tr("Widgets"),
|
"text": I18n.tr("Widgets"),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import qs.Widgets
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
|
readonly property var log: Log.scoped("BlurredWallpaperBackground")
|
||||||
model: {
|
model: {
|
||||||
if (SessionData.isGreeterMode) {
|
if (SessionData.isGreeterMode) {
|
||||||
return Quickshell.screens;
|
return Quickshell.screens;
|
||||||
@@ -32,6 +33,8 @@ Variants {
|
|||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
updatesEnabled: root.renderActive || root._settleFrames > 0
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: Item {}
|
item: Item {}
|
||||||
}
|
}
|
||||||
@@ -85,7 +88,6 @@ Variants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
blurWallpaperWindow.updatesEnabled = Qt.binding(() => !root.source || root.effectActive || root._renderSettling || currentWallpaper.status === Image.Loading || nextWallpaper.status === Image.Loading);
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,51 +95,67 @@ Variants {
|
|||||||
property real transitionProgress: 0
|
property real transitionProgress: 0
|
||||||
readonly property bool transitioning: transitionAnimation.running
|
readonly property bool transitioning: transitionAnimation.running
|
||||||
property bool effectActive: false
|
property bool effectActive: false
|
||||||
property bool _renderSettling: true
|
|
||||||
property bool useNextForEffect: false
|
property bool useNextForEffect: false
|
||||||
|
readonly property var backingWindow: Window.window
|
||||||
|
readonly property bool renderActive: !source || effectActive || currentWallpaper.status === Image.Loading || nextWallpaper.status === Image.Loading
|
||||||
|
property int _settleFrames: 3
|
||||||
|
|
||||||
Connections {
|
function invalidate() {
|
||||||
target: currentWallpaper
|
_settleFrames = 3;
|
||||||
function onStatusChanged() {
|
backingWindow?.update();
|
||||||
if (currentWallpaper.status !== Image.Ready && currentWallpaper.status !== Image.Error)
|
|
||||||
return;
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRenderActiveChanged: invalidate()
|
||||||
|
onBackingWindowChanged: invalidate()
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: blurWallpaperWindow
|
target: root.backingWindow
|
||||||
|
function onFrameSwapped() {
|
||||||
|
if (root._settleFrames > 0)
|
||||||
|
root._settleFrames--;
|
||||||
|
}
|
||||||
|
function onVisibleChanged() {
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
function onWidthChanged() {
|
function onWidthChanged() {
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
function onHeightChanged() {
|
function onHeightChanged() {
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Quickshell
|
target: Quickshell
|
||||||
function onScreensChanged() {
|
function onScreensChanged() {
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onWallpaperFillModeChanged() {
|
function onWallpaperFillModeChanged() {
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Connections {
|
||||||
id: renderSettleTimer
|
target: IdleService
|
||||||
interval: 1000
|
function onIsShellLockedChanged() {
|
||||||
onTriggered: root._renderSettling = false
|
if (IdleService.isShellLocked)
|
||||||
|
return;
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleTransitionLoadError(failedSource) {
|
||||||
|
log.warn("failed to load candidate wallpaper for", modelData.name + ":", failedSource);
|
||||||
|
transitionDelayTimer.stop();
|
||||||
|
transitionAnimation.stop();
|
||||||
|
root.useNextForEffect = false;
|
||||||
|
root.effectActive = false;
|
||||||
|
root.transitionProgress = 0.0;
|
||||||
|
nextWallpaper.source = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
onSourceChanged: {
|
onSourceChanged: {
|
||||||
@@ -164,8 +182,6 @@ Variants {
|
|||||||
transitionAnimation.stop();
|
transitionAnimation.stop();
|
||||||
root.transitionProgress = 0.0;
|
root.transitionProgress = 0.0;
|
||||||
root.effectActive = false;
|
root.effectActive = false;
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
currentWallpaper.source = newSource;
|
currentWallpaper.source = newSource;
|
||||||
nextWallpaper.source = "";
|
nextWallpaper.source = "";
|
||||||
}
|
}
|
||||||
@@ -194,8 +210,6 @@ Variants {
|
|||||||
transitionAnimation.stop();
|
transitionAnimation.stop();
|
||||||
root.transitionProgress = 0;
|
root.transitionProgress = 0;
|
||||||
root.effectActive = false;
|
root.effectActive = false;
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
currentWallpaper.source = nextWallpaper.source;
|
currentWallpaper.source = nextWallpaper.source;
|
||||||
nextWallpaper.source = "";
|
nextWallpaper.source = "";
|
||||||
}
|
}
|
||||||
@@ -204,9 +218,6 @@ Variants {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
|
|
||||||
nextWallpaper.source = newPath;
|
nextWallpaper.source = newPath;
|
||||||
|
|
||||||
if (nextWallpaper.status === Image.Ready)
|
if (nextWallpaper.status === Image.Ready)
|
||||||
@@ -215,7 +226,7 @@ Variants {
|
|||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: !root.source || root.isColorSource
|
active: !root.source || root.isColorSource || currentWallpaper.status === Image.Error
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: DankBackdrop {
|
sourceComponent: DankBackdrop {
|
||||||
@@ -238,6 +249,12 @@ Variants {
|
|||||||
cache: true
|
cache: true
|
||||||
sourceSize: Qt.size(root.textureWidth, root.textureHeight)
|
sourceSize: Qt.size(root.textureWidth, root.textureHeight)
|
||||||
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SessionData.getMonitorWallpaperFillMode(modelData.name))
|
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SessionData.getMonitorWallpaperFillMode(modelData.name))
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Image.Error) {
|
||||||
|
log.warn("failed to load active wallpaper for", modelData.name + ":", source);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -253,6 +270,10 @@ Variants {
|
|||||||
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SessionData.getMonitorWallpaperFillMode(modelData.name))
|
fillMode: root.getFillMode(SessionData.isGreeterMode ? GreetdSettings.wallpaperFillMode : SessionData.getMonitorWallpaperFillMode(modelData.name))
|
||||||
|
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
|
if (status === Image.Error) {
|
||||||
|
root.handleTransitionLoadError(source);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (status !== Image.Ready)
|
if (status !== Image.Ready)
|
||||||
return;
|
return;
|
||||||
if (!root.transitioning) {
|
if (!root.transitioning) {
|
||||||
@@ -329,8 +350,6 @@ Variants {
|
|||||||
root.useNextForEffect = false;
|
root.useNextForEffect = false;
|
||||||
nextWallpaper.source = "";
|
nextWallpaper.source = "";
|
||||||
root.transitionProgress = 0.0;
|
root.transitionProgress = 0.0;
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
root.effectActive = false;
|
root.effectActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -286,9 +286,6 @@ PanelWindow {
|
|||||||
|
|
||||||
readonly property bool isVertical: axis.isVertical
|
readonly property bool isVertical: axis.isVertical
|
||||||
|
|
||||||
property bool gothCornersEnabled: barConfig?.gothCornersEnabled ?? false
|
|
||||||
property real wingtipsRadius: barConfig?.gothCornerRadiusOverride ? (barConfig?.gothCornerRadiusValue ?? 12) : Theme.cornerRadius
|
|
||||||
readonly property real _wingR: Math.max(0, wingtipsRadius)
|
|
||||||
readonly property color _surfaceContainer: Theme.surfaceContainer
|
readonly property color _surfaceContainer: Theme.surfaceContainer
|
||||||
readonly property string _barId: barConfig?.id ?? "default"
|
readonly property string _barId: barConfig?.id ?? "default"
|
||||||
property real _backgroundAlpha: barConfig?.transparency ?? 1.0
|
property real _backgroundAlpha: barConfig?.transparency ?? 1.0
|
||||||
@@ -300,25 +297,30 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
readonly property real _dpr: CompositorService.getScreenScale(barWindow.screen)
|
readonly property real _dpr: CompositorService.getScreenScale(barWindow.screen)
|
||||||
|
|
||||||
|
property string screenName: modelData.name
|
||||||
|
|
||||||
|
readonly property bool usesConnectedFrameChrome: CompositorService.usesConnectedFrameChromeForScreen(screenName)
|
||||||
|
readonly property bool usesFrameBarChrome: CompositorService.frameWindowVisibleForScreen(screenName)
|
||||||
|
readonly property var renderBarConfig: SettingsData.effectiveBarConfigForRender(barConfig, usesFrameBarChrome)
|
||||||
|
|
||||||
|
property bool gothCornersEnabled: renderBarConfig?.gothCornersEnabled ?? false
|
||||||
|
property real wingtipsRadius: renderBarConfig?.gothCornerRadiusOverride ? (renderBarConfig?.gothCornerRadiusValue ?? 12) : Theme.cornerRadius
|
||||||
|
readonly property real _wingR: Math.max(0, wingtipsRadius)
|
||||||
|
|
||||||
// Shadow buffer: extra window space for shadow to render beyond bar bounds
|
// Shadow buffer: extra window space for shadow to render beyond bar bounds
|
||||||
readonly property bool _shadowActive: (Theme.elevationEnabled && (typeof SettingsData !== "undefined" ? (SettingsData.barElevationEnabled ?? true) : false)) || (barConfig?.shadowIntensity ?? 0) > 0
|
readonly property bool _shadowActive: (Theme.elevationEnabled && (typeof SettingsData !== "undefined" ? (SettingsData.barElevationEnabled ?? true) : false)) || (renderBarConfig?.shadowIntensity ?? 0) > 0
|
||||||
readonly property real _shadowBuffer: {
|
readonly property real _shadowBuffer: {
|
||||||
if (!_shadowActive)
|
if (!_shadowActive)
|
||||||
return 0;
|
return 0;
|
||||||
const hasOverride = (barConfig?.shadowIntensity ?? 0) > 0;
|
const hasOverride = (renderBarConfig?.shadowIntensity ?? 0) > 0;
|
||||||
if (hasOverride) {
|
if (hasOverride) {
|
||||||
const blur = (barConfig.shadowIntensity ?? 0) * 0.2;
|
const blur = (renderBarConfig.shadowIntensity ?? 0) * 0.2;
|
||||||
const offset = blur * 0.5;
|
const offset = blur * 0.5;
|
||||||
return Theme.snap(Math.max(16, blur + offset + 8), _dpr);
|
return Theme.snap(Math.max(16, blur + offset + 8), _dpr);
|
||||||
}
|
}
|
||||||
return Theme.snap(Theme.elevationRenderPadding(Theme.elevationLevel2, "top", 4, 8, 16), _dpr);
|
return Theme.snap(Theme.elevationRenderPadding(Theme.elevationLevel2, "top", 4, 8, 16), _dpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
property string screenName: modelData.name
|
|
||||||
|
|
||||||
readonly property bool usesConnectedFrameChrome: CompositorService.usesConnectedFrameChromeForScreen(screenName)
|
|
||||||
readonly property bool usesFrameBarChrome: CompositorService.frameWindowVisibleForScreen(screenName)
|
|
||||||
|
|
||||||
// Flatten/spacing collapse for maximized windows is only for frame-integrated layout.
|
// Flatten/spacing collapse for maximized windows is only for frame-integrated layout.
|
||||||
// When the bar draws its own pill, keep rounded corners and spacing like the dock.
|
// When the bar draws its own pill, keep rounded corners and spacing like the dock.
|
||||||
readonly property bool flattenForMaximizedWindow: !SettingsData.frameEnabled || usesFrameBarChrome
|
readonly property bool flattenForMaximizedWindow: !SettingsData.frameEnabled || usesFrameBarChrome
|
||||||
@@ -554,8 +556,8 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
screen: modelData
|
screen: modelData
|
||||||
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + effectiveSpacing + ((barConfig?.gothCornersEnabled ?? false) && !hasMaximizedToplevel ? _wingR : 0), _dpr) + _shadowBuffer : 0
|
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + effectiveSpacing + ((renderBarConfig?.gothCornersEnabled ?? false) && !hasMaximizedToplevel ? _wingR : 0), _dpr) + _shadowBuffer : 0
|
||||||
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + effectiveSpacing + ((barConfig?.gothCornersEnabled ?? false) && !hasMaximizedToplevel ? _wingR : 0), _dpr) + _shadowBuffer : 0
|
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + effectiveSpacing + ((renderBarConfig?.gothCornersEnabled ?? false) && !hasMaximizedToplevel ? _wingR : 0), _dpr) + _shadowBuffer : 0
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
@@ -707,6 +709,14 @@ PanelWindow {
|
|||||||
readonly property var _rightSection: topBarContent ? (barWindow.isVertical ? topBarContent.vRightSection : topBarContent.hRightSection) : null
|
readonly property var _rightSection: topBarContent ? (barWindow.isVertical ? topBarContent.vRightSection : topBarContent.hRightSection) : null
|
||||||
readonly property real _revealProgress: topBarSlide.x + topBarSlide.y
|
readonly property real _revealProgress: topBarSlide.x + topBarSlide.y
|
||||||
|
|
||||||
|
function containsGlobalPoint(gx, gy, padding) {
|
||||||
|
const pad = padding !== undefined ? padding : 16;
|
||||||
|
if (!inputMask.showing)
|
||||||
|
return false;
|
||||||
|
const topLeft = inputMask.mapToItem(null, 0, 0);
|
||||||
|
return gx >= topLeft.x - pad && gx < topLeft.x + inputMask.width + pad && gy >= topLeft.y - pad && gy < topLeft.y + inputMask.height + pad;
|
||||||
|
}
|
||||||
|
|
||||||
function sectionRect(section, isCenter, _dep) {
|
function sectionRect(section, isCenter, _dep) {
|
||||||
if (!section)
|
if (!section)
|
||||||
return {
|
return {
|
||||||
@@ -952,7 +962,7 @@ PanelWindow {
|
|||||||
id: barBackground
|
id: barBackground
|
||||||
barWindow: barWindow
|
barWindow: barWindow
|
||||||
axis: axis
|
axis: axis
|
||||||
barConfig: barWindow.barConfig
|
barConfig: barWindow.renderBarConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -1008,7 +1018,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onWheel: wheel => {
|
function processWheel(wheel) {
|
||||||
if (!(barConfig?.scrollEnabled ?? true) || actionInProgress) {
|
if (!(barConfig?.scrollEnabled ?? true) || actionInProgress) {
|
||||||
wheel.accepted = false;
|
wheel.accepted = false;
|
||||||
return;
|
return;
|
||||||
@@ -1077,6 +1087,8 @@ PanelWindow {
|
|||||||
|
|
||||||
wheel.accepted = false;
|
wheel.accepted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onWheel: wheel => processWheel(wheel)
|
||||||
}
|
}
|
||||||
|
|
||||||
DankBarContent {
|
DankBarContent {
|
||||||
@@ -1088,6 +1100,36 @@ PanelWindow {
|
|||||||
centerWidgetsModel: barWindow.centerWidgetsModel
|
centerWidgetsModel: barWindow.centerWidgetsModel
|
||||||
rightWidgetsModel: barWindow.rightWidgetsModel
|
rightWidgetsModel: barWindow.rightWidgetsModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: hoverPopoutArea
|
||||||
|
anchors.fill: parent
|
||||||
|
z: 1
|
||||||
|
hoverEnabled: barConfig?.hoverPopouts ?? false
|
||||||
|
enabled: hoverPopoutArea.hoverEnabled && !barWindow.clickThroughEnabled
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
propagateComposedEvents: true
|
||||||
|
|
||||||
|
property real lastGlobalX: 0
|
||||||
|
property real lastGlobalY: 0
|
||||||
|
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
const gp = mapToItem(null, mouse.x, mouse.y);
|
||||||
|
lastGlobalX = gp.x;
|
||||||
|
lastGlobalY = gp.y;
|
||||||
|
topBarContent.checkHoverPopout(gp.x, gp.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
onWheel: wheel => scrollArea.processWheel(wheel)
|
||||||
|
|
||||||
|
onContainsMouseChanged: {
|
||||||
|
if (containsMouse)
|
||||||
|
return;
|
||||||
|
if (topBarContent.cursorOverHoverChain(lastGlobalX, lastGlobalY))
|
||||||
|
return;
|
||||||
|
topBarContent.closeHoverSurfaces();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1922,4 +1922,53 @@ BasePill {
|
|||||||
return;
|
return;
|
||||||
currentTrayMenu.showForTrayItem(item, anchor, screen, atBottom, vertical ?? false, axisObj);
|
currentTrayMenu.showForTrayItem(item, anchor, screen, atBottom, vertical ?? false, axisObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _trayLayoutRoot() {
|
||||||
|
const contentChildren = root.visualContent?.children;
|
||||||
|
if (!contentChildren || contentChildren.length === 0)
|
||||||
|
return null;
|
||||||
|
const contentRoot = contentChildren[0];
|
||||||
|
return contentRoot?.layoutLoader?.item || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _trayHitAtGlobalPoint(gx, gy) {
|
||||||
|
if (!root.visible || root.width <= 0 || root.height <= 0)
|
||||||
|
return null;
|
||||||
|
const local = root.mapFromItem(null, gx, gy);
|
||||||
|
if (local.x < 0 || local.y < 0 || local.x > root.width || local.y > root.height)
|
||||||
|
return null;
|
||||||
|
const layout = _trayLayoutRoot();
|
||||||
|
if (!layout)
|
||||||
|
return null;
|
||||||
|
const layoutLocal = layout.mapFromItem(null, gx, gy);
|
||||||
|
const children = layout.children || [];
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i];
|
||||||
|
if (!child.visible || child.width <= 0 || child.height <= 0)
|
||||||
|
continue;
|
||||||
|
if (layoutLocal.x < child.x || layoutLocal.x >= child.x + child.width)
|
||||||
|
continue;
|
||||||
|
if (layoutLocal.y < child.y || layoutLocal.y >= child.y + child.height)
|
||||||
|
continue;
|
||||||
|
if (child.trayItem)
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hoverTriggerAtGlobalPoint(gx, gy) {
|
||||||
|
const hit = _trayHitAtGlobalPoint(gx, gy);
|
||||||
|
if (!hit?.trayItem?.hasMenu)
|
||||||
|
return "";
|
||||||
|
return "tray-" + (hit.trayItem.id || hit.itemKey || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function openHoverAtGlobalPoint(gx, gy) {
|
||||||
|
const hit = _trayHitAtGlobalPoint(gx, gy);
|
||||||
|
if (!hit?.trayItem?.hasMenu)
|
||||||
|
return false;
|
||||||
|
const anchor = hit.children?.length > 0 ? hit.children[0] : hit;
|
||||||
|
showForTrayItem(hit.trayItem, anchor, parentScreen, isAtBottom, isVerticalOrientation, axis);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,6 +330,24 @@ Item {
|
|||||||
pluginPopout.toggle();
|
pluginPopout.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function triggerHoverPopout(widgetHostId) {
|
||||||
|
if (pillClickAction) {
|
||||||
|
triggerPopout();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!hasPopout)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const pill = isVertical ? verticalPill : horizontalPill;
|
||||||
|
const globalPos = pill.visualContent.mapToItem(null, 0, 0);
|
||||||
|
const currentScreen = parentScreen || Screen;
|
||||||
|
const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
|
||||||
|
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, pill.visualWidth, barSpacing, barPosition, barConfig);
|
||||||
|
|
||||||
|
pluginPopout.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen, barPosition, barThickness, barSpacing, barConfig);
|
||||||
|
PopoutManager.requestHoverPopout(pluginPopout, undefined, widgetHostId || pluginId);
|
||||||
|
}
|
||||||
|
|
||||||
PluginPopout {
|
PluginPopout {
|
||||||
id: pluginPopout
|
id: pluginPopout
|
||||||
contentWidth: root.popoutWidth
|
contentWidth: root.popoutWidth
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ Item {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
readonly property var entryActionKeys: ["pin", "edit", "delete"]
|
||||||
|
readonly property var entryActionLabels: [I18n.tr("Pin"), I18n.tr("Edit"), I18n.tr("Delete")]
|
||||||
|
|
||||||
function getMaxHistoryText(value) {
|
function getMaxHistoryText(value) {
|
||||||
if (value <= 0)
|
if (value <= 0)
|
||||||
return "∞";
|
return "∞";
|
||||||
@@ -187,6 +190,29 @@ Item {
|
|||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function visibleEntryActionKeys() {
|
||||||
|
return SettingsData.clipboardVisibleEntryActions || ["pin", "edit", "delete"];
|
||||||
|
}
|
||||||
|
|
||||||
|
function visibleEntryActionLabels() {
|
||||||
|
const visibleKeys = visibleEntryActionKeys();
|
||||||
|
return entryActionKeys.map((key, index) => visibleKeys.includes(key) ? entryActionLabels[index] : null).filter(label => label !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVisibleEntryAction(index, selected) {
|
||||||
|
const actionKey = entryActionKeys[index];
|
||||||
|
if (!actionKey)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let actions = visibleEntryActionKeys().slice();
|
||||||
|
if (selected && !actions.includes(actionKey)) {
|
||||||
|
actions.push(actionKey);
|
||||||
|
} else if (!selected && actions.includes(actionKey)) {
|
||||||
|
actions = actions.filter(action => action !== actionKey);
|
||||||
|
}
|
||||||
|
SettingsData.set("clipboardVisibleEntryActions", actions);
|
||||||
|
}
|
||||||
|
|
||||||
function loadConfig() {
|
function loadConfig() {
|
||||||
configLoaded = false;
|
configLoaded = false;
|
||||||
configError = false;
|
configError = false;
|
||||||
@@ -437,6 +463,24 @@ Item {
|
|||||||
checked: SettingsData.clipboardEnterToPaste
|
checked: SettingsData.clipboardEnterToPaste
|
||||||
onToggled: checked => SettingsData.set("clipboardEnterToPaste", checked)
|
onToggled: checked => SettingsData.set("clipboardEnterToPaste", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsButtonGroupRow {
|
||||||
|
tab: "clipboard"
|
||||||
|
tags: ["clipboard", "actions", "buttons", "hide", "density", "pin", "edit", "delete"]
|
||||||
|
settingKey: "clipboardVisibleEntryActions"
|
||||||
|
text: I18n.tr("Visible Entry Actions")
|
||||||
|
description: I18n.tr("Choose which action buttons appear on clipboard entries")
|
||||||
|
selectionMode: "multi"
|
||||||
|
model: root.entryActionLabels
|
||||||
|
currentSelection: root.visibleEntryActionLabels()
|
||||||
|
checkEnabled: false
|
||||||
|
buttonHeight: 28
|
||||||
|
minButtonWidth: 56
|
||||||
|
buttonPadding: Theme.spacingS
|
||||||
|
textSize: Theme.fontSizeSmall
|
||||||
|
spacing: 1
|
||||||
|
onSelectionChanged: (index, selected) => root.setVisibleEntryAction(index, selected)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ Item {
|
|||||||
SettingsCard {
|
SettingsCard {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
||||||
title: I18n.tr("Niri Layout Overrides").replace("Niri", "niri")
|
title: I18n.tr("Niri Layout Overrides")
|
||||||
settingKey: "niriLayout"
|
settingKey: "niriLayout"
|
||||||
iconName: "crop_square"
|
iconName: "layers"
|
||||||
visible: CompositorService.isNiri
|
visible: CompositorService.isNiri
|
||||||
|
|
||||||
SettingsToggleRow {
|
SettingsToggleRow {
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ Item {
|
|||||||
scrollEnabled: defaultBar.scrollEnabled ?? true,
|
scrollEnabled: defaultBar.scrollEnabled ?? true,
|
||||||
scrollXBehavior: defaultBar.scrollXBehavior ?? "column",
|
scrollXBehavior: defaultBar.scrollXBehavior ?? "column",
|
||||||
scrollYBehavior: defaultBar.scrollYBehavior ?? "workspace",
|
scrollYBehavior: defaultBar.scrollYBehavior ?? "workspace",
|
||||||
|
hoverPopouts: defaultBar.hoverPopouts ?? false,
|
||||||
shadowIntensity: defaultBar.shadowIntensity ?? 0,
|
shadowIntensity: defaultBar.shadowIntensity ?? 0,
|
||||||
shadowOpacity: defaultBar.shadowOpacity ?? 60,
|
shadowOpacity: defaultBar.shadowOpacity ?? 60,
|
||||||
shadowDirectionMode: defaultBar.shadowDirectionMode ?? "inherit",
|
shadowDirectionMode: defaultBar.shadowDirectionMode ?? "inherit",
|
||||||
@@ -796,18 +797,81 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsCard {
|
||||||
|
tab: "appearance"
|
||||||
|
iconName: "opacity"
|
||||||
|
title: I18n.tr("Opacity")
|
||||||
|
settingKey: "barTransparency"
|
||||||
|
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
id: barTransparencySlider
|
||||||
|
visible: !SettingsData.frameEnabled
|
||||||
|
text: I18n.tr("Bar Opacity")
|
||||||
|
description: I18n.tr("Controls opacity of the bar background")
|
||||||
|
value: (selectedBarConfig?.transparency ?? 1.0) * 100
|
||||||
|
minimum: 0
|
||||||
|
maximum: 100
|
||||||
|
unit: "%"
|
||||||
|
defaultValue: 100
|
||||||
|
onSliderDragFinished: finalValue => {
|
||||||
|
SettingsData.updateBarConfig(selectedBarId, {
|
||||||
|
transparency: finalValue / 100
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: barTransparencySlider
|
||||||
|
property: "value"
|
||||||
|
value: (selectedBarConfig?.transparency ?? 1.0) * 100
|
||||||
|
restoreMode: Binding.RestoreBinding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
id: widgetTransparencySlider
|
||||||
|
text: I18n.tr("Widget Opacity")
|
||||||
|
description: I18n.tr("Controls opacity of widget backgrounds")
|
||||||
|
value: (selectedBarConfig?.widgetTransparency ?? 1.0) * 100
|
||||||
|
minimum: 0
|
||||||
|
maximum: 100
|
||||||
|
unit: "%"
|
||||||
|
defaultValue: 100
|
||||||
|
onSliderDragFinished: finalValue => {
|
||||||
|
SettingsData.updateBarConfig(selectedBarId, {
|
||||||
|
widgetTransparency: finalValue / 100
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: widgetTransparencySlider
|
||||||
|
property: "value"
|
||||||
|
value: (selectedBarConfig?.widgetTransparency ?? 1.0) * 100
|
||||||
|
restoreMode: Binding.RestoreBinding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsControlledByFrame {
|
||||||
|
visible: SettingsData.frameEnabled
|
||||||
|
parentModal: dankBarTab.parentModal
|
||||||
|
settingLabel: I18n.tr("Bar Opacity")
|
||||||
|
reason: I18n.tr("Managed by Frame")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: !dankBarTab.appearanceOnly && SettingsData.frameEnabled
|
visible: dankBarTab.appearanceOnly && SettingsData.frameEnabled
|
||||||
parentModal: dankBarTab.parentModal
|
parentModal: dankBarTab.parentModal
|
||||||
settingLabel: I18n.tr("Bar spacing and size")
|
settingLabel: I18n.tr("Bar spacing and size")
|
||||||
reason: I18n.tr("Managed by Frame")
|
reason: I18n.tr("Managed by Frame")
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
tab: "appearance"
|
||||||
iconName: "space_bar"
|
iconName: "space_bar"
|
||||||
title: I18n.tr("Spacing")
|
title: I18n.tr("Spacing")
|
||||||
settingKey: "barSpacing"
|
settingKey: "barSpacing"
|
||||||
visible: !dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled
|
visible: dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled
|
||||||
|
|
||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: edgeSpacingSlider
|
id: edgeSpacingSlider
|
||||||
@@ -956,68 +1020,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
|
||||||
tab: "appearance"
|
|
||||||
iconName: "opacity"
|
|
||||||
title: I18n.tr("Transparency")
|
|
||||||
settingKey: "barTransparency"
|
|
||||||
visible: dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
|
||||||
|
|
||||||
SettingsSliderRow {
|
|
||||||
id: barTransparencySlider
|
|
||||||
visible: !SettingsData.frameEnabled
|
|
||||||
text: I18n.tr("Bar Transparency")
|
|
||||||
description: I18n.tr("Opacity of the bar background")
|
|
||||||
value: (selectedBarConfig?.transparency ?? 1.0) * 100
|
|
||||||
minimum: 0
|
|
||||||
maximum: 100
|
|
||||||
unit: "%"
|
|
||||||
defaultValue: 100
|
|
||||||
onSliderDragFinished: finalValue => {
|
|
||||||
SettingsData.updateBarConfig(selectedBarId, {
|
|
||||||
transparency: finalValue / 100
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: barTransparencySlider
|
|
||||||
property: "value"
|
|
||||||
value: (selectedBarConfig?.transparency ?? 1.0) * 100
|
|
||||||
restoreMode: Binding.RestoreBinding
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsSliderRow {
|
|
||||||
id: widgetTransparencySlider
|
|
||||||
text: I18n.tr("Widget Transparency")
|
|
||||||
description: I18n.tr("Opacity of widget backgrounds")
|
|
||||||
value: (selectedBarConfig?.widgetTransparency ?? 1.0) * 100
|
|
||||||
minimum: 0
|
|
||||||
maximum: 100
|
|
||||||
unit: "%"
|
|
||||||
defaultValue: 100
|
|
||||||
onSliderDragFinished: finalValue => {
|
|
||||||
SettingsData.updateBarConfig(selectedBarId, {
|
|
||||||
widgetTransparency: finalValue / 100
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: widgetTransparencySlider
|
|
||||||
property: "value"
|
|
||||||
value: (selectedBarConfig?.widgetTransparency ?? 1.0) * 100
|
|
||||||
restoreMode: Binding.RestoreBinding
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsControlledByFrame {
|
|
||||||
visible: SettingsData.frameEnabled
|
|
||||||
parentModal: dankBarTab.parentModal
|
|
||||||
settingLabel: I18n.tr("Bar Transparency")
|
|
||||||
reason: I18n.tr("Managed by Frame")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsSliderCard {
|
SettingsSliderCard {
|
||||||
id: fontScaleSliderCard
|
id: fontScaleSliderCard
|
||||||
tab: "appearance"
|
tab: "appearance"
|
||||||
@@ -1358,7 +1360,7 @@ Item {
|
|||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: borderOpacitySlider
|
id: borderOpacitySlider
|
||||||
text: I18n.tr("Opacity")
|
text: I18n.tr("Opacity")
|
||||||
description: I18n.tr("Transparency of the border")
|
description: I18n.tr("Controls opacity of the border")
|
||||||
value: (selectedBarConfig?.borderOpacity ?? 1.0) * 100
|
value: (selectedBarConfig?.borderOpacity ?? 1.0) * 100
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
@@ -1453,7 +1455,7 @@ Item {
|
|||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: widgetOutlineOpacitySlider
|
id: widgetOutlineOpacitySlider
|
||||||
text: I18n.tr("Opacity")
|
text: I18n.tr("Opacity")
|
||||||
description: I18n.tr("Transparency of the widget outline")
|
description: I18n.tr("Controls opacity of the widget outline")
|
||||||
value: (selectedBarConfig?.widgetOutlineOpacity ?? 1.0) * 100
|
value: (selectedBarConfig?.widgetOutlineOpacity ?? 1.0) * 100
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
@@ -1562,7 +1564,7 @@ Item {
|
|||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
visible: shadowCard.shadowActive
|
visible: shadowCard.shadowActive
|
||||||
text: I18n.tr("Opacity")
|
text: I18n.tr("Opacity")
|
||||||
description: I18n.tr("Transparency of the shadow layer")
|
description: I18n.tr("Controls opacity of the shadow layer")
|
||||||
minimum: 10
|
minimum: 10
|
||||||
maximum: 100
|
maximum: 100
|
||||||
unit: "%"
|
unit: "%"
|
||||||
@@ -1740,6 +1742,19 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsToggleCard {
|
||||||
|
iconName: "touch_app"
|
||||||
|
title: I18n.tr("Hover Popouts")
|
||||||
|
description: I18n.tr("Open widget popouts by hovering over the bar. Moving to another widget switches the popout.")
|
||||||
|
visible: !dankBarTab.appearanceOnly && selectedBarConfig?.enabled
|
||||||
|
enabled: !(selectedBarConfig?.clickThrough ?? false)
|
||||||
|
opacity: (selectedBarConfig?.clickThrough ?? false) ? 0.5 : 1.0
|
||||||
|
checked: selectedBarConfig?.hoverPopouts ?? false
|
||||||
|
onToggled: checked => SettingsData.updateBarConfig(selectedBarId, {
|
||||||
|
hoverPopouts: checked
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
SettingsToggleCard {
|
SettingsToggleCard {
|
||||||
iconName: "mouse"
|
iconName: "mouse"
|
||||||
title: I18n.tr("Scroll Wheel")
|
title: I18n.tr("Scroll Wheel")
|
||||||
|
|||||||
@@ -643,19 +643,19 @@ Item {
|
|||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: root.connectedFrameModeActive
|
visible: root.connectedFrameModeActive
|
||||||
parentModal: root.parentModal
|
parentModal: root.parentModal
|
||||||
settingLabel: I18n.tr("Dock margin, transparency, and border")
|
settingLabel: I18n.tr("Dock margin, opacity, and border")
|
||||||
reason: I18n.tr("Managed by Frame in Connected Mode")
|
reason: I18n.tr("Managed by Frame in Connected Mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
iconName: "opacity"
|
iconName: "opacity"
|
||||||
title: I18n.tr("Transparency")
|
title: I18n.tr("Opacity")
|
||||||
settingKey: "dockTransparency"
|
settingKey: "dockTransparency"
|
||||||
visible: !root.connectedFrameModeActive
|
visible: !root.connectedFrameModeActive
|
||||||
|
|
||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
text: I18n.tr("Dock Transparency")
|
text: I18n.tr("Dock Opacity")
|
||||||
value: Math.round(SettingsData.dockTransparency * 100)
|
value: Math.round(SettingsData.dockTransparency * 100)
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
|
|||||||
@@ -1639,7 +1639,7 @@ Item {
|
|||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: themeColorsTab.connectedFrameModeActive
|
visible: themeColorsTab.connectedFrameModeActive
|
||||||
parentModal: themeColorsTab.parentModal
|
parentModal: themeColorsTab.parentModal
|
||||||
settingLabel: I18n.tr("Transparency")
|
settingLabel: I18n.tr("Surface Opacity")
|
||||||
reason: I18n.tr("Managed by Frame in Connected Mode")
|
reason: I18n.tr("Managed by Frame in Connected Mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1647,8 +1647,8 @@ Item {
|
|||||||
tab: "theme"
|
tab: "theme"
|
||||||
tags: ["surface", "popup", "transparency", "opacity", "modal"]
|
tags: ["surface", "popup", "transparency", "opacity", "modal"]
|
||||||
settingKey: "popupTransparency"
|
settingKey: "popupTransparency"
|
||||||
text: I18n.tr("Transparency")
|
text: I18n.tr("Surface Opacity")
|
||||||
description: I18n.tr("Controls opacity of all popouts, modals, and their content layers")
|
description: I18n.tr("Controls opacity of shell surfaces, popouts, and modals")
|
||||||
visible: !themeColorsTab.connectedFrameModeActive
|
visible: !themeColorsTab.connectedFrameModeActive
|
||||||
value: Math.round(SettingsData.popupTransparency * 100)
|
value: Math.round(SettingsData.popupTransparency * 100)
|
||||||
minimum: 0
|
minimum: 0
|
||||||
@@ -1671,6 +1671,113 @@ Item {
|
|||||||
defaultValue: 12
|
defaultValue: 12
|
||||||
onSliderValueChanged: newValue => SettingsData.setCornerRadius(newValue)
|
onSliderValueChanged: newValue => SettingsData.setCornerRadius(newValue)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsCard {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "background", "transparency", "glass", "frosted"]
|
||||||
|
title: I18n.tr("Background Blur")
|
||||||
|
settingKey: "blurEnabled"
|
||||||
|
iconName: "blur_on"
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "background", "transparency", "glass", "frosted"]
|
||||||
|
settingKey: "blurEnabled"
|
||||||
|
text: I18n.tr("Background Blur")
|
||||||
|
description: !BlurService.available ? I18n.tr("Your compositor does not support background blur (ext-background-effect-v1)") : I18n.tr("Blur the background behind bars, popouts, modals, and notifications. Requires compositor support. Adjust Opacity accordingly.")
|
||||||
|
checked: SettingsData.blurEnabled ?? false
|
||||||
|
enabled: BlurService.available
|
||||||
|
onToggled: checked => SettingsData.set("blurEnabled", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "foreground", "layers", "contrast", "glass", "frosted"]
|
||||||
|
settingKey: "blurForegroundLayers"
|
||||||
|
text: I18n.tr("Foreground Layers")
|
||||||
|
description: I18n.tr("Show foreground surfaces on blurred panels for stronger contrast")
|
||||||
|
checked: SettingsData.blurForegroundLayers ?? true
|
||||||
|
visible: BlurService.available && (SettingsData.blurEnabled ?? false)
|
||||||
|
enabled: BlurService.available
|
||||||
|
onToggled: checked => SettingsData.set("blurForegroundLayers", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "foreground", "layers", "outline", "border", "cards", "widgets", "notifications", "control center"]
|
||||||
|
settingKey: "blurLayerOutlineOpacity"
|
||||||
|
text: I18n.tr("Layer Outline Opacity")
|
||||||
|
description: I18n.tr("Controls outlines around blurred foreground cards, pills, and notification cards")
|
||||||
|
visible: BlurService.available && (SettingsData.blurEnabled ?? false)
|
||||||
|
value: Math.round((SettingsData.blurLayerOutlineOpacity ?? 0.12) * 100)
|
||||||
|
minimum: 0
|
||||||
|
maximum: 40
|
||||||
|
unit: "%"
|
||||||
|
defaultValue: 12
|
||||||
|
onSliderValueChanged: newValue => SettingsData.set("blurLayerOutlineOpacity", newValue / 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsDropdownRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "border", "outline", "edge"]
|
||||||
|
settingKey: "blurBorderColor"
|
||||||
|
text: I18n.tr("Blur Border Color")
|
||||||
|
description: I18n.tr("Border color around blurred surfaces")
|
||||||
|
visible: SettingsData.blurEnabled
|
||||||
|
options: [I18n.tr("Outline", "blur border color"), I18n.tr("Primary", "blur border color"), I18n.tr("Secondary", "blur border color"), I18n.tr("Text Color", "blur border color"), I18n.tr("Custom", "blur border color")]
|
||||||
|
currentValue: {
|
||||||
|
switch (SettingsData.blurBorderColor) {
|
||||||
|
case "primary":
|
||||||
|
return I18n.tr("Primary", "blur border color");
|
||||||
|
case "secondary":
|
||||||
|
return I18n.tr("Secondary", "blur border color");
|
||||||
|
case "surfaceText":
|
||||||
|
return I18n.tr("Text Color", "blur border color");
|
||||||
|
case "custom":
|
||||||
|
return I18n.tr("Custom", "blur border color");
|
||||||
|
default:
|
||||||
|
return I18n.tr("Outline", "blur border color");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onValueChanged: value => {
|
||||||
|
if (value === I18n.tr("Primary", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "primary");
|
||||||
|
} else if (value === I18n.tr("Secondary", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "secondary");
|
||||||
|
} else if (value === I18n.tr("Text Color", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "surfaceText");
|
||||||
|
} else if (value === I18n.tr("Custom", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "custom");
|
||||||
|
openBlurBorderColorPicker();
|
||||||
|
} else {
|
||||||
|
SettingsData.set("blurBorderColor", "outline");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "border", "opacity"]
|
||||||
|
settingKey: "blurBorderOpacity"
|
||||||
|
text: I18n.tr("Blur Border Opacity")
|
||||||
|
description: I18n.tr("Controls the outer edge of protocol-blurred windows")
|
||||||
|
visible: SettingsData.blurEnabled
|
||||||
|
value: Math.round((SettingsData.blurBorderOpacity ?? 0.35) * 100)
|
||||||
|
minimum: 0
|
||||||
|
maximum: 100
|
||||||
|
unit: "%"
|
||||||
|
defaultValue: 35
|
||||||
|
onSliderValueChanged: newValue => SettingsData.set("blurBorderOpacity", newValue / 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsCard {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["elevation", "shadow", "lift", "m3", "material"]
|
||||||
|
title: I18n.tr("Shadows")
|
||||||
|
settingKey: "m3ElevationEnabled"
|
||||||
|
iconName: "layers"
|
||||||
|
|
||||||
SettingsToggleRow {
|
SettingsToggleRow {
|
||||||
tab: "theme"
|
tab: "theme"
|
||||||
@@ -1702,7 +1809,7 @@ Item {
|
|||||||
tags: ["elevation", "shadow", "opacity", "transparency", "m3"]
|
tags: ["elevation", "shadow", "opacity", "transparency", "m3"]
|
||||||
settingKey: "m3ElevationOpacity"
|
settingKey: "m3ElevationOpacity"
|
||||||
text: I18n.tr("Shadow Opacity")
|
text: I18n.tr("Shadow Opacity")
|
||||||
description: I18n.tr("Controls the transparency of the shadow")
|
description: I18n.tr("Controls the opacity of the shadow")
|
||||||
value: SettingsData.m3ElevationOpacity ?? 30
|
value: SettingsData.m3ElevationOpacity ?? 30
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
@@ -1856,105 +1963,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
|
||||||
tab: "theme"
|
|
||||||
tags: ["blur", "background", "transparency", "glass", "frosted"]
|
|
||||||
title: I18n.tr("Background Blur")
|
|
||||||
settingKey: "blurEnabled"
|
|
||||||
iconName: "blur_on"
|
|
||||||
|
|
||||||
SettingsToggleRow {
|
|
||||||
tab: "theme"
|
|
||||||
tags: ["blur", "background", "transparency", "glass", "frosted"]
|
|
||||||
settingKey: "blurEnabled"
|
|
||||||
text: I18n.tr("Background Blur")
|
|
||||||
description: !BlurService.available ? I18n.tr("Your compositor does not support background blur (ext-background-effect-v1)") : I18n.tr("Blur the background behind bars, popouts, modals, and notifications. Requires compositor support and configuration.")
|
|
||||||
checked: SettingsData.blurEnabled ?? false
|
|
||||||
enabled: BlurService.available
|
|
||||||
onToggled: checked => SettingsData.set("blurEnabled", checked)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsToggleRow {
|
|
||||||
tab: "theme"
|
|
||||||
tags: ["blur", "foreground", "layers", "contrast", "glass", "frosted"]
|
|
||||||
settingKey: "blurForegroundLayers"
|
|
||||||
text: I18n.tr("Foreground Layers")
|
|
||||||
description: I18n.tr("Show foreground surfaces on blurred panels for stronger contrast")
|
|
||||||
checked: SettingsData.blurForegroundLayers ?? true
|
|
||||||
visible: BlurService.available && (SettingsData.blurEnabled ?? false)
|
|
||||||
enabled: BlurService.available
|
|
||||||
onToggled: checked => SettingsData.set("blurForegroundLayers", checked)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsSliderRow {
|
|
||||||
tab: "theme"
|
|
||||||
tags: ["blur", "foreground", "layers", "outline", "border", "cards", "widgets", "notifications", "control center"]
|
|
||||||
settingKey: "blurLayerOutlineOpacity"
|
|
||||||
text: I18n.tr("Layer Outline Opacity")
|
|
||||||
description: I18n.tr("Controls outlines around blurred foreground cards, pills, and notification cards")
|
|
||||||
visible: BlurService.available && (SettingsData.blurEnabled ?? false)
|
|
||||||
value: Math.round((SettingsData.blurLayerOutlineOpacity ?? 0.12) * 100)
|
|
||||||
minimum: 0
|
|
||||||
maximum: 40
|
|
||||||
unit: "%"
|
|
||||||
defaultValue: 12
|
|
||||||
onSliderValueChanged: newValue => SettingsData.set("blurLayerOutlineOpacity", newValue / 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsDropdownRow {
|
|
||||||
tab: "theme"
|
|
||||||
tags: ["blur", "border", "outline", "edge"]
|
|
||||||
settingKey: "blurBorderColor"
|
|
||||||
text: I18n.tr("Blur Border Color")
|
|
||||||
description: I18n.tr("Border color around blurred surfaces")
|
|
||||||
visible: SettingsData.blurEnabled
|
|
||||||
options: [I18n.tr("Outline", "blur border color"), I18n.tr("Primary", "blur border color"), I18n.tr("Secondary", "blur border color"), I18n.tr("Text Color", "blur border color"), I18n.tr("Custom", "blur border color")]
|
|
||||||
currentValue: {
|
|
||||||
switch (SettingsData.blurBorderColor) {
|
|
||||||
case "primary":
|
|
||||||
return I18n.tr("Primary", "blur border color");
|
|
||||||
case "secondary":
|
|
||||||
return I18n.tr("Secondary", "blur border color");
|
|
||||||
case "surfaceText":
|
|
||||||
return I18n.tr("Text Color", "blur border color");
|
|
||||||
case "custom":
|
|
||||||
return I18n.tr("Custom", "blur border color");
|
|
||||||
default:
|
|
||||||
return I18n.tr("Outline", "blur border color");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onValueChanged: value => {
|
|
||||||
if (value === I18n.tr("Primary", "blur border color")) {
|
|
||||||
SettingsData.set("blurBorderColor", "primary");
|
|
||||||
} else if (value === I18n.tr("Secondary", "blur border color")) {
|
|
||||||
SettingsData.set("blurBorderColor", "secondary");
|
|
||||||
} else if (value === I18n.tr("Text Color", "blur border color")) {
|
|
||||||
SettingsData.set("blurBorderColor", "surfaceText");
|
|
||||||
} else if (value === I18n.tr("Custom", "blur border color")) {
|
|
||||||
SettingsData.set("blurBorderColor", "custom");
|
|
||||||
openBlurBorderColorPicker();
|
|
||||||
} else {
|
|
||||||
SettingsData.set("blurBorderColor", "outline");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsSliderRow {
|
|
||||||
tab: "theme"
|
|
||||||
tags: ["blur", "border", "opacity"]
|
|
||||||
settingKey: "blurBorderOpacity"
|
|
||||||
text: I18n.tr("Blur Border Opacity")
|
|
||||||
description: I18n.tr("Controls the outer edge of protocol-blurred windows")
|
|
||||||
visible: SettingsData.blurEnabled
|
|
||||||
value: Math.round((SettingsData.blurBorderOpacity ?? 0.35) * 100)
|
|
||||||
minimum: 0
|
|
||||||
maximum: 100
|
|
||||||
unit: "%"
|
|
||||||
defaultValue: 35
|
|
||||||
onSliderValueChanged: newValue => SettingsData.set("blurBorderOpacity", newValue / 100)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
tab: "theme"
|
tab: "theme"
|
||||||
tags: ["modal", "darken", "background", "overlay"]
|
tags: ["modal", "darken", "background", "overlay"]
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ Item {
|
|||||||
|
|
||||||
property alias model: buttonGroup.model
|
property alias model: buttonGroup.model
|
||||||
property alias currentIndex: buttonGroup.currentIndex
|
property alias currentIndex: buttonGroup.currentIndex
|
||||||
|
property alias initialSelection: buttonGroup.initialSelection
|
||||||
|
property alias currentSelection: buttonGroup.currentSelection
|
||||||
property alias selectionMode: buttonGroup.selectionMode
|
property alias selectionMode: buttonGroup.selectionMode
|
||||||
property alias buttonHeight: buttonGroup.buttonHeight
|
property alias buttonHeight: buttonGroup.buttonHeight
|
||||||
property alias minButtonWidth: buttonGroup.minButtonWidth
|
property alias minButtonWidth: buttonGroup.minButtonWidth
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ Variants {
|
|||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
updatesEnabled: root.renderActive || root._settleFrames > 0
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: Item {}
|
item: Item {}
|
||||||
}
|
}
|
||||||
@@ -84,20 +86,59 @@ Variants {
|
|||||||
|
|
||||||
readonly property bool transitioning: transitionAnimation.running
|
readonly property bool transitioning: transitionAnimation.running
|
||||||
property bool effectActive: false
|
property bool effectActive: false
|
||||||
property bool _renderSettling: true
|
|
||||||
property bool _overviewBlurSettling: false
|
|
||||||
property bool useNextForEffect: false
|
property bool useNextForEffect: false
|
||||||
property string pendingWallpaper: ""
|
property string pendingWallpaper: ""
|
||||||
property string _deferredSource: ""
|
property string _deferredSource: ""
|
||||||
readonly property bool overviewBlurActive: CompositorService.isNiri && SettingsData.blurWallpaperOnOverview && NiriService.inOverview && currentWallpaper.source !== ""
|
readonly property bool overviewBlurActive: CompositorService.isNiri && SettingsData.blurWallpaperOnOverview && NiriService.inOverview && currentWallpaper.source !== ""
|
||||||
|
readonly property var backingWindow: Window.window
|
||||||
|
readonly property bool renderActive: !source || effectActive || overviewBlurActive || pendingWallpaper !== "" || _deferredSource !== "" || currentWallpaper.status === Image.Loading || nextWallpaper.status === Image.Loading
|
||||||
|
property int _settleFrames: 3
|
||||||
|
|
||||||
|
function invalidate() {
|
||||||
|
_settleFrames = 3;
|
||||||
|
backingWindow?.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
onRenderActiveChanged: invalidate()
|
||||||
|
onBackingWindowChanged: invalidate()
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: currentWallpaper
|
target: root.backingWindow
|
||||||
function onStatusChanged() {
|
function onFrameSwapped() {
|
||||||
if (currentWallpaper.status !== Image.Ready && currentWallpaper.status !== Image.Error)
|
if (root._settleFrames > 0)
|
||||||
|
root._settleFrames--;
|
||||||
|
}
|
||||||
|
function onVisibleChanged() {
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
|
function onWidthChanged() {
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
|
function onHeightChanged() {
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Quickshell
|
||||||
|
function onScreensChanged() {
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsData
|
||||||
|
function onWallpaperFillModeChanged() {
|
||||||
|
root.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: IdleService
|
||||||
|
function onIsShellLockedChanged() {
|
||||||
|
if (IdleService.isShellLocked)
|
||||||
return;
|
return;
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,32 +150,11 @@ Variants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: wallpaperWindow
|
|
||||||
function onWidthChanged() {
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
|
||||||
function onHeightChanged() {
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Quickshell
|
|
||||||
function onScreensChanged() {
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: NiriService
|
target: NiriService
|
||||||
function onDisplayScalesChanged() {
|
function onDisplayScalesChanged() {
|
||||||
root._recheckScreenScale();
|
root._recheckScreenScale();
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,29 +162,7 @@ Variants {
|
|||||||
target: WlrOutputService
|
target: WlrOutputService
|
||||||
function onWlrOutputAvailableChanged() {
|
function onWlrOutputAvailableChanged() {
|
||||||
root._recheckScreenScale();
|
root._recheckScreenScale();
|
||||||
root._renderSettling = true;
|
root.invalidate();
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: NiriService
|
|
||||||
function onInOverviewChanged() {
|
|
||||||
root._overviewBlurSettling = true;
|
|
||||||
overviewBlurSettleTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: SettingsData
|
|
||||||
function onBlurWallpaperOnOverviewChanged() {
|
|
||||||
root._overviewBlurSettling = true;
|
|
||||||
overviewBlurSettleTimer.restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWallpaperFillModeChanged() {
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,26 +179,22 @@ Variants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
function handleTransitionLoadError(failedSource) {
|
||||||
target: IdleService
|
log.warn("failed to load candidate wallpaper for", modelData.name + ":", failedSource);
|
||||||
function onIsShellLockedChanged() {
|
transitionDelayTimer.stop();
|
||||||
if (!IdleService.isShellLocked) {
|
transitionAnimation.stop();
|
||||||
root._renderSettling = true;
|
root.useNextForEffect = false;
|
||||||
renderSettleTimer.restart();
|
root.effectActive = false;
|
||||||
}
|
root.transitionProgress = 0.0;
|
||||||
}
|
currentWallpaper.layer.enabled = false;
|
||||||
}
|
nextWallpaper.layer.enabled = false;
|
||||||
|
nextWallpaper.source = "";
|
||||||
|
|
||||||
Timer {
|
if (!root.pendingWallpaper)
|
||||||
id: renderSettleTimer
|
return;
|
||||||
interval: 1000
|
const pending = root.pendingWallpaper;
|
||||||
onTriggered: root._renderSettling = false
|
root.pendingWallpaper = "";
|
||||||
}
|
Qt.callLater(() => root.changeWallpaper(pending, true));
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: overviewBlurSettleTimer
|
|
||||||
interval: 150
|
|
||||||
onTriggered: root._overviewBlurSettling = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFillMode(modeName) {
|
function getFillMode(modeName) {
|
||||||
@@ -227,11 +221,6 @@ Variants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
wallpaperWindow.updatesEnabled = Qt.binding(() => !root.source || root.effectActive || root._renderSettling || root.overviewBlurActive || root._overviewBlurSettling || root.pendingWallpaper !== "" || root._deferredSource !== "" || currentWallpaper.status === Image.Loading || nextWallpaper.status === Image.Loading);
|
|
||||||
|
|
||||||
if (!source) {
|
|
||||||
root._renderSettling = false;
|
|
||||||
}
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,8 +251,6 @@ Variants {
|
|||||||
transitionAnimation.stop();
|
transitionAnimation.stop();
|
||||||
root.transitionProgress = 0.0;
|
root.transitionProgress = 0.0;
|
||||||
root.effectActive = false;
|
root.effectActive = false;
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
root.screenScale = CompositorService.getScreenScale(modelData);
|
root.screenScale = CompositorService.getScreenScale(modelData);
|
||||||
currentWallpaper.source = newSource;
|
currentWallpaper.source = newSource;
|
||||||
nextWallpaper.source = "";
|
nextWallpaper.source = "";
|
||||||
@@ -328,9 +315,6 @@ Variants {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
|
|
||||||
nextWallpaper.source = newPath;
|
nextWallpaper.source = newPath;
|
||||||
|
|
||||||
if (nextWallpaper.status === Image.Ready)
|
if (nextWallpaper.status === Image.Ready)
|
||||||
@@ -339,7 +323,7 @@ Variants {
|
|||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: !root.source || root.isColorSource
|
active: !root.source || root.isColorSource || currentWallpaper.status === Image.Error
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: DankBackdrop {
|
sourceComponent: DankBackdrop {
|
||||||
@@ -364,6 +348,12 @@ Variants {
|
|||||||
cache: true
|
cache: true
|
||||||
sourceSize: Qt.size(root.textureWidth, root.textureHeight)
|
sourceSize: Qt.size(root.textureWidth, root.textureHeight)
|
||||||
fillMode: root.getFillMode(SessionData.getMonitorWallpaperFillMode(modelData.name))
|
fillMode: root.getFillMode(SessionData.getMonitorWallpaperFillMode(modelData.name))
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Image.Error) {
|
||||||
|
log.warn("failed to load active wallpaper for", modelData.name + ":", source);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -380,11 +370,13 @@ Variants {
|
|||||||
fillMode: root.getFillMode(SessionData.getMonitorWallpaperFillMode(modelData.name))
|
fillMode: root.getFillMode(SessionData.getMonitorWallpaperFillMode(modelData.name))
|
||||||
|
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
|
if (status === Image.Error) {
|
||||||
|
root.handleTransitionLoadError(source);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (status !== Image.Ready)
|
if (status !== Image.Ready)
|
||||||
return;
|
return;
|
||||||
if (root.actualTransitionType === "none") {
|
if (root.actualTransitionType === "none") {
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
currentWallpaper.source = source;
|
currentWallpaper.source = source;
|
||||||
nextWallpaper.source = "";
|
nextWallpaper.source = "";
|
||||||
root.transitionProgress = 0.0;
|
root.transitionProgress = 0.0;
|
||||||
@@ -632,8 +624,6 @@ Variants {
|
|||||||
root.transitionProgress = 0.0;
|
root.transitionProgress = 0.0;
|
||||||
currentWallpaper.layer.enabled = false;
|
currentWallpaper.layer.enabled = false;
|
||||||
nextWallpaper.layer.enabled = false;
|
nextWallpaper.layer.enabled = false;
|
||||||
root._renderSettling = true;
|
|
||||||
renderSettleTimer.restart();
|
|
||||||
root.effectActive = false;
|
root.effectActive = false;
|
||||||
|
|
||||||
if (!root.pendingWallpaper)
|
if (!root.pendingWallpaper)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ Item {
|
|||||||
property list<real> animationExitCurve: Theme.variantPopoutExitCurve
|
property list<real> animationExitCurve: Theme.variantPopoutExitCurve
|
||||||
property bool suspendShadowWhileResizing: false
|
property bool suspendShadowWhileResizing: false
|
||||||
property bool shouldBeVisible: false
|
property bool shouldBeVisible: false
|
||||||
|
property bool hoverDismissEnabled: false
|
||||||
property var customKeyboardFocus: null
|
property var customKeyboardFocus: null
|
||||||
property bool backgroundInteractive: true
|
property bool backgroundInteractive: true
|
||||||
property bool contentHandlesKeys: false
|
property bool contentHandlesKeys: false
|
||||||
@@ -82,6 +83,8 @@ Item {
|
|||||||
readonly property real alignedY: impl.item ? impl.item.alignedY : 0
|
readonly property real alignedY: impl.item ? impl.item.alignedY : 0
|
||||||
readonly property real alignedWidth: impl.item ? impl.item.alignedWidth : 0
|
readonly property real alignedWidth: impl.item ? impl.item.alignedWidth : 0
|
||||||
readonly property real alignedHeight: impl.item ? impl.item.alignedHeight : 0
|
readonly property real alignedHeight: impl.item ? impl.item.alignedHeight : 0
|
||||||
|
readonly property real renderedAlignedY: impl.item ? (impl.item.renderedAlignedY ?? impl.item.alignedY) : 0
|
||||||
|
readonly property real renderedAlignedHeight: impl.item ? (impl.item.renderedAlignedHeight ?? impl.item.alignedHeight) : 0
|
||||||
readonly property real maskX: impl.item ? impl.item.maskX : 0
|
readonly property real maskX: impl.item ? impl.item.maskX : 0
|
||||||
readonly property real maskY: impl.item ? impl.item.maskY : 0
|
readonly property real maskY: impl.item ? impl.item.maskY : 0
|
||||||
readonly property real maskWidth: impl.item ? impl.item.maskWidth : 0
|
readonly property real maskWidth: impl.item ? impl.item.maskWidth : 0
|
||||||
@@ -172,6 +175,32 @@ Item {
|
|||||||
impl.item.close();
|
impl.item.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancelHoverDismiss() {
|
||||||
|
if (impl.item?.cancelHoverDismiss)
|
||||||
|
impl.item.cancelHoverDismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeFromHoverDismiss() {
|
||||||
|
hoverDismissEnabled = false;
|
||||||
|
if (impl.item) {
|
||||||
|
impl.item.animationsEnabled = true;
|
||||||
|
impl.item.animationDuration = Math.round(Theme.expressiveDurations.expressiveDefaultSpatial);
|
||||||
|
impl.item.animationExitCurve = Theme.expressiveCurves.expressiveDefaultSpatial;
|
||||||
|
}
|
||||||
|
if (dashVisible !== undefined) {
|
||||||
|
dashVisible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (notificationHistoryVisible !== undefined) {
|
||||||
|
notificationHistoryVisible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (impl.item)
|
||||||
|
impl.item.close();
|
||||||
|
else
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
(shouldBeVisible || _pendingOpen) ? close() : open();
|
(shouldBeVisible || _pendingOpen) ? close() : open();
|
||||||
}
|
}
|
||||||
@@ -210,6 +239,20 @@ Item {
|
|||||||
impl.item.updateSurfacePosition();
|
impl.item.updateSurfacePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function containsGlobalPoint(gx, gy) {
|
||||||
|
if (!screen)
|
||||||
|
return false;
|
||||||
|
const presented = shouldBeVisible || (impl.item?.isClosing ?? false);
|
||||||
|
if (!presented)
|
||||||
|
return false;
|
||||||
|
const padding = 24;
|
||||||
|
const x = alignedX - padding;
|
||||||
|
const y = renderedAlignedY - padding;
|
||||||
|
const w = alignedWidth + padding * 2;
|
||||||
|
const h = renderedAlignedHeight + padding * 2;
|
||||||
|
return gx >= x && gx <= x + w && gy >= y && gy <= y + h;
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: impl
|
id: impl
|
||||||
active: root.screen !== null
|
active: root.screen !== null
|
||||||
@@ -261,6 +304,7 @@ Item {
|
|||||||
it.screen = Qt.binding(() => root.screen);
|
it.screen = Qt.binding(() => root.screen);
|
||||||
it.effectiveBarPosition = Qt.binding(() => root.effectiveBarPosition);
|
it.effectiveBarPosition = Qt.binding(() => root.effectiveBarPosition);
|
||||||
it.effectiveBarBottomGap = Qt.binding(() => root.effectiveBarBottomGap);
|
it.effectiveBarBottomGap = Qt.binding(() => root.effectiveBarBottomGap);
|
||||||
|
it.hoverDismissEnabled = Qt.binding(() => root.hoverDismissEnabled);
|
||||||
|
|
||||||
it.shouldBeVisible = root.shouldBeVisible;
|
it.shouldBeVisible = root.shouldBeVisible;
|
||||||
if (root._primeContent && typeof it.primeContent === "function")
|
if (root._primeContent && typeof it.primeContent === "function")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Quickshell
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -407,6 +408,20 @@ Item {
|
|||||||
onFrameOwnsConnectedChromeChanged: _syncPopoutChromeState()
|
onFrameOwnsConnectedChromeChanged: _syncPopoutChromeState()
|
||||||
|
|
||||||
property bool animationsEnabled: true
|
property bool animationsEnabled: true
|
||||||
|
property bool hoverDismissEnabled: false
|
||||||
|
|
||||||
|
function cancelHoverDismiss() {
|
||||||
|
hoverDismissTracker.cancelPending();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeFromHoverDismiss() {
|
||||||
|
if (isClosing || !shouldBeVisible)
|
||||||
|
return;
|
||||||
|
if (popoutHandle?.closeFromHoverDismiss)
|
||||||
|
popoutHandle.closeFromHoverDismiss();
|
||||||
|
else
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
if (!screen)
|
if (!screen)
|
||||||
@@ -761,6 +776,27 @@ Item {
|
|||||||
visible: false
|
visible: false
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
hoverEnabled: true
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
const gp = mapToItem(null, mouse.x, mouse.y);
|
||||||
|
PopoutManager.updateHoverCursor(gp.x, gp.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverDismissTracker {
|
||||||
|
id: hoverDismissTracker
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.hoverDismissEnabled && root.shouldBeVisible
|
||||||
|
shouldDismiss: function () {
|
||||||
|
return !PopoutManager.cursorOverBar(PopoutManager.hoverCursorGlobalX, PopoutManager.hoverCursorGlobalY);
|
||||||
|
}
|
||||||
|
onDismissRequested: root.closeFromHoverDismiss()
|
||||||
|
}
|
||||||
|
|
||||||
WindowBlur {
|
WindowBlur {
|
||||||
id: popoutBlur
|
id: popoutBlur
|
||||||
targetWindow: contentWindow
|
targetWindow: contentWindow
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Quickshell
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -35,6 +36,21 @@ Item {
|
|||||||
property bool shouldBeVisible: false
|
property bool shouldBeVisible: false
|
||||||
property bool isClosing: false
|
property bool isClosing: false
|
||||||
property bool animationsEnabled: true
|
property bool animationsEnabled: true
|
||||||
|
property bool hoverDismissEnabled: false
|
||||||
|
|
||||||
|
function cancelHoverDismiss() {
|
||||||
|
hoverDismissTracker.cancelPending();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeFromHoverDismiss() {
|
||||||
|
if (isClosing || !shouldBeVisible)
|
||||||
|
return;
|
||||||
|
if (popoutHandle?.closeFromHoverDismiss)
|
||||||
|
popoutHandle.closeFromHoverDismiss();
|
||||||
|
else
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
property var customKeyboardFocus: null
|
property var customKeyboardFocus: null
|
||||||
property bool backgroundInteractive: true
|
property bool backgroundInteractive: true
|
||||||
property bool contentHandlesKeys: false
|
property bool contentHandlesKeys: false
|
||||||
@@ -585,6 +601,27 @@ Item {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
readonly property bool closeVisualActive: root.shouldBeVisible || root.isClosing
|
readonly property bool closeVisualActive: root.shouldBeVisible || root.isClosing
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
hoverEnabled: true
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
const gp = mapToItem(null, mouse.x, mouse.y);
|
||||||
|
PopoutManager.updateHoverCursor(gp.x, gp.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverDismissTracker {
|
||||||
|
id: hoverDismissTracker
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.hoverDismissEnabled && root.shouldBeVisible
|
||||||
|
shouldDismiss: function () {
|
||||||
|
return !PopoutManager.cursorOverBar(PopoutManager.hoverCursorGlobalX, PopoutManager.hoverCursorGlobalY);
|
||||||
|
}
|
||||||
|
onDismissRequested: root.closeFromHoverDismiss()
|
||||||
|
}
|
||||||
|
|
||||||
WindowBlur {
|
WindowBlur {
|
||||||
id: popoutBlur
|
id: popoutBlur
|
||||||
targetWindow: contentWindow
|
targetWindow: contentWindow
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ PanelWindow {
|
|||||||
WlrLayershell.namespace: layerNamespace
|
WlrLayershell.namespace: layerNamespace
|
||||||
|
|
||||||
property bool isVisible: false
|
property bool isVisible: false
|
||||||
|
property bool hoverDismissEnabled: false
|
||||||
property var targetScreen: null
|
property var targetScreen: null
|
||||||
property var modelData: null
|
property var modelData: null
|
||||||
property bool triggerUsesOverlayLayer: false
|
property bool triggerUsesOverlayLayer: false
|
||||||
@@ -39,6 +40,24 @@ PanelWindow {
|
|||||||
isVisible = false;
|
isVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hideFromHoverDismiss() {
|
||||||
|
hoverDismissEnabled = false;
|
||||||
|
slideAnimation.duration = Math.round(Theme.expressiveDurations.expressiveDefaultSpatial);
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelHoverDismiss() {
|
||||||
|
hoverDismissTracker.cancelPending();
|
||||||
|
}
|
||||||
|
|
||||||
|
function containsGlobalPoint(gx, gy) {
|
||||||
|
if (!isVisible || !modelData)
|
||||||
|
return false;
|
||||||
|
const padding = 24;
|
||||||
|
const topLeft = slideContainer.mapToItem(null, 0, 0);
|
||||||
|
return gx >= topLeft.x - padding && gx < topLeft.x + slideContainer.width + padding && gy >= topLeft.y - padding && gy < topLeft.y + slideContainer.height + padding;
|
||||||
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
hide();
|
hide();
|
||||||
@@ -60,6 +79,27 @@ PanelWindow {
|
|||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
hoverEnabled: true
|
||||||
|
onPositionChanged: mouse => {
|
||||||
|
const gp = mapToItem(null, mouse.x, mouse.y);
|
||||||
|
PopoutManager.updateHoverCursor(gp.x, gp.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverDismissTracker {
|
||||||
|
id: hoverDismissTracker
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: root.hoverDismissEnabled && root.isVisible
|
||||||
|
shouldDismiss: function () {
|
||||||
|
return !PopoutManager.cursorOverBar(PopoutManager.hoverCursorGlobalX, PopoutManager.hoverCursorGlobalY);
|
||||||
|
}
|
||||||
|
onDismissRequested: root.hideFromHoverDismiss()
|
||||||
|
}
|
||||||
|
|
||||||
readonly property bool slideoutBlurActive: root.visible && BlurService.enabled && Theme.connectedSurfaceBlurEnabled
|
readonly property bool slideoutBlurActive: root.visible && BlurService.enabled && Theme.connectedSurfaceBlurEnabled
|
||||||
|
|
||||||
WlrLayershell.layer: (triggerUsesOverlayLayer || CompositorService.framePeerSurfacesUseOverlayForScreen(modelData)) ? WlrLayershell.Overlay : WlrLayershell.Top
|
WlrLayershell.layer: (triggerUsesOverlayLayer || CompositorService.framePeerSurfacesUseOverlayForScreen(modelData)) ? WlrLayershell.Overlay : WlrLayershell.Top
|
||||||
@@ -104,8 +144,10 @@ PanelWindow {
|
|||||||
easing.type: Easing.OutCubic
|
easing.type: Easing.OutCubic
|
||||||
|
|
||||||
onRunningChanged: {
|
onRunningChanged: {
|
||||||
if (!running && !root.isVisible) {
|
if (!running) {
|
||||||
root.mappedVisible = false;
|
if (!root.isVisible)
|
||||||
|
root.mappedVisible = false;
|
||||||
|
slideAnimation.duration = 450;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool enabled: false
|
||||||
|
property var shouldDismiss: null
|
||||||
|
|
||||||
|
signal dismissRequested
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
id: hoverHandler
|
||||||
|
enabled: root.enabled
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (hoverHandler.hovered || !root.enabled)
|
||||||
|
return;
|
||||||
|
if (typeof root.shouldDismiss === "function" && !root.shouldDismiss())
|
||||||
|
return;
|
||||||
|
root.dismissRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelPending() {}
|
||||||
|
}
|
||||||
@@ -546,6 +546,7 @@ def main():
|
|||||||
output_path = script_dir / "settings_search_index.json"
|
output_path = script_dir / "settings_search_index.json"
|
||||||
with open(output_path, "w", encoding="utf-8") as f:
|
with open(output_path, "w", encoding="utf-8") as f:
|
||||||
json.dump(all_entries, f, indent=2, ensure_ascii=False)
|
json.dump(all_entries, f, indent=2, ensure_ascii=False)
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
print(f"Found {len(settings_entries)} searchable settings")
|
print(f"Found {len(settings_entries)} searchable settings")
|
||||||
print(f"Found {len(tab_entries)} tab entries")
|
print(f"Found {len(tab_entries)} tab entries")
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
"targetable",
|
"targetable",
|
||||||
"wallpaper"
|
"wallpaper"
|
||||||
],
|
],
|
||||||
|
"icon": "blur_on",
|
||||||
"description": "Enable compositor-targetable blur layer (namespace: dms:blurwallpaper). Requires manual niri configuration.",
|
"description": "Enable compositor-targetable blur layer (namespace: dms:blurwallpaper). Requires manual niri configuration.",
|
||||||
"conditionKey": "isNiri"
|
"conditionKey": "isNiri"
|
||||||
},
|
},
|
||||||
@@ -727,21 +728,6 @@
|
|||||||
],
|
],
|
||||||
"icon": "dashboard"
|
"icon": "dashboard"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "_tab_3",
|
|
||||||
"label": "Dank Bar",
|
|
||||||
"tabIndex": 3,
|
|
||||||
"category": "Dank Bar",
|
|
||||||
"keywords": [
|
|
||||||
"bar",
|
|
||||||
"dank",
|
|
||||||
"panel",
|
|
||||||
"statusbar",
|
|
||||||
"taskbar",
|
|
||||||
"topbar"
|
|
||||||
],
|
|
||||||
"icon": "toolbar"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "barDisplay",
|
"section": "barDisplay",
|
||||||
"label": "Display Assignment",
|
"label": "Display Assignment",
|
||||||
@@ -777,30 +763,19 @@
|
|||||||
"icon": "vertical_align_center"
|
"icon": "vertical_align_center"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "barSpacing",
|
"section": "_tab_3",
|
||||||
"label": "Spacing",
|
"label": "Settings",
|
||||||
"tabIndex": 3,
|
"tabIndex": 3,
|
||||||
"category": "Dank Bar",
|
"category": "Dank Bar",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bar",
|
"bar",
|
||||||
"between",
|
|
||||||
"dank",
|
"dank",
|
||||||
"edges",
|
|
||||||
"gap",
|
|
||||||
"gaps",
|
|
||||||
"margin",
|
|
||||||
"margins",
|
|
||||||
"padding",
|
|
||||||
"panel",
|
"panel",
|
||||||
"screen",
|
"settings",
|
||||||
"space",
|
|
||||||
"spacing",
|
|
||||||
"statusbar",
|
"statusbar",
|
||||||
"taskbar",
|
|
||||||
"topbar"
|
"topbar"
|
||||||
],
|
],
|
||||||
"icon": "space_bar",
|
"icon": "tune"
|
||||||
"description": "Space between the bar and screen edges"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "barUseOverlayLayer",
|
"section": "barUseOverlayLayer",
|
||||||
@@ -1528,6 +1503,19 @@
|
|||||||
"windows"
|
"windows"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "dockTransparency",
|
||||||
|
"label": "Opacity",
|
||||||
|
"tabIndex": 5,
|
||||||
|
"category": "Dock",
|
||||||
|
"keywords": [
|
||||||
|
"dock",
|
||||||
|
"launcher bar",
|
||||||
|
"opacity",
|
||||||
|
"taskbar"
|
||||||
|
],
|
||||||
|
"icon": "opacity"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "dockTrashFileManager",
|
"section": "dockTrashFileManager",
|
||||||
"label": "Open Trash With",
|
"label": "Open Trash With",
|
||||||
@@ -1745,23 +1733,6 @@
|
|||||||
],
|
],
|
||||||
"icon": "space_bar"
|
"icon": "space_bar"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "dockTransparency",
|
|
||||||
"label": "Transparency",
|
|
||||||
"tabIndex": 5,
|
|
||||||
"category": "Dock",
|
|
||||||
"keywords": [
|
|
||||||
"alpha",
|
|
||||||
"dock",
|
|
||||||
"launcher bar",
|
|
||||||
"opacity",
|
|
||||||
"taskbar",
|
|
||||||
"translucent",
|
|
||||||
"transparency",
|
|
||||||
"transparent"
|
|
||||||
],
|
|
||||||
"icon": "opacity"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "dockTrash",
|
"section": "dockTrash",
|
||||||
"label": "Trash",
|
"label": "Trash",
|
||||||
@@ -1798,21 +1769,6 @@
|
|||||||
],
|
],
|
||||||
"description": "Place the dock on the Wayland overlay layer"
|
"description": "Place the dock on the Wayland overlay layer"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "_tab_6",
|
|
||||||
"label": "Appearance",
|
|
||||||
"tabIndex": 6,
|
|
||||||
"category": "Dank Bar",
|
|
||||||
"keywords": [
|
|
||||||
"appearance",
|
|
||||||
"bar",
|
|
||||||
"dank",
|
|
||||||
"panel",
|
|
||||||
"statusbar",
|
|
||||||
"topbar"
|
|
||||||
],
|
|
||||||
"icon": "palette"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "barBorder",
|
"section": "barBorder",
|
||||||
"label": "Border",
|
"label": "Border",
|
||||||
@@ -1862,6 +1818,21 @@
|
|||||||
"icon": "rounded_corner",
|
"icon": "rounded_corner",
|
||||||
"description": "Remove corner rounding from the bar"
|
"description": "Remove corner rounding from the bar"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "_tab_6",
|
||||||
|
"label": "Dank Bar",
|
||||||
|
"tabIndex": 6,
|
||||||
|
"category": "Dank Bar",
|
||||||
|
"keywords": [
|
||||||
|
"bar",
|
||||||
|
"dank",
|
||||||
|
"panel",
|
||||||
|
"statusbar",
|
||||||
|
"taskbar",
|
||||||
|
"topbar"
|
||||||
|
],
|
||||||
|
"icon": "toolbar"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "barAppearance",
|
"section": "barAppearance",
|
||||||
"label": "Dank Bar",
|
"label": "Dank Bar",
|
||||||
@@ -1982,6 +1953,25 @@
|
|||||||
],
|
],
|
||||||
"description": "Use a fixed shadow direction for this bar"
|
"description": "Use a fixed shadow direction for this bar"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "barTransparency",
|
||||||
|
"label": "Opacity",
|
||||||
|
"tabIndex": 6,
|
||||||
|
"category": "Dank Bar",
|
||||||
|
"keywords": [
|
||||||
|
"background",
|
||||||
|
"bar",
|
||||||
|
"controls",
|
||||||
|
"dank",
|
||||||
|
"opacity",
|
||||||
|
"panel",
|
||||||
|
"statusbar",
|
||||||
|
"taskbar",
|
||||||
|
"topbar"
|
||||||
|
],
|
||||||
|
"icon": "opacity",
|
||||||
|
"description": "Controls opacity of the bar background"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "barShadow",
|
"section": "barShadow",
|
||||||
"label": "Shadow Override",
|
"label": "Shadow Override",
|
||||||
@@ -2002,6 +1992,32 @@
|
|||||||
"icon": "layers",
|
"icon": "layers",
|
||||||
"description": "Override the global shadow with per-bar settings"
|
"description": "Override the global shadow with per-bar settings"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "barSpacing",
|
||||||
|
"label": "Spacing",
|
||||||
|
"tabIndex": 6,
|
||||||
|
"category": "Dank Bar",
|
||||||
|
"keywords": [
|
||||||
|
"bar",
|
||||||
|
"between",
|
||||||
|
"dank",
|
||||||
|
"edges",
|
||||||
|
"gap",
|
||||||
|
"gaps",
|
||||||
|
"margin",
|
||||||
|
"margins",
|
||||||
|
"padding",
|
||||||
|
"panel",
|
||||||
|
"screen",
|
||||||
|
"space",
|
||||||
|
"spacing",
|
||||||
|
"statusbar",
|
||||||
|
"taskbar",
|
||||||
|
"topbar"
|
||||||
|
],
|
||||||
|
"icon": "space_bar",
|
||||||
|
"description": "Space between the bar and screen edges"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "trayIconTint",
|
"section": "trayIconTint",
|
||||||
"label": "System Tray Icon Tint",
|
"label": "System Tray Icon Tint",
|
||||||
@@ -2030,28 +2046,6 @@
|
|||||||
"icon": "filter_b_and_w",
|
"icon": "filter_b_and_w",
|
||||||
"description": "Controls how much original icon color is removed before applying tint"
|
"description": "Controls how much original icon color is removed before applying tint"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "barTransparency",
|
|
||||||
"label": "Transparency",
|
|
||||||
"tabIndex": 6,
|
|
||||||
"category": "Dank Bar",
|
|
||||||
"keywords": [
|
|
||||||
"alpha",
|
|
||||||
"background",
|
|
||||||
"bar",
|
|
||||||
"dank",
|
|
||||||
"opacity",
|
|
||||||
"panel",
|
|
||||||
"statusbar",
|
|
||||||
"taskbar",
|
|
||||||
"topbar",
|
|
||||||
"translucent",
|
|
||||||
"transparency",
|
|
||||||
"transparent"
|
|
||||||
],
|
|
||||||
"icon": "opacity",
|
|
||||||
"description": "Opacity of the bar background"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "barWidgetOutline",
|
"section": "barWidgetOutline",
|
||||||
"label": "Widget Outline",
|
"label": "Widget Outline",
|
||||||
@@ -3792,7 +3786,6 @@
|
|||||||
"tabIndex": 10,
|
"tabIndex": 10,
|
||||||
"category": "Theme & Colors",
|
"category": "Theme & Colors",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"alpha",
|
|
||||||
"appearance",
|
"appearance",
|
||||||
"colors",
|
"colors",
|
||||||
"controls",
|
"controls",
|
||||||
@@ -3804,11 +3797,9 @@
|
|||||||
"shadow",
|
"shadow",
|
||||||
"style",
|
"style",
|
||||||
"theme",
|
"theme",
|
||||||
"translucent",
|
"transparency"
|
||||||
"transparency",
|
|
||||||
"transparent"
|
|
||||||
],
|
],
|
||||||
"description": "Controls the transparency of the shadow"
|
"description": "Controls the opacity of the shadow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "m3ElevationEnabled",
|
"section": "m3ElevationEnabled",
|
||||||
@@ -3833,8 +3824,34 @@
|
|||||||
"style",
|
"style",
|
||||||
"theme"
|
"theme"
|
||||||
],
|
],
|
||||||
|
"icon": "layers",
|
||||||
"description": "Material inspired shadows and elevation on modals, popouts, and dialogs"
|
"description": "Material inspired shadows and elevation on modals, popouts, and dialogs"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "popupTransparency",
|
||||||
|
"label": "Surface Opacity",
|
||||||
|
"tabIndex": 10,
|
||||||
|
"category": "Theme & Colors",
|
||||||
|
"keywords": [
|
||||||
|
"appearance",
|
||||||
|
"colors",
|
||||||
|
"controls",
|
||||||
|
"look",
|
||||||
|
"modal",
|
||||||
|
"modals",
|
||||||
|
"opacity",
|
||||||
|
"popouts",
|
||||||
|
"popup",
|
||||||
|
"scheme",
|
||||||
|
"shell",
|
||||||
|
"style",
|
||||||
|
"surface",
|
||||||
|
"surfaces",
|
||||||
|
"theme",
|
||||||
|
"transparency"
|
||||||
|
],
|
||||||
|
"description": "Controls opacity of shell surfaces, popouts, and modals"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "syncModeWithPortal",
|
"section": "syncModeWithPortal",
|
||||||
"label": "Sync Mode with Portal",
|
"label": "Sync Mode with Portal",
|
||||||
@@ -3966,35 +3983,6 @@
|
|||||||
"icon": "palette",
|
"icon": "palette",
|
||||||
"description": "Select the palette algorithm used for wallpaper-based colors"
|
"description": "Select the palette algorithm used for wallpaper-based colors"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "popupTransparency",
|
|
||||||
"label": "Transparency",
|
|
||||||
"tabIndex": 10,
|
|
||||||
"category": "Theme & Colors",
|
|
||||||
"keywords": [
|
|
||||||
"alpha",
|
|
||||||
"appearance",
|
|
||||||
"colors",
|
|
||||||
"content",
|
|
||||||
"controls",
|
|
||||||
"layers",
|
|
||||||
"look",
|
|
||||||
"modal",
|
|
||||||
"modals",
|
|
||||||
"opacity",
|
|
||||||
"popouts",
|
|
||||||
"popup",
|
|
||||||
"scheme",
|
|
||||||
"style",
|
|
||||||
"surface",
|
|
||||||
"their",
|
|
||||||
"theme",
|
|
||||||
"translucent",
|
|
||||||
"transparency",
|
|
||||||
"transparent"
|
|
||||||
],
|
|
||||||
"description": "Controls opacity of all popouts, modals, and their content layers"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "matugenTemplateVscode",
|
"section": "matugenTemplateVscode",
|
||||||
"label": "VS Code",
|
"label": "VS Code",
|
||||||
@@ -4563,6 +4551,27 @@
|
|||||||
],
|
],
|
||||||
"description": "Automatically lock the screen when DMS starts"
|
"description": "Automatically lock the screen when DMS starts"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "lockBeforeSuspend",
|
||||||
|
"label": "Lock before suspend",
|
||||||
|
"tabIndex": 11,
|
||||||
|
"category": "Lock Screen",
|
||||||
|
"keywords": [
|
||||||
|
"automatic",
|
||||||
|
"automatically",
|
||||||
|
"before",
|
||||||
|
"lock",
|
||||||
|
"login",
|
||||||
|
"password",
|
||||||
|
"prepares",
|
||||||
|
"screen",
|
||||||
|
"security",
|
||||||
|
"sleep",
|
||||||
|
"suspend",
|
||||||
|
"system"
|
||||||
|
],
|
||||||
|
"description": "Automatically lock the screen when the system prepares to suspend"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "lockScreenNotificationMode",
|
"section": "lockScreenNotificationMode",
|
||||||
"label": "Notification Display",
|
"label": "Notification Display",
|
||||||
@@ -5470,6 +5479,26 @@
|
|||||||
],
|
],
|
||||||
"icon": "dashboard"
|
"icon": "dashboard"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "notificationBodyFontSize",
|
||||||
|
"label": "Body Font Size",
|
||||||
|
"tabIndex": 17,
|
||||||
|
"category": "Notifications",
|
||||||
|
"keywords": [
|
||||||
|
"alert",
|
||||||
|
"alerts",
|
||||||
|
"body",
|
||||||
|
"font",
|
||||||
|
"messages",
|
||||||
|
"notif",
|
||||||
|
"notification",
|
||||||
|
"notifications",
|
||||||
|
"size",
|
||||||
|
"text",
|
||||||
|
"toast"
|
||||||
|
],
|
||||||
|
"description": "Set the font size for notification body text (htmlBody)"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "notificationCompactMode",
|
"section": "notificationCompactMode",
|
||||||
"label": "Compact",
|
"label": "Compact",
|
||||||
@@ -5867,22 +5896,19 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"alert",
|
"alert",
|
||||||
"alerts",
|
"alerts",
|
||||||
"appear",
|
"font",
|
||||||
"choose",
|
|
||||||
"location",
|
|
||||||
"messages",
|
"messages",
|
||||||
"notif",
|
"notif",
|
||||||
"notification",
|
"notification",
|
||||||
"notifications",
|
"notifications",
|
||||||
"popup",
|
|
||||||
"popups",
|
"popups",
|
||||||
"position",
|
"size",
|
||||||
"screen",
|
"summary",
|
||||||
"toast",
|
"text",
|
||||||
"where"
|
"toast"
|
||||||
],
|
],
|
||||||
"icon": "notifications",
|
"icon": "notifications",
|
||||||
"description": "Choose where notification popups appear on screen"
|
"description": "Set the font size for notification summary text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "notificationRules",
|
"section": "notificationRules",
|
||||||
@@ -6032,6 +6058,26 @@
|
|||||||
],
|
],
|
||||||
"description": "Hide notification content until expanded; popups show collapsed by default"
|
"description": "Hide notification content until expanded; popups show collapsed by default"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "notificationSummaryFontSize",
|
||||||
|
"label": "Summary Font Size",
|
||||||
|
"tabIndex": 17,
|
||||||
|
"category": "Notifications",
|
||||||
|
"keywords": [
|
||||||
|
"alert",
|
||||||
|
"alerts",
|
||||||
|
"font",
|
||||||
|
"messages",
|
||||||
|
"notif",
|
||||||
|
"notification",
|
||||||
|
"notifications",
|
||||||
|
"size",
|
||||||
|
"summary",
|
||||||
|
"text",
|
||||||
|
"toast"
|
||||||
|
],
|
||||||
|
"description": "Set the font size for notification summary text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "notificationDedupeEnabled",
|
"section": "notificationDedupeEnabled",
|
||||||
"label": "Suppress Duplicate Notifications",
|
"label": "Suppress Duplicate Notifications",
|
||||||
@@ -6054,6 +6100,32 @@
|
|||||||
"toast"
|
"toast"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "notificationShowTimeoutBar",
|
||||||
|
"label": "Timeout Progress Bar",
|
||||||
|
"tabIndex": 17,
|
||||||
|
"category": "Notifications",
|
||||||
|
"keywords": [
|
||||||
|
"alerts",
|
||||||
|
"bar",
|
||||||
|
"countdown",
|
||||||
|
"drains",
|
||||||
|
"messages",
|
||||||
|
"notification",
|
||||||
|
"notifications",
|
||||||
|
"panel",
|
||||||
|
"popup",
|
||||||
|
"progress",
|
||||||
|
"show",
|
||||||
|
"statusbar",
|
||||||
|
"taskbar",
|
||||||
|
"timeout",
|
||||||
|
"timer",
|
||||||
|
"toast",
|
||||||
|
"topbar"
|
||||||
|
],
|
||||||
|
"description": "Show a bar that drains as the popup"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "osdAlwaysShowValue",
|
"section": "osdAlwaysShowValue",
|
||||||
"label": "Always Show Percentage",
|
"label": "Always Show Percentage",
|
||||||
@@ -6697,27 +6769,6 @@
|
|||||||
"icon": "schedule",
|
"icon": "schedule",
|
||||||
"description": "Gradually fade the screen before locking with a configurable grace period"
|
"description": "Gradually fade the screen before locking with a configurable grace period"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"section": "lockBeforeSuspend",
|
|
||||||
"label": "Lock before suspend",
|
|
||||||
"tabIndex": 21,
|
|
||||||
"category": "Power & Sleep",
|
|
||||||
"keywords": [
|
|
||||||
"automatically",
|
|
||||||
"before",
|
|
||||||
"energy",
|
|
||||||
"lock",
|
|
||||||
"power",
|
|
||||||
"prepares",
|
|
||||||
"screen",
|
|
||||||
"security",
|
|
||||||
"shutdown",
|
|
||||||
"sleep",
|
|
||||||
"suspend",
|
|
||||||
"system"
|
|
||||||
],
|
|
||||||
"description": "Automatically lock the screen when the system prepares to suspend"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"section": "fadeToLockGracePeriod",
|
"section": "fadeToLockGracePeriod",
|
||||||
"label": "Lock fade grace period",
|
"label": "Lock fade grace period",
|
||||||
@@ -7119,6 +7170,36 @@
|
|||||||
],
|
],
|
||||||
"description": "Maximum number of entries that can be saved"
|
"description": "Maximum number of entries that can be saved"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "clipboardVisibleEntryActions",
|
||||||
|
"label": "Visible Entry Actions",
|
||||||
|
"tabIndex": 23,
|
||||||
|
"category": "System",
|
||||||
|
"keywords": [
|
||||||
|
"action",
|
||||||
|
"actions",
|
||||||
|
"appear",
|
||||||
|
"buttons",
|
||||||
|
"choose",
|
||||||
|
"clipboard",
|
||||||
|
"cliphist",
|
||||||
|
"copy",
|
||||||
|
"delete",
|
||||||
|
"density",
|
||||||
|
"edit",
|
||||||
|
"entries",
|
||||||
|
"entry",
|
||||||
|
"hide",
|
||||||
|
"history",
|
||||||
|
"linux",
|
||||||
|
"os",
|
||||||
|
"paste",
|
||||||
|
"pin",
|
||||||
|
"system",
|
||||||
|
"visible"
|
||||||
|
],
|
||||||
|
"description": "Choose which action buttons appear on clipboard entries"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "_tab_24",
|
"section": "_tab_24",
|
||||||
"label": "Displays",
|
"label": "Displays",
|
||||||
@@ -8399,7 +8480,7 @@
|
|||||||
"topbar",
|
"topbar",
|
||||||
"window"
|
"window"
|
||||||
],
|
],
|
||||||
"icon": "crop_square",
|
"icon": "layers",
|
||||||
"description": "Use custom gaps instead of bar spacing",
|
"description": "Use custom gaps instead of bar spacing",
|
||||||
"conditionKey": "isNiri"
|
"conditionKey": "isNiri"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user