removed proxy related code, and added a smooth animation to launcher when typing

This commit is contained in:
SomeElse
2026-05-04 21:45:08 +00:00
parent 0cb0054dd5
commit 8f25ee5caf
3 changed files with 127 additions and 102 deletions

View File

@@ -18,7 +18,7 @@ QtObject {
// ────────────────────────────────────────────────────────────────────────
// ── Position & Dimensions ─────────────────────────────────────────────────
property string barPosition: "bottom"
property string barPosition: "top"
property int barHeight: 35
property int margin: 15
property int radius: 26

View File

@@ -31,18 +31,8 @@ PanelWindow {
property bool _keyboardNav: false
property var allItems: []
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 var filteredItems: {
@@ -132,45 +122,13 @@ PanelWindow {
let cleanExec = item.exec.replace(/%[fFuUik]/g, "").trim()
const logPath = "/tmp/qml_launch.log"
const lowerExec = cleanExec.toLowerCase()
const isBrowser = lowerExec.includes("chromium") || lowerExec.includes("chrome") || lowerExec.includes("firefox")
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 &"
const args = parseExec(cleanExec)
const cmd = args.map(a => shellQuote(a)).join(" ") + " > " + shellQuote(logPath) + " 2>&1 < /dev/null &"
launchProc.command = ["sh", "-c", cmd]
launchProc.running = true
console.log("Launching: " + prefix + cleanExec + (extraArgs.length ? " " + extraArgs.join(" ") : ""))
console.log("Launching: " + cleanExec)
if (typeof close === "function") close()
}
@@ -186,8 +144,7 @@ PanelWindow {
WlrLayershell.keyboardFocus: _isOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
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 }
Timer {
@@ -225,20 +182,7 @@ PanelWindow {
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 {
anchors.fill: parent
enabled: root._isOpen && Cfg.Config.launcherCloseOnClickOutside
@@ -263,6 +207,10 @@ PanelWindow {
width: parent.width
property int targetHeight: Math.min(layout.implicitHeight + 28, 540)
height: targetHeight
Behavior on height {
enabled: root._isOpen
NumberAnimation { duration: 154; easing.type: Easing.OutCubic }
}
anchors.top: root.isTop ? parent.top : undefined
anchors.bottom: root.isTop ? undefined : parent.bottom
@@ -292,11 +240,12 @@ PanelWindow {
ColumnLayout {
id: layout
anchors.fill: parent
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 14
spacing: 10
// ── Search input ──────────────────────────────────────────
Rectangle {
Layout.fillWidth: true
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 {
id: resultsList
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
model: root.filteredItems
currentIndex: root.defaultIndex
@@ -442,6 +359,10 @@ PanelWindow {
onModelChanged: currentIndex = root.defaultIndex
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
add: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1; duration: 100; easing.type: Easing.InQuad }
}
delegate: Rectangle {
width: resultsList.width
height: 38

104
launcher/Launcher.sh Normal file
View 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