From 5c8c4e0aad4c1e2d05960efdfded7c69225e2d95 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 6 Jun 2013 17:27:32 -0400 Subject: [PATCH] panel: Move statuses to the aggregate menu Swap out the implementation of SystemIndicator with a dummy, and build the aggregate menu. At the same time, remove the poweroff and login screen menus, as those were fake aggregate menus beforehand. We lose some flexibility as we lose session-mode-based menu layout, but as each component of the aggregate menu is supposed to be "smart" in response to updating itself when session state changes, I believe it's better than a declarative model. https://bugzilla.gnome.org/show_bug.cgi?id=705845 --- data/theme/gnome-shell.css | 4 - js/Makefile.am | 2 - js/gdm/powerMenu.js | 129 --------------------------------- js/ui/panel.js | 50 +++++++++---- js/ui/panelMenu.js | 10 +-- js/ui/sessionMode.js | 10 +-- js/ui/status/lockScreenMenu.js | 62 ---------------- 7 files changed, 42 insertions(+), 225 deletions(-) delete mode 100644 js/gdm/powerMenu.js delete mode 100644 js/ui/status/lockScreenMenu.js diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index a63c5e739..6bf7095d6 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -616,10 +616,6 @@ StScrollBar StButton#vhandle:active { .panel-status-indicators-box, .panel-status-menu-box { - spacing: 4px; -} - -.lock-screen-status-button-box { spacing: 8px; } diff --git a/js/Makefile.am b/js/Makefile.am index 86fa47042..5184bb2f6 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -21,7 +21,6 @@ nobase_dist_js_DATA = \ gdm/batch.js \ gdm/fingerprint.js \ gdm/loginDialog.js \ - gdm/powerMenu.js \ gdm/realmd.js \ gdm/util.js \ extensionPrefs/main.js \ @@ -91,7 +90,6 @@ nobase_dist_js_DATA = \ ui/shellDBus.js \ ui/status/accessibility.js \ ui/status/keyboard.js \ - ui/status/lockScreenMenu.js \ ui/status/network.js \ ui/status/power.js \ ui/status/volume.js \ diff --git a/js/gdm/powerMenu.js b/js/gdm/powerMenu.js deleted file mode 100644 index 487c1c6fe..000000000 --- a/js/gdm/powerMenu.js +++ /dev/null @@ -1,129 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- -/* - * Copyright 2011 Red Hat, Inc - * - * 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, 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -const Gio = imports.gi.Gio; -const Lang = imports.lang; - -const LoginManager = imports.misc.loginManager; - -const GdmUtil = imports.gdm.util; -const PanelMenu = imports.ui.panelMenu; -const PopupMenu = imports.ui.popupMenu; - -const PowerMenuButton = new Lang.Class({ - Name: 'PowerMenuButton', - Extends: PanelMenu.SystemIndicator, - - _init: function() { - /* Translators: accessible name of the power menu in the login screen */ - this.parent('system-shutdown-symbolic', _("Power")); - - this._loginManager = LoginManager.getLoginManager(); - - this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); - this._settings.connect('changed::disable-restart-buttons', - Lang.bind(this, this._updateVisibility)); - - this._createSubMenu(); - - // ConsoleKit doesn't send notifications when shutdown/reboot - // are disabled, so we update the menu item each time the menu opens - this.menu.connect('open-state-changed', Lang.bind(this, - function(menu, open) { - if (open) { - this._updateHaveShutdown(); - this._updateHaveRestart(); - this._updateHaveSuspend(); - } - })); - this._updateHaveShutdown(); - this._updateHaveRestart(); - this._updateHaveSuspend(); - }, - - _updateVisibility: function() { - let shouldBeVisible = (this._haveSuspend || this._haveShutdown || this._haveRestart); - this.actor.visible = shouldBeVisible && !this._settings.get_boolean('disable-restart-buttons'); - }, - - _updateHaveShutdown: function() { - this._loginManager.canPowerOff(Lang.bind(this, function(result) { - this._haveShutdown = result; - this._powerOffItem.actor.visible = this._haveShutdown; - this._updateVisibility(); - })); - }, - - _updateHaveRestart: function() { - this._loginManager.canReboot(Lang.bind(this, function(result) { - this._haveRestart = result; - this._restartItem.actor.visible = this._haveRestart; - this._updateVisibility(); - })); - }, - - _updateHaveSuspend: function() { - this._loginManager.canSuspend(Lang.bind(this, function(result) { - this._haveSuspend = result; - this._suspendItem.actor.visible = this._haveSuspend; - this._updateVisibility(); - })); - }, - - _createSubMenu: function() { - let item; - - item = new PopupMenu.PopupMenuItem(_("Suspend")); - item.connect('activate', Lang.bind(this, this._onActivateSuspend)); - this.menu.addMenuItem(item); - this._suspendItem = item; - - item = new PopupMenu.PopupMenuItem(_("Restart")); - item.connect('activate', Lang.bind(this, this._onActivateRestart)); - this.menu.addMenuItem(item); - this._restartItem = item; - - item = new PopupMenu.PopupMenuItem(_("Power Off")); - item.connect('activate', Lang.bind(this, this._onActivatePowerOff)); - this.menu.addMenuItem(item); - this._powerOffItem = item; - }, - - _onActivateSuspend: function() { - if (!this._haveSuspend) - return; - - this._loginManager.suspend(); - }, - - _onActivateRestart: function() { - if (!this._haveRestart) - return; - - this._loginManager.reboot(); - }, - - _onActivatePowerOff: function() { - if (!this._haveShutdown) - return; - - this._loginManager.powerOff(); - } -}); diff --git a/js/ui/panel.js b/js/ui/panel.js index 342de77ef..145005139 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -837,31 +837,49 @@ const PanelCorner = new Lang.Class({ } }); +const AggregateMenu = new Lang.Class({ + Name: 'AggregateMenu', + Extends: PanelMenu.Button, + + _init: function() { + this.parent(0.0, _("Settings Menu"), false); + + this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' }); + this.actor.add_child(this._indicators); + + this._network = new imports.ui.status.network.NMApplet(); + this._bluetooth = new imports.ui.status.bluetooth.Indicator(); + this._power = new imports.ui.status.power.Indicator(); + this._volume = new imports.ui.status.volume.Indicator(); + this._system = new imports.ui.status.system.Indicator(); + + this._indicators.add_child(this._network.indicators); + this._indicators.add_child(this._bluetooth.indicators); + this._indicators.add_child(this._power.indicators); + this._indicators.add_child(this._volume.indicators); + this._indicators.add_child(this._system.indicators); + this._indicators.add_child(new St.Label({ text: '\u25BE' })); + + this.menu.addMenuItem(this._volume.menu); + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addMenuItem(this._network.menu); + this.menu.addMenuItem(this._bluetooth.menu); + this.menu.addMenuItem(this._power.menu); + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addMenuItem(this._system.menu); + }, +}); + const PANEL_ITEM_IMPLEMENTATIONS = { 'activities': ActivitiesButton, + 'aggregateMenu': AggregateMenu, 'appMenu': AppMenuButton, 'dateMenu': imports.ui.dateMenu.DateMenuButton, 'a11y': imports.ui.status.accessibility.ATIndicator, 'a11yGreeter': imports.ui.status.accessibility.ATGreeterIndicator, - 'volume': imports.ui.status.volume.Indicator, - 'battery': imports.ui.status.power.Indicator, - 'lockScreen': imports.ui.status.lockScreenMenu.Indicator, 'keyboard': imports.ui.status.keyboard.InputSourceIndicator, - 'powerMenu': imports.gdm.powerMenu.PowerMenuButton, - 'system': imports.ui.status.system.Indicator, }; -if (Config.HAVE_BLUETOOTH) - PANEL_ITEM_IMPLEMENTATIONS['bluetooth'] = - imports.ui.status.bluetooth.Indicator; - -try { - PANEL_ITEM_IMPLEMENTATIONS['network'] = - imports.ui.status.network.NMApplet; -} catch(e) { - log('NMApplet is not supported. It is possible that your NetworkManager version is too old'); -} - const Panel = new Lang.Class({ Name: 'Panel', diff --git a/js/ui/panelMenu.js b/js/ui/panelMenu.js index fb2156631..5dd8d4454 100644 --- a/js/ui/panelMenu.js +++ b/js/ui/panelMenu.js @@ -242,14 +242,11 @@ Signals.addSignalMethods(Button.prototype); */ const SystemIndicator = new Lang.Class({ Name: 'SystemIndicator', - Extends: Button, _init: function() { - this.parent(0.0); - this.actor.add_style_class_name('panel-status-button'); - - this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' }); - this.actor.add_actor(this.indicators); + this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box', + reactive: true }); + this.menu = new PopupMenu.PopupMenuSection(); }, addIndicator: function(gicon) { @@ -259,3 +256,4 @@ const SystemIndicator = new Lang.Class({ return icon; } }); +Signals.addSignalMethods(SystemIndicator.prototype); diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js index 035739cca..0f8b09170 100644 --- a/js/ui/sessionMode.js +++ b/js/ui/sessionMode.js @@ -48,8 +48,7 @@ const _modes = { panel: { left: [], center: ['dateMenu'], - right: ['a11yGreeter', 'display', 'keyboard', - 'volume', 'battery', 'powerMenu'] + right: ['a11yGreeter', 'keyboard', 'aggregateMenu'], }, panelStyle: 'login-screen' }, @@ -62,7 +61,7 @@ const _modes = { panel: { left: [], center: [], - right: ['lockScreen'] + right: ['aggregateMenu'] }, panelStyle: 'lock-screen' }, @@ -74,7 +73,7 @@ const _modes = { panel: { left: [], center: [], - right: ['a11y', 'keyboard', 'lockScreen'] + right: ['a11y', 'keyboard', 'aggregateMenu'] }, panelStyle: 'unlock-screen' }, @@ -96,8 +95,7 @@ const _modes = { panel: { left: ['activities', 'appMenu'], center: ['dateMenu'], - right: ['a11y', 'keyboard', 'volume', 'bluetooth', - 'network', 'battery', 'system'] + right: ['a11y', 'keyboard', 'aggregateMenu'] } } }; diff --git a/js/ui/status/lockScreenMenu.js b/js/ui/status/lockScreenMenu.js deleted file mode 100644 index a735ae82e..000000000 --- a/js/ui/status/lockScreenMenu.js +++ /dev/null @@ -1,62 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Clutter = imports.gi.Clutter; -const GObject = imports.gi.GObject; -const Lang = imports.lang; -const St = imports.gi.St; - -const Main = imports.ui.main; -const PanelMenu = imports.ui.panelMenu; -const PopupMenu = imports.ui.popupMenu; -const VolumeMenu = imports.ui.status.volume; - -const FakeStatusIcon = new Lang.Class({ - Name: 'FakeStatusIcon', - - _init: function(button) { - this.actor = new St.BoxLayout({ style_class: 'panel-status-button-box' }); - this._button = button; - this._button.connect('icons-updated', Lang.bind(this, this._reconstructIcons)); - this._button.actor.bind_property('visible', this.actor, 'visible', - GObject.BindingFlags.SYNC_CREATE); - this._reconstructIcons(); - }, - - _reconstructIcons: function() { - this.actor.destroy_all_children(); - this._button.icons.forEach(Lang.bind(this, function(icon) { - let newIcon = new St.Icon({ style_class: 'system-status-icon' }); - icon.bind_property('gicon', newIcon, 'gicon', - GObject.BindingFlags.SYNC_CREATE); - icon.bind_property('visible', newIcon, 'visible', - GObject.BindingFlags.SYNC_CREATE); - this.actor.add_actor(newIcon); - })); - } -}); - -const Indicator = new Lang.Class({ - Name: 'LockScreenMenuIndicator', - Extends: PanelMenu.SystemIndicator, - - _init: function() { - this.parent(null, _("Volume, network, battery")); - this.indicators.style_class = 'lock-screen-status-button-box'; - - this._volumeControl = VolumeMenu.getMixerControl(); - this._volumeMenu = new VolumeMenu.VolumeMenu(this._volumeControl); - this.menu.addMenuItem(this._volumeMenu); - - this._volume = new FakeStatusIcon(Main.panel.statusArea.volume); - this.indicators.add_child(this._volume.actor); - - // Network may not exist if the user doesn't have NetworkManager - if (Main.panel.statusArea.network) { - this._network = new FakeStatusIcon(Main.panel.statusArea.network); - this.indicators.add_child(this._network.actor); - } - - this._battery = new FakeStatusIcon(Main.panel.statusArea.battery); - this.indicators.add_child(this._battery.actor); - } -});