removed proxy related code, and added a smooth animation to launcher when typing
This commit is contained in:
@@ -18,7 +18,7 @@ QtObject {
|
|||||||
// ────────────────────────────────────────────────────────────────────────
|
// ────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// ── Position & Dimensions ─────────────────────────────────────────────────
|
// ── Position & Dimensions ─────────────────────────────────────────────────
|
||||||
property string barPosition: "bottom"
|
property string barPosition: "top"
|
||||||
property int barHeight: 35
|
property int barHeight: 35
|
||||||
property int margin: 15
|
property int margin: 15
|
||||||
property int radius: 26
|
property int radius: 26
|
||||||
|
|||||||
@@ -31,18 +31,8 @@ PanelWindow {
|
|||||||
property bool _keyboardNav: false
|
property bool _keyboardNav: false
|
||||||
property var allItems: []
|
property var allItems: []
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
property bool proxyMode: false
|
|
||||||
property string proxyUrl: ""
|
|
||||||
|
|
||||||
Component.onCompleted: readProxyUrl()
|
|
||||||
|
|
||||||
function readProxyUrl() {
|
|
||||||
proxyUrlProc.command = ["cat", Cfg.Config.launcherCacheDir + "/proxy.conf"]
|
|
||||||
proxyUrlProc.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// When launcherSelectFirst is true the first result is pre-selected;
|
|
||||||
// otherwise the list starts with no selection (-1).
|
|
||||||
readonly property int defaultIndex: Cfg.Config.launcherSelectFirst ? 0 : -1
|
readonly property int defaultIndex: Cfg.Config.launcherSelectFirst ? 0 : -1
|
||||||
|
|
||||||
readonly property var filteredItems: {
|
readonly property var filteredItems: {
|
||||||
@@ -132,45 +122,13 @@ PanelWindow {
|
|||||||
let cleanExec = item.exec.replace(/%[fFuUik]/g, "").trim()
|
let cleanExec = item.exec.replace(/%[fFuUik]/g, "").trim()
|
||||||
const logPath = "/tmp/qml_launch.log"
|
const logPath = "/tmp/qml_launch.log"
|
||||||
|
|
||||||
const lowerExec = cleanExec.toLowerCase()
|
const args = parseExec(cleanExec)
|
||||||
const isBrowser = lowerExec.includes("chromium") || lowerExec.includes("chrome") || lowerExec.includes("firefox")
|
const cmd = args.map(a => shellQuote(a)).join(" ") + " > " + shellQuote(logPath) + " 2>&1 < /dev/null &"
|
||||||
|
|
||||||
let extraArgs = []
|
|
||||||
let envVars = []
|
|
||||||
let prefix = ""
|
|
||||||
let useProxyChains = false
|
|
||||||
|
|
||||||
if (root.proxyMode) {
|
|
||||||
if (isBrowser && root.proxyUrl) {
|
|
||||||
// Browsers: use native proxy flags instead of proxychains4
|
|
||||||
// to avoid LD_PRELOAD sandbox conflicts
|
|
||||||
if (lowerExec.includes("chromium") || lowerExec.includes("chrome")) {
|
|
||||||
extraArgs.push("--proxy-server=" + root.proxyUrl)
|
|
||||||
}
|
|
||||||
if (lowerExec.includes("firefox")) {
|
|
||||||
envVars.push("all_proxy=" + root.proxyUrl)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Non-browsers: use proxychains4 normally
|
|
||||||
useProxyChains = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const envPrefix = envVars.length > 0 ? "env " + envVars.join(" ") + " " : ""
|
|
||||||
if (useProxyChains) {
|
|
||||||
prefix = envPrefix + "/usr/bin/proxychains4 "
|
|
||||||
} else {
|
|
||||||
prefix = envPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
const args = parseExec(cleanExec)
|
|
||||||
const fullArgs = args.concat(extraArgs)
|
|
||||||
const cmd = prefix + fullArgs.map(a => shellQuote(a)).join(" ") + " > " + shellQuote(logPath) + " 2>&1 < /dev/null &"
|
|
||||||
|
|
||||||
launchProc.command = ["sh", "-c", cmd]
|
launchProc.command = ["sh", "-c", cmd]
|
||||||
launchProc.running = true
|
launchProc.running = true
|
||||||
|
|
||||||
console.log("Launching: " + prefix + cleanExec + (extraArgs.length ? " " + extraArgs.join(" ") : ""))
|
console.log("Launching: " + cleanExec)
|
||||||
if (typeof close === "function") close()
|
if (typeof close === "function") close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,8 +144,7 @@ PanelWindow {
|
|||||||
WlrLayershell.keyboardFocus: _isOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: _isOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||||
mask: Region { item: (root._isOpen && Cfg.Config.launcherCloseOnClickOutside) ? fullMask : clipContainer }
|
mask: Region { item: (root._isOpen && Cfg.Config.launcherCloseOnClickOutside) ? fullMask : clipContainer }
|
||||||
|
|
||||||
// Full-screen item used as input mask when click-outside-to-close is enabled.
|
|
||||||
// Lets the background MouseArea receive events outside the bubble.
|
|
||||||
Item { id: fullMask; anchors.fill: parent }
|
Item { id: fullMask; anchors.fill: parent }
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -225,20 +182,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Process { id: launchProc }
|
Process { id: launchProc }
|
||||||
|
|
||||||
Process {
|
|
||||||
id: proxyUrlProc
|
|
||||||
property string rawOutput: ""
|
|
||||||
stdout: SplitParser { onRead: data => proxyUrlProc.rawOutput = data.trim() }
|
|
||||||
onRunningChanged: {
|
|
||||||
if (!running && rawOutput) {
|
|
||||||
root.proxyUrl = rawOutput
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transparent overlay — captures clicks outside the bubble and closes the
|
|
||||||
// launcher. Sits below clipContainer in stacking order (declared first),
|
|
||||||
// so clicks inside the bubble still reach the bubble's own MouseAreas.
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: root._isOpen && Cfg.Config.launcherCloseOnClickOutside
|
enabled: root._isOpen && Cfg.Config.launcherCloseOnClickOutside
|
||||||
@@ -263,6 +207,10 @@ PanelWindow {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
property int targetHeight: Math.min(layout.implicitHeight + 28, 540)
|
property int targetHeight: Math.min(layout.implicitHeight + 28, 540)
|
||||||
height: targetHeight
|
height: targetHeight
|
||||||
|
Behavior on height {
|
||||||
|
enabled: root._isOpen
|
||||||
|
NumberAnimation { duration: 154; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
anchors.top: root.isTop ? parent.top : undefined
|
anchors.top: root.isTop ? parent.top : undefined
|
||||||
anchors.bottom: root.isTop ? undefined : parent.bottom
|
anchors.bottom: root.isTop ? undefined : parent.bottom
|
||||||
@@ -292,11 +240,12 @@ PanelWindow {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: layout
|
id: layout
|
||||||
anchors.fill: parent
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
anchors.margins: 14
|
anchors.margins: 14
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
// ── Search input ──────────────────────────────────────────
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 44
|
height: 44
|
||||||
@@ -389,51 +338,19 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Proxychains toggle ────────────────────────────
|
|
||||||
Rectangle {
|
|
||||||
id: proxyBtn
|
|
||||||
height: 28
|
|
||||||
width: 110
|
|
||||||
radius: 8
|
|
||||||
color: root.proxyMode ? Qt.rgba(1, 0.35, 0.35, 0.22) : t.launcherPill
|
|
||||||
border.color: root.proxyMode ? Qt.rgba(1, 0.35, 0.35, 0.65) : t.launcherBorder
|
|
||||||
border.width: Cfg.Config.popupBorderWidth
|
|
||||||
Behavior on color { ColorAnimation { duration: 150 } }
|
|
||||||
Behavior on border.color { ColorAnimation { duration: 150 } }
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: proxyBtnRow
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 5
|
|
||||||
Text {
|
|
||||||
text: ""
|
|
||||||
font.pixelSize: 11
|
|
||||||
color: root.proxyMode ? Qt.rgba(1, 0.45, 0.45, 1) : t.launcherDim
|
|
||||||
Behavior on color { ColorAnimation { duration: 150 } }
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "proxychains4"
|
|
||||||
font.pixelSize: 10
|
|
||||||
font.bold: root.proxyMode
|
|
||||||
color: root.proxyMode ? Qt.rgba(1, 0.45, 0.45, 1) : t.launcherDim
|
|
||||||
Behavior on color { ColorAnimation { duration: 150 } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: root.proxyMode = !root.proxyMode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: resultsList
|
id: resultsList
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: Math.min(contentHeight, 400)
|
Layout.preferredHeight: listHeight
|
||||||
|
|
||||||
|
property int listHeight: Math.min(contentHeight, 400)
|
||||||
|
Behavior on listHeight {
|
||||||
|
NumberAnimation { duration: 154; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
model: root.filteredItems
|
model: root.filteredItems
|
||||||
currentIndex: root.defaultIndex
|
currentIndex: root.defaultIndex
|
||||||
@@ -442,6 +359,10 @@ PanelWindow {
|
|||||||
onModelChanged: currentIndex = root.defaultIndex
|
onModelChanged: currentIndex = root.defaultIndex
|
||||||
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
|
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
|
||||||
|
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 100; easing.type: Easing.InQuad }
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
width: resultsList.width
|
width: resultsList.width
|
||||||
height: 38
|
height: 38
|
||||||
|
|||||||
104
launcher/Launcher.sh
Normal file
104
launcher/Launcher.sh
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CACHE_DIR="/tmp/qs_launcher"
|
||||||
|
|
||||||
|
DRUN_CACHE="$CACHE_DIR/drun.txt"
|
||||||
|
RUN_CACHE="$CACHE_DIR/run.txt"
|
||||||
|
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
|
||||||
|
|
||||||
|
get_desktop_files() {
|
||||||
|
IFS=':' read -ra DIRS <<< \
|
||||||
|
"${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
|
||||||
|
|
||||||
|
for dir in "${DIRS[@]}"; do
|
||||||
|
APP_DIR="$dir/applications"
|
||||||
|
|
||||||
|
[ -d "$APP_DIR" ] || continue
|
||||||
|
|
||||||
|
find "$APP_DIR" \
|
||||||
|
-maxdepth 1 \
|
||||||
|
-name "*.desktop" \
|
||||||
|
2>/dev/null
|
||||||
|
done | while read -r f; do
|
||||||
|
|
||||||
|
name=$(
|
||||||
|
grep -m1 '^Name=' "$f" \
|
||||||
|
| cut -d= -f2-
|
||||||
|
)
|
||||||
|
|
||||||
|
exec=$(
|
||||||
|
grep -m1 '^Exec=' "$f" \
|
||||||
|
| cut -d= -f2- \
|
||||||
|
| sed 's/%[fFuUik]//g'
|
||||||
|
)
|
||||||
|
|
||||||
|
type=$(
|
||||||
|
grep -m1 '^Type=' "$f" \
|
||||||
|
| cut -d= -f2-
|
||||||
|
)
|
||||||
|
|
||||||
|
nodisplay=$(
|
||||||
|
grep -m1 '^NoDisplay=' "$f" \
|
||||||
|
| cut -d= -f2- \
|
||||||
|
| tr '[:upper:]' '[:lower:]'
|
||||||
|
)
|
||||||
|
|
||||||
|
icon=$(
|
||||||
|
grep -m1 '^Icon=' "$f" \
|
||||||
|
| cut -d= -f2-
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ "$type" == "Application" ]] || continue
|
||||||
|
[[ "$nodisplay" != "true" ]] || continue
|
||||||
|
[[ -n "$name" ]] || continue
|
||||||
|
|
||||||
|
printf "%s\t%s\t%s\t%s\n" \
|
||||||
|
"$name" \
|
||||||
|
"$exec" \
|
||||||
|
"$(basename "$f" .desktop)" \
|
||||||
|
"$icon"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get_binaries() {
|
||||||
|
compgen -c \
|
||||||
|
| sort -u \
|
||||||
|
| head -600 \
|
||||||
|
| awk '{
|
||||||
|
print $1 "\t" $1 "\t" $1
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
build_drun() {
|
||||||
|
get_desktop_files \
|
||||||
|
| sort -f -t$'\t' -k1,1 \
|
||||||
|
| awk -F'\t' '!seen[$1]++'
|
||||||
|
}
|
||||||
|
|
||||||
|
build_run() {
|
||||||
|
{
|
||||||
|
get_desktop_files
|
||||||
|
get_binaries
|
||||||
|
} \
|
||||||
|
| sort -f -t$'\t' -k1,1 \
|
||||||
|
| awk -F'\t' '!seen[$1]++'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
update_cache() {
|
||||||
|
build_drun > "$DRUN_CACHE.tmp"
|
||||||
|
build_run > "$RUN_CACHE.tmp"
|
||||||
|
|
||||||
|
mv "$DRUN_CACHE.tmp" "$DRUN_CACHE"
|
||||||
|
mv "$RUN_CACHE.tmp" "$RUN_CACHE"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$1" == "--update-only" ]; then
|
||||||
|
update_cache
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user