[gnome-tweak-tool] Support shell extension management in 3.0 and 3.2



commit 0c5c3258fdbe7c8ffec51382131c7a8d3cdf6bb9
Author: John Stowers <john stowers gmail com>
Date:   Sun Aug 28 12:28:52 2011 +1200

    Support shell extension management in 3.0 and 3.2

 gtweak/__init__.py                      |    1 +
 gtweak/gshellwrapper.py                 |   77 +++++++++++++++++++++++++++---
 gtweak/tweaks/tweak_shell_extensions.py |   32 ++++++-------
 gtweak/utils.py                         |   13 +++++
 4 files changed, 98 insertions(+), 25 deletions(-)
---
diff --git a/gtweak/__init__.py b/gtweak/__init__.py
index 95e1805..f817832 100644
--- a/gtweak/__init__.py
+++ b/gtweak/__init__.py
@@ -15,3 +15,4 @@
 # You should have received a copy of the GNU General Public License
 # along with gnome-tweak-tool.  If not, see <http://www.gnu.org/licenses/>.
 
+VERBOSE = False
diff --git a/gtweak/gshellwrapper.py b/gtweak/gshellwrapper.py
index ef1700a..fd8e587 100644
--- a/gtweak/gshellwrapper.py
+++ b/gtweak/gshellwrapper.py
@@ -17,14 +17,18 @@
 
 import os.path
 import json
+import logging
 
 from gi.repository import Gio
 from gi.repository import GLib
 
+import gtweak.utils
+from gtweak.gsettings import GSettingsSetting
+
 class _ShellProxy:
     def __init__(self):
         d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
-        self._proxy = Gio.DBusProxy.new_sync(
+        self.proxy = Gio.DBusProxy.new_sync(
                             d, 0, None,
                             'org.gnome.Shell',
                             '/org/gnome/Shell',
@@ -32,11 +36,15 @@ class _ShellProxy:
                             None)
 
     def execute_js(self, js):
-        result, output = self._proxy.Eval('(s)', js)
+        result, output = self.proxy.Eval('(s)', js)
         if not result:
             raise Exception(output)
         return output
 
+    @property
+    def version(self):
+        return json.loads(self.execute_js('const Config = imports.misc.config; Config.PACKAGE_VERSION'))
+
 class GnomeShell:
 
     EXTENSION_STATE = {
@@ -53,8 +61,9 @@ class GnomeShell:
 
     DATA_DIR = os.path.join(GLib.get_user_data_dir(), "gnome-shell")
 
-    def __init__(self):
-        self._proxy = _ShellProxy()
+    def __init__(self, shellproxy, shellsettings):
+        self._proxy = shellproxy
+        self._settings = shellsettings
 
     def restart(self):
         self._proxy.execute_js('global.reexec_self();')
@@ -62,17 +71,69 @@ class GnomeShell:
     def reload_theme(self):
         self._proxy.execute_js('const Main = imports.ui.main; Main.loadTheme();')
 
+    @property
+    def version(self):
+        return self._proxy.version
+
+class GnomeShell30(GnomeShell):
+
+    EXTENSION_DISABLED_KEY = "disabled-extensions"
+    EXTENSION_NEED_RESTART = True
+
+    def __init__(self, *args, **kwargs):
+        GnomeShell.__init__(self, *args, **kwargs)
+
     def list_extensions(self):
         out = self._proxy.execute_js('const ExtensionSystem = imports.ui.extensionSystem; ExtensionSystem.extensionMeta')
         return json.loads(out)
 
-    @property
-    def version(self):
-        return json.loads(self._proxy.execute_js('const Config = imports.misc.config; Config.PACKAGE_VERSION'))
+    def extension_is_active(self, state, uuid):
+        return state == GnomeShell.EXTENSION_STATE["ENABLED"] and \
+                not self._settings.setting_is_in_list(self.EXTENSION_DISABLED_KEY, uuid)
 
+    def enable_extension(self, uuid):
+        self._settings.setting_remove_from_list(self.EXTENSION_DISABLED_KEY, uuid)
 
+    def disable_extension(self, uuid):
+        self._settings.setting_add_to_list(self.EXTENSION_DISABLED_KEY, uuid)
+
+class GnomeShell32(GnomeShell):
+
+    EXTENSION_ENABLED_KEY = "enabled-extensions"
+    EXTENSION_NEED_RESTART = False
+
+    def extension_is_active(self, state, uuid):
+        return state == GnomeShell.EXTENSION_STATE["ENABLED"] and \
+                self._settings.setting_is_in_list(self.EXTENSION_ENABLED_KEY, uuid)
+
+    def enable_extension(self, uuid):
+        self._settings.setting_add_to_list(self.EXTENSION_ENABLED_KEY, uuid)
+
+    def disable_extension(self, uuid):
+        self._settings.setting_remove_from_list(self.EXTENSION_ENABLED_KEY, uuid)
+
+ gtweak utils singleton
+class GnomeShellFactory:
+    def __init__(self):
+        proxy = _ShellProxy()
+        settings = GSettingsSetting("org.gnome.shell")
+        v = map(int,proxy.version.split("."))
+
+        if v >= [3,1,4]:
+            self.shell = GnomeShell32(proxy, settings)
+        else:
+            self.shell = GnomeShell30(proxy, settings)
+
+        logging.debug("Shell version: %s", str(v))
+
+    def get_shell(self):
+        return self.shell
 
 if __name__ == "__main__":
-    s = GnomeShell()
+    gtweak.GSETTINGS_SCHEMA_DIR = "/usr/share/glib-2.0/schemas/"
+
+    s = GnomeShellFactory().get_shell()
     print "Shell Version: %s" % s.version
     print s.list_extensions()
+
+    print s == GnomeShellFactory().get_shell()
diff --git a/gtweak/tweaks/tweak_shell_extensions.py b/gtweak/tweaks/tweak_shell_extensions.py
index 3722a76..a453f33 100644
--- a/gtweak/tweaks/tweak_shell_extensions.py
+++ b/gtweak/tweaks/tweak_shell_extensions.py
@@ -8,27 +8,20 @@ from gi.repository import Gtk
 from gi.repository import GLib
 
 from gtweak.utils import extract_zip_file
-from gtweak.gsettings import GSettingsSetting
-from gtweak.gshellwrapper import GnomeShell
+from gtweak.gshellwrapper import GnomeShell, GnomeShellFactory
 from gtweak.tweakmodel import Tweak, TweakGroup
 from gtweak.widgets import ZipFileChooserButton, build_label_beside_widget, build_horizontal_sizegroup
 
 class _ShellExtensionTweak(Tweak):
 
-    EXTENSION_ENABLED_KEY = "enabled-extensions"
-
-    def __init__(self, shell, ext, settings, **options):
+    def __init__(self, shell, ext, **options):
         Tweak.__init__(self, ext["name"], ext.get("description",""), **options)
 
         self._shell = shell
-        self._settings = settings
+        state = ext.get("state")
 
         sw = Gtk.Switch()
-        state = ext.get("state")
-        sw.set_active(
-                state == GnomeShell.EXTENSION_STATE["ENABLED"] and \
-                self._settings.setting_is_in_list(self.EXTENSION_ENABLED_KEY, ext["uuid"])
-        )
+        sw.set_active(self._shell.extension_is_active(state, ext["uuid"]))
         sw.connect('notify::active', self._on_extension_toggled, ext["uuid"])
 
         warning = None
@@ -53,9 +46,15 @@ class _ShellExtensionTweak(Tweak):
 
     def _on_extension_toggled(self, sw, active, uuid):
         if not sw.get_active():
-            self._settings.setting_remove_from_list(self.EXTENSION_ENABLED_KEY, uuid)
+            self._shell.disable_extension(uuid)
         else:
-            self._settings.setting_add_to_list(self.EXTENSION_ENABLED_KEY, uuid)
+            self._shell.enable_extension(uuid)
+
+        if self._shell.EXTENSION_NEED_RESTART:
+            self.notify_action_required(
+                _("The shell must be restarted for changes to take effect"),
+                _("Restart"),
+                self._shell.restart)
 
 class _ShellExtensionInstallerTweak(Tweak):
 
@@ -143,25 +142,24 @@ class ShellExtensionTweakGroup(TweakGroup):
 
         #check the shell is running
         try:
-            shell = GnomeShell()
+            shell = GnomeShellFactory().get_shell()
 
             #add the extension installer
             extension_tweaks.append(
                 _ShellExtensionInstallerTweak(shell, size_group=sg))
 
             try:
-                settings = GSettingsSetting("org.gnome.shell")
                 #add a tweak for each installed extension
                 for extension in shell.list_extensions().values():
                     try:
                         extension_tweaks.append(
-                            _ShellExtensionTweak(shell, extension, settings, size_group=sg))
+                            _ShellExtensionTweak(shell, extension, size_group=sg))
                     except:
                         logging.warning("Invalid extension", exc_info=True)
             except:
                 logging.warning("Error listing extensions", exc_info=True)
         except:
-            logging.warning("Error detecting shell")
+            logging.warning("Error detecting shell", exc_info=True)
 
         self.set_tweaks(*extension_tweaks)
 
diff --git a/gtweak/utils.py b/gtweak/utils.py
index bf688f7..85f052f 100644
--- a/gtweak/utils.py
+++ b/gtweak/utils.py
@@ -26,6 +26,19 @@ from gtweak.gconf import GConfSetting
 
 from gi.repository import GLib
 
+def singleton(cls):
+    """
+    Singleton decorator that works with GObject derived types. The 'recommended'
+    python one - http://wiki.python.org/moin/PythonDecoratorLibrary#Singleton
+    does not (interacts badly with GObjectMeta
+    """
+    instances = {}
+    def getinstance():
+        if cls not in instances:
+            instances[cls] = cls()
+        return instances[cls]
+    return getinstance
+
 def make_combo_list_with_default(opts, default, title=True, default_text=None):
     """
     Turns a list of values into a list of value,name (where name is the



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