[gnome-tweak-tool] Greatly improve shell theme functionality



commit be8cdbb101624270c706848487530063d4284d54
Author: John Stowers <john stowers gmail com>
Date:   Thu Apr 28 00:04:22 2011 +1200

    Greatly improve shell theme functionality

 NEWS                         |    2 +
 gtweak/gshellwrapper.py      |    3 +
 gtweak/tweaks/tweak_shell.py |  115 ++++++++++++++++++++++++++++--------------
 gtweak/widgets.py            |    4 ++
 4 files changed, 86 insertions(+), 38 deletions(-)
---
diff --git a/NEWS b/NEWS
index 250663a..921a526 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@
      desktop icons (bug 648087)
    * Improved robustness for missing theme/icon
      directories (bug 648735)
+   * Fix shell theme installation for themes found in the wild
+   * Improve shell theme selection
 
 3.0.2
    * Really tweak window theme - both the fallback and the
diff --git a/gtweak/gshellwrapper.py b/gtweak/gshellwrapper.py
index 7ccc8d0..1b75b60 100644
--- a/gtweak/gshellwrapper.py
+++ b/gtweak/gshellwrapper.py
@@ -54,6 +54,9 @@ class GnomeShell:
         out = self._proxy.execute_js('const ExtensionSystem = imports.ui.extensionSystem; ExtensionSystem.extensionMeta')
         return json.loads(out)
 
+    def get_version(self):
+        return json.loads(self._proxy.execute_js('const Config = imports.misc.config; Config.PACKAGE_VERSION'))
+
 if __name__ == "__main__":
     s = GnomeShell()
     print s.list_extensions()
diff --git a/gtweak/tweaks/tweak_shell.py b/gtweak/tweaks/tweak_shell.py
index 0fd86a4..97cc3c2 100644
--- a/gtweak/tweaks/tweak_shell.py
+++ b/gtweak/tweaks/tweak_shell.py
@@ -19,14 +19,16 @@ import os.path
 import shutil
 import zipfile
 import tempfile
+import logging
 
 from gi.repository import Gtk
 from gi.repository import GLib
 
+from gtweak.utils import walk_directories
 from gtweak.gsettings import GSettingsSetting
 from gtweak.gshellwrapper import GnomeShell
 from gtweak.tweakmodel import Tweak, TweakGroup
-from gtweak.widgets import GConfComboTweak, GSettingsComboEnumTweak, GSettingsSwitchTweak, build_label_beside_widget, build_horizontal_sizegroup
+from gtweak.widgets import GConfComboTweak, GSettingsComboEnumTweak, GSettingsSwitchTweak, build_label_beside_widget, build_horizontal_sizegroup, build_combo_box_text
 
 class ShowWindowButtons(GConfComboTweak):
     def __init__(self, **options):
@@ -50,7 +52,7 @@ class _ThemeZipChooser(Gtk.FileChooserButton):
         #self.set_width_chars(15)
         self.set_local_only(True)
 
-class ThemeInstaller(Tweak):
+class ShellThemeTweak(Tweak):
 
     THEME_EXT_NAME = "user-theme gnome-shell-extensions gnome org"
     THEME_GSETTINGS_SCHEMA = "org.gnome.shell.extensions.user-theme"
@@ -68,11 +70,16 @@ class ThemeInstaller(Tweak):
             error = "Shell not running"
         try:
             extensions = self._shell.list_extensions()
-            if ThemeInstaller.THEME_EXT_NAME in extensions and extensions[ThemeInstaller.THEME_EXT_NAME]["state"] == 1:
+            if ShellThemeTweak.THEME_EXT_NAME in extensions and extensions[ShellThemeTweak.THEME_EXT_NAME]["state"] == 1:
                 #check the correct gsettings key is present
                 try:
-                    self._settings = GSettingsSetting(ThemeInstaller.THEME_GSETTINGS_SCHEMA)
-                    name = self._settings.get_value(ThemeInstaller.THEME_GSETTINGS_NAME)
+                    self._settings = GSettingsSetting(ShellThemeTweak.THEME_GSETTINGS_SCHEMA)
+                    name = self._settings.get_value(ShellThemeTweak.THEME_GSETTINGS_NAME)
+
+                    #assume the usertheme version is that version of the shell which
+                    #it most supports (this is a poor assumption)
+                    self._usertheme_extension_version = max(extensions[ShellThemeTweak.THEME_EXT_NAME]["shell-version"])
+
                     error = None
                 except:
                     error = "User Theme extension schema missing"
@@ -90,9 +97,21 @@ class ThemeInstaller(Tweak):
             self.widget_for_size_group = info
         else:
             hb = Gtk.HBox()
-            b = Gtk.Button.new_from_stock(Gtk.STOCK_REVERT_TO_SAVED)
-            b.connect("clicked", self._on_revert)
-            hb.pack_start(b, False, False, 5)
+
+            #build a combo box with all the valid theme options
+            valid = walk_directories( (ShellThemeTweak.THEME_DIR,), lambda d:
+                        os.path.exists(os.path.join(d, "gnome-shell")) and \
+                        os.path.exists(os.path.join(d, "gnome-shell", "gnome-shell.css")))
+            #manually add Adwiata to represent the default
+            #valid.append( ("Adwiata", "") )
+
+            cb = build_combo_box_text(
+                    self._settings.get_string(ShellThemeTweak.THEME_GSETTINGS_NAME),
+                    ("", "Adwiata"),
+                    *[(v,v) for v in valid])
+            cb.connect('changed', self._on_combo_changed)
+            hb.pack_start(cb, False, False, 5)
+            self.combo = cb
 
             chooser = _ThemeZipChooser()
             chooser.connect("file-set", self._on_file_set)
@@ -101,54 +120,74 @@ class ThemeInstaller(Tweak):
             self.widget = build_label_beside_widget(self.name, hb)
             self.widget_for_size_group = chooser
     
-    def _extract_theme_zip(self, z, theme_name):
+    def _extract_theme_zip(self, z, theme_name, theme_members_path):
         tmp = tempfile.mkdtemp()
-        dest = os.path.join(ThemeInstaller.THEME_DIR, theme_name, "gnome-shell")
+        dest = os.path.join(ShellThemeTweak.THEME_DIR, theme_name, "gnome-shell")
+
+        logging.info("Extracting theme %s to %s" % (theme_name, tmp))
+
         try:
             if os.path.exists(dest):
                 shutil.rmtree(dest)
             z.extractall(tmp)
-            shutil.copytree(os.path.join(tmp, "theme"), dest)
-            self._settings.set_value(ThemeInstaller.THEME_GSETTINGS_NAME, theme_name)
+            shutil.copytree(os.path.join(tmp, theme_members_path), dest)
+            return theme_name
         except OSError:
             self.notify_error("Error installing theme")
-
-    def _shell_reload_theme(self):
-        #reloading the theme works OK, however there are some problems with reloading images.
-        #https://bugzilla.gnome.org/show_bug.cgi?id=644125
-        #however, smashing the whole shell just to change themes is pretty extreme. So we
-        #just let the user-theme extension pick up the change by itself
-        #
-        #self._shell.reload_theme()
-        #self.notify_action_required(
-        #        "The shell must be restarted to apply the theme",
-        #        "Restart",
-        #        lambda: self._shell.restart())
-        pass
+            return None
 
     def _on_file_set(self, chooser):
         f = chooser.get_filename()
 
         with zipfile.ZipFile(f, 'r') as z:
             try:
-                #check this looks like a valid theme
-                info = z.getinfo('theme/gnome-shell.css')
-                #the theme name is the filename, for the moment
-                self._extract_theme_zip(
-                        z,
-                        os.path.splitext(os.path.basename(f))[0])
-                self._shell_reload_theme()
-            except KeyError:
+                fragment = ()
+                for n in z.namelist():
+                    if n.endswith("gnome-shell.css"):
+                        fragment = n.split("/")[0:-1]
+                        break
+
+                if not fragment:
+                    raise Exception("Could not find gnome-shell.css")
+
+                #old style themes name was taken from the zip name
+                if fragment[0] == "theme" and len(fragment) == 1:
+                    theme_name = os.path.basename(f)
+                else:
+                    theme_name = fragment[0]
+                theme_members_path = "/".join(fragment)
+
+                installed_name = self._extract_theme_zip(
+                                        z,
+                                        theme_name,
+                                        theme_members_path)
+                if installed_name:
+                    print self.combo.get_model().append( (installed_name, installed_name) )
+
+            except:
                 #does not look like a valid theme
                 self.notify_error("Invalid theme file")
         #set button back to default state
         chooser.unselect_all()
 
-    def _on_revert(self, btn):
-        self._settings.set_value(ThemeInstaller.THEME_GSETTINGS_NAME, "")
-        self._shell_reload_theme()
-
+    def _on_combo_changed(self, combo):
+        val = combo.get_model().get_value(combo.get_active_iter(), 0)
+        self._settings.set_value(ShellThemeTweak.THEME_GSETTINGS_NAME, val)
 
+        #reloading the theme is not really necessary, the user-theme should pick
+        #pick up the change.
+        #
+        #however there are some problems with reloading images.
+        #https://bugzilla.gnome.org/show_bug.cgi?id=644125
+        #
+        #resetting to the default theme is also fucked
+        #https://bugzilla.gnome.org/show_bug.cgi?id=647386
+        if not val:
+            if self._usertheme_extension_version < "3.0.2":
+                self.notify_action_required(
+                    "The shell must be restarted to apply the theme",
+                    "Restart",
+                    lambda: self._shell.restart())
 
 sg = build_horizontal_sizegroup()
 
@@ -158,7 +197,7 @@ TWEAK_GROUPS = (
             GSettingsSwitchTweak("org.gnome.shell.clock", "show-date", schema_filename="org.gnome.shell.gschema.xml"),
             GSettingsSwitchTweak("org.gnome.shell.calendar", "show-weekdate", schema_filename="org.gnome.shell.gschema.xml"),
             ShowWindowButtons(size_group=sg),
-            ThemeInstaller(size_group=sg),
+            ShellThemeTweak(size_group=sg),
             GSettingsComboEnumTweak("org.gnome.settings-daemon.plugins.power", "lid-close-battery-action", size_group=sg),
             GSettingsComboEnumTweak("org.gnome.settings-daemon.plugins.power", "lid-close-ac-action", size_group=sg)),
 )
diff --git a/gtweak/widgets.py b/gtweak/widgets.py
index 110cfce..f50ae29 100644
--- a/gtweak/widgets.py
+++ b/gtweak/widgets.py
@@ -31,6 +31,10 @@ def build_label_beside_widget(txt, widget, hbox=None):
     return hbox
 
 def build_combo_box_text(selected, *values):
+    """
+    builds a GtkComboBox and model containing the supplied values.
+    @values: a list of 2-tuples (value, name)
+    """
     store = Gtk.ListStore(str, str)
 
     selected_iter = None



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