From 77f1f7685c9b82b9bdaf9359e123afb12210b22b Mon Sep 17 00:00:00 2001 From: Bartosz Jaroszewski Date: Sat, 16 May 2020 14:41:28 +0200 Subject: add refresh button --- .gitignore | 1 + README.md | 11 +++++++++ extension.js | 29 +++++++++++++++------- extract.sh | 29 ++++++++++++++++++++++ ui.js | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+), 9 deletions(-) create mode 100755 extract.sh create mode 100644 ui.js diff --git a/.gitignore b/.gitignore index e666a92..d7a7d48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /.idea /schemas/gschemas.compiled +/gnome-shell diff --git a/README.md b/README.md index 5a6d8cb..ed4289c 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,14 @@ make rm -r ~/.local/share/gnome-shell/extensions/bluetooth-quick-connect@bjarosze.gmail.com cp -r gnome-bluetooth-quick-connect ~/.local/share/gnome-shell/extensions/bluetooth-quick-connect@bjarosze.gmail.com ``` + +## Troubleshooting + +### Reconnect does not work + +Not sure why, but sometimes bluetoothctl does not want to connect +device after it was disconnected. Reinstalling bluez helped on my ubuntu. +``` +$ sudo apt purge bluez gnome-bluetooth pulseaudio-module-bluetooth +$ sudo apt install bluez gnome-bluetooth pulseaudio-module-bluetooth +``` \ No newline at end of file diff --git a/extension.js b/extension.js index 403d956..33de925 100644 --- a/extension.js +++ b/extension.js @@ -16,13 +16,13 @@ const Main = imports.ui.main; const GnomeBluetooth = imports.gi.GnomeBluetooth; -const PopupMenu = imports.ui.popupMenu; const Util = imports.misc.util; const GLib = imports.gi.GLib; const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const Convenience = Me.imports.convenience; +const UiExtension = Me.imports.ui; class BluetoothDevice { constructor(model, device) { @@ -56,7 +56,11 @@ class BluetoothDevice { } _buildMenuItem() { - this._item = new PopupMenu.PopupSwitchMenuItem(this.name, this.isConnected); + this._item = new UiExtension.PopupSwitchWithButtonMenuItem( + this.name, + this.isConnected, + this.isConnected && 'view-refresh' + ); this._item.isDeviceSwitcher = true; this._item.connect('toggled', (item, state) => { if (state) @@ -64,19 +68,26 @@ class BluetoothDevice { else this._disconnect(); }); + + this._item.connect('clicked', () => { + this._reconnect() + }); } _disconnect() { - this._call_bluetoothctl(`disconnect ${this.mac}`) + this._call_cmd(`bluetoothctl -- disconnect ${this.mac}`) } _connect() { - this._call_bluetoothctl(`connect ${this.mac}`) + this._call_cmd(`bluetoothctl -- connect ${this.mac}`) + } + + _reconnect() { + this._call_cmd(`bluetoothctl -- disconnect ${this.mac} && bluetoothctl -- connect ${this.mac}`) } - _call_bluetoothctl(command) { - let btctl_command = `echo -e "${command}\\n" | bluetoothctl`; - Util.spawn(['/usr/bin/env', 'bash', '-c', btctl_command]); + _call_cmd(command) { + Util.spawn(['/usr/bin/env', 'bash', '-c', command]); } } @@ -113,8 +124,8 @@ class BluetoothQuickConnect { test() { try { GLib.spawn_command_line_sync("bluetoothctl --version"); - } catch(error) { - Main.notifyError(`Bluetooth quick connect: error trying to execute "bluetoothctl"`); + } catch (error) { + Main.notifyError(_('Bluetooth quick connect'), _(`Error trying to execute "bluetoothctl"`)); } } diff --git a/extract.sh b/extract.sh new file mode 100755 index 0000000..a4578fe --- /dev/null +++ b/extract.sh @@ -0,0 +1,29 @@ +#!/bin/bash +if [[ $# -ne 1 ]]; then + echo "usage $0 dir" >&2 + exit 1 +fi + +dir="$1" + +if [[ -e $dir ]]; then + echo "Error: $dir already exists" >&2 + exit 1 +fi + +mkdir -p "$dir" +cd "$dir" + +GS=/usr/lib/gnome-shell/libgnome-shell.so + +for r in $(gresource list $GS); do + t="${r/#\/org\/gnome\/shell\/}" + mkdir -p $(dirname $t) + echo Extracting $t + gresource extract $GS $r >$t +done + +echo +echo "Now add the following to /etc/environment and restart gnome-shell" +echo "if you want to run with these extracted source files." +echo "GNOME_SHELL_JS=$PWD" diff --git a/ui.js b/ui.js new file mode 100644 index 0000000..09895b9 --- /dev/null +++ b/ui.js @@ -0,0 +1,79 @@ +// Copyright 2018 Bartosz Jaroszewski +// SPDX-License-Identifier: GPL-2.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +const {Atk, Clutter, Gio, GObject, Graphene, Shell, St} = imports.gi; +const Tweener = imports.ui.tweener; +const PopupMenu = imports.ui.popupMenu; + +var PopupSwitchWithButtonMenuItem = GObject.registerClass( + {Signals: {'clicked': {}}}, + class PopupSwitchWithButtonMenuItem extends PopupMenu.PopupSwitchMenuItem { + _init(text, active, icon, params) { + super._init(text, active, params); + + this.label.x_expand = true; + this._statusBin.x_expand = false; + + if (icon) { + this.insert_child_at_index( + this.create_button(icon), + this.get_n_children() - 1 + ); + } + } + + create_button(iconName) { + let icon = new St.Icon({ + icon_name: iconName, + style_class: 'popup-menu-icon', + }); + + let button = new St.Button({ + child: icon, + x_align: Clutter.ActorAlign.END + }); + + button.connect("enter-event", (widget) => { + Tweener.addTween( + widget.child, { + scale_x: 1.1, + scale_y: 1.1, + time: 0.05, + transition: 'linear' + } + ); + }); + + button.connect("leave-event", (widget) => { + Tweener.addTween( + widget.child, { + scale_x: 1, + scale_y: 1, + time: 0.05, + transition: 'linear' + } + ); + }); + + button.connect('clicked', () => { + this.emit('clicked'); + }); + + return button; + } + } +); -- cgit v1.2.3