diff options
author | Bartosz Jaroszewski <b.jarosze@gmail.com> | 2018-03-18 11:35:13 +0100 |
---|---|---|
committer | Bartosz Jaroszewski <b.jarosze@gmail.com> | 2018-03-18 11:37:22 +0100 |
commit | 060371d0eacd6642c231efa8415969b69a4aa84d (patch) | |
tree | b05c0371d50443c0cebbd5633a80563f8f2cd86c |
initial commit
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | extension.js | 140 | ||||
-rw-r--r-- | metadata.json | 8 |
3 files changed, 149 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a09c56d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.idea diff --git a/extension.js b/extension.js new file mode 100644 index 0000000..acd316c --- /dev/null +++ b/extension.js @@ -0,0 +1,140 @@ +const Main = imports.ui.main; +const GnomeBluetooth = imports.gi.GnomeBluetooth; +const PopupMenu = imports.ui.popupMenu; +const GLib = imports.gi.GLib; +const Util = imports.misc.util; + +class BluetoothDevice { + constructor(model, device) { + this._name = model.get_value(device, GnomeBluetooth.Column.NAME); + this._isConnected = model.get_value(device, GnomeBluetooth.Column.CONNECTED); + this._isPaired = model.get_value(device, GnomeBluetooth.Column.PAIRED); + this._mac = model.get_value(device, GnomeBluetooth.Column.ADDRESS); + } + + get name() { + return this._name; + } + + get isConnected() { + return this._isConnected; + } + + get isPaired() { + return this._isPaired; + } + + get mac() { + return this._mac; + } + + get item() { + if (!this._item) + this._buildMenuItem(); + + return this._item; + } + + _buildMenuItem() { + this._item = new PopupMenu.PopupSwitchMenuItem(this.name, this.isConnected); + this._item.isDeviceSwitcher = true; + this._item.connect('toggled', (item, state) => { + if (state) + this._connect(); + else + this._disconnect(); + }); + } + + _disconnect() { + let command = `echo -e "disconnect ${this.mac}\\n" | bluetoothctl`; + Util.spawn(['/bin/bash', '-c', command]); + } + + _connect() { + let command = `echo -e "connect ${this.mac}\\n" | bluetoothctl`; + Util.spawn(['/bin/bash', '-c', command]); + } +} + +class BluetoothQuickConnect { + constructor(bluetooth) { + this._model = bluetooth._model; + this._getDefaultAdapter = bluetooth._getDefaultAdapter; + this._menu = bluetooth._item.menu; + + this._signals = []; + } + + enable() { + let signal = this._menu.connect('open-state-changed', (menu, isOpen) => { + if (isOpen) + this._sync(); + }); + + this._signals.push(signal); + } + + disable() { + this._destroy(); + } + + _getPairedDevices() { + let adapter = this._getDefaultAdapter(); + if (!adapter) + return []; + + let pairedDevices = []; + + let [ret, iter] = this._model.iter_children(adapter); + while (ret) { + let bluetoothDevice = new BluetoothDevice(this._model, iter); + if (bluetoothDevice.isPaired || bluetoothDevice.isConnected) + pairedDevices.push(bluetoothDevice); + + ret = this._model.iter_next(iter); + } + + return pairedDevices; + } + + _sync() { + this._removeDevicesFromMenu(); + this._addDevicesToMenu(); + } + + _addDevicesToMenu() { + this._getPairedDevices().forEach((device) => { + this._menu.addMenuItem(device.item, 1); + }); + } + + _removeDevicesFromMenu() { + this._menu._getMenuItems().forEach((item) => { + if (item.isDeviceSwitcher) { + item.destroy(); + } + }); + } + + _destroy() { + this._signals.forEach((signal) => { + this._menu.disconnect(signal); + }); + this._removeDevicesFromMenu(); + } +} + + +function init() { + let bluetooth = Main.panel.statusArea.aggregateMenu._bluetooth; + bluetoothQuickConnect = new BluetoothQuickConnect(bluetooth); +} + +function enable() { + bluetoothQuickConnect.enable(); +} + +function disable() { + bluetoothQuickConnect.disable(); +} diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..d099950 --- /dev/null +++ b/metadata.json @@ -0,0 +1,8 @@ +{ + "name": "Bluetooth quick connect", + "description": "Allow to connect to paired devices from gnome control panel.", + "uuid": "bluetooth-quick-connect@bjarosze.gmail.com", + "shell-version": [ + "3.26.2" + ] +} |