From c922384cf65c4ea3791375cc6131817aa5baac34 Mon Sep 17 00:00:00 2001 From: Ricardo Matsui Date: Mon, 24 Aug 2026 19:45:54 -0700 Subject: [PATCH 1/2] ManagerDeviceList: Expand connect/disconnect to more input methods Handle row-activated instead of two button press to support touchscreen double tap and Enter/Space in addition to double click. --- blueman/gui/manager/ManagerDeviceList.py | 39 +++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/blueman/gui/manager/ManagerDeviceList.py b/blueman/gui/manager/ManagerDeviceList.py index 2514a6ec6..de3002c0f 100644 --- a/blueman/gui/manager/ManagerDeviceList.py +++ b/blueman/gui/manager/ManagerDeviceList.py @@ -100,6 +100,7 @@ def __init__(self, inst: "Blueman", adapter: str | None = None) -> None: self.connect("popup-menu", self._on_popup_menu) self.connect("button-press-event", self._on_event_clicked) self.connect("button-release-event", self._on_event_clicked) + self.connect("row-activated", self._on_row_activated) self.connect("key-press-event", self._on_key_pressed) self.menu: ManagerDeviceMenu | None = None @@ -218,8 +219,30 @@ def _on_popup_menu(self, _widget: Gtk.Widget) -> bool: return True + def _row_at_path(self, path: Gtk.TreePath) -> dict[str, Any] | None: + tree_iter = self.filter.get_iter(path) + assert tree_iter is not None + child_iter = self.filter.convert_iter_to_child_iter(tree_iter) + assert child_iter is not None + row = self.get(child_iter, "device", "connected") + return row if row else None + + def _on_row_activated(self, _widget: Gtk.Widget, path: Gtk.TreePath, _column: Gtk.TreeViewColumn) -> None: + row = self._row_at_path(path) + if row is None: + return + + if self.menu is None: + self.menu = ManagerDeviceMenu(self.Blueman) + + if self.menu.show_generic_connect_calc(row["device"]['UUIDs']): + if row["connected"]: + self.menu.disconnect_service(row["device"]) + elif Adapter(obj_path=row["device"]["Adapter"])["Powered"]: + self.menu.connect_service(row["device"]) + def _on_event_clicked(self, _widget: Gtk.Widget, event: Gdk.Event) -> bool: - if event.type not in (Gdk.EventType._2BUTTON_PRESS, Gdk.EventType.BUTTON_PRESS): + if event.type != Gdk.EventType.BUTTON_PRESS: return False posdata = self.get_path_at_pos(int(cast(Gdk.EventButton, event).x), int(cast(Gdk.EventButton, event).y)) @@ -229,24 +252,12 @@ def _on_event_clicked(self, _widget: Gtk.Widget, event: Gdk.Event) -> bool: path = posdata[0] assert path is not None - tree_iter = self.filter.get_iter(path) - assert tree_iter is not None - child_iter = self.filter.convert_iter_to_child_iter(tree_iter) - assert child_iter is not None - row = self.get(child_iter, "device", "connected") - if not row: + if not self._row_at_path(path): return False if self.menu is None: self.menu = ManagerDeviceMenu(self.Blueman) - if event.type == Gdk.EventType._2BUTTON_PRESS and cast(Gdk.EventButton, event).button == 1: - if self.menu.show_generic_connect_calc(row["device"]['UUIDs']): - if row["connected"]: - self.menu.disconnect_service(row["device"]) - elif Adapter(obj_path=row["device"]["Adapter"])["Powered"]: - self.menu.connect_service(row["device"]) - if event.type == Gdk.EventType.BUTTON_PRESS and cast(Gdk.EventButton, event).button == 3: self.menu.popup_at_pointer(event) From c0398ba085e32e20c99019ea3b4ac12e6123265e Mon Sep 17 00:00:00 2001 From: Ricardo Matsui Date: Tue, 25 Aug 2026 18:11:15 -0700 Subject: [PATCH 2/2] ManagerDeviceList: Variable cleanup Rename the tree path variables introduced in the previous commit from "path" to "tree_path" for clarity, and the helper to _row_at_tree_path to match. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01T3w3t2L3XJWRziaAYLgdd9 --- blueman/gui/manager/ManagerDeviceList.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/blueman/gui/manager/ManagerDeviceList.py b/blueman/gui/manager/ManagerDeviceList.py index de3002c0f..d81d6665e 100644 --- a/blueman/gui/manager/ManagerDeviceList.py +++ b/blueman/gui/manager/ManagerDeviceList.py @@ -219,16 +219,16 @@ def _on_popup_menu(self, _widget: Gtk.Widget) -> bool: return True - def _row_at_path(self, path: Gtk.TreePath) -> dict[str, Any] | None: - tree_iter = self.filter.get_iter(path) + def _row_at_tree_path(self, tree_path: Gtk.TreePath) -> dict[str, Any] | None: + tree_iter = self.filter.get_iter(tree_path) assert tree_iter is not None child_iter = self.filter.convert_iter_to_child_iter(tree_iter) assert child_iter is not None row = self.get(child_iter, "device", "connected") return row if row else None - def _on_row_activated(self, _widget: Gtk.Widget, path: Gtk.TreePath, _column: Gtk.TreeViewColumn) -> None: - row = self._row_at_path(path) + def _on_row_activated(self, _widget: Gtk.Widget, tree_path: Gtk.TreePath, _column: Gtk.TreeViewColumn) -> None: + row = self._row_at_tree_path(tree_path) if row is None: return @@ -249,10 +249,10 @@ def _on_event_clicked(self, _widget: Gtk.Widget, event: Gdk.Event) -> bool: if posdata is None: return False else: - path = posdata[0] - assert path is not None + tree_path = posdata[0] + assert tree_path is not None - if not self._row_at_path(path): + if not self._row_at_tree_path(tree_path): return False if self.menu is None: