forked from Shinonome/dots-hyprland
search: use qs' execdetached instead of executor proc
This commit is contained in:
@@ -4,14 +4,11 @@ import "root:/modules/common"
|
|||||||
import "root:/modules/common/widgets"
|
import "root:/modules/common/widgets"
|
||||||
import "root:/modules/common/functions/string_utils.js" as StringUtils
|
import "root:/modules/common/functions/string_utils.js" as StringUtils
|
||||||
import Qt5Compat.GraphicalEffects
|
import Qt5Compat.GraphicalEffects
|
||||||
import Qt.labs.platform
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Effects
|
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Hyprland
|
|
||||||
|
|
||||||
Item { // Wrapper
|
Item { // Wrapper
|
||||||
id: root
|
id: root
|
||||||
@@ -29,9 +26,9 @@ Item { // Wrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
function cancelSearch() {
|
function cancelSearch() {
|
||||||
searchInput.selectAll()
|
searchInput.selectAll();
|
||||||
root.searchingText = ""
|
root.searchingText = "";
|
||||||
searchWidthBehavior.enabled = true;
|
searchWidthBehavior.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSearchingText(text) {
|
function setSearchingText(text) {
|
||||||
@@ -43,45 +40,44 @@ Item { // Wrapper
|
|||||||
{
|
{
|
||||||
action: "dark",
|
action: "dark",
|
||||||
execute: () => {
|
execute: () => {
|
||||||
executor.executeCommand(`${Directories.wallpaperSwitchScriptPath} --mode dark --noswitch`)
|
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--mode", "dark", "--noswitch"]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: "light",
|
action: "light",
|
||||||
execute: () => {
|
execute: () => {
|
||||||
executor.executeCommand(`${Directories.wallpaperSwitchScriptPath} --mode light --noswitch`)
|
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--mode", "light", "--noswitch"]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: "wall",
|
action: "wall",
|
||||||
execute: () => {
|
execute: () => {
|
||||||
executor.executeCommand(Directories.wallpaperSwitchScriptPath)
|
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: "konachanwall",
|
action: "konachanwall",
|
||||||
execute: () => {
|
execute: () => {
|
||||||
Quickshell.execDetached([Quickshell.configPath("scripts/colors/random_konachan_wall.sh")])
|
Quickshell.execDetached([Quickshell.configPath("scripts/colors/random_konachan_wall.sh")]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: "accentcolor",
|
action: "accentcolor",
|
||||||
execute: (args) => {
|
execute: args => {
|
||||||
executor.executeCommand(
|
Quickshell.execDetached([Directories.wallpaperSwitchScriptPath, "--noswitch", "--color", ...(args != '' ? [`${args}`] : [])]);
|
||||||
`${Directories.wallpaperSwitchScriptPath} --noswitch --color ${args != '' ? ("'"+args+"'") : ""}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
action: "todo",
|
action: "todo",
|
||||||
execute: (args) => {
|
execute: args => {
|
||||||
Todo.addTask(args)
|
Todo.addTask(args);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
function focusFirstItemIfNeeded() {
|
function focusFirstItemIfNeeded() {
|
||||||
if (searchInput.focus) appResults.currentIndex = 0; // Focus the first item
|
if (searchInput.focus)
|
||||||
|
appResults.currentIndex = 0; // Focus the first item
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -96,32 +92,22 @@ Item { // Wrapper
|
|||||||
id: mathProcess
|
id: mathProcess
|
||||||
property list<string> baseCommand: ["qalc", "-t"]
|
property list<string> baseCommand: ["qalc", "-t"]
|
||||||
function calculateExpression(expression) {
|
function calculateExpression(expression) {
|
||||||
mathProcess.running = false
|
mathProcess.running = false;
|
||||||
mathProcess.command = baseCommand.concat(expression)
|
mathProcess.command = baseCommand.concat(expression);
|
||||||
mathProcess.running = true
|
mathProcess.running = true;
|
||||||
}
|
}
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: data => {
|
onRead: data => {
|
||||||
root.mathResult = data
|
root.mathResult = data;
|
||||||
root.focusFirstItemIfNeeded()
|
root.focusFirstItemIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Keys.onPressed: event => {
|
||||||
id: executor
|
|
||||||
property list<string> baseCommand: ["bash", "-c"]
|
|
||||||
function executeCommand(command) {
|
|
||||||
executor.command = baseCommand.concat(
|
|
||||||
`${command}`
|
|
||||||
)
|
|
||||||
executor.startDetached()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onPressed: (event) => {
|
|
||||||
// Prevent Esc and Backspace from registering
|
// Prevent Esc and Backspace from registering
|
||||||
if (event.key === Qt.Key_Escape) return;
|
if (event.key === Qt.Key_Escape)
|
||||||
|
return;
|
||||||
|
|
||||||
// Handle Backspace: focus and delete character if not focused
|
// Handle Backspace: focus and delete character if not focused
|
||||||
if (event.key === Qt.Key_Backspace) {
|
if (event.key === Qt.Key_Backspace) {
|
||||||
@@ -142,8 +128,7 @@ Item { // Wrapper
|
|||||||
} else {
|
} else {
|
||||||
// Delete character before cursor if any
|
// Delete character before cursor if any
|
||||||
if (searchInput.cursorPosition > 0) {
|
if (searchInput.cursorPosition > 0) {
|
||||||
searchInput.text = searchInput.text.slice(0, searchInput.cursorPosition - 1) +
|
searchInput.text = searchInput.text.slice(0, searchInput.cursorPosition - 1) + searchInput.text.slice(searchInput.cursorPosition);
|
||||||
searchInput.text.slice(searchInput.cursorPosition);
|
|
||||||
searchInput.cursorPosition -= 1;
|
searchInput.cursorPosition -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,19 +141,12 @@ Item { // Wrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only handle visible printable characters (ignore control chars, arrows, etc.)
|
// Only handle visible printable characters (ignore control chars, arrows, etc.)
|
||||||
if (
|
if (event.text && event.text.length === 1 && event.key !== Qt.Key_Enter && event.key !== Qt.Key_Return && event.text.charCodeAt(0) >= 0x20) // ignore control chars like Backspace, Tab, etc.
|
||||||
event.text &&
|
{
|
||||||
event.text.length === 1 &&
|
|
||||||
event.key !== Qt.Key_Enter &&
|
|
||||||
event.key !== Qt.Key_Return &&
|
|
||||||
event.text.charCodeAt(0) >= 0x20 // ignore control chars like Backspace, Tab, etc.
|
|
||||||
) {
|
|
||||||
if (!searchInput.activeFocus) {
|
if (!searchInput.activeFocus) {
|
||||||
searchInput.forceActiveFocus();
|
searchInput.forceActiveFocus();
|
||||||
// Insert the character at the cursor position
|
// Insert the character at the cursor position
|
||||||
searchInput.text = searchInput.text.slice(0, searchInput.cursorPosition) +
|
searchInput.text = searchInput.text.slice(0, searchInput.cursorPosition) + event.text + searchInput.text.slice(searchInput.cursorPosition);
|
||||||
event.text +
|
|
||||||
searchInput.text.slice(searchInput.cursorPosition);
|
|
||||||
searchInput.cursorPosition += 1;
|
searchInput.cursorPosition += 1;
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
@@ -264,7 +242,8 @@ Item { // Wrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle { // Separator
|
Rectangle {
|
||||||
|
// Separator
|
||||||
visible: root.showResults
|
visible: root.showResults
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 1
|
height: 1
|
||||||
@@ -281,10 +260,11 @@ Item { // Wrapper
|
|||||||
bottomMargin: 10
|
bottomMargin: 10
|
||||||
spacing: 2
|
spacing: 2
|
||||||
KeyNavigation.up: searchBar
|
KeyNavigation.up: searchBar
|
||||||
highlightMoveDuration : 100
|
highlightMoveDuration: 100
|
||||||
|
|
||||||
onFocusChanged: {
|
onFocusChanged: {
|
||||||
if(focus) appResults.currentIndex = 1;
|
if (focus)
|
||||||
|
appResults.currentIndex = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@@ -297,12 +277,15 @@ Item { // Wrapper
|
|||||||
|
|
||||||
model: ScriptModel {
|
model: ScriptModel {
|
||||||
id: model
|
id: model
|
||||||
values: { // Search results are handled here
|
values: {
|
||||||
|
// Search results are handled here
|
||||||
////////////////// Skip? //////////////////
|
////////////////// Skip? //////////////////
|
||||||
if(root.searchingText == "") return [];
|
if (root.searchingText == "")
|
||||||
|
return [];
|
||||||
|
|
||||||
///////////// Special cases ///////////////
|
///////////// Special cases ///////////////
|
||||||
if (root.searchingText.startsWith(Config.options.search.prefix.clipboard)) { // Clipboard
|
if (root.searchingText.startsWith(Config.options.search.prefix.clipboard)) {
|
||||||
|
// Clipboard
|
||||||
const searchString = root.searchingText.slice(Config.options.search.prefix.clipboard.length);
|
const searchString = root.searchingText.slice(Config.options.search.prefix.clipboard.length);
|
||||||
return Cliphist.fuzzyQuery(searchString).map(entry => {
|
return Cliphist.fuzzyQuery(searchString).map(entry => {
|
||||||
return {
|
return {
|
||||||
@@ -311,14 +294,13 @@ Item { // Wrapper
|
|||||||
clickActionName: "",
|
clickActionName: "",
|
||||||
type: `#${entry.match(/^\s*(\S+)/)?.[1] || ""}`,
|
type: `#${entry.match(/^\s*(\S+)/)?.[1] || ""}`,
|
||||||
execute: () => {
|
execute: () => {
|
||||||
Quickshell.execDetached(
|
Quickshell.execDetached(["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`]);
|
||||||
["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}).filter(Boolean);
|
}).filter(Boolean);
|
||||||
}
|
}
|
||||||
if (root.searchingText.startsWith(Config.options.search.prefix.emojis)) { // Clipboard
|
if (root.searchingText.startsWith(Config.options.search.prefix.emojis)) {
|
||||||
|
// Clipboard
|
||||||
const searchString = root.searchingText.slice(Config.options.search.prefix.emojis.length);
|
const searchString = root.searchingText.slice(Config.options.search.prefix.emojis.length);
|
||||||
return Emojis.fuzzyQuery(searchString).map(entry => {
|
return Emojis.fuzzyQuery(searchString).map(entry => {
|
||||||
return {
|
return {
|
||||||
@@ -328,12 +310,11 @@ Item { // Wrapper
|
|||||||
clickActionName: "",
|
clickActionName: "",
|
||||||
type: "Emoji",
|
type: "Emoji",
|
||||||
execute: () => {
|
execute: () => {
|
||||||
Quickshell.clipboardText = entry.match(/^\s*(\S+)/)?.[1]
|
Quickshell.clipboardText = entry.match(/^\s*(\S+)/)?.[1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}).filter(Boolean);
|
}).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////// Init ///////////////////
|
////////////////// Init ///////////////////
|
||||||
nonAppResultsTimer.restart();
|
nonAppResultsTimer.restart();
|
||||||
@@ -346,7 +327,7 @@ Item { // Wrapper
|
|||||||
execute: () => {
|
execute: () => {
|
||||||
Quickshell.clipboardText = root.mathResult;
|
Quickshell.clipboardText = root.mathResult;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const commandResultObject = {
|
const commandResultObject = {
|
||||||
name: searchingText.replace("file://", ""),
|
name: searchingText.replace("file://", ""),
|
||||||
clickActionName: qsTr("Run"),
|
clickActionName: qsTr("Run"),
|
||||||
@@ -354,38 +335,34 @@ Item { // Wrapper
|
|||||||
fontType: "monospace",
|
fontType: "monospace",
|
||||||
materialSymbol: 'terminal',
|
materialSymbol: 'terminal',
|
||||||
execute: () => {
|
execute: () => {
|
||||||
executor.executeCommand(searchingText.startsWith('sudo') ? `${Config.options.apps.terminal} fish -C '${root.searchingText.replace("file://", "")}'` : root.searchingText.replace("file://", ""));
|
const cleanedCommand = root.searchingText.replace("file://", "");
|
||||||
|
Quickshell.execDetached(["bash", "-c", searchingText.startsWith('sudo') ? `${Config.options.apps.terminal} fish -C '${cleanedCommand}'` : cleanedCommand]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const launcherActionObjects = root.searchActions
|
const launcherActionObjects = root.searchActions.map(action => {
|
||||||
.map(action => {
|
const actionString = `${Config.options.search.prefix.action}${action.action}`;
|
||||||
const actionString = `${Config.options.search.prefix.action}${action.action}`;
|
if (actionString.startsWith(root.searchingText) || root.searchingText.startsWith(actionString)) {
|
||||||
if (actionString.startsWith(root.searchingText) || root.searchingText.startsWith(actionString)) {
|
return {
|
||||||
return {
|
name: root.searchingText.startsWith(actionString) ? root.searchingText : actionString,
|
||||||
name: root.searchingText.startsWith(actionString) ? root.searchingText : actionString,
|
clickActionName: qsTr("Run"),
|
||||||
clickActionName: qsTr("Run"),
|
type: qsTr("Action"),
|
||||||
type: qsTr("Action"),
|
materialSymbol: 'settings_suggest',
|
||||||
materialSymbol: 'settings_suggest',
|
execute: () => {
|
||||||
execute: () => {
|
action.execute(root.searchingText.split(" ").slice(1).join(" "));
|
||||||
action.execute(root.searchingText.split(" ").slice(1).join(" "))
|
}
|
||||||
},
|
};
|
||||||
};
|
}
|
||||||
}
|
return null;
|
||||||
return null;
|
}).filter(Boolean);
|
||||||
})
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
//////////////// Apps //////////////////
|
//////////////// Apps //////////////////
|
||||||
result = result.concat(
|
result = result.concat(AppSearch.fuzzyQuery(root.searchingText).map(entry => {
|
||||||
AppSearch.fuzzyQuery(root.searchingText)
|
entry.clickActionName = qsTr("Launch");
|
||||||
.map((entry) => {
|
entry.type = qsTr("App");
|
||||||
entry.clickActionName = qsTr("Launch");
|
return entry;
|
||||||
entry.type = qsTr("App");
|
}));
|
||||||
return entry;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
////////// Launcher actions ////////////
|
////////// Launcher actions ////////////
|
||||||
result = result.concat(launcherActionObjects);
|
result = result.concat(launcherActionObjects);
|
||||||
@@ -407,7 +384,7 @@ Item { // Wrapper
|
|||||||
type: qsTr("Search the web"),
|
type: qsTr("Search the web"),
|
||||||
materialSymbol: 'travel_explore',
|
materialSymbol: 'travel_explore',
|
||||||
execute: () => {
|
execute: () => {
|
||||||
let url = Config.options.search.engineBaseUrl + root.searchingText
|
let url = Config.options.search.engineBaseUrl + root.searchingText;
|
||||||
for (let site of Config.options.search.excludedSites) {
|
for (let site of Config.options.search.excludedSites) {
|
||||||
url += ` -site:${site}`;
|
url += ` -site:${site}`;
|
||||||
}
|
}
|
||||||
@@ -419,17 +396,15 @@ Item { // Wrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: SearchItem { // The selectable item for each search result
|
delegate: SearchItem {
|
||||||
|
// The selectable item for each search result
|
||||||
required property var modelData
|
required property var modelData
|
||||||
anchors.left: parent?.left
|
anchors.left: parent?.left
|
||||||
anchors.right: parent?.right
|
anchors.right: parent?.right
|
||||||
entry: modelData
|
entry: modelData
|
||||||
query: root.searchingText.startsWith(Config.options.search.prefix.clipboard) ?
|
query: root.searchingText.startsWith(Config.options.search.prefix.clipboard) ? root.searchingText.slice(Config.options.search.prefix.clipboard.length) : root.searchingText
|
||||||
root.searchingText.slice(Config.options.search.prefix.clipboard.length) :
|
|
||||||
root.searchingText;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user