diff --git a/.gitignore b/.gitignore index 18c3585..e58b4c7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /blueman-2.1.alpha2.tar.xz /blueman-2.1.alpha3.tar.xz /blueman-2.1.beta1.tar.gz +/blueman-2.1.tar.gz diff --git a/blueman-PR-1030.patch b/blueman-PR-1030.patch deleted file mode 100644 index 1df67d5..0000000 --- a/blueman-PR-1030.patch +++ /dev/null @@ -1,1025 +0,0 @@ -From bfcec02fbc07f5c0308f372fd1490da553e6b2c4 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 11:31:52 +0200 -Subject: [PATCH 01/13] Drop arguments to super() for python2 - -We are python3 only and We dropped a them in some places already ---- - blueman/bluez/AnyBase.py | 2 +- - blueman/bluez/Base.py | 2 +- - blueman/bluez/Device.py | 2 +- - blueman/gui/CommonUi.py | 4 ++-- - blueman/gui/DeviceList.py | 3 ++- - blueman/gui/DeviceSelectorList.py | 2 +- - blueman/gui/DeviceSelectorWidget.py | 6 +++--- - blueman/gui/GenericList.py | 2 +- - blueman/gui/GsmSettings.py | 2 +- - blueman/gui/GtkAnimation.py | 10 +++++----- - blueman/gui/MessageArea.py | 4 ++-- - blueman/gui/Notification.py | 8 ++++---- - blueman/gui/manager/ManagerDeviceList.py | 4 ++-- - blueman/gui/manager/ManagerDeviceMenu.py | 2 +- - blueman/gui/manager/ManagerProgressbar.py | 2 +- - blueman/main/Config.py | 4 ++-- - blueman/main/DhcpClient.py | 2 +- - blueman/main/Manager.py | 2 +- - blueman/main/PPPConnection.py | 2 +- - blueman/main/PluginManager.py | 4 ++-- - blueman/main/PulseAudioUtils.py | 2 +- - blueman/plugins/AppletPlugin.py | 6 +++--- - blueman/plugins/applet/NetUsage.py | 4 ++-- - blueman/services/meta/NetworkService.py | 2 +- - blueman/services/meta/SerialService.py | 2 +- - 25 files changed, 43 insertions(+), 42 deletions(-) - -diff --git a/blueman/bluez/AnyBase.py b/blueman/bluez/AnyBase.py -index 78e6f8f8..5d282847 100644 ---- a/blueman/bluez/AnyBase.py -+++ b/blueman/bluez/AnyBase.py -@@ -16,7 +16,7 @@ class AnyBase(GObject.GObject): - __bus_interface_name = 'org.freedesktop.DBus.Properties' - - def __init__(self, interface_name): -- super(AnyBase, self).__init__() -+ super().__init__() - - self.__interface_name = interface_name - self.__signal = None -diff --git a/blueman/bluez/Base.py b/blueman/bluez/Base.py -index 1fba4bfb..c16e3941 100644 ---- a/blueman/bluez/Base.py -+++ b/blueman/bluez/Base.py -@@ -53,7 +53,7 @@ class Base(Gio.DBusProxy, metaclass=BaseMeta): - } - - def __init__(self, interface_name, obj_path, *args, **kwargs): -- super(Base, self).__init__( -+ super().__init__( - g_name=self.__name, - g_interface_name=interface_name, - g_object_path=obj_path, -diff --git a/blueman/bluez/Device.py b/blueman/bluez/Device.py -index 30a9c902..e56b047c 100644 ---- a/blueman/bluez/Device.py -+++ b/blueman/bluez/Device.py -@@ -21,4 +21,4 @@ def disconnect(self, reply_handler=None, error_handler=None): - - class AnyDevice(AnyBase): - def __init__(self): -- super(AnyDevice, self).__init__('org.bluez.Device1') -+ super().__init__('org.bluez.Device1') -diff --git a/blueman/gui/CommonUi.py b/blueman/gui/CommonUi.py -index 8882a2bf..95f11f18 100644 ---- a/blueman/gui/CommonUi.py -+++ b/blueman/gui/CommonUi.py -@@ -10,8 +10,8 @@ - class ErrorDialog(Gtk.MessageDialog): - def __init__(self, markup, secondary_markup=None, excp=None, icon_name="dialog-error", - buttons=Gtk.ButtonsType.CLOSE, **kwargs): -- super(ErrorDialog, self).__init__(name="ErrorDialog", icon_name=icon_name, buttons=buttons, -- type=Gtk.MessageType.ERROR, **kwargs) -+ super().__init__(name="ErrorDialog", icon_name=icon_name, buttons=buttons, -+ type=Gtk.MessageType.ERROR, **kwargs) - - self.set_markup(markup) - -diff --git a/blueman/gui/DeviceList.py b/blueman/gui/DeviceList.py -index 2b0672c3..3396d1e9 100644 ---- a/blueman/gui/DeviceList.py -+++ b/blueman/gui/DeviceList.py -@@ -41,6 +41,7 @@ class DeviceList(GenericList): - - def __del__(self): - logging.debug("deleting mainlist") -+ super().__del__() - - def __init__(self, adapter_name=None, tabledata=None, **kwargs): - if not tabledata: -@@ -98,7 +99,7 @@ def on_device_removed(_manager, path): - {"id": "timestamp", "type": float} - ] - -- super(DeviceList, self).__init__(data, **kwargs) -+ super().__init__(data, **kwargs) - self.set_name("DeviceList") - - self.set_adapter(adapter_name) -diff --git a/blueman/gui/DeviceSelectorList.py b/blueman/gui/DeviceSelectorList.py -index 90fc4a14..ae9260bb 100644 ---- a/blueman/gui/DeviceSelectorList.py -+++ b/blueman/gui/DeviceSelectorList.py -@@ -24,7 +24,7 @@ def __init__(self, adapter_name=None): - "render_attrs": {"icon_name": 3}} - ] - -- super(DeviceSelectorList, self).__init__(adapter_name, tabledata, headers_visible=False) -+ super().__init__(adapter_name, tabledata, headers_visible=False) - - def on_icon_theme_changed(self, widget): - for row in self.liststore: -diff --git a/blueman/gui/DeviceSelectorWidget.py b/blueman/gui/DeviceSelectorWidget.py -index f93f84ae..20a5b6e8 100644 ---- a/blueman/gui/DeviceSelectorWidget.py -+++ b/blueman/gui/DeviceSelectorWidget.py -@@ -12,9 +12,9 @@ - class DeviceSelectorWidget(Gtk.Box): - def __init__(self, adapter_name=None, orientation=Gtk.Orientation.VERTICAL, **kwargs): - -- super(DeviceSelectorWidget, self).__init__(orientation=orientation, spacing=1, vexpand=True, -- width_request=360, height_request=340, -- name="DeviceSelectorWidget", **kwargs) -+ super().__init__(orientation=orientation, spacing=1, vexpand=True, -+ width_request=360, height_request=340, -+ name="DeviceSelectorWidget", **kwargs) - - self.List = DeviceSelectorList(adapter_name) - if self.List.Adapter is not None: -diff --git a/blueman/gui/GenericList.py b/blueman/gui/GenericList.py -index bfc32f90..be007dcd 100644 ---- a/blueman/gui/GenericList.py -+++ b/blueman/gui/GenericList.py -@@ -7,7 +7,7 @@ - # noinspection PyAttributeOutsideInit - class GenericList(Gtk.TreeView): - def __init__(self, data, **kwargs): -- super(GenericList, self).__init__(**kwargs) -+ super().__init__(**kwargs) - self.set_name("GenericList") - self.selection = self.get_selection() - self._load(data) -diff --git a/blueman/gui/GsmSettings.py b/blueman/gui/GsmSettings.py -index 00a8c2c2..3926c5e0 100644 ---- a/blueman/gui/GsmSettings.py -+++ b/blueman/gui/GsmSettings.py -@@ -11,7 +11,7 @@ - - class GsmSettings(Gtk.Dialog): - def __init__(self, bd_address): -- super(GsmSettings, self).__init__() -+ super().__init__() - - self.set_name("GsmSettings") - self.device = bd_address -diff --git a/blueman/gui/GtkAnimation.py b/blueman/gui/GtkAnimation.py -index 7c0c8c40..6c4029cf 100644 ---- a/blueman/gui/GtkAnimation.py -+++ b/blueman/gui/GtkAnimation.py -@@ -31,7 +31,7 @@ class AnimBase(GObject.GObject): - } - - def __init__(self, state=1.0): -- super(AnimBase, self).__init__() -+ super().__init__() - self._source = None - self._state = state - self.frozen = False -@@ -118,7 +118,7 @@ def is_animating(self): - - class TreeRowFade(AnimBase): - def __init__(self, tw, path, columns=None): -- super(TreeRowFade, self).__init__(1.0) -+ super().__init__(1.0) - self.tw = tw - - self.sig = self.tw.connect_after("draw", self.on_draw) -@@ -169,7 +169,7 @@ def state_changed(self, state): - - class TreeRowColorFade(TreeRowFade): - def __init__(self, tw, path, color): -- super(TreeRowColorFade, self).__init__(tw, path, None) -+ super().__init__(tw, path, None) - - self.color = color - -@@ -203,7 +203,7 @@ def on_draw(self, widget, cr): - - class CellFade(AnimBase): - def __init__(self, tw, path, columns=None): -- super(CellFade, self).__init__(1.0) -+ super().__init__(1.0) - self.tw = tw - - self.frozen = False -@@ -266,7 +266,7 @@ def state_changed(self, state): - - class WidgetFade(AnimBase): - def __init__(self, widget, color): -- super(WidgetFade, self).__init__(1.0) -+ super().__init__(1.0) - - self.widget = widget - self.color = color -diff --git a/blueman/gui/MessageArea.py b/blueman/gui/MessageArea.py -index 79ac09be..93ad8843 100644 ---- a/blueman/gui/MessageArea.py -+++ b/blueman/gui/MessageArea.py -@@ -14,12 +14,12 @@ class MessageArea(Gtk.InfoBar): - - def __new__(cls): - if not MessageArea._inst_: -- MessageArea._inst_ = super(MessageArea, cls).__new__(cls) -+ MessageArea._inst_ = super().__new__(cls) - - return MessageArea._inst_ - - def __init__(self): -- super(MessageArea, self).__init__(show_close_button=True) -+ super().__init__(show_close_button=True) - - self.set_name("MessageArea") - -diff --git a/blueman/gui/Notification.py b/blueman/gui/Notification.py -index 6661a101..0f3bef1c 100644 ---- a/blueman/gui/Notification.py -+++ b/blueman/gui/Notification.py -@@ -16,7 +16,7 @@ - - class Fade(AnimBase): - def __init__(self, window): -- super(Fade, self).__init__(state=OPACITY_START) -+ super().__init__(state=OPACITY_START) - self.window = window - - def state_changed(self, state): -@@ -26,8 +26,8 @@ def state_changed(self, state): - class _NotificationDialog(Gtk.MessageDialog): - def __init__(self, summary, message, timeout=-1, actions=None, actions_cb=None, - icon_name=None, image_data=None): -- super(_NotificationDialog, self).__init__(parent=None, flags=0, type=Gtk.MessageType.QUESTION, -- buttons=Gtk.ButtonsType.NONE, message_format=None) -+ super().__init__(parent=None, flags=0, type=Gtk.MessageType.QUESTION, -+ buttons=Gtk.ButtonsType.NONE, message_format=None) - - self.set_name("NotificationDialog") - i = 100 -@@ -130,7 +130,7 @@ def set_icon_from_icon_name(self, icon_name, size): - class _NotificationBubble(Gio.DBusProxy): - def __init__(self, summary, message, timeout=-1, actions=None, actions_cb=None, - icon_name=None, image_data=None): -- super(_NotificationBubble, self).__init__( -+ super().__init__( - g_name='org.freedesktop.Notifications', - g_interface_name='org.freedesktop.Notifications', - g_object_path='/org/freedesktop/Notifications', -diff --git a/blueman/gui/manager/ManagerDeviceList.py b/blueman/gui/manager/ManagerDeviceList.py -index 8c206e20..a31b1d95 100644 ---- a/blueman/gui/manager/ManagerDeviceList.py -+++ b/blueman/gui/manager/ManagerDeviceList.py -@@ -54,7 +54,7 @@ def __init__(self, adapter=None, inst=None): - {"id": "levels_visible", "type": bool}, - {"id": "initial_anim", "type": bool}, - ] -- super(ManagerDeviceList, self).__init__(adapter, tabledata) -+ super().__init__(adapter, tabledata) - self.set_name("ManagerDeviceList") - self.set_headers_visible(False) - self.props.has_tooltip = True -@@ -211,7 +211,7 @@ def on_finished(fader): - - fader.disconnect(signal) - fader.freeze() -- super(ManagerDeviceList, self).device_remove_event(device, tree_iter) -+ super().device_remove_event(device, tree_iter) - - signal = row_fader.connect("animation-finished", on_finished) - row_fader.thaw() -diff --git a/blueman/gui/manager/ManagerDeviceMenu.py b/blueman/gui/manager/ManagerDeviceMenu.py -index 0747dd7d..a101d008 100644 ---- a/blueman/gui/manager/ManagerDeviceMenu.py -+++ b/blueman/gui/manager/ManagerDeviceMenu.py -@@ -31,7 +31,7 @@ class ManagerDeviceMenu(Gtk.Menu): - __instances__ = [] - - def __init__(self, blueman): -- super(ManagerDeviceMenu, self).__init__() -+ super().__init__() - self.set_name("ManagerDeviceMenu") - self.Blueman = blueman - self.SelectedDevice = None -diff --git a/blueman/gui/manager/ManagerProgressbar.py b/blueman/gui/manager/ManagerProgressbar.py -index 4379436d..305fafdd 100644 ---- a/blueman/gui/manager/ManagerProgressbar.py -+++ b/blueman/gui/manager/ManagerProgressbar.py -@@ -18,7 +18,7 @@ class ManagerProgressbar(GObject.GObject): - __instances__ = [] - - def __init__(self, blueman, cancellable=True, text=_("Connecting")): -- super(ManagerProgressbar, self).__init__() -+ super().__init__() - self.Blueman = blueman - - self.cancellable = cancellable -diff --git a/blueman/main/Config.py b/blueman/main/Config.py -index 312d054a..4b32244a 100644 ---- a/blueman/main/Config.py -+++ b/blueman/main/Config.py -@@ -6,9 +6,9 @@ class Config(Gio.Settings): - def __init__(self, schema_id, path=None): - # Add backwards compat with pygobject < 3.11.2 - if Gio.Settings.__init__.__name__ == "new_init": -- super(Config, self).__init__(schema_id=schema_id, path=path) -+ super().__init__(schema_id=schema_id, path=path) - else: -- super(Config, self).__init__(schema=schema_id, path=path) -+ super().__init__(schema=schema_id, path=path) - - def bind_to_widget(self, key, widget, prop, flags=Gio.SettingsBindFlags.DEFAULT): - self.bind(key, widget, prop, flags) -diff --git a/blueman/main/DhcpClient.py b/blueman/main/DhcpClient.py -index 17efd7fc..0bf9e85f 100644 ---- a/blueman/main/DhcpClient.py -+++ b/blueman/main/DhcpClient.py -@@ -24,7 +24,7 @@ class DhcpClient(GObject.GObject): - quering = [] - - def __init__(self, interface, timeout=30): -- super(DhcpClient, self).__init__() -+ super().__init__() - - self._interface = interface - self._timeout = timeout -diff --git a/blueman/main/Manager.py b/blueman/main/Manager.py -index 54362fb0..93a104e4 100644 ---- a/blueman/main/Manager.py -+++ b/blueman/main/Manager.py -@@ -26,7 +26,7 @@ - - class Blueman(Gtk.Window): - def __init__(self): -- super(Blueman, self).__init__(title=_("Bluetooth Devices")) -+ super().__init__(title=_("Bluetooth Devices")) - - self._applet_sig = None - -diff --git a/blueman/main/PPPConnection.py b/blueman/main/PPPConnection.py -index 09dd5269..cea07fd1 100644 ---- a/blueman/main/PPPConnection.py -+++ b/blueman/main/PPPConnection.py -@@ -46,7 +46,7 @@ class PPPConnection(GObject.GObject): - } - - def __init__(self, port, number="*99#", apn="", user="", pwd=""): -- super(PPPConnection, self).__init__() -+ super().__init__() - - self.apn = apn - self.number = number -diff --git a/blueman/main/PluginManager.py b/blueman/main/PluginManager.py -index d25e25b6..5a056d24 100644 ---- a/blueman/main/PluginManager.py -+++ b/blueman/main/PluginManager.py -@@ -29,7 +29,7 @@ class PluginManager(GObject.GObject): - } - - def __init__(self, plugin_class, module_path, parent): -- super(PluginManager, self).__init__() -+ super().__init__() - self.__plugins = {} - self.__classes = {} - self.__deps = {} -@@ -229,7 +229,7 @@ def run_ex(self, func, callback, *args, **kwargs): - - class PersistentPluginManager(PluginManager): - def __init__(self, *args): -- super(PersistentPluginManager, self).__init__(*args) -+ super().__init__(*args) - - self.__config = Config("org.blueman.general") - -diff --git a/blueman/main/PulseAudioUtils.py b/blueman/main/PulseAudioUtils.py -index 8385f564..4b2b4561 100644 ---- a/blueman/main/PulseAudioUtils.py -+++ b/blueman/main/PulseAudioUtils.py -@@ -628,7 +628,7 @@ def __event_callback(self, context, event_type, idx, userdata): - self.emit("event", event_type, idx) - - def __init__(self): -- super(PulseAudioUtils, self).__init__() -+ super().__init__() - - self.event_cb = pa_context_subscribe_cb_t(self.__event_callback) - -diff --git a/blueman/plugins/AppletPlugin.py b/blueman/plugins/AppletPlugin.py -index 2cca1420..90cae0f7 100644 ---- a/blueman/plugins/AppletPlugin.py -+++ b/blueman/plugins/AppletPlugin.py -@@ -15,7 +15,7 @@ class AppletPlugin(BasePlugin): - _dbus_signals = None - - def __init__(self, parent): -- super(AppletPlugin, self).__init__(parent) -+ super().__init__(parent) - - if not ictheme.has_icon(self.__class__.__icon__): - self.__class__.__icon__ = "blueman-plugin" -@@ -46,7 +46,7 @@ def _unload(self): - for (obj, method, orig) in self.__overrides: - obj.__setattr__(method, orig) - -- super(AppletPlugin, self)._unload() -+ super()._unload() - - for method in self._dbus_methods: - self._dbus_service.remove_method(method) -@@ -54,7 +54,7 @@ def _unload(self): - self._dbus_service.remove_signal(signal) - - def _load(self): -- super(AppletPlugin, self)._load() -+ super()._load() - - # The applet will run on_manager_state_changed once at startup so until it has we don't. - if self.parent.plugin_run_state_changed: -diff --git a/blueman/plugins/applet/NetUsage.py b/blueman/plugins/applet/NetUsage.py -index 0ad1754b..b2300a58 100644 ---- a/blueman/plugins/applet/NetUsage.py -+++ b/blueman/plugins/applet/NetUsage.py -@@ -29,7 +29,7 @@ class MonitorBase(GObject.GObject): - } - - def __init__(self, device, interface): -- super(MonitorBase, self).__init__() -+ super().__init__() - - self.interface = interface - self.device = device -@@ -67,7 +67,7 @@ def disconnect_monitor(self): - - class Monitor(MonitorBase): - def __init__(self, device, interface): -- super(Monitor, self).__init__(device, interface) -+ super().__init__(device, interface) - self.poller = None - self.ppp_port = None - -diff --git a/blueman/services/meta/NetworkService.py b/blueman/services/meta/NetworkService.py -index f9e257de..f1a39950 100644 ---- a/blueman/services/meta/NetworkService.py -+++ b/blueman/services/meta/NetworkService.py -@@ -5,7 +5,7 @@ - - class NetworkService(Service): - def __init__(self, device, uuid): -- super(NetworkService, self).__init__(device, uuid) -+ super().__init__(device, uuid) - self._service = Network(device.get_object_path()) - - @property -diff --git a/blueman/services/meta/SerialService.py b/blueman/services/meta/SerialService.py -index f329380d..6b362a52 100644 ---- a/blueman/services/meta/SerialService.py -+++ b/blueman/services/meta/SerialService.py -@@ -14,7 +14,7 @@ - - class SerialService(Service): - def __init__(self, device, uuid): -- super(SerialService, self).__init__(device, uuid) -+ super().__init__(device, uuid) - self.file_changed_handler = None - - def serial_port_id(self, channel): - -From fd34cfac6b47f3b7c87b33132cc2ad3af9a41b23 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Mon, 20 May 2019 23:38:03 +0200 -Subject: [PATCH 02/13] sendto: Get basename from Gio.File - -We can't pass a Gio.File to os.path. ---- - blueman/main/Sendto.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index 53b53b3c..2cc635da 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -218,7 +218,7 @@ def send_file(self, file_path): - def on_transfer_error(self, _transfer, msg=""): - if not self.error_dialog: - self.speed.reset() -- d = ErrorDialog(msg, _("Error occurred while sending file %s") % os.path.basename(self.files[-1]), -+ d = ErrorDialog(msg, _("Error occurred while sending file %s") % self.files[-1].get_basename(), - modal=True, icon_name="blueman", parent=self.get_toplevel()) - - if len(self.files) > 1: - -From 2f7d3fdc42f114cbac3657d381b6877a0138a18f Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Mon, 20 May 2019 23:38:58 +0200 -Subject: [PATCH 03/13] sendto: Get file size from gio.File - -So we can drop os.path and use Gio for everything. ---- - blueman/main/Sendto.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index 2cc635da..82a6b42d 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -1,7 +1,6 @@ - # coding=utf-8 - import time - import logging --import os - from locale import bind_textdomain_codeset - from gettext import ngettext - -@@ -233,7 +232,8 @@ def on_response(dialog, resp): - if resp == "_Cancel": - self.on_cancel(None) - elif resp == Gtk.ResponseType.NO: -- self.total_bytes -= os.path.getsize(self.files[-1]) -+ finfo = self.files[-1].query_info('standard::*', Gio.FileQueryInfoFlags.NONE) -+ self.total_bytes -= finfo.get_size() - self.total_transferred -= self.transferred - self.transferred = 0 - del self.files[-1] - -From f5369870edda2419fde2064cadcd9d0edc3fd181 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Tue, 21 May 2019 00:05:25 +0200 -Subject: [PATCH 04/13] sendto: Do not have a close button - -We add a close button by default which is confusing in this case. ---- - blueman/main/Sendto.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index 82a6b42d..e9c799a6 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -218,7 +218,7 @@ def on_transfer_error(self, _transfer, msg=""): - if not self.error_dialog: - self.speed.reset() - d = ErrorDialog(msg, _("Error occurred while sending file %s") % self.files[-1].get_basename(), -- modal=True, icon_name="blueman", parent=self.get_toplevel()) -+ modal=True, icon_name="blueman", parent=self.get_toplevel(), buttons=[]) - - if len(self.files) > 1: - d.add_button(_("Skip"), Gtk.ResponseType.NO) - -From f284a1c00580cf9ab95596a8610c9ed8e6ab68cc Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 12:07:46 +0200 -Subject: [PATCH 05/13] DeviceList: Disconnect AnyDevice when being destroyed - -In DeviceSelectorWidget the DeviceSelectorList is destroyed but callbacks -from the AnyDevice in DeviceList are still run which fail as the model does -not exist anymore. - -Needed to properly close the DeviceSelectorDialog ---- - blueman/gui/DeviceList.py | 8 ++++++-- - blueman/gui/DeviceSelectorDialog.py | 4 ++++ - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/blueman/gui/DeviceList.py b/blueman/gui/DeviceList.py -index 3396d1e9..a4697bca 100644 ---- a/blueman/gui/DeviceList.py -+++ b/blueman/gui/DeviceList.py -@@ -85,8 +85,8 @@ def on_device_removed(_manager, path): - self.manager.connect_signal('device-created', on_device_created) - self.manager.connect_signal('device-removed', on_device_removed) - -- any_device = bluez.AnyDevice() -- any_device.connect_signal("property-changed", self._on_device_property_changed) -+ self.any_device = bluez.AnyDevice() -+ self.any_device.connect_signal("property-changed", self._on_device_property_changed) - - self.__discovery_time = 0 - self.__adapter_path = None -@@ -113,6 +113,10 @@ def on_device_removed(_manager, path): - # handle icon theme changes - self.icon_theme.connect("changed", self.on_icon_theme_changed) - -+ def destroy(self): -+ self.any_device.disconnect_by_func(self._on_device_property_changed) -+ super().destroy() -+ - def on_selection_changed(self, selection): - _model, tree_iter = selection.get_selected() - if tree_iter: -diff --git a/blueman/gui/DeviceSelectorDialog.py b/blueman/gui/DeviceSelectorDialog.py -index 5955b039..40a6f5d0 100644 ---- a/blueman/gui/DeviceSelectorDialog.py -+++ b/blueman/gui/DeviceSelectorDialog.py -@@ -29,6 +29,10 @@ def __init__(self, title=_("Select Device"), parent=None, discover=True, adapter - - self.selector.List.connect("row-activated", self.on_row_activated) - -+ def close(self): -+ self.selector.destroy() -+ super().close() -+ - def on_row_activated(self, treeview, path, view_column, *args): - self.response(Gtk.ResponseType.ACCEPT) - - -From 2b1ebdf38e71a8deb767fd662fe52bfea3f92240 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sat, 1 Jun 2019 17:01:03 +0200 -Subject: [PATCH 06/13] sendto: Close DeviceSelectorDialog - -We are done with it at this point and I see no point keeping it around. ---- - apps/blueman-sendto.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/apps/blueman-sendto.in b/apps/blueman-sendto.in -index d8e6dbc5..964c1bd8 100755 ---- a/apps/blueman-sendto.in -+++ b/apps/blueman-sendto.in -@@ -114,6 +114,7 @@ class SendTo: - adapter_name = os.path.split(self.adapter_path)[-1] - d = DeviceSelectorDialog(discover=False, adapter_name=adapter_name) - resp = d.run() -+ d.close() - if resp == Gtk.ResponseType.ACCEPT: - if d.selection: - self.adapter_path, self.device = d.selection - -From 5308750e2ad8a33bd8efe9507b960cc43cfbd20d Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 12:10:35 +0200 -Subject: [PATCH 07/13] Sendto: Do not exit but emit result - -blueman-sendto listens for this and calls Gtk.main_quit() ---- - blueman/main/Sendto.py | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index e9c799a6..bc07ae9f 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -96,7 +96,7 @@ def __init__(self, device, adapter_path, files): - self.total_bytes += file_info.get_size() - - if len(self.files) == 0: -- exit(1) -+ self.emit("result", False) - - try: - self.client = obex.Client() -@@ -107,7 +107,7 @@ def __init__(self, device, adapter_path, files): - "daemon is running"), parent=self.get_toplevel()) - d.run() - d.destroy() -- exit(1) -+ self.emit("result", False) - else: - # Fail on anything else - raise -@@ -266,7 +266,7 @@ def on_session_failed(self, _client, msg): - - d.run() - d.destroy() -- exit(1) -+ self.emit("result", False) - - def on_session_removed(self, _client): - self.emit("result", False) - -From 9993c848af61d853acc12936b4ce86fd399d0477 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 12:25:41 +0200 -Subject: [PATCH 08/13] Sedto: Use Gtk.ResponseType.CANCEL (int) instead of - string - ---- - blueman/main/Sendto.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index bc07ae9f..dee19702 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -229,7 +229,7 @@ def on_response(dialog, resp): - dialog.destroy() - self.error_dialog = None - -- if resp == "_Cancel": -+ if resp == Gtk.ResponseType.CANCEL: - self.on_cancel(None) - elif resp == Gtk.ResponseType.NO: - finfo = self.files[-1].query_info('standard::*', Gio.FileQueryInfoFlags.NONE) - -From a3013a63942996691724b84e4006b55ae3cf47c5 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 12:27:38 +0200 -Subject: [PATCH 09/13] Sendto: Always emit result in on_cancel - ---- - blueman/main/Sendto.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index dee19702..f5fde208 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -140,8 +140,8 @@ def on_cancel(self, button): - - if self.object_push: - self.client.remove_session(self.object_push.get_session_path()) -- else: -- self.emit("result", False) -+ -+ self.emit("result", False) - - def on_transfer_started(self, _object_push, transfer_path, filename): - if self.total_transferred == 0: - -From dc5cdda462f1b570eb64a785c1f5cc6ae5c4ddec Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 13:47:19 +0200 -Subject: [PATCH 10/13] DeviceList: Also disconnect the other signals - -This also merges all Manager callbacks functions for easier disconnection ---- - blueman/gui/DeviceList.py | 66 +++++++++++++++++++++------------------ - 1 file changed, 35 insertions(+), 31 deletions(-) - -diff --git a/blueman/gui/DeviceList.py b/blueman/gui/DeviceList.py -index a4697bca..7a0350d2 100644 ---- a/blueman/gui/DeviceList.py -+++ b/blueman/gui/DeviceList.py -@@ -47,43 +47,16 @@ def __init__(self, adapter_name=None, tabledata=None, **kwargs): - if not tabledata: - tabledata = [] - -- def on_adapter_removed(_manager, path): -- self.emit("adapter-removed", path) -- if path == self.__adapter_path: -- self.clear() -- self.Adapter = None -- self.set_adapter() -- -- def on_adapter_added(_manager, path): -- if self.Adapter is None: -- self.set_adapter(path) -- -- self.emit("adapter-added", path) -- -- def on_device_created(_adapter, path): -- tree_iter = self.find_device_by_path(path) -- if tree_iter is None: -- dev = bluez.Device(path) -- self.device_add_event(dev) -- -- def on_device_removed(_manager, path): -- tree_iter = self.find_device_by_path(path) -- if tree_iter: -- row = self.get(tree_iter, "device") -- dev = row["device"] -- -- self.device_remove_event(dev, tree_iter) -- - # cache for fast lookup in the list - self.path_to_row = {} - - self.monitored_devices = [] - - self.manager = bluez.Manager() -- self.manager.connect_signal('adapter-removed', on_adapter_removed) -- self.manager.connect_signal('adapter-added', on_adapter_added) -- self.manager.connect_signal('device-created', on_device_created) -- self.manager.connect_signal('device-removed', on_device_removed) -+ self.manager.connect_signal('adapter-removed', self.__on_manager_signal, 'adapter-removed') -+ self.manager.connect_signal('adapter-added', self.__on_manager_signal, 'adapter-added') -+ self.manager.connect_signal('device-created', self.__on_manager_signal, 'device-created') -+ self.manager.connect_signal('device-removed', self.__on_manager_signal, 'device-removed') - - self.any_device = bluez.AnyDevice() - self.any_device.connect_signal("property-changed", self._on_device_property_changed) -@@ -115,8 +88,39 @@ def on_device_removed(_manager, path): - - def destroy(self): - self.any_device.disconnect_by_func(self._on_device_property_changed) -+ self._any_adapter.disconnect_by_func(self._on_property_changed) -+ self.selection.disconnect_by_func(self.on_selection_changed) -+ self.manager.disconnect_by_func(self.__on_manager_signal) - super().destroy() - -+ def __on_manager_signal(self, manager, path, signal_name): -+ if signal_name == 'adapter-removed': -+ self.emit("adapter-removed", path) -+ if path == self.__adapter_path: -+ self.clear() -+ self.Adapter = None -+ self.set_adapter() -+ -+ if signal_name == 'adapter-added': -+ if self.Adapter is None: -+ self.set_adapter(path) -+ -+ self.emit("adapter-added", path) -+ -+ if signal_name == 'device-created': -+ tree_iter = self.find_device_by_path(path) -+ if tree_iter is None: -+ dev = bluez.Device(path) -+ self.device_add_event(dev) -+ -+ if signal_name == 'device-removed': -+ tree_iter = self.find_device_by_path(path) -+ if tree_iter: -+ row = self.get(tree_iter, "device") -+ dev = row["device"] -+ -+ self.device_remove_event(dev, tree_iter) -+ - def on_selection_changed(self, selection): - _model, tree_iter = selection.get_selected() - if tree_iter: - -From bef31cf2075a79158189fa339cbe2d3cbeb35ac1 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 14:57:12 +0200 -Subject: [PATCH 11/13] obex.Manager: Add session-added signal - -To be used in blueman-sendto so that we can detect a session was removed. - -This is different from the obex.Client it only sends it when we manually -remove the session. The signal on obex.Client will be dropped later. ---- - blueman/bluez/obex/Manager.py | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/blueman/bluez/obex/Manager.py b/blueman/bluez/obex/Manager.py -index 13f1bd95..1a86d25c 100644 ---- a/blueman/bluez/obex/Manager.py -+++ b/blueman/bluez/obex/Manager.py -@@ -18,6 +18,7 @@ def __call__(cls, *args, **kwargs): - - class Manager(GObject.GObject, metaclass=ManagerMeta): - __gsignals__ = { -+ 'session-added': (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT,)), - 'session-removed': (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT,)), - 'transfer-started': (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT,)), - 'transfer-completed': (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT)), -@@ -47,17 +48,21 @@ def _on_delete(self): - self._object_manager.disconnect(sig) - - def _on_object_added(self, object_manager, dbus_object): -+ session_proxy = dbus_object.get_interface('org.bluez.obex.Session1') - transfer_proxy = dbus_object.get_interface('org.bluez.obex.Transfer1') -+ object_path = dbus_object.get_object_path() - - if transfer_proxy: -- transfer_path = transfer_proxy.get_object_path() -- transfer = Transfer(transfer_path) -+ logging.info(object_path) -+ transfer = Transfer(object_path) - completed_sig = transfer.connect_signal('completed', self._on_transfer_completed, True) - error_sig = transfer.connect_signal('error', self._on_transfer_completed, False) -- self.__transfers[transfer_path] = (transfer, (completed_sig, error_sig)) -+ self.__transfers[object_path] = (transfer, (completed_sig, error_sig)) -+ self.emit('transfer-started', object_path) - -- logging.info(transfer_path) -- self.emit('transfer-started', transfer_path) -+ if session_proxy: -+ logging.info(object_path) -+ self.emit('session-added', object_path) - - def _on_object_removed(self, object_manager, dbus_object): - session_proxy = dbus_object.get_interface('org.bluez.obex.Session1') - -From caf603ba1e7113e2cae5b98d69e5d05bc323546a Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 15:19:02 +0200 -Subject: [PATCH 12/13] Sendto: Use obex.Manager to keep track of sessions - -The session-removed signal was only emitted when we manually remove the -session. However we did not handle when the receiver disconnects/stops the -transfer and the session is removed automatically. - -This commit also removes session-created/removed from the client leaving -session-error which it actually should handle. ---- - blueman/bluez/obex/Client.py | 4 ---- - blueman/main/Sendto.py | 17 +++++++++++------ - 2 files changed, 11 insertions(+), 10 deletions(-) - -diff --git a/blueman/bluez/obex/Client.py b/blueman/bluez/obex/Client.py -index b9f38588..1d8dbc66 100644 ---- a/blueman/bluez/obex/Client.py -+++ b/blueman/bluez/obex/Client.py -@@ -6,9 +6,7 @@ - - class Client(Base): - __gsignals__ = { -- 'session-created': (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT,)), - 'session-failed': (GObject.SignalFlags.NO_HOOKS, None, (GObject.TYPE_PYOBJECT,)), -- 'session-removed': (GObject.SignalFlags.NO_HOOKS, None, ()), - } - - _interface_name = 'org.bluez.obex.Client1' -@@ -19,7 +17,6 @@ def __init__(self): - def create_session(self, dest_addr, source_addr="00:00:00:00:00:00", pattern="opp"): - def on_session_created(session_path): - logging.info("%s %s %s %s" % (dest_addr, source_addr, pattern, session_path)) -- self.emit("session-created", session_path) - - def on_session_failed(error): - logging.error("%s %s %s %s" % (dest_addr, source_addr, pattern, error)) -@@ -33,7 +30,6 @@ def on_session_failed(error): - def remove_session(self, session_path): - def on_session_removed(): - logging.info(session_path) -- self.emit('session-removed') - - def on_session_remove_failed(error): - logging.error("%s %s" % (session_path, error)) -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index f5fde208..8613ce9d 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -10,6 +10,7 @@ - - from blueman.bluez.Adapter import Adapter - from blueman.bluez.obex.ObjectPush import ObjectPush -+from blueman.bluez.obex.Manager import Manager - from blueman.Functions import format_bytes - from blueman.Constants import UI_PATH - from blueman.main.SpeedCalc import SpeedCalc -@@ -59,6 +60,7 @@ def __init__(self, device, adapter_path, files): - - self.device = device - self.adapter = Adapter(adapter_path) -+ self.manager = Manager() - self.files = [] - self.num_files = 0 - self.object_push = None -@@ -100,6 +102,8 @@ def __init__(self, device, adapter_path, files): - - try: - self.client = obex.Client() -+ self.manager.connect_signal('session-added', self.on_session_added) -+ self.manager.connect_signal('session-removed', self.on_session_removed) - except GLib.Error as e: - if 'StartServiceByName' in e.message: - logging.debug(e.message) -@@ -114,9 +118,7 @@ def __init__(self, device, adapter_path, files): - - self.l_file.props.label = self.files[-1].get_basename() - -- self.client.connect('session-created', self.on_session_created) - self.client.connect('session-failed', self.on_session_failed) -- self.client.connect('session-removed', self.on_session_removed) - - logging.info("Sending to %s" % device['Address']) - self.l_dest.props.label = device['Alias'] -@@ -254,12 +256,18 @@ def on_response(dialog, resp): - d.show() - self.error_dialog = d - -- def on_session_created(self, _client, session_path): -+ def on_session_added(self, _manager, session_path): - self.object_push = ObjectPush(session_path) - self.object_push.connect("transfer-started", self.on_transfer_started) - self.object_push.connect("transfer-failed", self.on_transfer_failed) - self.process_queue() - -+ def on_session_removed(self, _manager, session_path): -+ logging.debug('Session removed: %s' % session_path) -+ self.object_push.disconnect_by_func(self.on_transfer_started) -+ self.object_push.disconnect_by_func(self.on_transfer_failed) -+ self.object_push = None -+ - def on_session_failed(self, _client, msg): - d = ErrorDialog(_("Error occurred"), msg.reason.split(None, 1)[1], icon_name="blueman", - parent=self.get_toplevel()) -@@ -267,6 +275,3 @@ def on_session_failed(self, _client, msg): - d.run() - d.destroy() - self.emit("result", False) -- -- def on_session_removed(self, _client): -- self.emit("result", False) - -From f97f84866199d96951adf3736ab7e66596e51dc8 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 15:49:04 +0200 -Subject: [PATCH 13/13] Sendto: Remove session on transfer error - -Using the same session after a transfer error never works for me. ---- - blueman/main/Sendto.py | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/blueman/main/Sendto.py b/blueman/main/Sendto.py -index 8613ce9d..3a93c0d9 100644 ---- a/blueman/main/Sendto.py -+++ b/blueman/main/Sendto.py -@@ -227,6 +227,8 @@ def on_transfer_error(self, _transfer, msg=""): - d.add_button(_("Retry"), Gtk.ResponseType.YES) - d.add_button("_Cancel", Gtk.ResponseType.CANCEL) - -+ self.client.remove_session(self.object_push.get_object_path()) -+ - def on_response(dialog, resp): - dialog.destroy() - self.error_dialog = None diff --git a/blueman-PR-1039.patch b/blueman-PR-1039.patch deleted file mode 100644 index 18ef16c..0000000 --- a/blueman-PR-1039.patch +++ /dev/null @@ -1,59 +0,0 @@ -From b0b661fb98e9c752d7e0d56e7eeff0863f59d471 Mon Sep 17 00:00:00 2001 -From: Sander Sweers -Date: Sun, 2 Jun 2019 18:28:08 +0200 -Subject: [PATCH] Check if an Adapter is present and exit if none found - ---- - blueman/main/Adapter.py | 13 ++++++------- - blueman/main/Manager.py | 6 ++++++ - 2 files changed, 12 insertions(+), 7 deletions(-) - -diff --git a/blueman/main/Adapter.py b/blueman/main/Adapter.py -index 02dd3edb..a710b406 100644 ---- a/blueman/main/Adapter.py -+++ b/blueman/main/Adapter.py -@@ -42,21 +42,20 @@ def __init__(self, selected_hci_dev, socket_id): - - setup_icon_path() - bluez.Manager.watch_name_owner(self._on_dbus_name_appeared, self._on_dbus_name_vanished) -+ self.manager = bluez.Manager() - - check_single_instance("blueman-adapters", lambda time: self.present_with_time(time)) - - check_bluetooth_status(_("Bluetooth needs to be turned on for the adapter manager to work"), lambda: exit()) - -- try: -- self.manager = bluez.Manager() -- except Exception as e: -- logging.exception(e) -- self.manager = None -- # fixme: show error dialog and exit -+ adapters = self.manager.get_adapters() -+ if not adapters: -+ logging.error('No adapter(s) found') -+ exit(1) - - self.manager.connect_signal('adapter-added', self.on_adapter_added) - self.manager.connect_signal('adapter-removed', self.on_adapter_removed) -- for adapter in self.manager.get_adapters(): -+ for adapter in adapters: - path = adapter.get_object_path() - hci_dev = os.path.basename(path) - self._adapters[hci_dev] = adapter -diff --git a/blueman/main/Manager.py b/blueman/main/Manager.py -index 54362fb0..226faf73 100644 ---- a/blueman/main/Manager.py -+++ b/blueman/main/Manager.py -@@ -111,6 +111,12 @@ def on_dbus_name_appeared(_connection, name, owner): - check_bluetooth_status(_("Bluetooth needs to be turned on for the device manager to function"), - lambda: Gtk.main_quit()) - -+ try: -+ bluez.Manager().get_adapter(self.Config['last-adapter']) -+ except bluez.errors.DBusNoSuchAdapterError: -+ logging.error('No bluetooth adapter(s) found.') -+ exit(1) -+ - self._applet_sig = self.Applet.connect('g-signal', on_applet_signal) - - self.connect("delete-event", on_window_delete) diff --git a/blueman.spec b/blueman.spec index 5e5a8a9..3376d88 100644 --- a/blueman.spec +++ b/blueman.spec @@ -1,21 +1,12 @@ Name: blueman Epoch: 1 Version: 2.1 -%global prerelease beta1 -Release: 0.17.%{prerelease}%{?dist} +Release: 1%{?dist} Summary: GTK+ Bluetooth Manager License: GPLv2+ URL: https://github.com/blueman-project/blueman -Source0: %{URL}/releases/download/%{version}.%{prerelease}/blueman-%{version}.%{prerelease}.tar.gz - -# Upstream patch, fixes crashes where no bluetooth adapters are active -# https://github.com/blueman-project/blueman/pull/1039/ -Patch0: blueman-PR-1039.patch - -# Upstream patch, fixes blueman not recognizing IO errors -# https://github.com/blueman-project/blueman/pull/1030/ -Patch1: blueman-PR-1030.patch +Source0: %{URL}/releases/download/%{version}/blueman-%{version}.tar.gz BuildRequires: pkgconfig(gtk+-3.0) BuildRequires: pkgconfig(pygobject-3.0) @@ -56,9 +47,7 @@ such as: %prep -%setup -q -n blueman-%{version}.%{prerelease} -%patch0 -p1 -%patch1 -p1 +%setup -q sed -e 's|/usr/sbin/bluetoothd|%{_libexecdir}/bluetooth/bluetoothd|g' -i apps/blueman-report.in %build @@ -130,6 +119,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/blueman-*.desktop %changelog +* Mon Jun 10 2019 Artur Iwicki - 1:2.1-1 +- Update to latest upstream release +- Drop Patch0 and Patch1 (they were backports from today's release) + * Sat Jun 08 2019 Artur Iwicki - 1:2.1-0.17.beta1 - Add two upstream patches for crashes and IO issues diff --git a/sources b/sources index ce9a58e..663df8c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (blueman-2.1.beta1.tar.gz) = 14dce69cc116231095997ba05c567c53c9be215b07e68397949a4d520832c36e39b18b67d98f79daaf5d368cf52041f060243014f4927c508558a127eedc092d +SHA512 (blueman-2.1.tar.gz) = 32e17d3d3624b96ea9ffcd333b0e8d3e98438e8cef0cf13e45f000a94c5c812b447ebb7a8e12b637bd7b574c0b68628650e92175ff530b2c21f255aa9008c5a5