Fix unreliable run dialogue history entries

This commit is contained in:
Storm Dragon committed 2026-09-27 16:55:56 -04:00
1 parent 1d20d95b26
commit 6bd3b13284
1 file changed
+48 -8
+48 -8
View File
@@ -87,16 +87,17 @@ def read_history():
def write_history(entry, items):
entry = entry.strip()
if not entry:
return
return items[:MAX_HISTORY_ENTRIES]
updated_items = [entry]
updated_items.extend(item for item in items if item != entry)
return updated_items[:MAX_HISTORY_ENTRIES]
def save_history(items):
path = history_path()
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
"\n".join(updated_items[:MAX_HISTORY_ENTRIES]) + "\n",
encoding="utf-8",
)
path.write_text("\n".join(items[:MAX_HISTORY_ENTRIES]) + "\n", encoding="utf-8")
def path_commands():
@@ -167,9 +168,11 @@ def application_results(query, applications):
for app in applications:
name = app.get_display_name() or app.get_name()
executable = app.get_executable() or ""
if not executable:
continue
if not matches(query, name) and not matches(query, executable):
continue
results.append(Result("application", name, f"Application: {executable}", name, app.get_id() or ""))
results.append(Result("application", name, f"Application: {executable}", executable, app.get_id() or ""))
return sorted(results, key=lambda item: item.label.casefold())
@@ -390,8 +393,23 @@ class RunDialog(Gtk.Window):
self.entry.set_text(result.value)
self.entry.set_position(-1)
def remember_history(self, entry):
entry = entry.strip()
if not entry:
return
self.history = write_history(entry, self.history)
save_history(self.history)
def forget_history(self, entry):
entry = entry.strip()
if entry not in self.history:
return
self.history.remove(entry)
save_history(self.history)
def activate(self, result=None):
if result is not None and result.kind == "directory":
self.remember_history(result.value)
self.entry.set_text(result.value)
self.entry.set_position(-1)
return
@@ -400,7 +418,6 @@ class RunDialog(Gtk.Window):
if not text:
return
write_history(text, self.history)
if result is not None and result.kind == "application":
self.launch_application(result)
return
@@ -412,10 +429,16 @@ class RunDialog(Gtk.Window):
self.show_error(f"Application is no longer available: {result.label}")
return
try:
app.launch([], None)
launched = app.launch([], None)
except GLib.Error as error:
self.forget_history(result.value)
self.show_error(f"Could not open {result.label}.\n\n{error.message}")
return
if not launched:
self.forget_history(result.value)
self.show_error(f"Could not open {result.label}.")
return
self.remember_history(result.value)
self.close()
def launch_raw(self, text):
@@ -467,12 +490,15 @@ class RunDialog(Gtk.Window):
def check_process(self, process, description):
status = process.poll()
if status is None:
self.remember_history(description)
Gtk.main_quit()
return False
if status == 0:
self.remember_history(description)
Gtk.main_quit()
return False
self.forget_history(description)
self.show_all()
self.entry.grab_focus()
self.show_error(
@@ -547,6 +573,19 @@ class RunDialog(Gtk.Window):
def run_self_test():
class FakeApplication:
def get_display_name(self):
return "Mozilla Firefox"
def get_name(self):
return "Mozilla Firefox"
def get_executable(self):
return "/usr/lib/firefox/firefox"
def get_id(self):
return "firefox.desktop"
test_dir = Path(os.environ["I38_RUN_DIALOG_TEST_DIR"])
(test_dir / "folder").mkdir(parents=True)
(test_dir / "tool").write_text("#!/bin/sh\n", encoding="utf-8")
@@ -560,6 +599,7 @@ def run_self_test():
assert raw_target_kind("man://bash") == "manual"
assert raw_target_kind(str(test_dir / "note.txt")) == "path"
assert raw_target_kind('python3 "/tmp/file with spaces.py"') == "command"
assert application_results("firef", [FakeApplication()])[0].value == "/usr/lib/firefox/firefox"
assert merge_results(
[Result("history", "firefox", "History", "firefox")],
[Result("command", "firefox", "Command", "firefox")],