diff --git a/sims/modules/launcher/base.py b/sims/modules/launcher/base.py index 24ff73c..e13fa5e 100644 --- a/sims/modules/launcher/base.py +++ b/sims/modules/launcher/base.py @@ -7,6 +7,8 @@ from fabric.widgets.label import Label from fabric.widgets.wayland import WaylandWindow as Window from gi.repository import Gdk, Gtk +from sims.services.fenster import focused_output_index + class LauncherProvider(Protocol): def items(self) -> list[Any]: ... @@ -118,6 +120,7 @@ class FuzzyMenu(Window): self._selected_index = 0 self._scroll_offset = 0 self._refresh_viewport("") + self.monitor = focused_output_index() super().show() self.search_entry.grab_focus() diff --git a/sims/services/fenster.py b/sims/services/fenster.py index 3d62c5f..9d16683 100644 --- a/sims/services/fenster.py +++ b/sims/services/fenster.py @@ -5,7 +5,7 @@ Provides a singleton I3 connection configured for Fenster's SWAYSOCK. """ import os -from sims.services.i3 import I3 +from sims.services.i3 import I3, I3MessageType _connection: I3 | None = None @@ -27,3 +27,29 @@ def get_i3_connection() -> I3: I3.SOCKET_PATH = fallback _connection = I3() return _connection + + +def focused_output_index() -> int: + """Index of the currently focused output in active GET_OUTPUTS order. + + Matches the indexing main.spawn_bars uses for `monitor=` so layer-shell + windows opened with the same index land on the focused output. Returns 0 + on any IPC failure or if the focused output cannot be located. + """ + ws_reply = I3.send_command("", I3MessageType.GET_WORKSPACES) + if not (ws_reply.is_ok and isinstance(ws_reply.reply, list)): + return 0 + focused_output = next( + (ws.get("output") for ws in ws_reply.reply if ws.get("focused")), + None, + ) + if not focused_output: + return 0 + out_reply = I3.send_command("", I3MessageType.GET_OUTPUTS) + if not (out_reply.is_ok and isinstance(out_reply.reply, list)): + return 0 + active = [o for o in out_reply.reply if o.get("active")] + for i, o in enumerate(active): + if o.get("name") == focused_output: + return i + return 0