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



commit 7dd6b5e11279f12bc1cb1b0bd5b057e18c3c7260
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>

 extensions/alternative-status-menu/extension.js |  152 +++++++++++------------
 1 files changed, 74 insertions(+), 78 deletions(-)
---
diff --git a/extensions/alternative-status-menu/extension.js b/extensions/alternative-status-menu/extension.js
index c0b3646..9675196 100644
--- a/extensions/alternative-status-menu/extension.js
+++ b/extensions/alternative-status-menu/extension.js
@@ -1,15 +1,17 @@
 /* -*- mode: js2 - indent-tabs-mode: nil - js2-basic-offset: 4 -*- */
 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,69 +37,7 @@ 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);
 
-    // clear out this to avoid criticals
-    this._suspendOrPowerOffItem = null;
 }
 
 // Put your extension initialization code here
@@ -106,25 +46,81 @@ function init(metadata) {
     me.convenience.initTranslations(metadata);
 }
 
-function reset(statusMenu) {
-    statusMenu._updateSwitchUser();
-    statusMenu._updateLogout();
-    statusMenu._updateLockScreen();
-
-    statusMenu._updateSwitch(statusMenu._presence.status);
+function resetMenu() {
 }
 
 function enable() {
     let statusMenu = Main.panel._statusArea.userMenu;
-    statusMenu.menu.removeAll();
-    createSubMenu.call(statusMenu);
-    reset(statusMenu);
+
+    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);
+
+    // 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;
-    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]