Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare for 2.4.4 #2515

Open
wants to merge 7 commits into
base: 2-4-stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
* Fix Rfcom plugin dbus signature
* Set an initial selected device in blueman-sendto
* AutoConnect: Store bluetooth address instead of object path
* Applet: Handle UnknownObject DBus error (@tommie)
* Make search button available after device list becomes empty (@astcri)

### Changes
* Terminate applet on manager termination if it was started by manager
* Add Galic and Esperanto translations
* AutoConnect: Automatically convert path to address
* Add toggle to force symbolic statusicon

## 2.4.3

Expand Down
5 changes: 5 additions & 0 deletions blueman/bluez/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ class DBusUnsupportedMajorClassError(BluezDBusException):
pass


class DBusUnknownObjectError(BluezDBusException):
pass


class DBusServiceUnknownError(BluezDBusException):
pass

Expand Down Expand Up @@ -121,6 +125,7 @@ class BluezUnavailableAgentMethodError(BluezDBusException):
'org.bluez.Error.AuthenticationCanceled': DBusAuthenticationCanceledError,
'org.bluez.serial.Error.NotSupported': DBusNotSupportedError,
'org.bluez.Error.UnsupportedMajorClass': DBusUnsupportedMajorClassError,
'org.freedesktop.DBus.Error.UnknownObject': DBusUnknownObjectError,
'org.freedesktop.DBus.Error.ServiceUnknown': DBusServiceUnknownError}


Expand Down
2 changes: 1 addition & 1 deletion blueman/gui/manager/ManagerToolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def on_device_selected(
device: Optional[Device],
_tree_iter: Gtk.TreeIter,
) -> None:
self._update_buttons(None if device is None else Adapter(obj_path=device["Adapter"]))
self._update_buttons(dev_list.Adapter)

def _update_buttons(self, adapter: Optional[Adapter]) -> None:
powered = adapter is not None and adapter["Powered"]
Expand Down
5 changes: 5 additions & 0 deletions blueman/main/Applet.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ def do_quit(_: object) -> bool:

def do_startup(self) -> None:
Gtk.Application.do_startup(self)

quit_action = Gio.SimpleAction.new("Quit", None)
quit_action.connect("activate", lambda _action, _param: self.quit())
self.add_action(quit_action)

self.set_accels_for_action("win.close", ["<Ctrl>w", "Escape"])

def do_activate(self) -> None:
Expand Down
19 changes: 18 additions & 1 deletion blueman/main/DBusProxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,35 @@ def call_finish(proxy: ProxyBase, response: Gio.AsyncResult) -> None:
self.call(name, params, Gio.DBusCallFlags.NONE, -1, None, call_finish)


class DBus(ProxyBase):
def __init__(self) -> None:
super().__init__(name="org.freedesktop.DBus", interface_name="org.freedesktop.DBus",
object_path="/org/freedesktop/DBus")


class Mechanism(ProxyBase):
def __init__(self) -> None:
super().__init__(name='org.blueman.Mechanism', interface_name='org.blueman.Mechanism',
object_path="/org/blueman/mechanism", systembus=True)


class AppletService(ProxyBase):
NAME = "org.blueman.Applet"

def __init__(self) -> None:
super().__init__(name='org.blueman.Applet', interface_name='org.blueman.Applet',
super().__init__(name=self.NAME, interface_name='org.blueman.Applet',
object_path="/org/blueman/Applet")


class AppletServiceApplication(ProxyBase):
def __init__(self) -> None:
super().__init__(name=AppletService.NAME, interface_name="org.freedesktop.Application",
object_path="/org/blueman/Applet")

def stop(self) -> None:
self.ActivateAction('(sava{sv})', "Quit", [], {})


class ManagerService(ProxyBase):
def __init__(self) -> None:
super().__init__(name="org.blueman.Manager", interface_name="org.freedesktop.Application",
Expand Down
9 changes: 8 additions & 1 deletion blueman/main/Manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from blueman.gui.manager.ManagerStats import ManagerStats
from blueman.gui.manager.ManagerProgressbar import ManagerProgressbar
from blueman.main.Builder import Builder
from blueman.main.DBusProxies import AppletService, DBusProxyFailed
from blueman.main.DBusProxies import AppletService, DBusProxyFailed, DBus, AppletServiceApplication
from blueman.gui.CommonUi import ErrorDialog
from blueman.gui.Notification import Notification
from blueman.main.PluginManager import PluginManager
Expand All @@ -29,6 +29,7 @@
class Blueman(Gtk.Application):
def __init__(self) -> None:
super().__init__(application_id="org.blueman.Manager")
self._applet_was_running = DBus().NameHasOwner("(s)", AppletService.NAME)

def do_quit(_: object) -> bool:
self.quit()
Expand Down Expand Up @@ -60,6 +61,12 @@ def doquit(_a: Gio.SimpleAction, _param: None) -> None:
bt_status_action.connect("change-state", self._on_bt_state_changed)
self.add_action(bt_status_action)

def do_shutdown(self) -> None:
Gtk.Application.do_shutdown(self)

if not self._applet_was_running:
AppletServiceApplication().stop()

def do_activate(self) -> None:
if not self.window:
self.window = self.builder.get_widget("manager_window", Gtk.ApplicationWindow)
Expand Down
6 changes: 3 additions & 3 deletions blueman/plugins/BasePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class BasePlugin:

def __init__(self, *_args: object) -> None:
if self.__options__:
self.__config = Gio.Settings(
self._config = Gio.Settings(
schema_id=self.__class__.__gsettings__["schema"],
path=self.__class__.__gsettings__["path"]
)
Expand Down Expand Up @@ -99,15 +99,15 @@ def on_delete(self) -> None:
def get_option(self, key: str) -> Any:
if key not in self.__class__.__options__:
raise KeyError("No such option")
return self.__config[key]
return self._config[key]

def set_option(self, key: str, value: Any) -> None:
if key not in self.__class__.__options__:
raise KeyError("No such option")
opt = self.__class__.__options__[key]

if type(value) is opt["type"]:
self.__config[key] = value
self._config[key] = value
self.option_changed(key, value)
else:
raise TypeError(f"Wrong type, must be {repr(opt['type'])}")
Expand Down
8 changes: 6 additions & 2 deletions blueman/plugins/applet/RecentConns.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import List, TYPE_CHECKING, Optional, Callable, cast, Union

from blueman.bluez.Device import Device
from blueman.bluez.errors import DBusNoSuchAdapterError
from blueman.bluez.errors import DBusNoSuchAdapterError, DBusUnknownObjectError
from blueman.gui.Notification import Notification
from blueman.Sdp import ServiceUUID
from blueman.plugins.AppletPlugin import AppletPlugin
Expand Down Expand Up @@ -199,7 +199,11 @@ def _get_device_path(self, adapter_path: str, address: str) -> Optional[str]:
except DBusNoSuchAdapterError:
return None

device = self.parent.Manager.find_device(address, adapter.get_object_path())
try:
device = self.parent.Manager.find_device(address, adapter.get_object_path())
except DBusUnknownObjectError:
return None

return device.get_object_path() if device is not None else None

def _get_items(self) -> List["Item"]:
Expand Down
19 changes: 15 additions & 4 deletions blueman/plugins/applet/StatusIcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ class StatusIcon(AppletPlugin, GObject.GObject):
__icon__ = "bluetooth-symbolic"
__depends__ = ["StandardItems", "Menu"]

__gsettings__ = {
"schema": "org.blueman.general",
"path": None
}
__options__ = {
"symbolic-status-icons": {
"type": bool,
"default": False,
"name": _("Force symbolic status icons"),
"desc": _("When enabled this will force the use of a symbolic version of the blueman statusicon"),
}
}

visible = None

visibility_timeout: Optional[int] = None
Expand All @@ -38,9 +51,7 @@ def on_load(self) -> None:
self._tooltip_title = _("Bluetooth Enabled")
self._tooltip_text = ""

self.general_config = Gio.Settings(schema_id="org.blueman.general")
self.general_config.connect("changed::symbolic-status-icons", self.on_symbolic_config_change)

self._config.connect("changed::symbolic-status-icons", self.on_symbolic_config_change)
self.query_visibility(emit=False)

self.parent.Plugins.connect('plugin-loaded', self._on_plugins_changed)
Expand Down Expand Up @@ -133,7 +144,7 @@ def _get_icon_name(self) -> str:

# depending on configuration, ensure fullcolor icons..
name = name.replace("-symbolic", "")
if self.general_config.get_boolean("symbolic-status-icons"):
if self.get_option("symbolic-status-icons"):
# or symbolic
name = f"{name}-symbolic"

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
AC_PREREQ(2.61)

AC_INIT([blueman], [2.4.3], [https://github.com/blueman-project/blueman/issues])
AC_INIT([blueman], [2.4.4], [https://github.com/blueman-project/blueman/issues])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_MACRO_DIRS([m4])
AM_INIT_AUTOMAKE([1.16.3 foreign dist-xz])
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(
'blueman', 'c',
version: '2.4.3',
version: '2.4.4',
license: 'GPL3',
meson_version: '>=0.56.0',
default_options: 'b_lundef=false'
Expand Down