Launcher: clipboard, prevent unecessary refresh while browsing
This commit is contained in:
parent
20b29f98a7
commit
7b2d490ba7
6 changed files with 91 additions and 37 deletions
|
|
@ -11,8 +11,18 @@ NPanel {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Panel configuration
|
// Panel configuration
|
||||||
panelWidth: Math.min(700 * scaling, screen?.width * 0.75)
|
panelWidth: {
|
||||||
panelHeight: Math.min(600 * scaling, screen?.height * 0.8)
|
var w = Math.round(Math.max(screen?.width * 0.3, 500) * scaling)
|
||||||
|
w = Math.min(w, screen?.width - Style.marginL * 2)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
panelHeight: {
|
||||||
|
var h = Math.round(Math.max(screen?.height * 0.5, 600) * scaling)
|
||||||
|
h = Math.min(h, screen?.height - Style.barHeight * scaling - Style.marginL * 2)
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
panelKeyboardFocus: true
|
panelKeyboardFocus: true
|
||||||
panelBackgroundColor: Qt.rgba(Color.mSurface.r, Color.mSurface.g, Color.mSurface.b,
|
panelBackgroundColor: Qt.rgba(Color.mSurface.r, Color.mSurface.g, Color.mSurface.b,
|
||||||
Settings.data.appLauncher.backgroundOpacity)
|
Settings.data.appLauncher.backgroundOpacity)
|
||||||
|
|
@ -246,7 +256,7 @@ NPanel {
|
||||||
id: entry
|
id: entry
|
||||||
|
|
||||||
property bool isSelected: mouseArea.containsMouse || (index === selectedIndex)
|
property bool isSelected: mouseArea.containsMouse || (index === selectedIndex)
|
||||||
property int badgeSize: Style.baseWidgetSize * 1.75 * scaling
|
property int badgeSize: Style.baseWidgetSize * 1.6 * scaling
|
||||||
|
|
||||||
// Property to reliably track the current item's ID.
|
// Property to reliably track the current item's ID.
|
||||||
// This changes whenever the delegate is recycled for a new item.
|
// This changes whenever the delegate is recycled for a new item.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import "../../../Helpers/FuzzySort.js" as Fuzzysort
|
import "../../../Helpers/FuzzySort.js" as Fuzzysort
|
||||||
|
|
||||||
QtObject {
|
Item {
|
||||||
property var launcher: null
|
property var launcher: null
|
||||||
property string name: "Applications"
|
property string name: "Applications"
|
||||||
property bool handleSearch: true
|
property bool handleSearch: true
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import QtQuick
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import "../../../Helpers/AdvancedMath.js" as AdvancedMath
|
import "../../../Helpers/AdvancedMath.js" as AdvancedMath
|
||||||
|
|
||||||
QtObject {
|
Item {
|
||||||
property var launcher: null
|
property var launcher: null
|
||||||
property string name: "Calculator"
|
property string name: "Calculator"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import Quickshell
|
||||||
import qs.Commons
|
import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
QtObject {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Plugin metadata
|
// Plugin metadata
|
||||||
|
|
@ -13,26 +13,47 @@ QtObject {
|
||||||
// Plugin capabilities
|
// Plugin capabilities
|
||||||
property bool handleSearch: false // Don't handle regular search
|
property bool handleSearch: false // Don't handle regular search
|
||||||
|
|
||||||
|
// Internal state
|
||||||
|
property bool isWaitingForData: false
|
||||||
|
property bool gotResults: false
|
||||||
|
property string lastSearchText: ""
|
||||||
|
|
||||||
// Listen for clipboard data updates
|
// Listen for clipboard data updates
|
||||||
// Connections {
|
Connections {
|
||||||
// target: ClipboardService
|
target: ClipboardService
|
||||||
// function onListCompleted() {
|
function onListCompleted() {
|
||||||
// // Only refresh if the clipboard plugin is active
|
if (gotResults) {
|
||||||
// if (launcher && launcher.activePlugin === root) {
|
// Do not update results after the first fetch.
|
||||||
// launcher.updateResults()
|
// This will avoid the list resetting every 2seconds when the service updates.
|
||||||
// }
|
return
|
||||||
// }
|
}
|
||||||
// }
|
// Refresh results if we're waiting for data or if clipboard plugin is active
|
||||||
|
if (isWaitingForData || (launcher && launcher.searchText.startsWith(">clip"))) {
|
||||||
|
isWaitingForData = false
|
||||||
|
gotResults = true
|
||||||
|
if (launcher) {
|
||||||
|
launcher.updateResults()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize plugin
|
// Initialize plugin
|
||||||
function init() {
|
function init() {
|
||||||
Logger.log("ClipboardPlugin", "Initialized")
|
Logger.log("ClipboardPlugin", "Initialized")
|
||||||
|
// Pre-load clipboard data if service is active
|
||||||
|
if (ClipboardService.active) {
|
||||||
|
ClipboardService.list(100)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when launcher opens
|
// Called when launcher opens
|
||||||
function onOpened() {
|
function onOpened() {
|
||||||
// Refresh clipboard history when launcher opens
|
// Refresh clipboard history when launcher opens
|
||||||
ClipboardService.list(100)
|
if (ClipboardService.active) {
|
||||||
|
isWaitingForData = true
|
||||||
|
ClipboardService.list(100)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this plugin handles the command
|
// Check if this plugin handles the command
|
||||||
|
|
@ -45,7 +66,7 @@ QtObject {
|
||||||
return [{
|
return [{
|
||||||
"name": ">clip",
|
"name": ">clip",
|
||||||
"description": "Search clipboard history",
|
"description": "Search clipboard history",
|
||||||
"icon": "content_paste",
|
"icon": "text-x-generic",
|
||||||
"isImage": false,
|
"isImage": false,
|
||||||
"onActivate": function () {
|
"onActivate": function () {
|
||||||
launcher.setSearchText(">clip ")
|
launcher.setSearchText(">clip ")
|
||||||
|
|
@ -53,7 +74,7 @@ QtObject {
|
||||||
}, {
|
}, {
|
||||||
"name": ">clip clear",
|
"name": ">clip clear",
|
||||||
"description": "Clear all clipboard history",
|
"description": "Clear all clipboard history",
|
||||||
"icon": "delete_sweep",
|
"icon": "text-x-generic",
|
||||||
"isImage": false,
|
"isImage": false,
|
||||||
"onActivate": function () {
|
"onActivate": function () {
|
||||||
ClipboardService.wipeAll()
|
ClipboardService.wipeAll()
|
||||||
|
|
@ -68,15 +89,28 @@ QtObject {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastSearchText = searchText
|
||||||
const results = []
|
const results = []
|
||||||
const query = searchText.slice(5).trim()
|
const query = searchText.slice(5).trim()
|
||||||
|
|
||||||
|
// Check if clipboard service is not active
|
||||||
|
if (!ClipboardService.active) {
|
||||||
|
return [{
|
||||||
|
"name": "Clipboard History Disabled",
|
||||||
|
"description": "Enable clipboard history in settings or install cliphist",
|
||||||
|
"icon": "view-refresh",
|
||||||
|
"isImage": false,
|
||||||
|
"onActivate": function () {}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
// Special command: clear
|
// Special command: clear
|
||||||
if (query === "clear") {
|
if (query === "clear") {
|
||||||
return [{
|
return [{
|
||||||
"name": "Clear Clipboard History",
|
"name": "Clear Clipboard History",
|
||||||
"description": "Remove all items from clipboard history",
|
"description": "Remove all items from clipboard history",
|
||||||
"icon": "delete_sweep",
|
"icon": "delete_sweep",
|
||||||
|
"isImage": false,
|
||||||
"onActivate": function () {
|
"onActivate": function () {
|
||||||
ClipboardService.wipeAll()
|
ClipboardService.wipeAll()
|
||||||
launcher.close()
|
launcher.close()
|
||||||
|
|
@ -84,8 +118,24 @@ QtObject {
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show loading state if data isn't ready yet
|
// Show loading state if data is being loaded
|
||||||
if (ClipboardService.loading) {
|
if (ClipboardService.loading || isWaitingForData) {
|
||||||
|
return [{
|
||||||
|
"name": "Loading clipboard history...",
|
||||||
|
"description": "Please wait",
|
||||||
|
"icon": "view-refresh",
|
||||||
|
"isImage": false,
|
||||||
|
"onActivate": function () {}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get clipboard items
|
||||||
|
const items = ClipboardService.items || []
|
||||||
|
|
||||||
|
// If no items and we haven't tried loading yet, trigger a load
|
||||||
|
if (items.length === 0 && !ClipboardService.loading) {
|
||||||
|
isWaitingForData = true
|
||||||
|
ClipboardService.list(100)
|
||||||
return [{
|
return [{
|
||||||
"name": "Loading clipboard history...",
|
"name": "Loading clipboard history...",
|
||||||
"description": "Please wait",
|
"description": "Please wait",
|
||||||
|
|
@ -98,10 +148,6 @@ QtObject {
|
||||||
// Search clipboard items
|
// Search clipboard items
|
||||||
const searchTerm = query.toLowerCase()
|
const searchTerm = query.toLowerCase()
|
||||||
|
|
||||||
// Force dependency update
|
|
||||||
const _rev = ClipboardService.revision
|
|
||||||
const items = ClipboardService.items || []
|
|
||||||
|
|
||||||
// Filter and format results
|
// Filter and format results
|
||||||
items.forEach(function (item) {
|
items.forEach(function (item) {
|
||||||
const preview = (item.preview || "").toLowerCase()
|
const preview = (item.preview || "").toLowerCase()
|
||||||
|
|
@ -140,7 +186,7 @@ QtObject {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.log("ClipboardPlugin", `Returning ${results.length} results`)
|
//Logger.log("ClipboardPlugin", `Returning ${results.length} results for query: "${query}"`)
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,4 +262,4 @@ QtObject {
|
||||||
function getImageForItem(clipboardId) {
|
function getImageForItem(clipboardId) {
|
||||||
return ClipboardService.getImageData ? ClipboardService.getImageData(clipboardId) : null
|
return ClipboardService.getImageData ? ClipboardService.getImageData(clipboardId) : null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,9 @@ Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Public API
|
// Public API
|
||||||
property var items: [] // [{id, preview, mime, isImage}]
|
property bool active: Settings.isLoaded && Settings.data.appLauncher.enableClipboardHistory && cliphistAvailable
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
// Active only when feature is enabled, settings have finished initial load, and cliphist is available
|
property var items: [] // [{id, preview, mime, isImage}]
|
||||||
property bool active: Settings.data.appLauncher.enableClipboardHistory && Settings.isLoaded && cliphistAvailable
|
|
||||||
|
|
||||||
// Check if cliphist is available on the system
|
// Check if cliphist is available on the system
|
||||||
property bool cliphistAvailable: false
|
property bool cliphistAvailable: false
|
||||||
|
|
@ -39,7 +38,7 @@ Singleton {
|
||||||
property string _b64CurrentMime: ""
|
property string _b64CurrentMime: ""
|
||||||
property string _b64CurrentId: ""
|
property string _b64CurrentId: ""
|
||||||
|
|
||||||
signal listCompleted()
|
signal listCompleted
|
||||||
|
|
||||||
// Check if cliphist is available
|
// Check if cliphist is available
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
@ -82,7 +81,7 @@ Singleton {
|
||||||
|
|
||||||
// Start/stop watchers when enabled changes
|
// Start/stop watchers when enabled changes
|
||||||
onActiveChanged: {
|
onActiveChanged: {
|
||||||
if (root.active && root.cliphistAvailable) {
|
if (root.active) {
|
||||||
startWatchers()
|
startWatchers()
|
||||||
} else {
|
} else {
|
||||||
stopWatchers()
|
stopWatchers()
|
||||||
|
|
@ -96,7 +95,7 @@ Singleton {
|
||||||
Timer {
|
Timer {
|
||||||
interval: 5000
|
interval: 5000
|
||||||
repeat: true
|
repeat: true
|
||||||
running: root.active && root.cliphistAvailable
|
running: root.active
|
||||||
onTriggered: list()
|
onTriggered: list()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,9 +184,9 @@ Singleton {
|
||||||
const url = `data:${root._b64CurrentMime};base64,${b64}`
|
const url = `data:${root._b64CurrentMime};base64,${b64}`
|
||||||
try {
|
try {
|
||||||
root._b64CurrentCb(url)
|
root._b64CurrentCb(url)
|
||||||
} finally {
|
} catch (e) {
|
||||||
|
|
||||||
/* noop */ }
|
}
|
||||||
}
|
}
|
||||||
if (root._b64CurrentId !== "") {
|
if (root._b64CurrentId !== "") {
|
||||||
root.imageDataById[root._b64CurrentId] = `data:${root._b64CurrentMime};base64,${b64}`
|
root.imageDataById[root._b64CurrentId] = `data:${root._b64CurrentMime};base64,${b64}`
|
||||||
|
|
@ -321,6 +320,7 @@ Singleton {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Quickshell.execDetached(["cliphist", "delete", id])
|
Quickshell.execDetached(["cliphist", "delete", id])
|
||||||
|
revision++
|
||||||
Qt.callLater(() => list())
|
Qt.callLater(() => list())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -330,9 +330,7 @@ Singleton {
|
||||||
}
|
}
|
||||||
|
|
||||||
Quickshell.execDetached(["cliphist", "wipe"])
|
Quickshell.execDetached(["cliphist", "wipe"])
|
||||||
|
|
||||||
revision++
|
revision++
|
||||||
|
|
||||||
Qt.callLater(() => list())
|
Qt.callLater(() => list())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import qs.Commons
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
|
|
||||||
QtObject {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Notification server instance
|
// Notification server instance
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue