[gnome-shell-extensions/gnome-3-2] alternative-status-menu: make it coexist with other extensions



commit 6405b010207e45d6bceedbdf65f98c6b8ccd07d0
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Dec 27 15:22:43 2011 +0100

    alternative-status-menu: make it coexist with other extensions
    
    Instead of destroying the whole menu and recreating it, find the
    right position and just destroy/recreate the items we care about.
    
    Based on a patch by Andrea Santilli <andreasantilli gmx com>,
    and cherrypicked from master.
    
    Conflicts:
    
    	extensions/alternative-status-menu/extension.js

 extensions/alternative-status-menu/extension.js |  164 ++++++++++-------------
 1 files changed, 70 insertions(+), 94 deletions(-)
---
diff --git a/extensions/alternative-status-menu/extension.js b/extensions/alternative-status-menu/extension.js
index 08c2f9e..ed21fee 100644
--- a/extensions/alternative-status-menu/extension.js
+++ b/extensions/alternative-status-menu/extension.js
@@ -2,15 +2,17 @@
 const GLib = imports.gi.GLib;
 const Lang = imports.lang;
 const St = imports.gi.St;
-
 const Main = imports.ui.main;
 const PopupMenu = imports.ui.popupMenu;
-const GnomeSession = imports.misc.gnomeSession;
-const UserMenu = imports.ui.userMenu;
 
 const Gettext = imports.gettext.domain('gnome-shell-extensions');
 const _ = Gettext.gettext;
 
+let suspend_item = null;
+let hibernate_item = null;
+let poweroff_item = null;
+let suspend_signal_id = 0, hibernate_signal_id = 0;
+
 function updateSuspend(object, pspec, item) {
     item.actor.visible = object.get_can_suspend();
 }
@@ -35,109 +37,83 @@ function onHibernateActivate(item) {
     }));
 }
 
-function createSubMenu() {
-    let item;
-
-    item = new UserMenu.IMStatusChooserItem();
-    item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupSwitchMenuItem(_("Notifications"));
-    item.connect('activate', Lang.bind(this, this._updatePresenceStatus));
-    this.menu.addMenuItem(item);
-    this._notificationsSwitch = item;
-
-    item = new PopupMenu.PopupSeparatorMenuItem();
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupMenuItem(_("Online Accounts"));
-    item.connect('activate', Lang.bind(this, this._onOnlineAccountsActivate));
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupMenuItem(_("System Settings"));
-    item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupSeparatorMenuItem();
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupMenuItem(_("Lock Screen"));
-    item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
-    this.menu.addMenuItem(item);
-    this._lockScreenItem = item;
-
-    item = new PopupMenu.PopupMenuItem(_("Switch User"));
-    item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
-    this.menu.addMenuItem(item);
-    this._loginScreenItem = item;
-
-    item = new PopupMenu.PopupMenuItem(_("Log Out..."));
-    item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
-    this.menu.addMenuItem(item);
-    this._logoutItem = item;
-
-    item = new PopupMenu.PopupSeparatorMenuItem();
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupMenuItem(_("Suspend"));
-    item.connect('activate', Lang.bind(this, onSuspendActivate));
-    this._upClient.connect('notify::can-suspend', Lang.bind(this, updateSuspend, item));
-    updateSuspend(this._upClient, null, item);
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupMenuItem(_("Hibernate"));
-    item.connect('activate', Lang.bind(this, onHibernateActivate));
-    this._upClient.connect('notify::can-hibernate', Lang.bind(this, updateHibernate, item));
-    updateHibernate(this._upClient, null, item);
-    this.menu.addMenuItem(item);
-
-    item = new PopupMenu.PopupMenuItem(_("Power Off..."));
-    item.connect('activate', Lang.bind(this, function() {
-	this._session.ShutdownRemote();
-    }));
-    this.menu.addMenuItem(item);
-}
-
 // Put your extension initialization code here
 function init(metadata) {
     imports.gettext.bindtextdomain('gnome-shell-extensions', GLib.build_filenamev([metadata.path, 'locale']));
 }
 
-function predestroy(statusMenu) {
-    // HACK! disconnect signals to avoid references to destroyed objects
-    let imstatusitem = statusMenu.menu._getMenuItems()[0];
-    imstatusitem._user.disconnect(imstatusitem._userLoadedId);
-    imstatusitem._user.disconnect(imstatusitem._userChangedId);
-}
-
-function reset(statusMenu) {
-    statusMenu._updateSwitchUser();
-    statusMenu._updateLogout();
-    statusMenu._updateLockScreen();
-
-    statusMenu._presence.getStatus(Lang.bind(statusMenu, statusMenu._updateSwitch));
-
-    // HACK! Obtain the IMStatusChooserItem and force a _updateUser
-    statusMenu.menu._getMenuItems()[0]._updateUser();
-}
-
 function enable() {
     let statusMenu = Main.panel._statusArea.userMenu;
 
-    predestroy(statusMenu);
-    statusMenu.menu.removeAll();
+    let children = statusMenu.menu._getMenuItems();
+    let index = children.length;
+
+    /* find and destroy the old entry */
+    for (let i = children.length - 1; i >= 0; i--) {
+        if (children[i] == statusMenu._suspendOrPowerOffItem) {
+            children[i].destroy();
+            index = i;
+            break;
+        }
+    }
+
+    /* add the new entries */
+    suspend_item = new PopupMenu.PopupMenuItem(_("Suspend"));
+    suspend_item.connect('activate', Lang.bind(statusMenu, onSuspendActivate));
+    suspend_signal_id = statusMenu._upClient.connect('notify::can-suspend', Lang.bind(statusMenu, updateSuspend, suspend_item));
+    updateSuspend(statusMenu._upClient, null, suspend_item);
+    
+    hibernate_item = new PopupMenu.PopupMenuItem(_("Hibernate"));
+    hibernate_item.connect('activate', Lang.bind(statusMenu, onHibernateActivate));
+    hibernate_signal_id = statusMenu._upClient.connect('notify::can-hibernate', Lang.bind(statusMenu, updateHibernate, hibernate_item));
+    updateHibernate(statusMenu._upClient, null, hibernate_item);
+    
+    poweroff_item = new PopupMenu.PopupMenuItem(_("Power Off..."), { style_class: 'popup-alternating-menu-item' });
+    poweroff_item.actor.add_style_pseudo_class('alternate');
+    poweroff_item.connect('activate', Lang.bind(statusMenu, function() {
+	    this._session.ShutdownRemote();
+    }));
+
+    /* insert the entries at the found position */
+    statusMenu.menu.addMenuItem(suspend_item, index);
+    statusMenu.menu.addMenuItem(hibernate_item, index + 1);
+    statusMenu.menu.addMenuItem(poweroff_item, index + 2);
 
-    createSubMenu.call(statusMenu);
-    reset(statusMenu);
+    // clear out this to avoid criticals (we don't mess with
+    // updateSuspendOrPowerOff)
+    statusMenu._suspendOrPowerOffItem = null;
 }
 
 function disable() {
-    // not guarranteed to work, if more extensions operate in the same place
     let statusMenu = Main.panel._statusArea.userMenu;
 
-    predestroy(statusMenu);
-    statusMenu.menu.removeAll();
-
-    statusMenu._createSubMenu();
-    reset(statusMenu);
+    let children = statusMenu.menu._getMenuItems();
+    let index = children.length;
+
+    /* find the index for the previously created suspend entry */
+    for (let i = children.length - 1; i >= 0; i--) {
+        if (children[i] == suspend_item) {
+            index = i;
+            break;
+        }
+    }
+
+    /* disconnect signals */
+    statusMenu._upClient.disconnect(suspend_signal_id);
+    statusMenu._upClient.disconnect(hibernate_signal_id);
+    suspend_signal_id = hibernate_signal_id = 0;
+
+    /* destroy the entries we had created */
+    suspend_item.destroy();
+    hibernate_item.destroy();
+    poweroff_item.destroy();
+
+    /* create a new suspend/poweroff entry */
+    /* empty strings are fine for the labels, since we immediately call updateSuspendOrPowerOff */
+    let item = new PopupMenu.PopupAlternatingMenuItem("", "");
+    /* restore the userMenu field */
+    statusMenu._suspendOrPowerOffItem = item;
+    statusMenu.menu.addMenuItem(item, index);
+    item.connect('activate', Lang.bind(statusMenu, statusMenu._onSuspendOrPowerOffActivate));
+    statusMenu._updateSuspendOrPowerOff();
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]