mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-20 18:15:24 -04:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d94117a69 | |||
| 92569d8b4d | |||
| fdee09b583 | |||
| b60af507d7 | |||
| 2cc12b70d2 | |||
| 2df1dfe0bd | |||
| abf084eea2 |
@@ -108,7 +108,6 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property bool clipboardEnterToPaste: false
|
property bool clipboardEnterToPaste: false
|
||||||
property var clipboardVisibleEntryActions: ["pin", "edit", "delete"]
|
|
||||||
|
|
||||||
property var launcherPluginVisibility: ({})
|
property var launcherPluginVisibility: ({})
|
||||||
|
|
||||||
@@ -397,7 +396,6 @@ Singleton {
|
|||||||
property bool audioVisualizerEnabled: true
|
property bool audioVisualizerEnabled: true
|
||||||
property string audioScrollMode: "volume"
|
property string audioScrollMode: "volume"
|
||||||
property int audioWheelScrollAmount: 5
|
property int audioWheelScrollAmount: 5
|
||||||
property bool audioDeviceScrollVolumeEnabled: false
|
|
||||||
property bool clockCompactMode: false
|
property bool clockCompactMode: false
|
||||||
property int focusedWindowSize: 1
|
property int focusedWindowSize: 1
|
||||||
property bool focusedWindowCompactMode: false
|
property bool focusedWindowCompactMode: false
|
||||||
@@ -520,39 +518,13 @@ Singleton {
|
|||||||
property real notificationSummaryFontSize: Spec.SPEC.notificationSummaryFontSize.def
|
property real notificationSummaryFontSize: Spec.SPEC.notificationSummaryFontSize.def
|
||||||
property real notificationBodyFontSize: Spec.SPEC.notificationBodyFontSize.def
|
property real notificationBodyFontSize: Spec.SPEC.notificationBodyFontSize.def
|
||||||
property bool notepadShowLineNumbers: false
|
property bool notepadShowLineNumbers: false
|
||||||
property bool notepadAutoSave: false
|
|
||||||
property string notepadSlideoutSide: "right"
|
|
||||||
property string notepadDefaultMode: "slideout"
|
|
||||||
property real notepadTransparencyOverride: -1
|
property real notepadTransparencyOverride: -1
|
||||||
property real notepadLastCustomTransparency: 0.7
|
property real notepadLastCustomTransparency: 0.7
|
||||||
property bool notepadUseCompositorGap: false
|
|
||||||
property int notepadEdgeGap: 0
|
|
||||||
|
|
||||||
// Compositor layout gap when enabled and available, else the manual value.
|
|
||||||
readonly property int notepadEffectiveEdgeGap: {
|
|
||||||
if (notepadUseCompositorGap) {
|
|
||||||
var g = -1;
|
|
||||||
if (CompositorService.isNiri)
|
|
||||||
g = niriLayoutGapsOverride;
|
|
||||||
else if (CompositorService.isHyprland)
|
|
||||||
g = hyprlandLayoutGapsOverride;
|
|
||||||
else if (CompositorService.isMango)
|
|
||||||
g = mangoLayoutGapsOverride;
|
|
||||||
if (g >= 0)
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
return Math.max(0, notepadEdgeGap);
|
|
||||||
}
|
|
||||||
|
|
||||||
onNotepadUseMonospaceChanged: saveSettings()
|
onNotepadUseMonospaceChanged: saveSettings()
|
||||||
onNotepadFontFamilyChanged: saveSettings()
|
onNotepadFontFamilyChanged: saveSettings()
|
||||||
onNotepadFontSizeChanged: saveSettings()
|
onNotepadFontSizeChanged: saveSettings()
|
||||||
onNotepadShowLineNumbersChanged: saveSettings()
|
onNotepadShowLineNumbersChanged: saveSettings()
|
||||||
onNotepadAutoSaveChanged: saveSettings()
|
|
||||||
onNotepadSlideoutSideChanged: saveSettings()
|
|
||||||
onNotepadDefaultModeChanged: saveSettings()
|
|
||||||
onNotepadUseCompositorGapChanged: saveSettings()
|
|
||||||
onNotepadEdgeGapChanged: saveSettings()
|
|
||||||
// onCenteringModeChanged: saveSettings()
|
// onCenteringModeChanged: saveSettings()
|
||||||
onNotepadTransparencyOverrideChanged: {
|
onNotepadTransparencyOverrideChanged: {
|
||||||
if (notepadTransparencyOverride > 0) {
|
if (notepadTransparencyOverride > 0) {
|
||||||
@@ -1678,15 +1650,6 @@ 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() {
|
||||||
|
|||||||
@@ -156,7 +156,6 @@ var SPEC = {
|
|||||||
audioVisualizerEnabled: { def: true },
|
audioVisualizerEnabled: { def: true },
|
||||||
audioScrollMode: { def: "volume" },
|
audioScrollMode: { def: "volume" },
|
||||||
audioWheelScrollAmount: { def: 5 },
|
audioWheelScrollAmount: { def: 5 },
|
||||||
audioDeviceScrollVolumeEnabled: { def: false },
|
|
||||||
clockCompactMode: { def: false },
|
clockCompactMode: { def: false },
|
||||||
focusedWindowCompactMode: { def: false },
|
focusedWindowCompactMode: { def: false },
|
||||||
focusedWindowSize: { def: 1 },
|
focusedWindowSize: { def: 1 },
|
||||||
@@ -264,13 +263,8 @@ var SPEC = {
|
|||||||
notificationSummaryFontSize: { def: 0 },
|
notificationSummaryFontSize: { def: 0 },
|
||||||
notificationBodyFontSize: { def: 0 },
|
notificationBodyFontSize: { def: 0 },
|
||||||
notepadShowLineNumbers: { def: false },
|
notepadShowLineNumbers: { def: false },
|
||||||
notepadAutoSave: { def: false },
|
|
||||||
notepadSlideoutSide: { def: "right" },
|
|
||||||
notepadDefaultMode: { def: "slideout" },
|
|
||||||
notepadTransparencyOverride: { def: -1 },
|
notepadTransparencyOverride: { def: -1 },
|
||||||
notepadLastCustomTransparency: { def: 0.7 },
|
notepadLastCustomTransparency: { def: 0.7 },
|
||||||
notepadUseCompositorGap: { def: false },
|
|
||||||
notepadEdgeGap: { def: 0 },
|
|
||||||
|
|
||||||
soundsEnabled: { def: true },
|
soundsEnabled: { def: true },
|
||||||
useSystemSoundTheme: { def: false },
|
useSystemSoundTheme: { def: false },
|
||||||
@@ -578,7 +572,6 @@ 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: [] },
|
||||||
|
|||||||
+19
-31
@@ -64,15 +64,27 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool wallpaperSurfacesLoaded: true
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: blurredWallpaperBackgroundLoader
|
id: blurredWallpaperBackgroundLoader
|
||||||
active: SettingsData.blurredWallpaperLayer && CompositorService.isNiri
|
active: root.wallpaperSurfacesLoaded && SettingsData.blurredWallpaperLayer && CompositorService.isNiri
|
||||||
asynchronous: false
|
asynchronous: false
|
||||||
|
|
||||||
sourceComponent: BlurredWallpaperBackground {}
|
sourceComponent: BlurredWallpaperBackground {}
|
||||||
}
|
}
|
||||||
|
|
||||||
WallpaperBackground {}
|
DeferredAction {
|
||||||
|
id: wallpaperSurfaceReloadAction
|
||||||
|
onTriggered: root.wallpaperSurfacesLoaded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: wallpaperBackgroundLoader
|
||||||
|
active: root.wallpaperSurfacesLoaded
|
||||||
|
asynchronous: false
|
||||||
|
sourceComponent: WallpaperBackground {}
|
||||||
|
}
|
||||||
|
|
||||||
DesktopWidgetLayer {}
|
DesktopWidgetLayer {}
|
||||||
|
|
||||||
@@ -386,6 +398,11 @@ 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;
|
||||||
@@ -1093,22 +1110,11 @@ Item {
|
|||||||
slideoutWidth: 480
|
slideoutWidth: 480
|
||||||
expandable: true
|
expandable: true
|
||||||
expandedWidthValue: 960
|
expandedWidthValue: 960
|
||||||
edgeGap: SettingsData.notepadEffectiveEdgeGap
|
|
||||||
slideEdge: SettingsData.notepadSlideoutSide
|
|
||||||
|
|
||||||
onIsVisibleChanged: {
|
|
||||||
if (isVisible)
|
|
||||||
PopoutService.notepadPopout?.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
content: Component {
|
content: Component {
|
||||||
Notepad {
|
Notepad {
|
||||||
slideout: notepadSlideout
|
slideout: notepadSlideout
|
||||||
onHideRequested: notepadSlideout.hide()
|
onHideRequested: notepadSlideout.hide()
|
||||||
onPopoutRequested: {
|
|
||||||
notepadSlideout.hide();
|
|
||||||
PopoutService.openNotepadPopout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1125,24 +1131,6 @@ Item {
|
|||||||
Component.onCompleted: PopoutService.notepadSlideouts = instances
|
Component.onCompleted: PopoutService.notepadSlideouts = instances
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: notepadPopoutLoader
|
|
||||||
active: false
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
PopoutService.notepadPopoutLoader = notepadPopoutLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
onActiveChanged: {
|
|
||||||
if (active && item) {
|
|
||||||
PopoutService.notepadPopout = item;
|
|
||||||
PopoutService._onNotepadPopoutLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NotepadPopoutWindow {}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: powerMenuModalLoader
|
id: powerMenuModalLoader
|
||||||
|
|
||||||
|
|||||||
@@ -373,10 +373,6 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function open(): string {
|
function open(): string {
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
PopoutService.openNotepadPopout();
|
|
||||||
return "NOTEPAD_OPEN_SUCCESS";
|
|
||||||
}
|
|
||||||
var instance = getActiveNotepadInstance();
|
var instance = getActiveNotepadInstance();
|
||||||
if (instance) {
|
if (instance) {
|
||||||
instance.show();
|
instance.show();
|
||||||
@@ -386,10 +382,6 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function close(): string {
|
function close(): string {
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
PopoutService.notepadPopout?.hide();
|
|
||||||
return "NOTEPAD_CLOSE_SUCCESS";
|
|
||||||
}
|
|
||||||
var instance = getActiveNotepadInstance();
|
var instance = getActiveNotepadInstance();
|
||||||
if (instance) {
|
if (instance) {
|
||||||
instance.hide();
|
instance.hide();
|
||||||
@@ -399,10 +391,6 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggle(): string {
|
function toggle(): string {
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
PopoutService.toggleNotepadPopout();
|
|
||||||
return "NOTEPAD_TOGGLE_SUCCESS";
|
|
||||||
}
|
|
||||||
var instance = getActiveNotepadInstance();
|
var instance = getActiveNotepadInstance();
|
||||||
if (instance) {
|
if (instance) {
|
||||||
instance.toggle();
|
instance.toggle();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ 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
|
||||||
@@ -32,7 +33,14 @@ 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: modal.confirmClearAll()
|
onClearAllClicked: {
|
||||||
|
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,14 +22,7 @@ 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 hasPinnedDuplicate: pinnedDuplicateEntry !== null
|
readonly property bool effectivePinned: entry.pinned || 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: {
|
||||||
@@ -70,28 +63,12 @@ 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: (entry.pinned || hasPinnedDuplicate) ? Theme.primary : Theme.surfaceText
|
iconColor: effectivePinned ? Theme.primary : Theme.surfaceText
|
||||||
backgroundColor: (entry.pinned || hasPinnedDuplicate) ? Theme.primarySelected : "transparent"
|
backgroundColor: effectivePinned ? Theme.primarySelected : "transparent"
|
||||||
visible: root.showPinAction
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (entry.pinned) {
|
if (entry.pinned) {
|
||||||
unpinRequested(entry);
|
unpinRequested(entry);
|
||||||
@@ -109,7 +86,6 @@ 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") {
|
||||||
@@ -123,7 +99,6 @@ 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,8 +106,8 @@ Rectangle {
|
|||||||
Item {
|
Item {
|
||||||
anchors.left: indexBadge.right
|
anchors.left: indexBadge.right
|
||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
anchors.right: root.showAnyAction ? actionButtons.left : parent.right
|
anchors.right: actionButtons.left
|
||||||
anchors.rightMargin: root.showAnyAction ? Theme.spacingM : Theme.spacingS
|
anchors.rightMargin: Theme.spacingM
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
// height: contentColumn.implicitHeight
|
// height: contentColumn.implicitHeight
|
||||||
height: ClipboardConstants.itemHeight
|
height: ClipboardConstants.itemHeight
|
||||||
@@ -193,8 +168,8 @@ Rectangle {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: root.showAnyAction ? actionButtons.left : parent.right
|
anchors.right: actionButtons.left
|
||||||
anchors.rightMargin: root.showAnyAction ? Theme.spacingS : 0
|
anchors.rightMargin: Theme.spacingS
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|||||||
@@ -82,15 +82,6 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -144,6 +135,7 @@ FocusScope {
|
|||||||
id: historyContent
|
id: historyContent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
modal: root
|
modal: root
|
||||||
|
clearConfirmDialog: root.clearConfirmDialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,35 +77,22 @@ DankModal {
|
|||||||
id: clearConfirmDialog
|
id: clearConfirmDialog
|
||||||
confirmButtonText: I18n.tr("Clear All")
|
confirmButtonText: I18n.tr("Clear All")
|
||||||
confirmButtonColor: Theme.primary
|
confirmButtonColor: Theme.primary
|
||||||
onShouldBeVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (shouldBeVisible) {
|
if (visible) {
|
||||||
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 = Qt.binding(() => clipboardHistoryModal.shouldBeVisible);
|
clipboardHistoryModal.shouldHaveFocus = true;
|
||||||
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,7 +1,6 @@
|
|||||||
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
|
||||||
@@ -96,35 +95,6 @@ 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,6 +125,8 @@ 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();
|
||||||
}
|
}
|
||||||
@@ -153,6 +155,8 @@ 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();
|
||||||
}
|
}
|
||||||
@@ -180,7 +184,8 @@ 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.confirmClearAll();
|
modal.clearAll();
|
||||||
|
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": "layers",
|
"icon": "crop_square",
|
||||||
"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_appearance",
|
|
||||||
"text": I18n.tr("Appearance"),
|
|
||||||
"icon": "palette",
|
|
||||||
"tabIndex": 6
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "dankbar_settings",
|
"id": "dankbar_settings",
|
||||||
"text": I18n.tr("Settings"),
|
"text": I18n.tr("Settings"),
|
||||||
"icon": "tune",
|
"icon": "tune",
|
||||||
"tabIndex": 3
|
"tabIndex": 3
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "dankbar_appearance",
|
||||||
|
"text": I18n.tr("Appearance"),
|
||||||
|
"icon": "palette",
|
||||||
|
"tabIndex": 6
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "dankbar_widgets",
|
"id": "dankbar_widgets",
|
||||||
"text": I18n.tr("Widgets"),
|
"text": I18n.tr("Widgets"),
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ 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;
|
||||||
@@ -33,8 +32,6 @@ Variants {
|
|||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
updatesEnabled: root.renderActive || root._settleFrames > 0
|
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: Item {}
|
item: Item {}
|
||||||
}
|
}
|
||||||
@@ -88,6 +85,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,67 +93,51 @@ 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
|
|
||||||
|
|
||||||
function invalidate() {
|
|
||||||
_settleFrames = 3;
|
|
||||||
backingWindow?.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
onRenderActiveChanged: invalidate()
|
|
||||||
onBackingWindowChanged: invalidate()
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.backingWindow
|
target: currentWallpaper
|
||||||
function onFrameSwapped() {
|
function onStatusChanged() {
|
||||||
if (root._settleFrames > 0)
|
if (currentWallpaper.status !== Image.Ready && currentWallpaper.status !== Image.Error)
|
||||||
root._settleFrames--;
|
return;
|
||||||
}
|
root._renderSettling = true;
|
||||||
function onVisibleChanged() {
|
renderSettleTimer.restart();
|
||||||
root.invalidate();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: blurWallpaperWindow
|
||||||
function onWidthChanged() {
|
function onWidthChanged() {
|
||||||
root.invalidate();
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
}
|
}
|
||||||
function onHeightChanged() {
|
function onHeightChanged() {
|
||||||
root.invalidate();
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Quickshell
|
target: Quickshell
|
||||||
function onScreensChanged() {
|
function onScreensChanged() {
|
||||||
root.invalidate();
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onWallpaperFillModeChanged() {
|
function onWallpaperFillModeChanged() {
|
||||||
root.invalidate();
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Timer {
|
||||||
target: IdleService
|
id: renderSettleTimer
|
||||||
function onIsShellLockedChanged() {
|
interval: 1000
|
||||||
if (IdleService.isShellLocked)
|
onTriggered: root._renderSettling = false
|
||||||
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: {
|
||||||
@@ -182,6 +164,8 @@ 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 = "";
|
||||||
}
|
}
|
||||||
@@ -210,6 +194,8 @@ 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 = "";
|
||||||
}
|
}
|
||||||
@@ -218,6 +204,9 @@ Variants {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
|
|
||||||
nextWallpaper.source = newPath;
|
nextWallpaper.source = newPath;
|
||||||
|
|
||||||
if (nextWallpaper.status === Image.Ready)
|
if (nextWallpaper.status === Image.Ready)
|
||||||
@@ -226,7 +215,7 @@ Variants {
|
|||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: !root.source || root.isColorSource || currentWallpaper.status === Image.Error
|
active: !root.source || root.isColorSource
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: DankBackdrop {
|
sourceComponent: DankBackdrop {
|
||||||
@@ -249,12 +238,6 @@ 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 {
|
||||||
@@ -270,10 +253,6 @@ 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) {
|
||||||
@@ -350,6 +329,8 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,6 +286,9 @@ 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
|
||||||
@@ -297,30 +300,25 @@ 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)) || (renderBarConfig?.shadowIntensity ?? 0) > 0
|
readonly property bool _shadowActive: (Theme.elevationEnabled && (typeof SettingsData !== "undefined" ? (SettingsData.barElevationEnabled ?? true) : false)) || (barConfig?.shadowIntensity ?? 0) > 0
|
||||||
readonly property real _shadowBuffer: {
|
readonly property real _shadowBuffer: {
|
||||||
if (!_shadowActive)
|
if (!_shadowActive)
|
||||||
return 0;
|
return 0;
|
||||||
const hasOverride = (renderBarConfig?.shadowIntensity ?? 0) > 0;
|
const hasOverride = (barConfig?.shadowIntensity ?? 0) > 0;
|
||||||
if (hasOverride) {
|
if (hasOverride) {
|
||||||
const blur = (renderBarConfig.shadowIntensity ?? 0) * 0.2;
|
const blur = (barConfig.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
|
||||||
@@ -556,8 +554,8 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
screen: modelData
|
screen: modelData
|
||||||
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + effectiveSpacing + ((renderBarConfig?.gothCornersEnabled ?? false) && !hasMaximizedToplevel ? _wingR : 0), _dpr) + _shadowBuffer : 0
|
implicitHeight: !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
|
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + effectiveSpacing + ((barConfig?.gothCornersEnabled ?? false) && !hasMaximizedToplevel ? _wingR : 0), _dpr) + _shadowBuffer : 0
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
@@ -954,7 +952,7 @@ PanelWindow {
|
|||||||
id: barBackground
|
id: barBackground
|
||||||
barWindow: barWindow
|
barWindow: barWindow
|
||||||
axis: axis
|
axis: axis
|
||||||
barConfig: barWindow.renderBarConfig
|
barConfig: barWindow.barConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
@@ -32,20 +32,9 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly property var notepadInstance: resolveNotepadInstance()
|
readonly property var notepadInstance: resolveNotepadInstance()
|
||||||
readonly property bool popoutDefault: SettingsData.notepadDefaultMode === "popout"
|
readonly property bool isActive: notepadInstance?.isVisible ?? false
|
||||||
readonly property bool isActive: popoutDefault ? (PopoutService.notepadPopout?.visible ?? false) : (notepadInstance?.isVisible ?? false)
|
|
||||||
property bool isAutoHideBar: false
|
property bool isAutoHideBar: false
|
||||||
|
|
||||||
function showActiveSurface() {
|
|
||||||
if (root.popoutDefault) {
|
|
||||||
PopoutService.openNotepadPopout();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const instance = prepareNotepadInstance(root.notepadInstance);
|
|
||||||
if (instance && typeof instance.show === "function")
|
|
||||||
instance.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareNotepadInstance(instance) {
|
function prepareNotepadInstance(instance) {
|
||||||
if (instance)
|
if (instance)
|
||||||
instance.triggerUsesOverlayLayer = root.barUsesOverlayLayer;
|
instance.triggerUsesOverlayLayer = root.barUsesOverlayLayer;
|
||||||
@@ -86,14 +75,20 @@ BasePill {
|
|||||||
function openTabByIndex(tabIndex) {
|
function openTabByIndex(tabIndex) {
|
||||||
if (tabIndex < 0)
|
if (tabIndex < 0)
|
||||||
return;
|
return;
|
||||||
showActiveSurface();
|
const instance = prepareNotepadInstance(root.notepadInstance);
|
||||||
|
if (instance && typeof instance.show === "function") {
|
||||||
|
instance.show();
|
||||||
|
}
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
NotepadStorageService.switchToTab(tabIndex);
|
NotepadStorageService.switchToTab(tabIndex);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function openNewNote() {
|
function openNewNote() {
|
||||||
showActiveSurface();
|
const instance = prepareNotepadInstance(root.notepadInstance);
|
||||||
|
if (instance && typeof instance.show === "function") {
|
||||||
|
instance.show();
|
||||||
|
}
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
NotepadStorageService.createNewTab();
|
NotepadStorageService.createNewTab();
|
||||||
});
|
});
|
||||||
@@ -152,10 +147,6 @@ BasePill {
|
|||||||
openContextMenu();
|
openContextMenu();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (root.popoutDefault) {
|
|
||||||
PopoutService.toggleNotepadPopout();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const inst = prepareNotepadInstance(root.notepadInstance);
|
const inst = prepareNotepadInstance(root.notepadInstance);
|
||||||
if (inst) {
|
if (inst) {
|
||||||
inst.toggle();
|
inst.toggle();
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ DankPopout {
|
|||||||
MprisController.setActivePlayer(player);
|
MprisController.setActivePlayer(player);
|
||||||
root.__hideDropdowns();
|
root.__hideDropdowns();
|
||||||
}
|
}
|
||||||
|
onDeviceSelected: device => {
|
||||||
|
root.__hideDropdowns();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -383,27 +383,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
onClicked: {
|
||||||
onPressed: mouse => {
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
mouse.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onWheel: wheelEvent => {
|
|
||||||
if (SettingsData.audioDeviceScrollVolumeEnabled && wheelEvent.x >= deviceMouseArea.width / 2) {
|
|
||||||
AudioService.handleNodeVolumeWheel(modelData, wheelEvent);
|
|
||||||
} else {
|
|
||||||
wheelEvent.accepted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClicked: mouse => {
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
if (modelData && modelData.audio) {
|
|
||||||
SessionData.suppressOSDTemporarily();
|
|
||||||
modelData.audio.muted = !modelData.audio.muted;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (modelData && modelData.name) {
|
if (modelData && modelData.name) {
|
||||||
AudioService.setDefaultSinkByName(modelData.name);
|
AudioService.setDefaultSinkByName(modelData.name);
|
||||||
root.deviceSelected(modelData);
|
root.deviceSelected(modelData);
|
||||||
|
|||||||
@@ -866,27 +866,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
onClicked: {
|
||||||
onPressed: mouse => {
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
mouse.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onWheel: wheelEvent => {
|
|
||||||
const delta = wheelEvent.angleDelta.y;
|
|
||||||
if (delta !== 0) {
|
|
||||||
AudioService.cycleAudioOutputDirection(delta < 0);
|
|
||||||
wheelEvent.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClicked: mouse => {
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
if (AudioService.sink?.audio) {
|
|
||||||
SessionData.suppressOSDTemporarily();
|
|
||||||
AudioService.sink.audio.muted = !AudioService.sink.audio.muted;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (devicesExpanded) {
|
if (devicesExpanded) {
|
||||||
const sinks = AudioService.getAvailableSinks();
|
const sinks = AudioService.getAvailableSinks();
|
||||||
if (sinks && sinks.length > 1) {
|
if (sinks && sinks.length > 1) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import qs.Common
|
import qs.Common
|
||||||
@@ -22,24 +21,11 @@ Item {
|
|||||||
property var currentTab: NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null
|
property var currentTab: NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null
|
||||||
property bool showSettingsMenu: false
|
property bool showSettingsMenu: false
|
||||||
property string pendingSaveContent: ""
|
property string pendingSaveContent: ""
|
||||||
readonly property bool conflictBannerVisible: currentTab !== null && NotepadStorageService.conflictTabId === currentTab.id
|
|
||||||
property var slideout: null
|
property var slideout: null
|
||||||
property bool inPopout: false
|
|
||||||
property bool surfaceVisible: slideout ? slideout.isVisible : true
|
|
||||||
|
|
||||||
signal hideRequested
|
signal hideRequested
|
||||||
signal popoutRequested
|
|
||||||
signal dockRequested
|
|
||||||
signal previewRequested(string content)
|
signal previewRequested(string content)
|
||||||
|
|
||||||
function externalSync() {
|
|
||||||
textEditor.syncFromDisk();
|
|
||||||
}
|
|
||||||
|
|
||||||
function flushAutoSave() {
|
|
||||||
textEditor.autoSaveToSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref {
|
Ref {
|
||||||
service: NotepadStorageService
|
service: NotepadStorageService
|
||||||
}
|
}
|
||||||
@@ -50,37 +36,6 @@ Item {
|
|||||||
function onAboutToHide() {
|
function onAboutToHide() {
|
||||||
textEditor.autoSaveToSession();
|
textEditor.autoSaveToSession();
|
||||||
}
|
}
|
||||||
function onRevealed() {
|
|
||||||
textEditor.syncFromDisk();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showConflictBanner(diskContent) {
|
|
||||||
if (!currentTab)
|
|
||||||
return;
|
|
||||||
NotepadStorageService.flagConflict(currentTab.id, diskContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveConflictKeepEdits() {
|
|
||||||
if (!root.conflictBannerVisible)
|
|
||||||
return;
|
|
||||||
NotepadStorageService.clearConflict();
|
|
||||||
if (currentTab && currentTab.filePath && !currentTab.isTemporary) {
|
|
||||||
root.saveToFile("file://" + currentTab.filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveConflictReload() {
|
|
||||||
if (!root.conflictBannerVisible)
|
|
||||||
return;
|
|
||||||
const diskContent = NotepadStorageService.conflictDiskContent;
|
|
||||||
NotepadStorageService.clearConflict();
|
|
||||||
textEditor.reloadFromDisk(diskContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function dismissConflictBanner() {
|
|
||||||
if (root.conflictBannerVisible)
|
|
||||||
NotepadStorageService.clearConflict();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasUnsavedChanges() {
|
function hasUnsavedChanges() {
|
||||||
@@ -96,14 +51,10 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function performCreateNewTab() {
|
function performCreateNewTab() {
|
||||||
textEditor.commitLiveBuffer();
|
|
||||||
NotepadStorageService.createNewTab();
|
NotepadStorageService.createNewTab();
|
||||||
textEditor.applyingShared = true;
|
|
||||||
textEditor.text = "";
|
textEditor.text = "";
|
||||||
textEditor.lastSavedContent = "";
|
textEditor.lastSavedContent = "";
|
||||||
textEditor.loadedTabId = -1;
|
|
||||||
textEditor.contentLoaded = true;
|
textEditor.contentLoaded = true;
|
||||||
textEditor.applyingShared = false;
|
|
||||||
textEditor.textArea.forceActiveFocus();
|
textEditor.textArea.forceActiveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +86,7 @@ Item {
|
|||||||
|
|
||||||
NotepadStorageService.switchToTab(tabIndex);
|
NotepadStorageService.switchToTab(tabIndex);
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
|
textEditor.loadCurrentTabContent();
|
||||||
if (currentTab) {
|
if (currentTab) {
|
||||||
root.currentFileName = currentTab.fileName || "";
|
root.currentFileName = currentTab.fileName || "";
|
||||||
root.currentFileUrl = currentTab.fileUrl || "";
|
root.currentFileUrl = currentTab.fileUrl || "";
|
||||||
@@ -148,7 +100,6 @@ Item {
|
|||||||
var content = textEditor.text;
|
var content = textEditor.text;
|
||||||
var filePath = fileUrl.toString().replace(/^file:\/\//, '');
|
var filePath = fileUrl.toString().replace(/^file:\/\//, '');
|
||||||
|
|
||||||
textEditor.externalWatchPaused = true;
|
|
||||||
saveFileView.path = "";
|
saveFileView.path = "";
|
||||||
pendingSaveContent = content;
|
pendingSaveContent = content;
|
||||||
saveFileView.path = filePath;
|
saveFileView.path = filePath;
|
||||||
@@ -158,53 +109,6 @@ Item {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveExternalWithFreshnessCheck() {
|
|
||||||
if (!currentTab || currentTab.isTemporary || !currentTab.filePath)
|
|
||||||
return;
|
|
||||||
const filePath = currentTab.filePath;
|
|
||||||
loadFileView.path = "";
|
|
||||||
loadFileView.path = filePath;
|
|
||||||
|
|
||||||
if (!loadFileView.waitForJob()) {
|
|
||||||
saveToFile("file://" + filePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Qt.callLater(() => {
|
|
||||||
if (!currentTab || currentTab.isTemporary || currentTab.filePath !== filePath)
|
|
||||||
return;
|
|
||||||
const diskContent = loadFileView.text();
|
|
||||||
if (diskContent !== undefined && diskContent !== null && diskContent !== textEditor.text && diskContent !== textEditor.lastSavedContent) {
|
|
||||||
root.showConflictBanner(diskContent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
saveToFile("file://" + filePath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function autoSaveExternal() {
|
|
||||||
if (!SettingsData.notepadAutoSave)
|
|
||||||
return;
|
|
||||||
if (!currentTab || currentTab.isTemporary || !currentTab.filePath)
|
|
||||||
return;
|
|
||||||
if (!textEditor.hasUnsavedChanges())
|
|
||||||
return;
|
|
||||||
const filePath = currentTab.filePath;
|
|
||||||
loadFileView.path = "";
|
|
||||||
loadFileView.path = filePath;
|
|
||||||
if (!loadFileView.waitForJob())
|
|
||||||
return;
|
|
||||||
Qt.callLater(() => {
|
|
||||||
if (!currentTab || currentTab.isTemporary || currentTab.filePath !== filePath)
|
|
||||||
return;
|
|
||||||
const diskContent = loadFileView.text();
|
|
||||||
if (diskContent === undefined || diskContent === null)
|
|
||||||
return;
|
|
||||||
if (diskContent !== textEditor.lastSavedContent)
|
|
||||||
return;
|
|
||||||
saveToFile("file://" + filePath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadFromFile(fileUrl) {
|
function loadFromFile(fileUrl) {
|
||||||
if (hasUnsavedTemporaryContent()) {
|
if (hasUnsavedTemporaryContent()) {
|
||||||
root.pendingFileUrl = fileUrl;
|
root.pendingFileUrl = fileUrl;
|
||||||
@@ -242,155 +146,14 @@ Item {
|
|||||||
|
|
||||||
root.currentFileName = fileName;
|
root.currentFileName = fileName;
|
||||||
root.currentFileUrl = fileUrl;
|
root.currentFileUrl = fileUrl;
|
||||||
textEditor.loadedTabId = currentTab.id;
|
textEditor.saveCurrentTabContent();
|
||||||
NotepadStorageService.clearSessionBuffer(currentTab.id);
|
|
||||||
if (root.conflictBannerVisible)
|
|
||||||
NotepadStorageService.clearConflict();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
id: conflictBanner
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: root.conflictBannerVisible ? bannerRect.implicitHeight : 0
|
|
||||||
visible: height > 0
|
|
||||||
clip: true
|
|
||||||
z: 5
|
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.shortDuration
|
|
||||||
easing.type: Theme.standardEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
id: bannerRect
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
implicitHeight: bannerLayout.implicitHeight + Theme.spacingM * 2
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Theme.withAlpha(Theme.warning, 0.12)
|
|
||||||
border.color: Theme.withAlpha(Theme.warning, 0.5)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: bannerLayout
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: Theme.spacingM
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
name: "sync_problem"
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.warning
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
text: I18n.tr("File changed on disk")
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
iconName: "close"
|
|
||||||
iconSize: Theme.iconSizeSmall
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
buttonSize: 28
|
|
||||||
onClicked: root.dismissConflictBanner()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 32
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: bannerActions
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
readonly property real available: parent.width
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: Math.min(keepText.implicitWidth + Theme.spacingM * 2, Math.max(104, (bannerActions.available - bannerActions.spacing) / 2))
|
|
||||||
height: 32
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: "transparent"
|
|
||||||
border.color: Theme.outlineMedium
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
anchors.fill: parent
|
|
||||||
cornerRadius: parent.radius
|
|
||||||
stateColor: Theme.surfaceText
|
|
||||||
onClicked: root.resolveConflictKeepEdits()
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: keepText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width - Theme.spacingM
|
|
||||||
text: I18n.tr("Keep My Edits")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: Math.min(reloadText.implicitWidth + Theme.spacingM * 2, Math.max(116, (bannerActions.available - bannerActions.spacing) / 2))
|
|
||||||
height: 32
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Theme.primary
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
anchors.fill: parent
|
|
||||||
cornerRadius: parent.radius
|
|
||||||
stateColor: Theme.background
|
|
||||||
onClicked: root.resolveConflictReload()
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: reloadText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width - Theme.spacingM
|
|
||||||
text: I18n.tr("Reload From Disk")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.background
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.top: conflictBanner.bottom
|
anchors.fill: parent
|
||||||
anchors.topMargin: root.conflictBannerVisible ? Theme.spacingM : 0
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
NotepadTabs {
|
NotepadTabs {
|
||||||
@@ -415,12 +178,11 @@ Item {
|
|||||||
id: textEditor
|
id: textEditor
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - tabBar.height - Theme.spacingM * 2
|
height: parent.height - tabBar.height - Theme.spacingM * 2
|
||||||
inPopout: root.inPopout
|
|
||||||
surfaceVisible: root.surfaceVisible
|
|
||||||
|
|
||||||
onSaveRequested: {
|
onSaveRequested: {
|
||||||
if (currentTab && !currentTab.isTemporary && currentTab.filePath) {
|
if (currentTab && !currentTab.isTemporary && currentTab.filePath) {
|
||||||
root.saveExternalWithFreshnessCheck();
|
var fileUrl = "file://" + currentTab.filePath;
|
||||||
|
saveToFile(fileUrl);
|
||||||
} else {
|
} else {
|
||||||
root.fileDialogOpen = true;
|
root.fileDialogOpen = true;
|
||||||
saveBrowserLoader.active = true;
|
saveBrowserLoader.active = true;
|
||||||
@@ -452,28 +214,12 @@ Item {
|
|||||||
|
|
||||||
onEscapePressed: {
|
onEscapePressed: {
|
||||||
textEditor.autoSaveToSession();
|
textEditor.autoSaveToSession();
|
||||||
if (showSettingsMenu) {
|
root.hideRequested();
|
||||||
showSettingsMenu = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!root.inPopout) {
|
|
||||||
root.hideRequested();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSettingsRequested: {
|
onSettingsRequested: {
|
||||||
showSettingsMenu = !showSettingsMenu;
|
showSettingsMenu = !showSettingsMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPopoutRequested: root.popoutRequested()
|
|
||||||
|
|
||||||
onDockRequested: root.dockRequested()
|
|
||||||
|
|
||||||
onConflictDetected: diskContent => {
|
|
||||||
root.showConflictBanner(diskContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
onAutoSaveRequested: root.autoSaveExternal()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,24 +242,17 @@ Item {
|
|||||||
printErrors: true
|
printErrors: true
|
||||||
|
|
||||||
onSaved: {
|
onSaved: {
|
||||||
if (currentTab && saveFileView.path) {
|
if (currentTab && saveFileView.path && pendingSaveContent) {
|
||||||
NotepadStorageService.updateTabMetadata(NotepadStorageService.currentTabIndex, {
|
NotepadStorageService.updateTabMetadata(NotepadStorageService.currentTabIndex, {
|
||||||
hasUnsavedChanges: false,
|
hasUnsavedChanges: false,
|
||||||
lastSavedContent: pendingSaveContent
|
lastSavedContent: pendingSaveContent
|
||||||
});
|
});
|
||||||
root.lastSavedFileContent = pendingSaveContent;
|
root.lastSavedFileContent = pendingSaveContent;
|
||||||
textEditor.lastSavedContent = pendingSaveContent;
|
pendingSaveContent = "";
|
||||||
textEditor.ignoreNextExternalChange = true;
|
|
||||||
textEditor.commitLiveBuffer();
|
|
||||||
if (root.conflictBannerVisible)
|
|
||||||
NotepadStorageService.clearConflict();
|
|
||||||
}
|
}
|
||||||
textEditor.externalWatchPaused = false;
|
|
||||||
pendingSaveContent = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSaveFailed: error => {
|
onSaveFailed: error => {
|
||||||
textEditor.externalWatchPaused = false;
|
|
||||||
pendingSaveContent = "";
|
pendingSaveContent = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -559,7 +298,6 @@ Item {
|
|||||||
|
|
||||||
root.currentFileName = fileName;
|
root.currentFileName = fileName;
|
||||||
root.currentFileUrl = fileUrl;
|
root.currentFileUrl = fileUrl;
|
||||||
textEditor.externalWatchPaused = true;
|
|
||||||
|
|
||||||
if (currentTab) {
|
if (currentTab) {
|
||||||
NotepadStorageService.saveTabAs(NotepadStorageService.currentTabIndex, cleanPath);
|
NotepadStorageService.saveTabAs(NotepadStorageService.currentTabIndex, cleanPath);
|
||||||
@@ -605,7 +343,7 @@ Item {
|
|||||||
browserTitle: I18n.tr("Open Notepad File")
|
browserTitle: I18n.tr("Open Notepad File")
|
||||||
browserIcon: "folder_open"
|
browserIcon: "folder_open"
|
||||||
browserType: "notepad_load"
|
browserType: "notepad_load"
|
||||||
fileExtensions: ["*"]
|
fileExtensions: ["*.txt", "*.md", "*.*"]
|
||||||
allowStacking: true
|
allowStacking: true
|
||||||
|
|
||||||
onFileSelected: path => {
|
onFileSelected: path => {
|
||||||
@@ -638,7 +376,6 @@ Item {
|
|||||||
modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 180
|
modalHeight: contentLoader.item ? contentLoader.item.implicitHeight + Theme.spacingM * 2 : 180
|
||||||
shouldBeVisible: false
|
shouldBeVisible: false
|
||||||
allowStacking: true
|
allowStacking: true
|
||||||
useOverlayLayer: true
|
|
||||||
|
|
||||||
onBackgroundClicked: {
|
onBackgroundClicked: {
|
||||||
close();
|
close();
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
import qs.Modules.Notepad
|
|
||||||
|
|
||||||
FloatingWindow {
|
|
||||||
id: win
|
|
||||||
|
|
||||||
property alias shouldBeVisible: win.visible
|
|
||||||
|
|
||||||
function show() {
|
|
||||||
visible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
|
||||||
visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
visible = !visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
title: I18n.tr("Notepad")
|
|
||||||
minimumSize: Qt.size(360, 320)
|
|
||||||
implicitWidth: 640
|
|
||||||
implicitHeight: 760
|
|
||||||
color: Theme.surfaceContainer
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
Qt.callLater(notepad.externalSync);
|
|
||||||
} else {
|
|
||||||
notepad.flushAutoSave();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A compositor close (e.g. niri close-window)
|
|
||||||
onClosed: win.visible = false
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: titleBar
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: 44
|
|
||||||
z: 10
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onPressed: windowControls.tryStartMove()
|
|
||||||
onDoubleClicked: windowControls.tryToggleMaximize()
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Theme.surfaceContainerHigh
|
|
||||||
opacity: 0.5
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingM
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "edit_note"
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Notepad")
|
|
||||||
font.pixelSize: Theme.fontSizeLarge
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
visible: windowControls.canMaximize
|
|
||||||
circular: false
|
|
||||||
iconName: win.maximized ? "fullscreen_exit" : "fullscreen"
|
|
||||||
iconSize: Theme.iconSize - 4
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: windowControls.tryToggleMaximize()
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
circular: false
|
|
||||||
iconName: "close"
|
|
||||||
iconSize: Theme.iconSize - 4
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: win.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Notepad {
|
|
||||||
id: notepad
|
|
||||||
anchors.top: titleBar.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.topMargin: Theme.spacingM
|
|
||||||
anchors.leftMargin: Theme.spacingM
|
|
||||||
anchors.rightMargin: Theme.spacingM
|
|
||||||
anchors.bottomMargin: Theme.spacingM
|
|
||||||
inPopout: true
|
|
||||||
surfaceVisible: win.visible
|
|
||||||
onHideRequested: win.hide()
|
|
||||||
onDockRequested: {
|
|
||||||
win.hide();
|
|
||||||
PopoutService.openNotepadSlideout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatingWindowControls {
|
|
||||||
id: windowControls
|
|
||||||
targetWindow: win
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,6 @@ Item {
|
|||||||
property var cachedFontFamilies: []
|
property var cachedFontFamilies: []
|
||||||
property var cachedMonoFamilies: []
|
property var cachedMonoFamilies: []
|
||||||
property bool fontsEnumerated: false
|
property bool fontsEnumerated: false
|
||||||
property bool shortcutsExpanded: false
|
|
||||||
|
|
||||||
signal settingsRequested
|
signal settingsRequested
|
||||||
signal findRequested
|
signal findRequested
|
||||||
@@ -63,23 +62,11 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: root.isVisible
|
visible: root.isVisible
|
||||||
|
onClicked: root.settingsRequested()
|
||||||
z: 50
|
z: 50
|
||||||
color: Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, 0.85)
|
|
||||||
|
|
||||||
WheelHandler {
|
|
||||||
// Hold scroll so the editor beneath doesn't move while settings are open.
|
|
||||||
onWheel: event => {
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: root.settingsRequested()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -87,8 +74,8 @@ Item {
|
|||||||
visible: root.isVisible
|
visible: root.isVisible
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Math.min(360, root.width - Theme.spacingL * 2)
|
width: 360
|
||||||
height: Math.min(settingsColumn.implicitHeight + Theme.spacingXL * 2, root.height - Theme.spacingL * 2)
|
height: settingsColumn.implicitHeight + Theme.spacingXL * 2
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, Theme.notepadTransparency)
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, Theme.notepadTransparency)
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
@@ -106,459 +93,275 @@ Item {
|
|||||||
z: parent.z - 1
|
z: parent.z - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
DankFlickable {
|
Column {
|
||||||
id: settingsFlickable
|
id: settingsColumn
|
||||||
anchors.fill: parent
|
width: parent.width - Theme.spacingXL * 2
|
||||||
clip: true
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
contentWidth: width
|
anchors.top: parent.top
|
||||||
contentHeight: settingsColumn.implicitHeight + Theme.spacingXL * 2
|
anchors.topMargin: Theme.spacingXL
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
Column {
|
Rectangle {
|
||||||
id: settingsColumn
|
width: parent.width
|
||||||
x: Theme.spacingXL
|
height: 36
|
||||||
y: Theme.spacingXL
|
color: "transparent"
|
||||||
width: settingsFlickable.width - Theme.spacingXL * 2
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: 36
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingXS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: I18n.tr("Notepad Settings")
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: 1
|
|
||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
text: I18n.tr("Use Monospace Font")
|
|
||||||
description: I18n.tr("Toggle fonts")
|
|
||||||
checked: SettingsData.notepadUseMonospace
|
|
||||||
onToggled: checked => {
|
|
||||||
SettingsData.notepadUseMonospace = checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
text: I18n.tr("Show Line Numbers")
|
|
||||||
description: I18n.tr("Display line numbers in editor")
|
|
||||||
checked: SettingsData.notepadShowLineNumbers
|
|
||||||
onToggled: checked => {
|
|
||||||
SettingsData.notepadShowLineNumbers = checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
text: I18n.tr("Auto-save to disk")
|
|
||||||
description: I18n.tr("Automatically save changes to opened files as you type")
|
|
||||||
checked: SettingsData.notepadAutoSave
|
|
||||||
onToggled: checked => {
|
|
||||||
SettingsData.notepadAutoSave = checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
width: parent.width
|
|
||||||
height: 60
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
stateColor: Theme.primary
|
|
||||||
cornerRadius: parent.radius
|
|
||||||
onClicked: root.findRequested()
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Theme.spacingM
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingM
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "search"
|
|
||||||
size: Theme.iconSize - 2
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Find in Text")
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Open search bar to find text")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: visible ? (fontDropdown.height + Theme.spacingS) : 0
|
|
||||||
color: "transparent"
|
|
||||||
visible: !SettingsData.notepadUseMonospace
|
|
||||||
|
|
||||||
DankDropdown {
|
|
||||||
id: fontDropdown
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
text: I18n.tr("Font Family")
|
|
||||||
options: cachedFontFamilies
|
|
||||||
currentValue: {
|
|
||||||
if (!SettingsData.notepadFontFamily || SettingsData.notepadFontFamily === "")
|
|
||||||
return I18n.tr("Default (Global)");
|
|
||||||
else
|
|
||||||
return SettingsData.notepadFontFamily;
|
|
||||||
}
|
|
||||||
enableFuzzySearch: true
|
|
||||||
onValueChanged: value => {
|
|
||||||
if (value && (value.startsWith("Default") || value === "Default (Global)")) {
|
|
||||||
SettingsData.notepadFontFamily = "";
|
|
||||||
} else {
|
|
||||||
SettingsData.notepadFontFamily = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: fontSizeRow.height + Theme.spacingS
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: fontSizeRow
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width - fontSizeControls.width - Theme.spacingM
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Font Size")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: SettingsData.notepadFontSize + "px"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
width: parent.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: fontSizeControls
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
buttonSize: 32
|
|
||||||
iconName: "remove"
|
|
||||||
iconSize: Theme.iconSizeSmall
|
|
||||||
enabled: SettingsData.notepadFontSize > 8
|
|
||||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: {
|
|
||||||
var newSize = Math.max(8, SettingsData.notepadFontSize - 1);
|
|
||||||
SettingsData.notepadFontSize = newSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 60
|
|
||||||
height: 32
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: SettingsData.notepadFontSize + "px"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
buttonSize: 32
|
|
||||||
iconName: "add"
|
|
||||||
iconSize: Theme.iconSizeSmall
|
|
||||||
enabled: SettingsData.notepadFontSize < 48
|
|
||||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: {
|
|
||||||
var newSize = Math.min(48, SettingsData.notepadFontSize + 1);
|
|
||||||
SettingsData.notepadFontSize = newSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: transparencySliderColumn.height + Theme.spacingS
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: transparencySliderColumn
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
text: I18n.tr("Surface Opacity")
|
|
||||||
description: I18n.tr("Override global transparency for Notepad")
|
|
||||||
checked: SettingsData.notepadTransparencyOverride >= 0
|
|
||||||
onToggled: checked => {
|
|
||||||
if (checked) {
|
|
||||||
SettingsData.notepadTransparencyOverride = SettingsData.notepadLastCustomTransparency;
|
|
||||||
} else {
|
|
||||||
SettingsData.notepadTransparencyOverride = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankSlider {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
height: 24
|
|
||||||
visible: SettingsData.notepadTransparencyOverride >= 0
|
|
||||||
value: Math.round((SettingsData.notepadTransparencyOverride >= 0 ? SettingsData.notepadTransparencyOverride : SettingsData.popupTransparency) * 100)
|
|
||||||
minimum: 0
|
|
||||||
maximum: 100
|
|
||||||
unit: ""
|
|
||||||
showValue: true
|
|
||||||
wheelEnabled: false
|
|
||||||
onSliderValueChanged: newValue => {
|
|
||||||
if (SettingsData.notepadTransparencyOverride >= 0) {
|
|
||||||
SettingsData.notepadTransparencyOverride = newValue / 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: parent.width
|
|
||||||
height: gapColumn.height + Theme.spacingS
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: gapColumn
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Default Mode")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
DankButtonGroup {
|
|
||||||
model: [I18n.tr("Slideout"), I18n.tr("Popout")]
|
|
||||||
size: "small"
|
|
||||||
currentIndex: SettingsData.notepadDefaultMode === "popout" ? 1 : 0
|
|
||||||
onSelectionChanged: (index, selected) => {
|
|
||||||
if (!selected)
|
|
||||||
return;
|
|
||||||
SettingsData.notepadDefaultMode = index === 1 ? "popout" : "slideout";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: SettingsData.notepadDefaultMode !== "popout"
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Open From")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
DankButtonGroup {
|
|
||||||
model: [I18n.tr("Right"), I18n.tr("Left")]
|
|
||||||
size: "small"
|
|
||||||
currentIndex: SettingsData.notepadSlideoutSide === "left" ? 1 : 0
|
|
||||||
onSelectionChanged: (index, selected) => {
|
|
||||||
if (!selected)
|
|
||||||
return;
|
|
||||||
SettingsData.notepadSlideoutSide = index === 1 ? "left" : "right";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DankToggle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: -Theme.spacingM
|
|
||||||
width: parent.width + Theme.spacingM
|
|
||||||
text: I18n.tr("Auto Compositor Gaps")
|
|
||||||
description: I18n.tr("Inset the Notepad from screen edges using the compositor's configured gaps")
|
|
||||||
checked: SettingsData.notepadUseCompositorGap
|
|
||||||
onToggled: checked => {
|
|
||||||
SettingsData.notepadUseCompositorGap = checked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
visible: !SettingsData.notepadUseCompositorGap
|
|
||||||
text: I18n.tr("Manual Gaps")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
DankSlider {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingXS
|
|
||||||
width: parent.width - Theme.spacingXS * 2
|
|
||||||
height: 24
|
|
||||||
visible: !SettingsData.notepadUseCompositorGap
|
|
||||||
value: SettingsData.notepadEdgeGap
|
|
||||||
minimum: 0
|
|
||||||
maximum: 64
|
|
||||||
unit: "px"
|
|
||||||
showValue: true
|
|
||||||
wheelEnabled: false
|
|
||||||
onSliderValueChanged: newValue => {
|
|
||||||
SettingsData.notepadEdgeGap = newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
anchors.left: parent.left
|
||||||
text: SettingsData.notepadUseMonospace ? I18n.tr("Using global monospace font from Settings → Personalization") : I18n.tr("Global fonts can be configured in Settings → Personalization")
|
anchors.leftMargin: -Theme.spacingXS
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: Theme.surfaceTextMedium
|
text: I18n.tr("Notepad Font Settings")
|
||||||
wrapMode: Text.WordWrap
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
opacity: 0.8
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -Theme.spacingM
|
||||||
|
width: parent.width + Theme.spacingM
|
||||||
|
text: I18n.tr("Use Monospace Font")
|
||||||
|
description: I18n.tr("Toggle fonts")
|
||||||
|
checked: SettingsData.notepadUseMonospace
|
||||||
|
onToggled: checked => {
|
||||||
|
SettingsData.notepadUseMonospace = checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -Theme.spacingM
|
||||||
|
width: parent.width + Theme.spacingM
|
||||||
|
text: I18n.tr("Show Line Numbers")
|
||||||
|
description: I18n.tr("Display line numbers in editor")
|
||||||
|
checked: SettingsData.notepadShowLineNumbers
|
||||||
|
onToggled: checked => {
|
||||||
|
SettingsData.notepadShowLineNumbers = checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
width: parent.width
|
||||||
|
height: 60
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: -Theme.spacingM
|
||||||
|
width: parent.width + Theme.spacingM
|
||||||
|
stateColor: Theme.primary
|
||||||
|
cornerRadius: parent.radius
|
||||||
|
onClicked: root.findRequested()
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledRect {
|
Row {
|
||||||
width: parent.width
|
anchors.left: parent.left
|
||||||
implicitHeight: shortcutsHeader.height + (root.shortcutsExpanded ? shortcutsColumn.implicitHeight + Theme.spacingM : 0)
|
anchors.leftMargin: -Theme.spacingM
|
||||||
radius: Theme.cornerRadius
|
anchors.right: parent.right
|
||||||
color: root.shortcutsExpanded ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : "transparent"
|
anchors.rightMargin: Theme.spacingM
|
||||||
border.color: root.shortcutsExpanded ? Theme.primary : Theme.outlineMedium
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
border.width: root.shortcutsExpanded ? 2 : 1
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
StateLayer {
|
DankIcon {
|
||||||
anchors.fill: parent
|
name: "search"
|
||||||
stateColor: Theme.primary
|
size: Theme.iconSize - 2
|
||||||
cornerRadius: parent.radius
|
color: Theme.primary
|
||||||
onClicked: root.shortcutsExpanded = !root.shortcutsExpanded
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: shortcutsHeader
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.leftMargin: Theme.spacingM
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
height: 36
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: root.shortcutsExpanded ? "expand_less" : "expand_more"
|
|
||||||
size: Theme.iconSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: I18n.tr("Keyboard Shortcuts")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: shortcutsColumn
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: root.shortcutsExpanded
|
spacing: Theme.spacingXS
|
||||||
width: parent.width - Theme.spacingL * 2
|
|
||||||
anchors.top: shortcutsHeader.bottom
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
text: I18n.tr("Find in Text")
|
||||||
text: I18n.tr("Ctrl+S: Save • Ctrl+O: Open • Ctrl+N: New • Ctrl+F: Find")
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.weight: Font.Medium
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceText
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
width: parent.width
|
text: I18n.tr("Open search bar to find text")
|
||||||
text: I18n.tr("Ctrl+A: Select All • Ctrl+P: Preview • Enter/Shift+Enter: Find Next/Previous • Esc: Close")
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.surfaceText
|
color: Theme.surfaceVariantText
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: visible ? (fontDropdown.height + Theme.spacingS) : 0
|
||||||
|
color: "transparent"
|
||||||
|
visible: !SettingsData.notepadUseMonospace
|
||||||
|
|
||||||
|
DankDropdown {
|
||||||
|
id: fontDropdown
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -Theme.spacingM
|
||||||
|
width: parent.width + Theme.spacingM
|
||||||
|
text: I18n.tr("Font Family")
|
||||||
|
options: cachedFontFamilies
|
||||||
|
currentValue: {
|
||||||
|
if (!SettingsData.notepadFontFamily || SettingsData.notepadFontFamily === "")
|
||||||
|
return I18n.tr("Default (Global)");
|
||||||
|
else
|
||||||
|
return SettingsData.notepadFontFamily;
|
||||||
|
}
|
||||||
|
enableFuzzySearch: true
|
||||||
|
onValueChanged: value => {
|
||||||
|
if (value && (value.startsWith("Default") || value === "Default (Global)")) {
|
||||||
|
SettingsData.notepadFontFamily = "";
|
||||||
|
} else {
|
||||||
|
SettingsData.notepadFontFamily = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: fontSizeRow.height + Theme.spacingS
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: fontSizeRow
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width - fontSizeControls.width - Theme.spacingM
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: I18n.tr("Font Size")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: SettingsData.notepadFontSize + "px"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceVariantText
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: fontSizeControls
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
buttonSize: 32
|
||||||
|
iconName: "remove"
|
||||||
|
iconSize: Theme.iconSizeSmall
|
||||||
|
enabled: SettingsData.notepadFontSize > 8
|
||||||
|
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
onClicked: {
|
||||||
|
var newSize = Math.max(8, SettingsData.notepadFontSize - 1);
|
||||||
|
SettingsData.notepadFontSize = newSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 60
|
||||||
|
height: 32
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: SettingsData.notepadFontSize + "px"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
buttonSize: 32
|
||||||
|
iconName: "add"
|
||||||
|
iconSize: Theme.iconSizeSmall
|
||||||
|
enabled: SettingsData.notepadFontSize < 48
|
||||||
|
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
onClicked: {
|
||||||
|
var newSize = Math.min(48, SettingsData.notepadFontSize + 1);
|
||||||
|
SettingsData.notepadFontSize = newSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: transparencySliderColumn.height + Theme.spacingS
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: transparencySliderColumn
|
||||||
|
width: parent.width
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankToggle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -Theme.spacingM
|
||||||
|
width: parent.width + Theme.spacingM
|
||||||
|
text: I18n.tr("Custom Transparency")
|
||||||
|
description: I18n.tr("Override global transparency for Notepad")
|
||||||
|
checked: SettingsData.notepadTransparencyOverride >= 0
|
||||||
|
onToggled: checked => {
|
||||||
|
if (checked) {
|
||||||
|
SettingsData.notepadTransparencyOverride = SettingsData.notepadLastCustomTransparency;
|
||||||
|
} else {
|
||||||
|
SettingsData.notepadTransparencyOverride = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankSlider {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -Theme.spacingM
|
||||||
|
width: parent.width + Theme.spacingM
|
||||||
|
height: 24
|
||||||
|
visible: SettingsData.notepadTransparencyOverride >= 0
|
||||||
|
value: Math.round((SettingsData.notepadTransparencyOverride >= 0 ? SettingsData.notepadTransparencyOverride : SettingsData.popupTransparency) * 100)
|
||||||
|
minimum: 0
|
||||||
|
maximum: 100
|
||||||
|
unit: ""
|
||||||
|
showValue: true
|
||||||
|
wheelEnabled: false
|
||||||
|
onSliderValueChanged: newValue => {
|
||||||
|
if (SettingsData.notepadTransparencyOverride >= 0) {
|
||||||
|
SettingsData.notepadTransparencyOverride = newValue / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
width: parent.width
|
||||||
|
text: SettingsData.notepadUseMonospace ? I18n.tr("Using global monospace font from Settings → Personalization") : I18n.tr("Global fonts can be configured in Settings → Personalization")
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceTextMedium
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
opacity: 0.8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,23 +32,6 @@ Column {
|
|||||||
property string pluginHighlightedHtml: ""
|
property string pluginHighlightedHtml: ""
|
||||||
property string lastPluginContent: ""
|
property string lastPluginContent: ""
|
||||||
property int loadRequestId: 0
|
property int loadRequestId: 0
|
||||||
property bool ignoreNextExternalChange: false
|
|
||||||
property bool watcherReloadPending: false
|
|
||||||
property bool externalWatchPaused: false
|
|
||||||
property bool inPopout: false
|
|
||||||
property bool surfaceVisible: true
|
|
||||||
// Tab ids are Date.now() timestamps (~1.78e12) which overflow a 32-bit `int`,
|
|
||||||
// corrupting the value (e.g. -946062153) and breaking buffer keying. `var`
|
|
||||||
// holds the full JS-safe integer.
|
|
||||||
property var loadedTabId: -1
|
|
||||||
property bool applyingShared: false
|
|
||||||
property bool showPathInfo: false
|
|
||||||
|
|
||||||
function currentFilePath() {
|
|
||||||
if (!currentTab)
|
|
||||||
return "";
|
|
||||||
return currentTab.isTemporary ? (NotepadStorageService.baseDir + "/" + currentTab.filePath) : currentTab.filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
signal saveRequested
|
signal saveRequested
|
||||||
signal openRequested
|
signal openRequested
|
||||||
@@ -57,10 +40,6 @@ Column {
|
|||||||
signal escapePressed
|
signal escapePressed
|
||||||
signal contentChanged
|
signal contentChanged
|
||||||
signal settingsRequested
|
signal settingsRequested
|
||||||
signal popoutRequested
|
|
||||||
signal dockRequested
|
|
||||||
signal conflictDetected(string diskContent)
|
|
||||||
signal autoSaveRequested
|
|
||||||
|
|
||||||
function hasUnsavedChanges() {
|
function hasUnsavedChanges() {
|
||||||
if (!currentTab || !contentLoaded) {
|
if (!currentTab || !contentLoaded) {
|
||||||
@@ -73,12 +52,6 @@ Column {
|
|||||||
return textArea.text !== lastSavedContent;
|
return textArea.text !== lastSavedContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
function commitLiveBuffer() {
|
|
||||||
if (loadedTabId < 0 || !contentLoaded)
|
|
||||||
return;
|
|
||||||
NotepadStorageService.setSessionBuffer(loadedTabId, textArea.text, lastSavedContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadCurrentTabContent() {
|
function loadCurrentTabContent() {
|
||||||
if (!currentTab)
|
if (!currentTab)
|
||||||
return;
|
return;
|
||||||
@@ -89,25 +62,8 @@ Column {
|
|||||||
const activeTab = NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null;
|
const activeTab = NotepadStorageService.tabs.length > NotepadStorageService.currentTabIndex ? NotepadStorageService.tabs[NotepadStorageService.currentTabIndex] : null;
|
||||||
if (requestId !== loadRequestId || !activeTab || activeTab.id !== requestedTabId)
|
if (requestId !== loadRequestId || !activeTab || activeTab.id !== requestedTabId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const buffer = NotepadStorageService.getSessionBuffer(requestedTabId);
|
|
||||||
if (buffer !== undefined) {
|
|
||||||
applyingShared = true;
|
|
||||||
lastSavedContent = buffer.baseline;
|
|
||||||
textArea.text = buffer.content;
|
|
||||||
applyingShared = false;
|
|
||||||
loadedTabId = requestedTabId;
|
|
||||||
contentLoaded = true;
|
|
||||||
syncContentToPlugin();
|
|
||||||
applyDiskContent(content);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyingShared = true;
|
|
||||||
lastSavedContent = content;
|
lastSavedContent = content;
|
||||||
textArea.text = content;
|
textArea.text = content;
|
||||||
applyingShared = false;
|
|
||||||
loadedTabId = requestedTabId;
|
|
||||||
contentLoaded = true;
|
contentLoaded = true;
|
||||||
syncContentToPlugin();
|
syncContentToPlugin();
|
||||||
});
|
});
|
||||||
@@ -116,56 +72,14 @@ Column {
|
|||||||
function saveCurrentTabContent() {
|
function saveCurrentTabContent() {
|
||||||
if (!currentTab || !contentLoaded)
|
if (!currentTab || !contentLoaded)
|
||||||
return;
|
return;
|
||||||
if (!currentTab.isTemporary)
|
|
||||||
return;
|
|
||||||
NotepadStorageService.saveTabContent(NotepadStorageService.currentTabIndex, textArea.text);
|
NotepadStorageService.saveTabContent(NotepadStorageService.currentTabIndex, textArea.text);
|
||||||
lastSavedContent = textArea.text;
|
lastSavedContent = textArea.text;
|
||||||
NotepadStorageService.clearSessionBuffer(loadedTabId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoSaveToSession() {
|
function autoSaveToSession() {
|
||||||
commitLiveBuffer();
|
|
||||||
if (!currentTab || !contentLoaded)
|
if (!currentTab || !contentLoaded)
|
||||||
return;
|
return;
|
||||||
if (currentTab.isTemporary) {
|
saveCurrentTabContent();
|
||||||
saveCurrentTabContent();
|
|
||||||
} else if (SettingsData.notepadAutoSave) {
|
|
||||||
root.autoSaveRequested();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncFromDisk() {
|
|
||||||
if (!currentTab)
|
|
||||||
return;
|
|
||||||
loadCurrentTabContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyDiskContent(diskContent) {
|
|
||||||
if (diskContent === undefined || diskContent === null)
|
|
||||||
return;
|
|
||||||
if (diskContent === textArea.text) {
|
|
||||||
lastSavedContent = diskContent;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (diskContent === lastSavedContent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (textArea.text === lastSavedContent) {
|
|
||||||
reloadFromDisk(diskContent);
|
|
||||||
} else if (surfaceVisible) {
|
|
||||||
conflictDetected(diskContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function reloadFromDisk(diskContent) {
|
|
||||||
applyingShared = true;
|
|
||||||
contentLoaded = false;
|
|
||||||
textArea.text = diskContent;
|
|
||||||
lastSavedContent = diskContent;
|
|
||||||
contentLoaded = true;
|
|
||||||
applyingShared = false;
|
|
||||||
NotepadStorageService.clearSessionBuffer(loadedTabId);
|
|
||||||
syncContentToPlugin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTextDocumentLineHeight() {
|
function setTextDocumentLineHeight() {
|
||||||
@@ -288,8 +202,7 @@ Column {
|
|||||||
if (!currentTab)
|
if (!currentTab)
|
||||||
return;
|
return;
|
||||||
const filePath = currentTab?.filePath || "";
|
const filePath = currentTab?.filePath || "";
|
||||||
const baseName = filePath.split('/').pop();
|
const ext = filePath.split('.').pop().toLowerCase();
|
||||||
const ext = baseName.includes('.') ? baseName.split('.').pop().toLowerCase() : "";
|
|
||||||
const content = textArea.text;
|
const content = textArea.text;
|
||||||
|
|
||||||
if (content === lastPluginContent && SettingsData.getBuiltInPluginSetting("dankNotepadModule", "previewActive", false) === inlinePreviewVisible) {
|
if (content === lastPluginContent && SettingsData.getBuiltInPluginSetting("dankNotepadModule", "previewActive", false) === inlinePreviewVisible) {
|
||||||
@@ -637,7 +550,6 @@ Column {
|
|||||||
Connections {
|
Connections {
|
||||||
target: NotepadStorageService
|
target: NotepadStorageService
|
||||||
function onCurrentTabIndexChanged() {
|
function onCurrentTabIndexChanged() {
|
||||||
root.commitLiveBuffer();
|
|
||||||
loadCurrentTabContent();
|
loadCurrentTabContent();
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
textArea.forceActiveFocus();
|
textArea.forceActiveFocus();
|
||||||
@@ -658,9 +570,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
// Debounced flush to the shared buffer (+ optional disk
|
if (contentLoaded && text !== lastSavedContent) {
|
||||||
// autosave) for every loaded tab, not just scratch notes.
|
|
||||||
if (contentLoaded && !applyingShared) {
|
|
||||||
autoSaveTimer.restart();
|
autoSaveTimer.restart();
|
||||||
}
|
}
|
||||||
root.contentChanged();
|
root.contentChanged();
|
||||||
@@ -834,7 +744,6 @@ Column {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: buttonBarItem
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 32
|
height: 32
|
||||||
|
|
||||||
@@ -911,98 +820,17 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
DankActionButton {
|
||||||
id: rightButtonRow
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingS
|
iconName: "more_horiz"
|
||||||
|
iconSize: Theme.iconSize - 2
|
||||||
DankActionButton {
|
iconColor: Theme.surfaceText
|
||||||
visible: !root.inPopout
|
onClicked: root.settingsRequested()
|
||||||
iconName: "open_in_new"
|
|
||||||
iconSize: Theme.iconSize - 2
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: root.popoutRequested()
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
visible: root.inPopout
|
|
||||||
iconName: "dock_to_right"
|
|
||||||
iconSize: Theme.iconSize - 2
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: root.dockRequested()
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
iconName: "more_horiz"
|
|
||||||
iconSize: Theme.iconSize - 2
|
|
||||||
iconColor: Theme.surfaceText
|
|
||||||
onClicked: root.settingsRequested()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
id: pathInfoPopup
|
|
||||||
visible: root.showPathInfo
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.top
|
|
||||||
anchors.bottomMargin: Theme.spacingS
|
|
||||||
width: Math.min(root.width, 360)
|
|
||||||
height: pathInfoRow.implicitHeight + Theme.spacingS * 2
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)
|
|
||||||
border.color: Theme.outlineMedium
|
|
||||||
border.width: 1
|
|
||||||
z: 10
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: pathInfoRow
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.leftMargin: Theme.spacingM
|
|
||||||
anchors.rightMargin: Theme.spacingM
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: currentTab && currentTab.isTemporary ? "draft" : "description"
|
|
||||||
size: Theme.iconSize - 4
|
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
width: pathInfoRow.width - (Theme.iconSize - 4) - copyPathButton.width - Theme.spacingS * 2
|
|
||||||
text: root.currentFilePath()
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
elide: Text.ElideMiddle
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
|
||||||
id: copyPathButton
|
|
||||||
iconName: "content_copy"
|
|
||||||
iconSize: Theme.iconSize - 6
|
|
||||||
iconColor: Theme.surfaceTextMedium
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
onClicked: {
|
|
||||||
const proc = clipboardCopyProcComp.createObject(root, {
|
|
||||||
content: root.currentFilePath(),
|
|
||||||
running: true
|
|
||||||
});
|
|
||||||
proc.exited.connect(() => {
|
|
||||||
ToastService.showInfo(I18n.tr("Path copied to clipboard"));
|
|
||||||
proc.destroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: statusRow
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
@@ -1025,46 +853,35 @@ Column {
|
|||||||
opacity: 1.0
|
opacity: 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
StyledText {
|
||||||
visible: textArea.text.length > 0
|
text: {
|
||||||
spacing: Theme.spacingXS
|
if (autoSaveTimer.running) {
|
||||||
|
return I18n.tr("Auto-saving...");
|
||||||
StyledText {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
readonly property bool savingToDisk: autoSaveTimer.running && currentTab && (currentTab.isTemporary || SettingsData.notepadAutoSave)
|
|
||||||
text: {
|
|
||||||
if (savingToDisk) {
|
|
||||||
return I18n.tr("Saving...");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentTab && currentTab.isTemporary) {
|
|
||||||
return I18n.tr("Auto saved");
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasUnsavedChanges() ? I18n.tr("Unsaved changes") : I18n.tr("Saved");
|
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: {
|
|
||||||
if (savingToDisk) {
|
|
||||||
return Theme.primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (hasUnsavedChanges()) {
|
||||||
if (currentTab && currentTab.isTemporary) {
|
if (currentTab && currentTab.isTemporary) {
|
||||||
return Theme.success;
|
return I18n.tr("Unsaved note...");
|
||||||
|
} else {
|
||||||
|
return I18n.tr("Unsaved changes");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
return hasUnsavedChanges() ? Theme.warning : Theme.success;
|
return I18n.tr("Saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: {
|
||||||
|
if (autoSaveTimer.running) {
|
||||||
|
return Theme.primary;
|
||||||
|
}
|
||||||
|
|
||||||
DankActionButton {
|
if (hasUnsavedChanges()) {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
return Theme.warning;
|
||||||
iconName: "info"
|
} else {
|
||||||
iconSize: Theme.iconSizeSmall
|
return Theme.success;
|
||||||
iconColor: root.showPathInfo ? Theme.primary : Theme.surfaceTextMedium
|
}
|
||||||
buttonSize: 20
|
|
||||||
onClicked: root.showPathInfo = !root.showPathInfo
|
|
||||||
}
|
}
|
||||||
|
opacity: textArea.text.length > 0 ? 1.0 : 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1085,38 +902,6 @@ Column {
|
|||||||
onTriggered: syncContentToPlugin()
|
onTriggered: syncContentToPlugin()
|
||||||
}
|
}
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: externalWatch
|
|
||||||
path: (!root.externalWatchPaused && currentTab && !currentTab.isTemporary && currentTab.filePath) ? currentTab.filePath : ""
|
|
||||||
blockLoading: true
|
|
||||||
preload: true
|
|
||||||
watchChanges: true
|
|
||||||
|
|
||||||
onFileChanged: {
|
|
||||||
root.watcherReloadPending = true;
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
if (root.ignoreNextExternalChange) {
|
|
||||||
root.ignoreNextExternalChange = false;
|
|
||||||
root.lastSavedContent = externalWatch.text();
|
|
||||||
root.watcherReloadPending = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!root.watcherReloadPending)
|
|
||||||
return;
|
|
||||||
root.watcherReloadPending = false;
|
|
||||||
if (!root.contentLoaded || !root.currentTab || root.currentTab.isTemporary)
|
|
||||||
return;
|
|
||||||
if (!root.surfaceVisible)
|
|
||||||
return;
|
|
||||||
root.applyDiskContent(externalWatch.text());
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoadFailed: error => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onBuiltInPluginSettingsChanged() {
|
function onBuiltInPluginSettingsChanged() {
|
||||||
@@ -1125,24 +910,4 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: NotepadStorageService
|
|
||||||
function onSessionBufferRevisionChanged() {
|
|
||||||
if (applyingShared || !contentLoaded || loadedTabId < 0)
|
|
||||||
return;
|
|
||||||
if (textArea.activeFocus)
|
|
||||||
return;
|
|
||||||
var buffer = NotepadStorageService.getSessionBuffer(loadedTabId);
|
|
||||||
if (buffer === undefined || buffer.content === textArea.text)
|
|
||||||
return;
|
|
||||||
if (textArea.text === lastSavedContent) {
|
|
||||||
applyingShared = true;
|
|
||||||
lastSavedContent = buffer.baseline;
|
|
||||||
textArea.text = buffer.content;
|
|
||||||
applyingShared = false;
|
|
||||||
syncContentToPlugin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,9 +152,6 @@ 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 "∞";
|
||||||
@@ -190,29 +187,6 @@ 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;
|
||||||
@@ -463,24 +437,6 @@ 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")
|
title: I18n.tr("Niri Layout Overrides").replace("Niri", "niri")
|
||||||
settingKey: "niriLayout"
|
settingKey: "niriLayout"
|
||||||
iconName: "layers"
|
iconName: "crop_square"
|
||||||
visible: CompositorService.isNiri
|
visible: CompositorService.isNiri
|
||||||
|
|
||||||
SettingsToggleRow {
|
SettingsToggleRow {
|
||||||
|
|||||||
@@ -796,81 +796,18 @@ 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
|
||||||
@@ -1019,6 +956,68 @@ 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"
|
||||||
@@ -1359,7 +1358,7 @@ Item {
|
|||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: borderOpacitySlider
|
id: borderOpacitySlider
|
||||||
text: I18n.tr("Opacity")
|
text: I18n.tr("Opacity")
|
||||||
description: I18n.tr("Controls opacity of the border")
|
description: I18n.tr("Transparency of the border")
|
||||||
value: (selectedBarConfig?.borderOpacity ?? 1.0) * 100
|
value: (selectedBarConfig?.borderOpacity ?? 1.0) * 100
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
@@ -1454,7 +1453,7 @@ Item {
|
|||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
id: widgetOutlineOpacitySlider
|
id: widgetOutlineOpacitySlider
|
||||||
text: I18n.tr("Opacity")
|
text: I18n.tr("Opacity")
|
||||||
description: I18n.tr("Controls opacity of the widget outline")
|
description: I18n.tr("Transparency of the widget outline")
|
||||||
value: (selectedBarConfig?.widgetOutlineOpacity ?? 1.0) * 100
|
value: (selectedBarConfig?.widgetOutlineOpacity ?? 1.0) * 100
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
@@ -1563,7 +1562,7 @@ Item {
|
|||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
visible: shadowCard.shadowActive
|
visible: shadowCard.shadowActive
|
||||||
text: I18n.tr("Opacity")
|
text: I18n.tr("Opacity")
|
||||||
description: I18n.tr("Controls opacity of the shadow layer")
|
description: I18n.tr("Transparency of the shadow layer")
|
||||||
minimum: 10
|
minimum: 10
|
||||||
maximum: 100
|
maximum: 100
|
||||||
unit: "%"
|
unit: "%"
|
||||||
|
|||||||
@@ -643,19 +643,19 @@ Item {
|
|||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: root.connectedFrameModeActive
|
visible: root.connectedFrameModeActive
|
||||||
parentModal: root.parentModal
|
parentModal: root.parentModal
|
||||||
settingLabel: I18n.tr("Dock margin, opacity, and border")
|
settingLabel: I18n.tr("Dock margin, transparency, 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("Opacity")
|
title: I18n.tr("Transparency")
|
||||||
settingKey: "dockTransparency"
|
settingKey: "dockTransparency"
|
||||||
visible: !root.connectedFrameModeActive
|
visible: !root.connectedFrameModeActive
|
||||||
|
|
||||||
SettingsSliderRow {
|
SettingsSliderRow {
|
||||||
text: I18n.tr("Dock Opacity")
|
text: I18n.tr("Dock Transparency")
|
||||||
value: Math.round(SettingsData.dockTransparency * 100)
|
value: Math.round(SettingsData.dockTransparency * 100)
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
|
|||||||
@@ -113,13 +113,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsToggleRow {
|
|
||||||
text: I18n.tr("Device list scroll volume")
|
|
||||||
description: I18n.tr("Allow adjusting device volume by scrolling on the right half of items in the device list")
|
|
||||||
checked: SettingsData.audioDeviceScrollVolumeEnabled
|
|
||||||
onToggled: checked => SettingsData.set("audioDeviceScrollVolumeEnabled", checked)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1639,7 +1639,7 @@ Item {
|
|||||||
SettingsControlledByFrame {
|
SettingsControlledByFrame {
|
||||||
visible: themeColorsTab.connectedFrameModeActive
|
visible: themeColorsTab.connectedFrameModeActive
|
||||||
parentModal: themeColorsTab.parentModal
|
parentModal: themeColorsTab.parentModal
|
||||||
settingLabel: I18n.tr("Surface Opacity")
|
settingLabel: I18n.tr("Transparency")
|
||||||
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("Surface Opacity")
|
text: I18n.tr("Transparency")
|
||||||
description: I18n.tr("Controls opacity of shell surfaces, popouts, and modals")
|
description: I18n.tr("Controls opacity of all popouts, modals, and their content layers")
|
||||||
visible: !themeColorsTab.connectedFrameModeActive
|
visible: !themeColorsTab.connectedFrameModeActive
|
||||||
value: Math.round(SettingsData.popupTransparency * 100)
|
value: Math.round(SettingsData.popupTransparency * 100)
|
||||||
minimum: 0
|
minimum: 0
|
||||||
@@ -1671,113 +1671,6 @@ 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"
|
||||||
@@ -1809,7 +1702,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 opacity of the shadow")
|
description: I18n.tr("Controls the transparency of the shadow")
|
||||||
value: SettingsData.m3ElevationOpacity ?? 30
|
value: SettingsData.m3ElevationOpacity ?? 30
|
||||||
minimum: 0
|
minimum: 0
|
||||||
maximum: 100
|
maximum: 100
|
||||||
@@ -1963,6 +1856,105 @@ 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,8 +64,6 @@ 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,8 +32,6 @@ Variants {
|
|||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
updatesEnabled: root.renderActive || root._settleFrames > 0
|
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: Item {}
|
item: Item {}
|
||||||
}
|
}
|
||||||
@@ -86,59 +84,20 @@ 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: root.backingWindow
|
target: currentWallpaper
|
||||||
function onFrameSwapped() {
|
function onStatusChanged() {
|
||||||
if (root._settleFrames > 0)
|
if (currentWallpaper.status !== Image.Ready && currentWallpaper.status !== Image.Error)
|
||||||
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.invalidate();
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,11 +109,32 @@ 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.invalidate();
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +142,29 @@ Variants {
|
|||||||
target: WlrOutputService
|
target: WlrOutputService
|
||||||
function onWlrOutputAvailableChanged() {
|
function onWlrOutputAvailableChanged() {
|
||||||
root._recheckScreenScale();
|
root._recheckScreenScale();
|
||||||
root.invalidate();
|
root._renderSettling = true;
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,22 +181,26 @@ Variants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTransitionLoadError(failedSource) {
|
Connections {
|
||||||
log.warn("failed to load candidate wallpaper for", modelData.name + ":", failedSource);
|
target: IdleService
|
||||||
transitionDelayTimer.stop();
|
function onIsShellLockedChanged() {
|
||||||
transitionAnimation.stop();
|
if (!IdleService.isShellLocked) {
|
||||||
root.useNextForEffect = false;
|
root._renderSettling = true;
|
||||||
root.effectActive = false;
|
renderSettleTimer.restart();
|
||||||
root.transitionProgress = 0.0;
|
}
|
||||||
currentWallpaper.layer.enabled = false;
|
}
|
||||||
nextWallpaper.layer.enabled = false;
|
}
|
||||||
nextWallpaper.source = "";
|
|
||||||
|
|
||||||
if (!root.pendingWallpaper)
|
Timer {
|
||||||
return;
|
id: renderSettleTimer
|
||||||
const pending = root.pendingWallpaper;
|
interval: 1000
|
||||||
root.pendingWallpaper = "";
|
onTriggered: root._renderSettling = false
|
||||||
Qt.callLater(() => root.changeWallpaper(pending, true));
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: overviewBlurSettleTimer
|
||||||
|
interval: 150
|
||||||
|
onTriggered: root._overviewBlurSettling = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFillMode(modeName) {
|
function getFillMode(modeName) {
|
||||||
@@ -221,6 +227,11 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +262,8 @@ 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 = "";
|
||||||
@@ -315,6 +328,9 @@ Variants {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root._renderSettling = true;
|
||||||
|
renderSettleTimer.restart();
|
||||||
|
|
||||||
nextWallpaper.source = newPath;
|
nextWallpaper.source = newPath;
|
||||||
|
|
||||||
if (nextWallpaper.status === Image.Ready)
|
if (nextWallpaper.status === Image.Ready)
|
||||||
@@ -323,7 +339,7 @@ Variants {
|
|||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: !root.source || root.isColorSource || currentWallpaper.status === Image.Error
|
active: !root.source || root.isColorSource
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: DankBackdrop {
|
sourceComponent: DankBackdrop {
|
||||||
@@ -348,12 +364,6 @@ 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 {
|
||||||
@@ -370,13 +380,11 @@ 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;
|
||||||
@@ -624,6 +632,8 @@ 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)
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ Singleton {
|
|||||||
return SessionData.deviceMaxVolumes[name] ?? 100;
|
return SessionData.deviceMaxVolumes[name] ?? 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property int wheelVolumeStep: SettingsData.audioWheelScrollAmount
|
|
||||||
|
|
||||||
signal micMuteChanged
|
signal micMuteChanged
|
||||||
signal audioOutputCycled(string deviceName, string deviceIcon)
|
signal audioOutputCycled(string deviceName, string deviceIcon)
|
||||||
signal deviceAliasChanged(string nodeName, string newAlias)
|
signal deviceAliasChanged(string nodeName, string newAlias)
|
||||||
@@ -158,19 +156,14 @@ Singleton {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cycleAudioOutputDirection(forward) {
|
function cycleAudioOutput() {
|
||||||
const sinks = getAvailableSinks();
|
const sinks = getAvailableSinks();
|
||||||
if (sinks.length < 2)
|
if (sinks.length < 2)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
const currentName = root.sink?.name ?? "";
|
const currentName = root.sink?.name ?? "";
|
||||||
const currentIndex = sinks.findIndex(s => s.name === currentName);
|
const currentIndex = sinks.findIndex(s => s.name === currentName);
|
||||||
let nextIndex;
|
const nextIndex = (currentIndex + 1) % sinks.length;
|
||||||
if (forward) {
|
|
||||||
nextIndex = (currentIndex + 1) % sinks.length;
|
|
||||||
} else {
|
|
||||||
nextIndex = (currentIndex - 1 + sinks.length) % sinks.length;
|
|
||||||
}
|
|
||||||
const nextSink = sinks[nextIndex];
|
const nextSink = sinks[nextIndex];
|
||||||
setDefaultSinkByName(nextSink.name);
|
setDefaultSinkByName(nextSink.name);
|
||||||
const name = displayName(nextSink);
|
const name = displayName(nextSink);
|
||||||
@@ -178,10 +171,6 @@ Singleton {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cycleAudioOutput() {
|
|
||||||
return cycleAudioOutputDirection(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDeviceAlias(nodeName) {
|
function getDeviceAlias(nodeName) {
|
||||||
if (!nodeName)
|
if (!nodeName)
|
||||||
return null;
|
return null;
|
||||||
@@ -844,28 +833,6 @@ EOFCONFIG
|
|||||||
return root.sink.audio.muted ? "Audio muted" : "Audio unmuted";
|
return root.sink.audio.muted ? "Audio muted" : "Audio unmuted";
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNodeVolumeWheel(node, wheelEvent) {
|
|
||||||
if (!node?.audio)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SessionData.suppressOSDTemporarily();
|
|
||||||
const delta = wheelEvent.angleDelta.y;
|
|
||||||
if (delta === 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const current = Math.round(node.audio.volume * 100);
|
|
||||||
const maxVol = getMaxVolumePercent(node);
|
|
||||||
const newVolume = delta > 0 ? Math.min(maxVol, current + root.wheelVolumeStep) : Math.max(0, current - root.wheelVolumeStep);
|
|
||||||
|
|
||||||
node.audio.muted = false;
|
|
||||||
node.audio.volume = newVolume / 100;
|
|
||||||
|
|
||||||
if (node === sink) {
|
|
||||||
playVolumeChangeSoundIfEnabled();
|
|
||||||
}
|
|
||||||
wheelEvent.accepted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setMicVolume(percentage) {
|
function setMicVolume(percentage) {
|
||||||
if (!root.source?.audio) {
|
if (!root.source?.audio) {
|
||||||
return "No audio source available";
|
return "No audio source available";
|
||||||
|
|||||||
@@ -23,49 +23,6 @@ Singleton {
|
|||||||
property var tabsBeingCreated: ({})
|
property var tabsBeingCreated: ({})
|
||||||
property bool metadataLoaded: false
|
property bool metadataLoaded: false
|
||||||
|
|
||||||
// Shared live edit state across slideout and popout surfaces.
|
|
||||||
property var sessionBuffers: ({})
|
|
||||||
property int sessionBufferRevision: 0
|
|
||||||
|
|
||||||
function setSessionBuffer(tabId, content, baseline) {
|
|
||||||
if (tabId === undefined || tabId === null || tabId < 0)
|
|
||||||
return
|
|
||||||
var next = Object.assign({}, sessionBuffers)
|
|
||||||
if (content !== baseline) {
|
|
||||||
next[tabId] = { content: content, baseline: baseline }
|
|
||||||
} else {
|
|
||||||
delete next[tabId]
|
|
||||||
}
|
|
||||||
sessionBuffers = next
|
|
||||||
sessionBufferRevision++
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSessionBuffer(tabId) {
|
|
||||||
return sessionBuffers[tabId]
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearSessionBuffer(tabId) {
|
|
||||||
if (sessionBuffers[tabId] === undefined)
|
|
||||||
return
|
|
||||||
var next = Object.assign({}, sessionBuffers)
|
|
||||||
delete next[tabId]
|
|
||||||
sessionBuffers = next
|
|
||||||
sessionBufferRevision++
|
|
||||||
}
|
|
||||||
|
|
||||||
property var conflictTabId: -1
|
|
||||||
property string conflictDiskContent: ""
|
|
||||||
|
|
||||||
function flagConflict(tabId, diskContent) {
|
|
||||||
conflictDiskContent = diskContent
|
|
||||||
conflictTabId = tabId
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearConflict() {
|
|
||||||
conflictTabId = -1
|
|
||||||
conflictDiskContent = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
ensureDirectories()
|
ensureDirectories()
|
||||||
}
|
}
|
||||||
@@ -252,10 +209,6 @@ Singleton {
|
|||||||
if (tabIndex < 0 || tabIndex >= tabs.length) return
|
if (tabIndex < 0 || tabIndex >= tabs.length) return
|
||||||
|
|
||||||
var newTabs = tabs.slice()
|
var newTabs = tabs.slice()
|
||||||
var closedTabId = newTabs[tabIndex] ? newTabs[tabIndex].id : -1
|
|
||||||
clearSessionBuffer(closedTabId)
|
|
||||||
if (conflictTabId === closedTabId)
|
|
||||||
clearConflict()
|
|
||||||
|
|
||||||
if (newTabs.length <= 1) {
|
if (newTabs.length <= 1) {
|
||||||
var id = Date.now()
|
var id = Date.now()
|
||||||
|
|||||||
@@ -789,97 +789,21 @@ Singleton {
|
|||||||
networkInfoModal?.close();
|
networkInfoModal?.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeNotepadSlideouts() {
|
function openNotepad() {
|
||||||
for (var i = 0; i < notepadSlideouts.length; i++) {
|
|
||||||
if (notepadSlideouts[i] && notepadSlideouts[i].isVisible)
|
|
||||||
notepadSlideouts[i].hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openNotepadSlideout() {
|
|
||||||
notepadPopout?.hide();
|
|
||||||
if (notepadSlideouts.length > 0) {
|
if (notepadSlideouts.length > 0) {
|
||||||
notepadSlideouts[0]?.show();
|
notepadSlideouts[0]?.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the notepad in a single presentation for default modes
|
|
||||||
Connections {
|
|
||||||
target: SettingsData
|
|
||||||
function onNotepadDefaultModeChanged() {
|
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
var hadSlideout = false;
|
|
||||||
for (var i = 0; i < root.notepadSlideouts.length; i++) {
|
|
||||||
if (root.notepadSlideouts[i] && root.notepadSlideouts[i].isVisible) {
|
|
||||||
hadSlideout = true;
|
|
||||||
root.notepadSlideouts[i].hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hadSlideout)
|
|
||||||
root.openNotepadPopout();
|
|
||||||
} else if (root.notepadPopout && root.notepadPopout.visible) {
|
|
||||||
root.notepadPopout.hide();
|
|
||||||
root.openNotepadSlideout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openNotepad() {
|
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
openNotepadPopout();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
openNotepadSlideout();
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeNotepad() {
|
function closeNotepad() {
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
notepadPopout?.hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (notepadSlideouts.length > 0) {
|
if (notepadSlideouts.length > 0) {
|
||||||
notepadSlideouts[0]?.hide();
|
notepadSlideouts[0]?.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleNotepad() {
|
function toggleNotepad() {
|
||||||
if (SettingsData.notepadDefaultMode === "popout") {
|
|
||||||
toggleNotepadPopout();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (notepadSlideouts.length > 0) {
|
if (notepadSlideouts.length > 0) {
|
||||||
notepadSlideouts[0]?.toggle();
|
notepadSlideouts[0]?.toggle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property var notepadPopout: null
|
|
||||||
property var notepadPopoutLoader: null
|
|
||||||
property bool _notepadPopoutWantsOpen: false
|
|
||||||
|
|
||||||
function openNotepadPopout() {
|
|
||||||
closeNotepadSlideouts();
|
|
||||||
if (notepadPopout) {
|
|
||||||
notepadPopout.show();
|
|
||||||
} else if (notepadPopoutLoader) {
|
|
||||||
_notepadPopoutWantsOpen = true;
|
|
||||||
notepadPopoutLoader.active = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _onNotepadPopoutLoaded() {
|
|
||||||
if (_notepadPopoutWantsOpen && notepadPopout) {
|
|
||||||
_notepadPopoutWantsOpen = false;
|
|
||||||
notepadPopout.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleNotepadPopout() {
|
|
||||||
if (notepadPopout) {
|
|
||||||
if (!notepadPopout.visible)
|
|
||||||
closeNotepadSlideouts();
|
|
||||||
notepadPopout.toggle();
|
|
||||||
} else {
|
|
||||||
openNotepadPopout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,11 @@ Row {
|
|||||||
property var initialSelection: []
|
property var initialSelection: []
|
||||||
property var currentSelection: initialSelection
|
property var currentSelection: initialSelection
|
||||||
property bool checkEnabled: true
|
property bool checkEnabled: true
|
||||||
property string size: "medium"
|
property int buttonHeight: 40
|
||||||
property int buttonHeight: size === "small" ? 32 : 40
|
property int minButtonWidth: 64
|
||||||
property int minButtonWidth: size === "small" ? 56 : 64
|
property int buttonPadding: Theme.spacingL
|
||||||
property int buttonPadding: size === "small" ? Theme.spacingM : Theme.spacingL
|
property int checkIconSize: Theme.iconSizeSmall
|
||||||
property int checkIconSize: size === "small" ? Theme.iconSizeSmall - 2 : Theme.iconSizeSmall
|
property int textSize: Theme.fontSizeMedium
|
||||||
property int textSize: size === "small" ? Theme.fontSizeSmall : Theme.fontSizeMedium
|
|
||||||
property bool userInteracted: false
|
property bool userInteracted: false
|
||||||
|
|
||||||
signal selectionChanged(int index, bool selected)
|
signal selectionChanged(int index, bool selected)
|
||||||
|
|||||||
@@ -20,22 +20,17 @@ PanelWindow {
|
|||||||
property bool expandable: false
|
property bool expandable: false
|
||||||
property bool expandedWidth: false
|
property bool expandedWidth: false
|
||||||
property real expandedWidthValue: 960
|
property real expandedWidthValue: 960
|
||||||
property real edgeGap: 0
|
|
||||||
property string slideEdge: "right"
|
|
||||||
readonly property bool slideFromLeft: slideEdge === "left"
|
|
||||||
property Component content: null
|
property Component content: null
|
||||||
property string title: ""
|
property string title: ""
|
||||||
property alias container: contentContainer
|
property alias container: contentContainer
|
||||||
property real customTransparency: -1
|
property real customTransparency: -1
|
||||||
property bool mappedVisible: false
|
property bool mappedVisible: false
|
||||||
signal aboutToHide
|
signal aboutToHide
|
||||||
signal revealed
|
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
mappedVisible = true;
|
mappedVisible = true;
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
isVisible = true;
|
isVisible = true;
|
||||||
revealed();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,9 +52,9 @@ PanelWindow {
|
|||||||
|
|
||||||
anchors.top: true
|
anchors.top: true
|
||||||
anchors.bottom: true
|
anchors.bottom: true
|
||||||
anchors.right: !root.slideFromLeft
|
anchors.right: true
|
||||||
anchors.left: root.slideFromLeft
|
|
||||||
|
|
||||||
|
// Expandable: fixed max surface width; strip width is slideContainer only (keeps blur/mask aligned).
|
||||||
implicitWidth: expandable ? expandedWidthValue : slideoutWidth
|
implicitWidth: expandable ? expandedWidthValue : slideoutWidth
|
||||||
implicitHeight: modelData ? modelData.height : 800
|
implicitHeight: modelData ? modelData.height : 800
|
||||||
|
|
||||||
@@ -74,15 +69,14 @@ PanelWindow {
|
|||||||
readonly property real dpr: CompositorService.getScreenScale(root.screen)
|
readonly property real dpr: CompositorService.getScreenScale(root.screen)
|
||||||
readonly property real alignedWidth: Theme.px(expandable && expandedWidth ? expandedWidthValue : slideoutWidth, dpr)
|
readonly property real alignedWidth: Theme.px(expandable && expandedWidth ? expandedWidthValue : slideoutWidth, dpr)
|
||||||
readonly property real alignedHeight: Theme.px(modelData ? modelData.height : 800, dpr)
|
readonly property real alignedHeight: Theme.px(modelData ? modelData.height : 800, dpr)
|
||||||
readonly property real alignedEdgeGap: Theme.px(edgeGap, dpr)
|
|
||||||
readonly property real slideoutSlideSnapX: Theme.snap(slideContainer.slideOffset, dpr)
|
readonly property real slideoutSlideSnapX: Theme.snap(slideContainer.slideOffset, dpr)
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: Rectangle {
|
item: Rectangle {
|
||||||
x: root.slideFromLeft ? root.alignedEdgeGap : (root.width - slideContainer.width - root.alignedEdgeGap)
|
x: root.width - slideContainer.width
|
||||||
y: root.alignedEdgeGap
|
y: 0
|
||||||
width: slideContainer.width
|
width: slideContainer.width
|
||||||
height: root.height - root.alignedEdgeGap * 2
|
height: root.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,21 +84,16 @@ PanelWindow {
|
|||||||
id: slideContainer
|
id: slideContainer
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: root.slideFromLeft ? undefined : parent.right
|
anchors.right: parent.right
|
||||||
anchors.left: root.slideFromLeft ? parent.left : undefined
|
|
||||||
anchors.topMargin: root.alignedEdgeGap
|
|
||||||
anchors.bottomMargin: root.alignedEdgeGap
|
|
||||||
anchors.rightMargin: root.alignedEdgeGap
|
|
||||||
anchors.leftMargin: root.alignedEdgeGap
|
|
||||||
width: root.alignedWidth
|
width: root.alignedWidth
|
||||||
height: root.alignedHeight - root.alignedEdgeGap * 2
|
height: root.alignedHeight
|
||||||
|
|
||||||
property real slideOffset: root.slideFromLeft ? -root.alignedWidth : root.alignedWidth
|
property real slideOffset: root.alignedWidth
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root
|
target: root
|
||||||
function onIsVisibleChanged() {
|
function onIsVisibleChanged() {
|
||||||
slideContainer.slideOffset = root.isVisible ? 0 : (root.slideFromLeft ? -slideContainer.width : slideContainer.width);
|
slideContainer.slideOffset = root.isVisible ? 0 : slideContainer.width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +111,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expandable only; mask/blur bind to slideContainer geometry so they track this animation.
|
||||||
Behavior on width {
|
Behavior on width {
|
||||||
enabled: root.expandable
|
enabled: root.expandable
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -227,6 +217,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blur region from slideContainer (not layered contentRect); position uses x + slideoutSlideSnapX, not mapToItem(root).
|
||||||
WindowBlur {
|
WindowBlur {
|
||||||
targetWindow: root
|
targetWindow: root
|
||||||
blurX: root.slideoutBlurActive ? slideContainer.x + root.slideoutSlideSnapX : 0
|
blurX: root.slideoutBlurActive ? slideContainer.x + root.slideoutSlideSnapX : 0
|
||||||
|
|||||||
@@ -546,7 +546,6 @@ 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,7 +58,6 @@
|
|||||||
"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"
|
||||||
},
|
},
|
||||||
@@ -728,6 +727,21 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -763,19 +777,30 @@
|
|||||||
"icon": "vertical_align_center"
|
"icon": "vertical_align_center"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "_tab_3",
|
"section": "barSpacing",
|
||||||
"label": "Settings",
|
"label": "Spacing",
|
||||||
"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",
|
||||||
"settings",
|
"screen",
|
||||||
|
"space",
|
||||||
|
"spacing",
|
||||||
"statusbar",
|
"statusbar",
|
||||||
|
"taskbar",
|
||||||
"topbar"
|
"topbar"
|
||||||
],
|
],
|
||||||
"icon": "tune"
|
"icon": "space_bar",
|
||||||
|
"description": "Space between the bar and screen edges"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "barUseOverlayLayer",
|
"section": "barUseOverlayLayer",
|
||||||
@@ -1503,19 +1528,6 @@
|
|||||||
"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",
|
||||||
@@ -1733,6 +1745,23 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -1769,6 +1798,21 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -1818,21 +1862,6 @@
|
|||||||
"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",
|
||||||
@@ -1953,25 +1982,6 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -1992,32 +2002,6 @@
|
|||||||
"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",
|
||||||
@@ -2046,6 +2030,28 @@
|
|||||||
"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",
|
||||||
@@ -3786,6 +3792,7 @@
|
|||||||
"tabIndex": 10,
|
"tabIndex": 10,
|
||||||
"category": "Theme & Colors",
|
"category": "Theme & Colors",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
"alpha",
|
||||||
"appearance",
|
"appearance",
|
||||||
"colors",
|
"colors",
|
||||||
"controls",
|
"controls",
|
||||||
@@ -3797,9 +3804,11 @@
|
|||||||
"shadow",
|
"shadow",
|
||||||
"style",
|
"style",
|
||||||
"theme",
|
"theme",
|
||||||
"transparency"
|
"translucent",
|
||||||
|
"transparency",
|
||||||
|
"transparent"
|
||||||
],
|
],
|
||||||
"description": "Controls the opacity of the shadow"
|
"description": "Controls the transparency of the shadow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "m3ElevationEnabled",
|
"section": "m3ElevationEnabled",
|
||||||
@@ -3824,34 +3833,8 @@
|
|||||||
"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",
|
||||||
@@ -3983,6 +3966,35 @@
|
|||||||
"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",
|
||||||
@@ -4551,27 +4563,6 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -5479,26 +5470,6 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -5896,19 +5867,22 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"alert",
|
"alert",
|
||||||
"alerts",
|
"alerts",
|
||||||
"font",
|
"appear",
|
||||||
|
"choose",
|
||||||
|
"location",
|
||||||
"messages",
|
"messages",
|
||||||
"notif",
|
"notif",
|
||||||
"notification",
|
"notification",
|
||||||
"notifications",
|
"notifications",
|
||||||
|
"popup",
|
||||||
"popups",
|
"popups",
|
||||||
"size",
|
"position",
|
||||||
"summary",
|
"screen",
|
||||||
"text",
|
"toast",
|
||||||
"toast"
|
"where"
|
||||||
],
|
],
|
||||||
"icon": "notifications",
|
"icon": "notifications",
|
||||||
"description": "Set the font size for notification summary text"
|
"description": "Choose where notification popups appear on screen"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"section": "notificationRules",
|
"section": "notificationRules",
|
||||||
@@ -6058,26 +6032,6 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -6100,32 +6054,6 @@
|
|||||||
"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",
|
||||||
@@ -6769,6 +6697,27 @@
|
|||||||
"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",
|
||||||
@@ -7170,36 +7119,6 @@
|
|||||||
],
|
],
|
||||||
"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",
|
||||||
@@ -8480,7 +8399,7 @@
|
|||||||
"topbar",
|
"topbar",
|
||||||
"window"
|
"window"
|
||||||
],
|
],
|
||||||
"icon": "layers",
|
"icon": "crop_square",
|
||||||
"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