bluetooth: Adapt to new designs for the bluetooth menu
This is a part of the new system status design, see https://wiki.gnome.org/GnomeShell/Design/Guidelines/SystemStatus/ for design details. https://bugzilla.gnome.org/show_bug.cgi?id=704368
This commit is contained in:
parent
87245c7b33
commit
7dc9a9bf2f
@ -13,13 +13,6 @@ const NotificationDaemon = imports.ui.notificationDaemon;
|
|||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
const ConnectionState = {
|
|
||||||
DISCONNECTED: 0,
|
|
||||||
CONNECTED: 1,
|
|
||||||
DISCONNECTING: 2,
|
|
||||||
CONNECTING: 3
|
|
||||||
}
|
|
||||||
|
|
||||||
const Indicator = new Lang.Class({
|
const Indicator = new Lang.Class({
|
||||||
Name: 'BTIndicator',
|
Name: 'BTIndicator',
|
||||||
Extends: PanelMenu.SystemStatusButton,
|
Extends: PanelMenu.SystemStatusButton,
|
||||||
@ -27,59 +20,18 @@ const Indicator = new Lang.Class({
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
this.parent('bluetooth-disabled-symbolic', _("Bluetooth"));
|
this.parent('bluetooth-disabled-symbolic', _("Bluetooth"));
|
||||||
|
|
||||||
|
// The Bluetooth menu only appears when Bluetooth is in use,
|
||||||
|
// so just statically build it with a "Turn Off" menu item.
|
||||||
|
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Bluetooth"), true);
|
||||||
|
this._item.icon.icon_name = 'bluetooth-active-symbolic';
|
||||||
|
this._item.menu.addAction(_("Turn Off"), Lang.bind(this, function() {
|
||||||
|
this._applet.killswitch_state = GnomeBluetooth.KillswitchState.SOFT_BLOCKED;
|
||||||
|
}));
|
||||||
|
this._item.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
|
||||||
|
|
||||||
this._applet = new GnomeBluetoothApplet.Applet();
|
this._applet = new GnomeBluetoothApplet.Applet();
|
||||||
|
this._applet.connect('devices-changed', Lang.bind(this, this._sync));
|
||||||
this._killswitch = new PopupMenu.PopupSwitchMenuItem(_("Bluetooth"), false);
|
this._sync();
|
||||||
this._applet.connect('notify::killswitch-state', Lang.bind(this, this._updateKillswitch));
|
|
||||||
this._killswitch.connect('toggled', Lang.bind(this, function() {
|
|
||||||
let current_state = this._applet.killswitch_state;
|
|
||||||
if (current_state != GnomeBluetooth.KillswitchState.HARD_BLOCKED &&
|
|
||||||
current_state != GnomeBluetooth.KillswitchState.NO_ADAPTER) {
|
|
||||||
this._applet.killswitch_state = this._killswitch.state ?
|
|
||||||
GnomeBluetooth.KillswitchState.UNBLOCKED:
|
|
||||||
GnomeBluetooth.KillswitchState.SOFT_BLOCKED;
|
|
||||||
} else
|
|
||||||
this._killswitch.setToggleState(false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._discoverable = new PopupMenu.PopupSwitchMenuItem(_("Visibility"), this._applet.discoverable);
|
|
||||||
this._applet.connect('notify::discoverable', Lang.bind(this, function() {
|
|
||||||
this._discoverable.setToggleState(this._applet.discoverable);
|
|
||||||
}));
|
|
||||||
this._discoverable.connect('toggled', Lang.bind(this, function() {
|
|
||||||
this._applet.discoverable = this._discoverable.state;
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._updateKillswitch();
|
|
||||||
this.menu.addMenuItem(this._killswitch);
|
|
||||||
this.menu.addMenuItem(this._discoverable);
|
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
||||||
|
|
||||||
this._fullMenuItems = [new PopupMenu.PopupSeparatorMenuItem(),
|
|
||||||
new PopupMenu.PopupMenuItem(_("Send Files to Device…")),
|
|
||||||
new PopupMenu.PopupMenuItem(_("Set Up a New Device…")),
|
|
||||||
new PopupMenu.PopupSeparatorMenuItem()];
|
|
||||||
this._hasDevices = false;
|
|
||||||
|
|
||||||
this._fullMenuItems[1].connect('activate', function() {
|
|
||||||
GLib.spawn_command_line_async('bluetooth-sendto');
|
|
||||||
});
|
|
||||||
this._fullMenuItems[2].connect('activate', function() {
|
|
||||||
GLib.spawn_command_line_async('bluetooth-wizard');
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let i = 0; i < this._fullMenuItems.length; i++) {
|
|
||||||
let item = this._fullMenuItems[i];
|
|
||||||
this.menu.addMenuItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._deviceItemPosition = 3;
|
|
||||||
this._deviceItems = [];
|
|
||||||
this._applet.connect('devices-changed', Lang.bind(this, this._updateDevices));
|
|
||||||
this._updateDevices();
|
|
||||||
|
|
||||||
this._applet.connect('notify::show-full-menu', Lang.bind(this, this._updateFullMenu));
|
|
||||||
this._updateFullMenu();
|
|
||||||
|
|
||||||
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
|
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
|
||||||
this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
|
this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
|
||||||
@ -88,183 +40,18 @@ const Indicator = new Lang.Class({
|
|||||||
this._applet.connect('cancel-request', Lang.bind(this, this._cancelRequest));
|
this._applet.connect('cancel-request', Lang.bind(this, this._cancelRequest));
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateKillswitch: function() {
|
_sync: function() {
|
||||||
let current_state = this._applet.killswitch_state;
|
let connectedDevices = this._applet.get_devices().filter(function(device) {
|
||||||
let on = current_state == GnomeBluetooth.KillswitchState.UNBLOCKED;
|
return device.connected;
|
||||||
let has_adapter = current_state != GnomeBluetooth.KillswitchState.NO_ADAPTER;
|
});
|
||||||
let can_toggle = current_state != GnomeBluetooth.KillswitchState.NO_ADAPTER &&
|
let nDevices = connectedDevices.length;
|
||||||
current_state != GnomeBluetooth.KillswitchState.HARD_BLOCKED;
|
|
||||||
|
|
||||||
this._killswitch.setToggleState(on);
|
let on = nDevices > 0;
|
||||||
if (can_toggle)
|
this.mainIcon.visible = on;
|
||||||
this._killswitch.setStatus(null);
|
this.actor.visible = on;
|
||||||
else
|
|
||||||
/* TRANSLATORS: this means that bluetooth was disabled by hardware rfkill */
|
|
||||||
this._killswitch.setStatus(_("hardware disabled"));
|
|
||||||
|
|
||||||
this.actor.visible = has_adapter;
|
if (on)
|
||||||
|
this._item.status.text = ngettext("%d Connected Device", "%d Connected Devices").format(nDevices);
|
||||||
if (on) {
|
|
||||||
this._discoverable.actor.show();
|
|
||||||
this.setIcon('bluetooth-active-symbolic');
|
|
||||||
} else {
|
|
||||||
this._discoverable.actor.hide();
|
|
||||||
this.setIcon('bluetooth-disabled-symbolic');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateDevices: function() {
|
|
||||||
let devices = this._applet.get_devices();
|
|
||||||
|
|
||||||
let newlist = [ ];
|
|
||||||
for (let i = 0; i < this._deviceItems.length; i++) {
|
|
||||||
let item = this._deviceItems[i];
|
|
||||||
let destroy = true;
|
|
||||||
for (let j = 0; j < devices.length; j++) {
|
|
||||||
if (item._device.device_path == devices[j].device_path) {
|
|
||||||
this._updateDeviceItem(item, devices[j]);
|
|
||||||
destroy = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (destroy)
|
|
||||||
item.destroy();
|
|
||||||
else
|
|
||||||
newlist.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._deviceItems = newlist;
|
|
||||||
this._hasDevices = newlist.length > 0;
|
|
||||||
for (let i = 0; i < devices.length; i++) {
|
|
||||||
let d = devices[i];
|
|
||||||
if (d._item)
|
|
||||||
continue;
|
|
||||||
let item = this._createDeviceItem(d);
|
|
||||||
if (item) {
|
|
||||||
this.menu.addMenuItem(item, this._deviceItemPosition + this._deviceItems.length);
|
|
||||||
this._deviceItems.push(item);
|
|
||||||
this._hasDevices = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateDeviceItem: function(item, device) {
|
|
||||||
if (!device.can_connect && device.capabilities == GnomeBluetoothApplet.Capabilities.NONE) {
|
|
||||||
item.destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prevDevice = item._device;
|
|
||||||
let prevCapabilities = prevDevice.capabilities;
|
|
||||||
let prevCanConnect = prevDevice.can_connect;
|
|
||||||
|
|
||||||
// adopt the new device object
|
|
||||||
item._device = device;
|
|
||||||
device._item = item;
|
|
||||||
|
|
||||||
// update properties
|
|
||||||
item.label.text = device.alias;
|
|
||||||
|
|
||||||
if (prevCapabilities != device.capabilities ||
|
|
||||||
prevCanConnect != device.can_connect) {
|
|
||||||
// need to rebuild the submenu
|
|
||||||
item.menu.removeAll();
|
|
||||||
this._buildDeviceSubMenu(item, device);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update connected property
|
|
||||||
if (device.can_connect)
|
|
||||||
item._connectedMenuItem.setToggleState(device.connected);
|
|
||||||
},
|
|
||||||
|
|
||||||
_createDeviceItem: function(device) {
|
|
||||||
if (!device.can_connect && device.capabilities == GnomeBluetoothApplet.Capabilities.NONE)
|
|
||||||
return null;
|
|
||||||
let item = new PopupMenu.PopupSubMenuMenuItem(device.alias);
|
|
||||||
|
|
||||||
// adopt the device object, and add a back link
|
|
||||||
item._device = device;
|
|
||||||
device._item = item;
|
|
||||||
|
|
||||||
this._buildDeviceSubMenu(item, device);
|
|
||||||
|
|
||||||
return item;
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildDeviceSubMenu: function(item, device) {
|
|
||||||
if (device.can_connect) {
|
|
||||||
let menuitem = new PopupMenu.PopupSwitchMenuItem(_("Connection"), device.connected);
|
|
||||||
item._connected = device.connected;
|
|
||||||
item._connectedMenuItem = menuitem;
|
|
||||||
menuitem.connect('toggled', Lang.bind(this, function() {
|
|
||||||
if (item._connected > ConnectionState.CONNECTED) {
|
|
||||||
// operation already in progress, revert
|
|
||||||
// (should not happen anyway)
|
|
||||||
menuitem.setToggleState(menuitem.state);
|
|
||||||
}
|
|
||||||
if (item._connected) {
|
|
||||||
item._connected = ConnectionState.DISCONNECTING;
|
|
||||||
menuitem.setStatus(_("disconnecting..."));
|
|
||||||
this._applet.disconnect_device(item._device.device_path, function(applet, success) {
|
|
||||||
if (success) { // apply
|
|
||||||
item._connected = ConnectionState.DISCONNECTED;
|
|
||||||
menuitem.setToggleState(false);
|
|
||||||
} else { // revert
|
|
||||||
item._connected = ConnectionState.CONNECTED;
|
|
||||||
menuitem.setToggleState(true);
|
|
||||||
}
|
|
||||||
menuitem.setStatus(null);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
item._connected = ConnectionState.CONNECTING;
|
|
||||||
menuitem.setStatus(_("connecting..."));
|
|
||||||
this._applet.connect_device(item._device.device_path, function(applet, success) {
|
|
||||||
if (success) { // apply
|
|
||||||
item._connected = ConnectionState.CONNECTED;
|
|
||||||
menuitem.setToggleState(true);
|
|
||||||
} else { // revert
|
|
||||||
item._connected = ConnectionState.DISCONNECTED;
|
|
||||||
menuitem.setToggleState(false);
|
|
||||||
}
|
|
||||||
menuitem.setStatus(null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
item.menu.addMenuItem(menuitem);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_PUSH) {
|
|
||||||
item.menu.addAction(_("Send Files…"), Lang.bind(this, function() {
|
|
||||||
this._applet.send_to_address(device.bdaddr, device.alias);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateFullMenu: function() {
|
|
||||||
if (this._applet.show_full_menu) {
|
|
||||||
this._showAll(this._fullMenuItems);
|
|
||||||
if (this._hasDevices)
|
|
||||||
this._showAll(this._deviceItems);
|
|
||||||
} else {
|
|
||||||
this._hideAll(this._fullMenuItems);
|
|
||||||
this._hideAll(this._deviceItems);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_showAll: function(items) {
|
|
||||||
for (let i = 0; i < items.length; i++)
|
|
||||||
items[i].actor.show();
|
|
||||||
},
|
|
||||||
|
|
||||||
_hideAll: function(items) {
|
|
||||||
for (let i = 0; i < items.length; i++)
|
|
||||||
items[i].actor.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
_destroyAll: function(items) {
|
|
||||||
for (let i = 0; i < items.length; i++)
|
|
||||||
items[i].destroy();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_ensureSource: function() {
|
_ensureSource: function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user