Fix image selector IPC reloads

This commit is contained in:
David Heinemeier Hansson
2026-06-24 13:49:22 +02:00
parent c43afa52ac
commit 89abbddc77
4 changed files with 86 additions and 43 deletions
+7 -2
View File
@@ -233,14 +233,19 @@ if [[ $preload == true ]]; then
exit 0
fi
if ! omarchy-shell image-selector open \
if ! open_result=$(omarchy-shell image-selector open \
"" \
"$rows_b64" \
"$selected_list_image" \
"$selection_file" \
"$done_file" \
"$show_labels" \
"$filterable" >/dev/null; then
"$filterable"); then
echo "Image selector failed to accept request" >&2
exit 1
fi
if [[ $open_result != "ok" ]]; then
echo "Image selector failed to accept request" >&2
exit 1
fi
+2 -41
View File
@@ -302,9 +302,8 @@ Item {
// Lifecycle hooks invoked by omarchy-shell summon/hide. shell.summon(id,
// payloadJson) hands the JSON to open() here; shell.hide(id) calls close().
// External CLI callers can either go through `shell summon omarchy.image-
// picker` (JSON payload), or hit the dedicated `image-selector` IpcHandler
// below for the lower-level positional call that omarchy-menu-images uses.
// The shell host owns the stable `image-selector` IPC target and forwards
// those lower-level positional calls here.
function open(payload) {
var args = {}
if (payload) {
@@ -347,44 +346,6 @@ Item {
}
}
// IPC surface. All arguments are strings (Quickshell IPC marshalling).
// imageRows can contain newlines/tabs, so the CLI caller base64-encodes
// it; everything else passes through verbatim. The two boolean-like
// fields use the literal strings "true" or "false".
IpcHandler {
target: "image-selector"
function open(imageDirs: string,
imageRowsB64: string,
selectedImage: string,
selectionFile: string,
doneFile: string,
showLabels: string,
filterable: string): string {
var rows = Util.decodeBase64(imageRowsB64)
root.openSelector(imageDirs, rows, selectedImage, selectionFile, doneFile,
showLabels, filterable)
return "ok"
}
function preload(imageRowsB64: string,
selectedImage: string,
showLabels: string,
filterable: string): string {
var rows = Util.decodeBase64(imageRowsB64)
root.preloadRows(rows, selectedImage, showLabels, filterable)
return "ok"
}
function cancel(doneFile: string): void {
root.closeSelector(doneFile || "")
}
function ping(): string {
return "ok"
}
}
Process {
id: applyProc
onExited: {
+56
View File
@@ -752,6 +752,62 @@ ShellRoot {
}
}
// --------------------------------------------------- image selector IPC
function imagePickerItem() {
var loader = panelLoaders["omarchy.image-picker"]
return loader && loader.item ? loader.item : null
}
IpcHandler {
target: "image-selector"
function open(imageDirs: string,
imageRowsB64: string,
selectedImage: string,
selectionFile: string,
doneFile: string,
showLabels: string,
filterable: string): string {
var payload = JSON.stringify({
imageDirs: imageDirs,
imageRows: Util.decodeBase64(imageRowsB64),
selectedImage: selectedImage,
selectionFile: selectionFile,
doneFile: doneFile,
showLabels: showLabels,
filterable: filterable
})
return shell.summon("omarchy.image-picker", payload) ? "ok" : "unknown"
}
function preload(imageRowsB64: string,
selectedImage: string,
showLabels: string,
filterable: string): string {
var picker = shell.imagePickerItem()
if (picker && typeof picker.preloadRows === "function") {
picker.preloadRows(Util.decodeBase64(imageRowsB64), selectedImage,
showLabels, filterable)
}
return "ok"
}
function cancel(doneFile: string): string {
var picker = shell.imagePickerItem()
if (picker && typeof picker.closeSelector === "function") {
picker.closeSelector(doneFile || "")
} else {
shell.hide("omarchy.image-picker")
}
return "ok"
}
function ping(): string {
return "ok"
}
}
// ---------------------------------------------------------- shell IPC
IpcHandler {
+21
View File
@@ -134,6 +134,27 @@ jq -e '.locked | type == "boolean"' <<<"$(shell_ipc lock status)" >/dev/null ||
[[ $(shell_ipc osd close) == "ok" ]] || fail_with_log "OSD IPC closes"
pass "plugin IPC contracts respond"
shell_ipc_quiet shell rescanPlugins >/dev/null
selector_rows_b64=$(printf '%s\t%s' "$TMPDIR/selector.png" "$TMPDIR/selector.png" | base64 -w 0)
selector_selection_file=$(mktemp "$TMPDIR/selector-selection.XXXXXX")
selector_done_file=$(mktemp "$TMPDIR/selector-done.XXXXXX")
rm -f "$selector_done_file"
selector_open=""
for _ in {1..80}; do
selector_open=$(shell_ipc image-selector open "" "$selector_rows_b64" "" "$selector_selection_file" "$selector_done_file" false false 2>/dev/null || true)
if [[ $selector_open == "ok" ]]; then
break
fi
if ! kill -0 "$QS_PID" 2>/dev/null; then
fail_with_log "test shell exited during plugin rescan"
fi
sleep 0.1
done
[[ $selector_open == "ok" ]] || fail_with_log "image selector IPC survives plugin rescan"
shell_ipc_quiet image-selector cancel "$selector_done_file" >/dev/null
rm -f "$selector_selection_file" "$selector_done_file"
pass "image selector IPC survives plugin rescan"
shell_ipc_quiet omarchy.system-update refresh >/dev/null 2>&1 || true
sleep 0.8