Fix wallpaper persistence, tray icons, Booru bugs, session launcher

- Persist last-set wallpaper and restore it via exec-once, since
  hyprpaper/mpvpaper start every session with nothing loaded
- Fix Vesktop's system tray icon rendering as a broken texture: only
  resolve tray icons through the icon theme when they're actual names,
  not raw pixmap-sourced image:// URLs
- Launch Hyprland via start-hyprland (its official watchdog launcher)
  instead of the raw binary, removing the startup warning and adding
  hang recovery
- Fix Booru panel: Lewds toggle now actually persists, tag autocomplete
  no longer drops/races overlapping requests, and pagination wraps
  instead of overflowing off-screen
- Remove the redundant gap between windows and sidebars/tiles
  (gaps_in/gaps_out, and duplicate flyout margins stacked on top of
  Hyprland's automatic exclusive-zone inset)
This commit is contained in:
Nexoniarz 2026-08-30 15:48:06 +02:00
commit ea7fefbba8
7 changed files with 96 additions and 4 deletions

View file

@ -1100,6 +1100,16 @@ Rectangle {
}
var url = "https://danbooru.donmai.us/autocomplete.json?search%5Bquery%5D="
+ encodeURIComponent(partial) + "&search%5Btype%5D=tag_query&limit=8";
// If a previous keystroke's request is still in flight (curl
// hasn't returned yet), reassigning .command and setting
// .running = true on an already-running Process is a no-op
// — running:true -> true is not a change, so nothing
// restarts and the newer query silently never gets sent.
// That's the "sometimes works, sometimes not" flakiness:
// explicitly stop it first so the new request actually
// fires.
if (autocompleteProc.running) autocompleteProc.running = false;
autocompleteProc.requestedPartial = partial;
autocompleteProc.command = ["curl", "-s", "-A", booruCol.userAgent, url];
autocompleteProc.running = true;
}
@ -1211,8 +1221,15 @@ Rectangle {
}
Process {
id: autocompleteProc
property string requestedPartial: ""
stdout: StdioCollector {
onStreamFinished: {
// Drop stale responses: even with the running-guard
// above, a slow request can still resolve after a
// faster, newer one — without this check whichever
// curl happens to finish last wins, regardless of
// which one actually matches what's typed now.
if (autocompleteProc.requestedPartial !== booruCol.currentPartialTag()) return;
try {
var d = JSON.parse(text);
booruCol.suggestions = Array.isArray(d) ? d : [];
@ -1354,7 +1371,20 @@ Rectangle {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: { booruSettings.lewds = booruCol.lewds ? "0" : "1"; booruCol.doSearch(); }
onClicked: {
// save() here, not just the property assignment:
// this was the actual persistence bug — toggling
// Lewds never wrote to disk on its own, only the
// source-switcher below called save(). So Lewds
// only ever "stuck" as a side effect of also
// switching source afterward, and turning it
// back off never stuck at all — reopening Booru
// always reloaded whatever was last written that
// way instead of the toggle's actual state.
booruSettings.lewds = booruCol.lewds ? "0" : "1";
booruSettings.save();
booruCol.doSearch();
}
}
}
}
@ -1468,7 +1498,16 @@ Rectangle {
}
// -- Pagination --
Row {
// Flow, not Row: Row lays out children at their natural
// width regardless of the width assigned to the Row
// itself, so when Prev + "Page" + the page field + "of
// N" + Next added up to more than booruCol.width (which
// happened often enough — "of N" varies in width with
// page count, and it was already close to the edge) the
// Next button rendered past the flyout's right edge,
// off the visible screen. Flow wraps overflow onto a
// second line instead of spilling past the edge.
Flow {
visible: !booruCol.searching && (booruCol.page > 1 || booruCol.hasNextPage)
width: booruCol.width
spacing: 8

View file

@ -76,7 +76,19 @@ PanelWindow {
delegate: IconImage {
id: trayIcon
implicitSize: 18
source: Quickshell.iconPath(modelData.icon, "")
// Only resolve through the icon theme when this is
// actually a themed icon name (e.g. Steam's
// "steam_tray_mono"). Apps that only ever supply a raw
// IconPixmap over the SNI protocol and no IconName at
// all (confirmed via busctl: Vesktop's tray item has no
// IconName property) get an already-usable image:// URL
// back from modelData.icon instead — running that
// through iconPath(), a name/path resolver, mangled it
// into nothing, which is what rendered as a broken-
// texture checkerboard instead of the actual icon.
source: modelData.icon.includes("://")
? modelData.icon
: Quickshell.iconPath(modelData.icon, "")
MouseArea {
anchors.fill: parent
hoverEnabled: true