diff --git a/blueman/gui/manager/ManagerProgressbar.py b/blueman/gui/manager/ManagerProgressbar.py index c57e37f2f..9433ad178 100644 --- a/blueman/gui/manager/ManagerProgressbar.py +++ b/blueman/gui/manager/ManagerProgressbar.py @@ -61,7 +61,7 @@ def __init__(self, blueman: "Blueman", cancellable: bool = True, text: str = _(" self.show() if not self.cancellable: - self.eventbox.props.sensitive = False + self.eventbox.set_visible(False) self.pulsing = False self.finalized = False diff --git a/blueman/gui/manager/ManagerToolbar.py b/blueman/gui/manager/ManagerToolbar.py index 9ecb4b6a7..34771d8c6 100644 --- a/blueman/gui/manager/ManagerToolbar.py +++ b/blueman/gui/manager/ManagerToolbar.py @@ -1,6 +1,6 @@ from gettext import gettext as _ import logging -from typing import TYPE_CHECKING, Callable, Tuple, Optional +from typing import TYPE_CHECKING, Callable, Tuple, Optional, Union import gi @@ -24,8 +24,8 @@ def __init__(self, blueman: "Blueman") -> None: self.blueman.List.connect("adapter-changed", self.on_adapter_changed) self.blueman.List.connect("adapter-property-changed", self.on_adapter_property_changed) - self.b_search = blueman.builder.get_widget("b_search", Gtk.ToolButton) - self.b_search.connect("clicked", lambda button: blueman.inquiry()) + self.b_search = blueman.builder.get_widget("b_search", Gtk.ToggleToolButton) + self.b_search.connect("toggled", self.on_search_toggled) self.b_bond = blueman.builder.get_widget("b_bond", Gtk.ToolButton) self.b_bond.connect("clicked", self.on_action, self.blueman.bond) @@ -56,14 +56,45 @@ def on_action(self, _button: Gtk.ToolButton, func: Callable[[Device], None]) -> if device is not None: func(device) + def _update_search_toggle(self, button: Gtk.ToggleToolButton, searching: bool) -> None: + icon_widget: Union[Gtk.Image, Gtk.Spinner] + if searching: + icon_widget = Gtk.Spinner(visible=True) + icon_widget.start() + label = _("Searching") + tooltip = _("Click to stop searching") + else: + icon_widget = Gtk.Image(icon_name="edit-find-symbolic", icon_size=Gtk.IconSize.LARGE_TOOLBAR, visible=True) + label = _("Search") + tooltip = _("Search for nearby devices") + + button.set_active(searching) + button.set_icon_widget(icon_widget) + button.set_label(label) + button.set_tooltip_text(tooltip) + + def on_search_toggled(self, button: Gtk.ToggleToolButton) -> None: + if not self.blueman.List.discovering and button.get_active(): + self.blueman.inquiry() + self._update_search_toggle(button, True) + elif self.blueman.List.discovering: + self.blueman.List.stop_discovery() + self._update_search_toggle(button, False) + def on_adapter_property_changed(self, _lst: ManagerDeviceList, _adapter: Adapter, key_value: Tuple[str, object]) -> None: key, value = key_value if key == "Discovering": - if value: - self.b_search.props.sensitive = False - else: - self.b_search.props.sensitive = True + if value and not self.blueman.List.discovering: + # It's not blueman discovering + self.b_search.set_sensitive(False) + elif not value: + self.b_search.set_sensitive(True) + + # Block or we end in an infinite loop + self.b_search.handler_block_by_func(self.on_search_toggled) + self._update_search_toggle(self.b_search, True if value else False) + self.b_search.handler_unblock_by_func(self.on_search_toggled) def on_adapter_changed(self, _lst: ManagerDeviceList, adapter_path: Optional[str]) -> None: logging.debug(f"toolbar adapter {adapter_path}") diff --git a/blueman/main/Manager.py b/blueman/main/Manager.py index c74ccef7c..2af16cd2f 100644 --- a/blueman/main/Manager.py +++ b/blueman/main/Manager.py @@ -200,8 +200,7 @@ def on_progress(_lst: ManagerDeviceList, frac: float) -> None: else: prog.fraction(frac) - prog = ManagerProgressbar(self, text=_("Searching")) - prog.connect("cancelled", lambda x: self.List.stop_discovery()) + prog = ManagerProgressbar(self, text=_("Searching"), cancellable=False) def on_error(e: Exception) -> None: prog.finalize() diff --git a/data/ui/manager-main.ui b/data/ui/manager-main.ui index 58aeeced7..e5e67e241 100644 --- a/data/ui/manager-main.ui +++ b/data/ui/manager-main.ui @@ -2,6 +2,12 @@ + + True + False + edit-find-symbolic + 3 + True False @@ -289,14 +295,14 @@ True False - + True False False Search for nearby devices True - Search - edit-find-symbolic + Search + discover_widget False diff --git a/stubs/gi/repository/GObject.pyi b/stubs/gi/repository/GObject.pyi index 67e0f597c..3c4712284 100644 --- a/stubs/gi/repository/GObject.pyi +++ b/stubs/gi/repository/GObject.pyi @@ -131,10 +131,14 @@ class Object(): def handler_block(self, handler_id: builtins.int) -> None: ... + def handler_block_by_func(self, handlerr: function) -> None: ... + def handler_is_connected(self, handler_id: int) -> bool: ... def handler_unblock(self, handler_id: builtins.int) -> None: ... + def handler_unblock_by_func(self, handler: function) -> None: ... + @staticmethod def interface_find_property(g_iface: TypeInterface, property_name: builtins.str) -> ParamSpec: ... diff --git a/stubs/gi/repository/Gtk.pyi b/stubs/gi/repository/Gtk.pyi index 55ddf8e3f..d39a9d745 100644 --- a/stubs/gi/repository/Gtk.pyi +++ b/stubs/gi/repository/Gtk.pyi @@ -7052,6 +7052,7 @@ class Image(Misc): def __init__(self, *, icon_name: typing.Optional[str] = None, + icon_size: typing.Optional[int] = 4, pixel_size: int = -1, # Widget halign: Align = Align.FILL,