[gnome-shell/wip/background-rework: 4/4] add background thing



commit 509afe66939d98b563eb3dcc46649f9d732709c1
Author: Ray Strode <rstrode redhat com>
Date:   Fri Jan 11 10:51:57 2013 -0500

    add background thing

 js/Makefile.am              |    1 +
 js/ui/background.js         |  157 +++++++++++++++++++++++++++++++++++++++++++
 js/ui/layout.js             |   30 ++++++++-
 js/ui/overview.js           |   23 ++-----
 js/ui/screenShield.js       |   28 ++++----
 js/ui/workspaceThumbnail.js |   12 ++--
 src/shell-global.c          |   11 ---
 7 files changed, 215 insertions(+), 47 deletions(-)
---
diff --git a/js/Makefile.am b/js/Makefile.am
index 29187da..b7bfa9e 100644
--- a/js/Makefile.am
+++ b/js/Makefile.am
@@ -38,6 +38,7 @@ nobase_dist_js_DATA = 	\
 	ui/altTab.js		\
 	ui/appDisplay.js	\
 	ui/appFavorites.js	\
+ 	ui/background.js	\
 	ui/boxpointer.js	\
 	ui/calendar.js		\
 	ui/checkBox.js		\
diff --git a/js/ui/background.js b/js/ui/background.js
new file mode 100644
index 0000000..f3be5f5
--- /dev/null
+++ b/js/ui/background.js
@@ -0,0 +1,157 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Cairo = imports.cairo;
+const Clutter = imports.gi.Clutter;
+const GdkPixbuf = imports.gi.GdkPixbuf;
+const GDesktopEnums = imports.gi.GDesktopEnums;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GnomeDesktop = imports.gi.GnomeDesktop;
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+const Shell = imports.gi.Shell;
+const Signals = imports.signals;
+const St = imports.gi.St;
+
+const Layout = imports.ui.layout;
+const Util = imports.misc.util;
+
+const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
+const DRAW_BACKGROUND_KEY = 'draw-background';
+const PRIMARY_COLOR_KEY = 'primary-color';
+const SECONDARY_COLOR_KEY = 'secondary-color';
+const COLOR_SHADING_TYPE_KEY = 'color-shading-type';
+const PICTURE_OPTIONS_KEY = 'picture-options';
+const PICTURE_OPACITY_KEY = 'picture-opacity';
+const PICTURE_URI_KEY = 'picture-uri';
+
+const BackgroundCanvas = new Lang.Class({
+    Name: 'BackgroundCanvas',
+
+    _init: function(width, height, shadingType, primaryColor, secondaryColor) {
+        this.actor = new St.DrawingArea();
+        this.actor.set_style("width: " + width + "px; height: " + height + "px;");
+
+        this._shadingType = shadingType;
+        this._primaryColor = primaryColor;
+        this._secondaryColor = secondaryColor;
+
+        this.actor.connect('repaint', Lang.bind(this, this._onRepaint));
+    },
+
+    _onRepaint: function(area) {
+        let cr = area.get_context();
+        let [width, height] = area.get_surface_size();
+
+        if (this._shadingType == GDesktopEnums.BackgroundShading.SOLID) {
+                Clutter.cairo_set_source_color(cr, this._primaryColor);
+        } else if (this._shadingType == GDesktopEnums.BackgroundShading.HORIZONTAL ||
+                   this._shadingType == GDesktopEnums.BackgroundShading.VERTICAL) {
+            let pattern;
+
+            if (this._shadingType == GDesktopEnums.BackgroundShading.HORIZONTAL) {
+                pattern = new Cairo.LinearGradient(0, height / 2, width, height / 2);
+            } else {
+                pattern = new Cairo.LinearGradient(width / 2, 0, width / 2, height);
+            }
+
+            pattern.addColorStopRGBA(0, this._primaryColor.red / 255, this._primaryColor.green / 255, this._primaryColor.blue / 255, this._primaryColor.alpha / 255);
+            pattern.addColorStopRGBA(1.0, this._secondaryColor.red / 255, this._secondaryColor.green / 255, this._secondaryColor.blue / 255, this._secondaryColor.alpha / 255);
+            cr.setSource(pattern);
+        }
+        cr.rectangle(0, 0, width, height);
+        cr.fill();
+        cr.$dispose();
+    }
+});
+
+const Background = new Lang.Class({
+    Name: 'Background',
+
+    _init: function(monitor) {
+        this.actor = new St.Widget({ name: 'background',
+                                     layout_manager: new Clutter.BinLayout() });
+
+        this._settings = new Gio.Settings({ schema: BACKGROUND_SCHEMA });
+        this._monitor = monitor;
+
+        this._load();
+    },
+
+    _load: function () {
+        this.actor.set_size(this._monitor.width, this._monitor.height);
+
+        let res, colorString, primaryColor, secondaryColor;
+        colorString = this._settings.get_string(PRIMARY_COLOR_KEY);
+        [res, primaryColor] = Clutter.Color.from_string(colorString)
+        colorString = this._settings.get_string(SECONDARY_COLOR_KEY);
+        [res, secondaryColor] = Clutter.Color.from_string(colorString)
+        let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY);
+        this._backgroundCanvas = new BackgroundCanvas(this._monitor.width, this._monitor.height, shadingType, primaryColor, secondaryColor);
+        this.actor.add_child(this._backgroundCanvas.actor);
+
+        let options = this._settings.get_enum(PICTURE_OPTIONS_KEY);
+        if (options != GDesktopEnums.BackgroundStyle.NONE) {
+
+            let uri = this._settings.get_string(PICTURE_URI_KEY);
+            let cache = St.TextureCache.get_default();
+            let image = cache.load_uri_async(uri, -1, -1);
+            image.set_keep_aspect_ratio(true);
+            this.actor.insert_child_above(image, this._backgroundCanvas.actor);
+            if (options == GDesktopEnums.BackgroundStyle.WALLPAPER) {
+                image.set_sync_size(false);
+                image.set_repeat(true, true);
+                image.set_size(this._monitor.width, this._monitor.height);
+            } else if (options == GDesktopEnums.BackgroundStyle.CENTERED) {
+                image.connect('size-change',
+                              Lang.bind(this,function() {
+                                  let [width, height] = image.get_base_size();
+                                  image.set_size(width, height);
+                              }));
+                image.x_align = Clutter.ActorAlign.CENTER;
+                image.y_align = Clutter.ActorAlign.CENTER;
+            } else if (options == GDesktopEnums.BackgroundStyle.SCALED) {
+                image.connect('size-change',
+                              Lang.bind(this,function() {
+                                  let [width, height] = image.get_base_size();
+
+                                  let scaledWidth = width * (this._monitor.height / height);
+                                  let scaledHeight = height * (this._monitor.width / width);
+                                  if (scaledHeight < this._monitor.height) 
+                                      image.set_size(this._monitor.width, scaledHeight);
+                                  else
+                                      image.set_size(scaledWidth, this._monitor.height);
+                              }));
+
+                image.x_align = Clutter.ActorAlign.CENTER;
+                image.y_align = Clutter.ActorAlign.CENTER;
+            } else if (options == GDesktopEnums.BackgroundStyle.ZOOM) {
+                image.set_size(this._monitor.width, this._monitor.height);
+            } else if (options == GDesktopEnums.BackgroundStyle.SPANNED) {
+                image.set_size(this._monitor.width, this._monitor_height);
+
+                let scaleX = global.screen_width / this._monitor.width;
+                let scaleY = global.screen_height / this._monitor.height;
+                image.set_scale(scaleX, scaleY);
+                image.set_clip(this._monitor.x, this._monitor.y, this._monitor.width, this._monitor.height);
+            }
+
+            image.opacity = (this._settings.get_int(PICTURE_OPACITY_KEY) / 100.0) * 255;
+
+        }
+
+
+        if (!this._settings.get_boolean(DRAW_BACKGROUND_KEY)) {
+            this.actor.opacity = 0;
+        }
+    },
+
+    get dim_factor() {
+        return 1.0;
+    },
+
+    set dim_factor(factor) {
+    }
+});
+Signals.addSignalMethods(Background.prototype);
+
diff --git a/js/ui/layout.js b/js/ui/layout.js
index 73ec3d5..b99e311 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -10,6 +10,7 @@ const Shell = imports.gi.Shell;
 const Signals = imports.signals;
 const St = imports.gi.St;
 
+const Background = imports.ui.background;
 const DND = imports.ui.dnd;
 const Main = imports.ui.main;
 const Params = imports.misc.params;
@@ -106,7 +107,7 @@ const LayoutManager = new Lang.Class({
         this.primaryIndex = -1;
         this._keyboardIndex = -1;
         this._hotCorners = [];
-        this._background = null;
+        this._backgrounds = [];
         this._leftPanelBarrier = 0;
         this._rightPanelBarrier = 0;
         this._trayBarrier = 0;
@@ -270,6 +271,32 @@ const LayoutManager = new Lang.Class({
         }
     },
 
+    _updateBackgrounds: function() {
+        // destroy old backgrounds
+        for (let i = 0; i < this._backgrounds.length; i++)
+            this._backgrounds[i].actor.destroy();
+        this._backgrounds = [];
+
+        // build new backgrounds
+        for (let i = 0; i < this.monitors.length; i++) {
+
+            let monitor = this.monitors[i];
+
+            let background = new Background.Background(monitor)
+            this._backgrounds.push(background);
+            background.actor.set_position(monitor.x, monitor.y);
+            this.addChrome(background.actor, { affectsInputRegion: false });
+            background.actor.lower_bottom();
+            background.actor.opacity = 0;
+
+            Tweener.addTween(background.actor,
+                             { opacity: 255,
+                               time: 2,
+                               transition: 'easeOutQuad'
+                             });
+        }
+    },
+
     _updateBoxes: function() {
         this.screenShieldGroup.set_position(0, 0);
         this.screenShieldGroup.set_size(global.screen_width, global.screen_height);
@@ -323,6 +350,7 @@ const LayoutManager = new Lang.Class({
         this._updateMonitors();
         this._updateBoxes();
         this._updateHotCorners();
+        this._updateBackgrounds();
 
         this.emit('monitors-changed');
     },
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 84cd48c..c37f4f3 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -10,6 +10,7 @@ const St = imports.gi.St;
 const Shell = imports.gi.Shell;
 const Gdk = imports.gi.Gdk;
 
+const Background = imports.ui.background;
 const Dash = imports.ui.dash;
 const DND = imports.ui.dnd;
 const Main = imports.ui.main;
@@ -122,13 +123,10 @@ const Overview = new Lang.Class({
         // one. Instances of this class share a single CoglTexture behind the
         // scenes which allows us to show the background with different
         // rendering options without duplicating the texture data.
-        this._background = Meta.BackgroundActor.new_for_screen(global.screen);
-        this._background.add_glsl_snippet(Meta.SnippetHook.FRAGMENT,
-                                          GLSL_DIM_EFFECT_DECLARATIONS,
-                                          GLSL_DIM_EFFECT_CODE,
-                                          false);
-        this._background.hide();
-        global.overlay_group.add_actor(this._background);
+        let monitor = Main.layoutManager.primaryMonitor;
+        this._background = new Background.Background(monitor);
+        this._background.actor.hide();
+        global.overlay_group.add_actor(this._background.actor);
 
         this._desktopFade = new St.Bin();
         global.overlay_group.add_actor(this._desktopFade);
@@ -479,7 +477,7 @@ const Overview = new Lang.Class({
         Meta.disable_unredirect_for_screen(global.screen);
         global.window_group.hide();
         this._overview.show();
-        this._background.show();
+        this._background.actor.show();
         this._viewSelector.show();
 
         this._overview.opacity = 0;
@@ -491,12 +489,6 @@ const Overview = new Lang.Class({
                            onCompleteScope: this
                          });
 
-        Tweener.addTween(this._background,
-                         { dim_factor: 0.8,
-                           time: ANIMATION_TIME,
-                           transition: 'easeOutQuad'
-                         });
-
         this._coverPane.raise_top();
         this._coverPane.show();
         this.emit('showing');
@@ -647,8 +639,7 @@ const Overview = new Lang.Class({
         global.window_group.show();
 
         this._viewSelector.hide();
-        this._desktopFade.hide();
-        this._background.hide();
+        this._background.actor.hide();
         this._overview.hide();
 
         this.visible = false;
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index 699fb96..7aac256 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -406,20 +406,20 @@ const ScreenShield = new Lang.Class({
                                                    name: 'lockScreenContents' });
         this._lockScreenContents.add_constraint(new Layout.MonitorConstraint({ primary: true }));
 
-        let backgroundActor = Meta.BackgroundActor.new_for_screen(global.screen);
-        backgroundActor.add_glsl_snippet(Meta.SnippetHook.TEXTURE_LOOKUP,
-                                         GLSL_BLUR_EFFECT_DECLARATIONS,
-                                         GLSL_BLUR_EFFECT_CODE,
-                                         true);
-        backgroundActor.set_uniform_float('desaturation',
-                                          1, 1, [0.6]);
-        backgroundActor.connect('notify::size', function(actor) {
-            actor.set_uniform_float('pixel_step', 2, 1, [1/actor.width, 1/actor.height]);
-        });
-
-        this._background = new St.Bin({ style_class: 'screen-shield-background',
-                                        child: backgroundActor });
-        this._lockScreenGroup.add_actor(this._background);
+//        let backgroundActor = Meta.BackgroundActor.new_for_screen(global.screen);
+//        backgroundActor.add_glsl_snippet(Meta.SnippetHook.TEXTURE_LOOKUP,
+//                                         GLSL_BLUR_EFFECT_DECLARATIONS,
+//                                         GLSL_BLUR_EFFECT_CODE,
+//                                         true);
+//        backgroundActor.set_uniform_float('desaturation',
+//                                          1, 1, [0.6]);
+//        backgroundActor.connect('notify::size', function(actor) {
+//            actor.set_uniform_float('pixel_step', 2, 1, [1/actor.width, 1/actor.height]);
+//        });
+//
+//        this._background = new St.Bin({ style_class: 'screen-shield-background',
+//                                        child: backgroundActor });
+//        this._lockScreenGroup.add_actor(this._background);
         this._lockScreenGroup.add_actor(this._lockScreenContents);
 
         this._arrowContainer = new St.BoxLayout({ style_class: 'screen-shield-arrows',
diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js
index fd68ce5..d5ba93c 100644
--- a/js/ui/workspaceThumbnail.js
+++ b/js/ui/workspaceThumbnail.js
@@ -9,6 +9,7 @@ const Shell = imports.gi.Shell;
 const Signals = imports.signals;
 const St = imports.gi.St;
 
+const Background = imports.ui.background;
 const DND = imports.ui.dnd;
 const Main = imports.ui.main;
 const Tweener = imports.ui.tweener;
@@ -170,10 +171,11 @@ const WorkspaceThumbnail = new Lang.Class({
 
         this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 
-        this._background = Meta.BackgroundActor.new_for_screen(global.screen);
-        this._contents.add_actor(this._background);
-
         let monitor = Main.layoutManager.primaryMonitor;
+
+        this._background = new Background.Background(monitor);
+        this._contents.add_actor(this._background.actor);
+
         this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
 
         let windows = global.get_window_actors().filter(this._isWorkspaceWindow, this);
@@ -233,7 +235,7 @@ const WorkspaceThumbnail = new Lang.Class({
             let clone = this._windows[i];
             let metaWindow = clone.metaWindow;
             if (i == 0) {
-                clone.setStackAbove(this._background);
+                clone.setStackAbove(this._background.actor);
             } else {
                 let previousClone = this._windows[i - 1];
                 clone.setStackAbove(previousClone.actor);
@@ -418,7 +420,7 @@ const WorkspaceThumbnail = new Lang.Class({
         this._contents.add_actor(clone.actor);
 
         if (this._windows.length == 0)
-            clone.setStackAbove(this._background);
+            clone.setStackAbove(this._background.actor);
         else
             clone.setStackAbove(this._windows[this._windows.length - 1].actor);
 
diff --git a/src/shell-global.c b/src/shell-global.c
index 10b1fc1..23d5648 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -107,7 +107,6 @@ enum {
   PROP_STAGE,
   PROP_STAGE_INPUT_MODE,
   PROP_WINDOW_GROUP,
-  PROP_BACKGROUND_ACTOR,
   PROP_WINDOW_MANAGER,
   PROP_SETTINGS,
   PROP_DATADIR,
@@ -203,9 +202,6 @@ shell_global_get_property(GObject         *object,
     case PROP_WINDOW_GROUP:
       g_value_set_object (value, meta_get_window_group_for_screen (global->meta_screen));
       break;
-    case PROP_BACKGROUND_ACTOR:
-      g_value_set_object (value, meta_get_background_actor_for_screen (global->meta_screen));
-      break;
     case PROP_WINDOW_MANAGER:
       g_value_set_object (value, global->wm);
       break;
@@ -419,13 +415,6 @@ shell_global_class_init (ShellGlobalClass *klass)
                                                         CLUTTER_TYPE_ACTOR,
                                                         G_PARAM_READABLE));
   g_object_class_install_property (gobject_class,
-                                   PROP_BACKGROUND_ACTOR,
-                                   g_param_spec_object ("background-actor",
-                                                        "Background Actor",
-                                                        "Actor drawing root window background",
-                                                        CLUTTER_TYPE_ACTOR,
-                                                        G_PARAM_READABLE));
-  g_object_class_install_property (gobject_class,
                                    PROP_WINDOW_MANAGER,
                                    g_param_spec_object ("window-manager",
                                                         "Window Manager",



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