Compare commits
	
		
			7 Commits
		
	
	
		
			3.9.1
			...
			wip/gcampa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3e79d293f7 | ||
|   | d457073c10 | ||
|   | 8b2864ee70 | ||
|   | af1c799246 | ||
|   | f6aa0ee532 | ||
|   | b0e22a795e | ||
|   | f91671498b | 
							
								
								
									
										180
									
								
								js/ui/layout.js
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								js/ui/layout.js
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- | ||||
|  | ||||
| const Clutter = imports.gi.Clutter; | ||||
| const ClutterX11 = imports.gi.ClutterX11; | ||||
| const GObject = imports.gi.GObject; | ||||
| const Lang = imports.lang; | ||||
| const Mainloop = imports.mainloop; | ||||
| @@ -15,9 +16,9 @@ const Params = imports.misc.params; | ||||
| const Tweener = imports.ui.tweener; | ||||
|  | ||||
| const HOT_CORNER_ACTIVATION_TIMEOUT = 0.5; | ||||
| const STARTUP_ANIMATION_TIME = 0.2; | ||||
| const STARTUP_ANIMATION_TIME = 1; | ||||
| const KEYBOARD_ANIMATION_TIME = 0.15; | ||||
| const PLYMOUTH_TRANSITION_TIME = 1; | ||||
| const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); | ||||
|  | ||||
| const MonitorConstraint = new Lang.Class({ | ||||
|     Name: 'MonitorConstraint', | ||||
| @@ -111,7 +112,6 @@ const LayoutManager = new Lang.Class({ | ||||
|         this.primaryIndex = -1; | ||||
|         this._keyboardIndex = -1; | ||||
|         this._hotCorners = []; | ||||
|         this._background = null; | ||||
|         this._leftPanelBarrier = 0; | ||||
|         this._rightPanelBarrier = 0; | ||||
|  | ||||
| @@ -120,6 +120,42 @@ const LayoutManager = new Lang.Class({ | ||||
|  | ||||
|         this._trackedActors = []; | ||||
|  | ||||
|         // Normally, the stage is always covered so Clutter doesn't need to clear | ||||
|         // it; however it becomes visible during the startup animation | ||||
|         // See the comment below for a longer explanation | ||||
|         global.stage.color = DEFAULT_BACKGROUND_COLOR; | ||||
|  | ||||
|         // Set up stage hierarchy to group all UI actors under one container. | ||||
|         this.uiGroup = new Shell.GenericContainer({ name: 'uiGroup' }); | ||||
|         this.uiGroup.connect('allocate', | ||||
|                         function (actor, box, flags) { | ||||
|                             let children = actor.get_children(); | ||||
|                             for (let i = 0; i < children.length; i++) | ||||
|                                 children[i].allocate_preferred_size(flags); | ||||
|                         }); | ||||
|         this.uiGroup.connect('get-preferred-width', | ||||
|                         function(actor, forHeight, alloc) { | ||||
|                             let width = global.stage.width; | ||||
|                             [alloc.min_size, alloc.natural_size] = [width, width]; | ||||
|                         }); | ||||
|         this.uiGroup.connect('get-preferred-height', | ||||
|                         function(actor, forWidth, alloc) { | ||||
|                             let height = global.stage.height; | ||||
|                             [alloc.min_size, alloc.natural_size] = [height, height]; | ||||
|                         }); | ||||
|  | ||||
|         global.window_group.reparent(this.uiGroup); | ||||
|  | ||||
|         // Now, you might wonder why we went through all the hoops to implement | ||||
|         // the GDM greeter inside an X11 compositor, to do this at the end... | ||||
|         // However, hiding this is necessary to avoid showing the background during | ||||
|         // the initial animation, before Gdm.LoginDialog covers everything | ||||
|         if (Main.sessionMode.isGreeter) | ||||
|             global.window_group.hide(); | ||||
|  | ||||
|         global.overlay_group.reparent(this.uiGroup); | ||||
|         global.stage.add_child(this.uiGroup); | ||||
|  | ||||
|         this.screenShieldGroup = new St.Widget({ name: 'screenShieldGroup', | ||||
|                                                  visible: false, | ||||
|                                                  clip_to_allocation: true, | ||||
| @@ -135,7 +171,7 @@ const LayoutManager = new Lang.Class({ | ||||
|                               Lang.bind(this, this._panelBoxChanged)); | ||||
|  | ||||
|         this.trayBox = new St.Widget({ name: 'trayBox', | ||||
|                                        layout_manager: new Clutter.BinLayout() });  | ||||
|                                        layout_manager: new Clutter.BinLayout() }); | ||||
|         this.addChrome(this.trayBox); | ||||
|  | ||||
|         this.keyboardBox = new St.BoxLayout({ name: 'keyboardBox', | ||||
| @@ -161,7 +197,8 @@ const LayoutManager = new Lang.Class({ | ||||
|         Main.overview.connect('showing', Lang.bind(this, this._overviewShowing)); | ||||
|         Main.overview.connect('hidden', Lang.bind(this, this._overviewHidden)); | ||||
|         Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); | ||||
|         this._startupAnimation(); | ||||
|  | ||||
|         this._prepareStartupAnimation(); | ||||
|     }, | ||||
|  | ||||
|     _overviewShowing: function() { | ||||
| @@ -254,7 +291,7 @@ const LayoutManager = new Lang.Class({ | ||||
|             if (!haveTopLeftCorner) | ||||
|                 continue; | ||||
|  | ||||
|             let corner = new HotCorner(); | ||||
|             let corner = new HotCorner(this); | ||||
|             this._hotCorners.push(corner); | ||||
|             corner.actor.set_position(cornerX, cornerY); | ||||
|             this.addChrome(corner.actor); | ||||
| @@ -376,51 +413,106 @@ const LayoutManager = new Lang.Class({ | ||||
|         return this._keyboardIndex; | ||||
|     }, | ||||
|  | ||||
|     _startupAnimation: function() { | ||||
|         this.panelBox.translation_y = -this.panelBox.height; | ||||
|     _acquireRootBackground: function() { | ||||
|         let rootpmap = Shell.util_get_root_background(); | ||||
|         let texture = ClutterX11.TexturePixmap.new_with_pixmap(rootpmap); | ||||
|         // The texture size might not match the screen size, for example | ||||
|         // if the session has a different XRandR configuration than the greeter | ||||
|         texture.x = 0; | ||||
|         texture.y = 0; | ||||
|         texture.width = global.screen_width; | ||||
|         texture.height = global.screen_height; | ||||
|         texture.set_automatic(true); | ||||
|  | ||||
|         let plymouthTransitionRunning = false; | ||||
|  | ||||
|         // If we're the greeter, put up the xrootpmap actor | ||||
|         // and fade it out to have a nice transition from plymouth | ||||
|         // to the greeter. Otherwise, we'll just animate the panel, | ||||
|         // as usual. | ||||
|         if (Main.sessionMode.isGreeter) { | ||||
|             this._background = Meta.BackgroundActor.new_for_screen(global.screen); | ||||
|             if (this._background != null) { | ||||
|                 Main.uiGroup.add_actor(this._background); | ||||
|                 Tweener.addTween(this._background, | ||||
|                                  { opacity: 0, | ||||
|                                    time: PLYMOUTH_TRANSITION_TIME, | ||||
|                                    transition: 'linear', | ||||
|                                    onComplete: this._fadeBackgroundComplete, | ||||
|                                    onCompleteScope: this }); | ||||
|                 plymouthTransitionRunning = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!plymouthTransitionRunning) | ||||
|             this._fadeBackgroundComplete(); | ||||
|         this._rootTexture = texture; | ||||
|     }, | ||||
|  | ||||
|     _fadeBackgroundComplete: function() { | ||||
|     // Startup Animations | ||||
|     // | ||||
|     // We have two different animations, depending on whether we're a greeter | ||||
|     // or a normal session. | ||||
|     // | ||||
|     // In the greeter, we want to animate the panel from the top, and smoothly | ||||
|     // fade the login dialog on top of whatever plymouth left on screen, which we | ||||
|     // grab as a X11 texture_from_pixmap. | ||||
|     // Here we just have the code to animate the panel, the login dialog animation | ||||
|     // is handled by modalDialog.js | ||||
|     // | ||||
|     // In a normal session, we want to take the root background, which now holds | ||||
|     // the final frame of the GDM greeter, and slide it from the bottom, while | ||||
|     // at the same time scaling the UI contents of the new shell on top of the | ||||
|     // stage background. | ||||
|     // | ||||
|     // Usually, we don't want to paint the stage background color because the | ||||
|     // MetaBackgroundActor inside global.window_group covers the entirety of the | ||||
|     // screen. So, we set no_clear_hint at the end of the animation. | ||||
|  | ||||
|     _prepareStartupAnimation: function() { | ||||
|         // Set ourselves to FULLSCREEN input mode while the animation is running | ||||
|         // so events don't get delivered to X11 windows (which are distorted by the animation) | ||||
|         global.stage_input_mode = Shell.StageInputMode.FULLSCREEN; | ||||
|  | ||||
|         this._acquireRootBackground(); | ||||
|  | ||||
|         if (Main.sessionMode.isGreeter) { | ||||
|             global.stage.insert_child_below(this._rootTexture, null); | ||||
|  | ||||
|             this._panelBox.translation_y = -this._panelBox.height; | ||||
|         } else { | ||||
|             global.stage.insert_child_above(this._rootTexture, null); | ||||
|  | ||||
|             this.uiGroup.set_pivot_point(0.5, 0.5); | ||||
|             this.uiGroup.scale_x = this.uiGroup.scale_y = 0; | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     startupAnimation: function() { | ||||
|         if (Main.sessionMode.isGreeter) | ||||
|             this._startupAnimationGreeter(); | ||||
|         else | ||||
|             this._startupAnimationSession(); | ||||
|     }, | ||||
|  | ||||
|     _startupAnimationGreeter: function() { | ||||
|         // Don't animate the strut | ||||
|         this._freezeUpdateRegions(); | ||||
|  | ||||
|         if (this._background != null) { | ||||
|             this._background.destroy(); | ||||
|             this._background = null; | ||||
|         } | ||||
|  | ||||
|         Tweener.addTween(this.panelBox, | ||||
|         Tweener.addTween(this._panelBox, | ||||
|                          { translation_y: 0, | ||||
|                            time: STARTUP_ANIMATION_TIME, | ||||
|                            transition: 'easeOutQuad', | ||||
|                            onComplete: this._startupAnimationComplete, | ||||
|                            onCompleteScope: this | ||||
|                          }); | ||||
|                            onCompleteScope: this }); | ||||
|     }, | ||||
|  | ||||
|     _startupAnimationSession: function() { | ||||
|         // Don't animate the strut | ||||
|         this._freezeUpdateRegions(); | ||||
|  | ||||
|         Tweener.addTween(this._rootTexture, | ||||
|                          { translation_y: -global.screen_height, | ||||
|                            time: STARTUP_ANIMATION_TIME, | ||||
|                            transition: 'linear' }); | ||||
|  | ||||
|         Tweener.addTween(this.uiGroup, | ||||
|                          { scale_x: 1, | ||||
|                            scale_y: 1, | ||||
|                            time: STARTUP_ANIMATION_TIME, | ||||
|                            transition: 'easeOutQuad', | ||||
|                            onComplete: this._startupAnimationComplete, | ||||
|                            onCompleteScope: this }); | ||||
|     }, | ||||
|  | ||||
|     _startupAnimationComplete: function() { | ||||
|         // At this point, the UI group is covering everything, so | ||||
|         // we no longer need to clear the stage | ||||
|         global.stage.no_clear_hint = true; | ||||
|  | ||||
|         global.stage_input_mode = Shell.StageInputMode.NORMAL; | ||||
|  | ||||
|         this._rootTexture.destroy(); | ||||
|         this._rootTexture = null; | ||||
|  | ||||
|         this.emit('panel-box-changed'); | ||||
|         this._thawUpdateRegions(); | ||||
|     }, | ||||
| @@ -506,7 +598,7 @@ const LayoutManager = new Lang.Class({ | ||||
|     // monitor (it will be hidden whenever a fullscreen window is visible, | ||||
|     // and shown otherwise) | ||||
|     addChrome: function(actor, params) { | ||||
|         Main.uiGroup.add_actor(actor); | ||||
|         this.uiGroup.add_actor(actor); | ||||
|         this._trackActor(actor, params); | ||||
|     }, | ||||
|  | ||||
| @@ -557,7 +649,7 @@ const LayoutManager = new Lang.Class({ | ||||
|     // | ||||
|     // Removes @actor from the chrome | ||||
|     removeChrome: function(actor) { | ||||
|         Main.uiGroup.remove_actor(actor); | ||||
|         this.uiGroup.remove_actor(actor); | ||||
|         this._untrackActor(actor); | ||||
|     }, | ||||
|  | ||||
| @@ -576,7 +668,7 @@ const LayoutManager = new Lang.Class({ | ||||
|  | ||||
|         let actorData = Params.parse(params, defaultParams); | ||||
|         actorData.actor = actor; | ||||
|         actorData.isToplevel = actor.get_parent() == Main.uiGroup; | ||||
|         actorData.isToplevel = actor.get_parent() == this.uiGroup; | ||||
|         actorData.visibleId = actor.connect('notify::visible', | ||||
|                                             Lang.bind(this, this._queueUpdateRegions)); | ||||
|         actorData.allocationId = actor.connect('notify::allocation', | ||||
| @@ -612,7 +704,7 @@ const LayoutManager = new Lang.Class({ | ||||
|         } else { | ||||
|             let i = this._findActor(actor); | ||||
|             let actorData = this._trackedActors[i]; | ||||
|             actorData.isToplevel = (newParent == Main.uiGroup); | ||||
|             actorData.isToplevel = (newParent == this.uiGroup); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
| @@ -812,7 +904,7 @@ const LayoutManager = new Lang.Class({ | ||||
|  | ||||
|             if (actorData.affectsInputRegion && | ||||
|                 actorData.actor.get_paint_visibility() && | ||||
|                 !Main.uiGroup.get_skip_paint(actorData.actor)) | ||||
|                 !this.uiGroup.get_skip_paint(actorData.actor)) | ||||
|                 rects.push(rect); | ||||
|  | ||||
|             if (!actorData.affectsStruts) | ||||
|   | ||||
| @@ -38,7 +38,6 @@ const XdndHandler = imports.ui.xdndHandler; | ||||
| const Util = imports.misc.util; | ||||
|  | ||||
| const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides'; | ||||
| const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); | ||||
|  | ||||
| let componentManager = null; | ||||
| let panel = null; | ||||
| @@ -63,6 +62,7 @@ let magnifier = null; | ||||
| let xdndHandler = null; | ||||
| let keyboard = null; | ||||
| let layoutManager = null; | ||||
| let background = null; | ||||
| let _startDate; | ||||
| let _defaultCssStylesheet = null; | ||||
| let _cssStylesheet = null; | ||||
| @@ -111,38 +111,17 @@ function start() { | ||||
|  | ||||
|     tracker.connect('startup-sequence-changed', _queueCheckWorkspaces); | ||||
|  | ||||
|     // The stage is always covered so Clutter doesn't need to clear it; however | ||||
|     // the color is used as the default contents for the Mutter root background | ||||
|     // actor so set it anyways. | ||||
|     global.stage.color = DEFAULT_BACKGROUND_COLOR; | ||||
|     global.stage.no_clear_hint = true; | ||||
|     // Setup the stage hierarchy early | ||||
|     layoutManager = new Layout.LayoutManager(); | ||||
|     // For backward compatibility | ||||
|     uiGroup = layoutManager.uiGroup; | ||||
|  | ||||
|     let backgroundActor = global.window_group.background; | ||||
|     background = backgroundActor.settings; | ||||
|  | ||||
|     _defaultCssStylesheet = global.datadir + '/theme/gnome-shell.css'; | ||||
|     loadTheme(); | ||||
|  | ||||
|     // Set up stage hierarchy to group all UI actors under one container. | ||||
|     uiGroup = new Shell.GenericContainer({ name: 'uiGroup' }); | ||||
|     uiGroup.connect('allocate', | ||||
|                     function (actor, box, flags) { | ||||
|                         let children = uiGroup.get_children(); | ||||
|                         for (let i = 0; i < children.length; i++) | ||||
|                             children[i].allocate_preferred_size(flags); | ||||
|                     }); | ||||
|     uiGroup.connect('get-preferred-width', | ||||
|                     function(actor, forHeight, alloc) { | ||||
|                         let width = global.stage.width; | ||||
|                         [alloc.min_size, alloc.natural_size] = [width, width]; | ||||
|                     }); | ||||
|     uiGroup.connect('get-preferred-height', | ||||
|                     function(actor, forWidth, alloc) { | ||||
|                         let height = global.stage.height; | ||||
|                         [alloc.min_size, alloc.natural_size] = [height, height]; | ||||
|                     }); | ||||
|     global.window_group.reparent(uiGroup); | ||||
|     global.overlay_group.reparent(uiGroup); | ||||
|     global.stage.add_actor(uiGroup); | ||||
|  | ||||
|     layoutManager = new Layout.LayoutManager(); | ||||
|     xdndHandler = new XdndHandler.XdndHandler(); | ||||
|     ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); | ||||
|     overview = new Overview.Overview(); | ||||
| @@ -196,6 +175,14 @@ function start() { | ||||
|  | ||||
|     ExtensionDownloader.init(); | ||||
|     ExtensionSystem.init(); | ||||
|  | ||||
|     // Run the startup animation as soon as the mainloop is idle enough | ||||
|     // This is necessary to have it smooth and without interruptions from | ||||
|     // completed IO tasks | ||||
|     GLib.idle_add(GLib.PRIORITY_LOW, function() { | ||||
|         layoutManager.startupAnimation(); | ||||
|         return false; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| let _workspaces = []; | ||||
|   | ||||
| @@ -122,7 +122,8 @@ 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 = new Meta.BackgroundActor({ screen: global.screen, | ||||
|                                                       settings: Main.background }); | ||||
|         this._background.add_glsl_snippet(Meta.SnippetHook.FRAGMENT, | ||||
|                                           GLSL_DIM_EFFECT_DECLARATIONS, | ||||
|                                           GLSL_DIM_EFFECT_CODE, | ||||
|   | ||||
| @@ -644,7 +644,7 @@ const ActivitiesButton = new Lang.Class({ | ||||
|  | ||||
|         this.actor.label_actor = this._label; | ||||
|  | ||||
|         this.hotCorner = new Layout.HotCorner(); | ||||
|         this.hotCorner = new Layout.HotCorner(Main.layoutManager); | ||||
|         container.add_actor(this.hotCorner.actor); | ||||
|  | ||||
|         this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent)); | ||||
|   | ||||
| @@ -52,36 +52,16 @@ const SUMMARY_ICON_SIZE = 48; | ||||
| const STANDARD_FADE_TIME = 10; | ||||
| const SHORT_FADE_TIME = 0.3; | ||||
|  | ||||
| function sample(offx, offy) { | ||||
|     return 'texel += texture2D (sampler, tex_coord.st + pixel_step * ' + | ||||
|         'vec2 (' + offx + ',' + offy + '));\n' | ||||
| } | ||||
| const GLSL_BLUR_EFFECT_DECLARATIONS = ' \ | ||||
| uniform vec2 pixel_step;\n \ | ||||
| uniform float desaturation;\n \ | ||||
| vec4 apply_blur(in sampler2D sampler, in vec2 tex_coord) {\n \ | ||||
|   vec4 texel;\n \ | ||||
|   texel = texture2D (sampler, tex_coord.st);\n' | ||||
|   + sample(-1.0, -1.0) | ||||
|   + sample( 0.0, -1.0) | ||||
|   + sample(+1.0, -1.0) | ||||
|   + sample(-1.0,  0.0) | ||||
|   + sample(+1.0,  0.0) | ||||
|   + sample(-1.0, +1.0) | ||||
|   + sample( 0.0, +1.0) | ||||
|   + sample(+1.0, +1.0) + ' \ | ||||
|    texel /= 9.0;\n \ | ||||
|    return texel;\n \ | ||||
| }\n \ | ||||
| const GLSL_EFFECT_DECLARATIONS = ' \ | ||||
| uniform float desaturation; \n \ | ||||
| vec3 desaturate (const vec3 color)\n \ | ||||
| {\n \ | ||||
|    const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n \ | ||||
|    vec3 gray = vec3 (dot (gray_conv, color));\n \ | ||||
|    return vec3 (mix (color.rgb, gray, desaturation));\n \ | ||||
| }'; | ||||
| const GLSL_BLUR_EFFECT_CODE = ' \ | ||||
| cogl_texel = apply_blur(cogl_sampler, cogl_tex_coord.st);\n \ | ||||
| cogl_texel.rgb = desaturate(cogl_texel.rgb);\n'; | ||||
| const GLSL_EFFECT_CODE = ' \ | ||||
| cogl_color_out.rgb = desaturate(cogl_color_out.rgb);\n'; | ||||
|  | ||||
|  | ||||
| const Clock = new Lang.Class({ | ||||
| @@ -467,16 +447,16 @@ 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); | ||||
|         this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); | ||||
|  | ||||
|         let backgroundActor = new Meta.BackgroundActor({ screen: global.screen, | ||||
|                                                          settings: this._settings }); | ||||
|         backgroundActor.add_glsl_snippet(Meta.SnippetHook.FRAGMENT, | ||||
|                                          GLSL_EFFECT_DECLARATIONS, | ||||
|                                          GLSL_EFFECT_CODE, | ||||
|                                          false); | ||||
|         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 }); | ||||
| @@ -531,8 +511,6 @@ const ScreenShield = new Lang.Class({ | ||||
|         this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); })); | ||||
|         this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); })); | ||||
|  | ||||
|         this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); | ||||
|  | ||||
|         this._isModal = false; | ||||
|         this._hasLockScreen = false; | ||||
|         this._isGreeter = false; | ||||
|   | ||||
| @@ -170,7 +170,8 @@ const WorkspaceThumbnail = new Lang.Class({ | ||||
|  | ||||
|         this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); | ||||
|  | ||||
|         this._background = Meta.BackgroundActor.new_for_screen(global.screen); | ||||
|         this._background = new Meta.BackgroundActor({ screen: global.screen, | ||||
|                                                       settings: Main.background }); | ||||
|         this._contents.add_actor(this._background); | ||||
|  | ||||
|         let monitor = Main.layoutManager.primaryMonitor; | ||||
|   | ||||
| @@ -292,7 +292,7 @@ libgnome_shell_la_LIBADD =		\ | ||||
| libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags) | ||||
|  | ||||
| Shell-0.1.gir: libgnome-shell.la St-1.0.gir | ||||
| Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0 | ||||
| Shell_0_1_gir_INCLUDES = Clutter-1.0 ClutterX11-1.0 Meta-3.0 TelepathyGLib-0.12 TelepathyLogger-0.2 Soup-2.4 GMenu-3.0 NetworkManager-1.0 NMClient-1.0 xlib-2.0 | ||||
| Shell_0_1_gir_CFLAGS = $(libgnome_shell_la_CPPFLAGS) -I $(srcdir) | ||||
| Shell_0_1_gir_LIBS = libgnome-shell.la | ||||
| Shell_0_1_gir_FILES = $(libgnome_shell_la_gir_sources) | ||||
|   | ||||
| @@ -9,6 +9,8 @@ | ||||
| #include <glib/gi18n-lib.h> | ||||
| #include <gtk/gtk.h> | ||||
| #include <gdk-pixbuf/gdk-pixbuf.h> | ||||
| #include <gdk/gdkx.h> | ||||
| #include <X11/Xatom.h> | ||||
|  | ||||
| #ifdef HAVE__NL_TIME_FIRST_WEEKDAY | ||||
| #include <langinfo.h> | ||||
| @@ -430,3 +432,56 @@ shell_util_create_pixbuf_from_data (const guchar      *data, | ||||
|                                    bits_per_sample, width, height, rowstride, | ||||
|                                    (GdkPixbufDestroyNotify) g_free, NULL); | ||||
| } | ||||
|  | ||||
| Pixmap | ||||
| shell_util_get_root_background (void) | ||||
| { | ||||
|   Display *display; | ||||
|   Pixmap pixmap; | ||||
|   Window rootwin; | ||||
|   Atom xrootpmap; | ||||
|   Atom actual_type; | ||||
|   int actual_format; | ||||
|   unsigned long n_items; | ||||
|   unsigned long bytes_after; | ||||
|   unsigned char *buffer; | ||||
|  | ||||
|   display = gdk_x11_get_default_xdisplay (); | ||||
|  | ||||
|   xrootpmap = gdk_x11_atom_to_xatom (gdk_atom_intern_static_string ("_XROOTPMAP_ID")); | ||||
|   rootwin = gdk_x11_get_default_root_xwindow (); | ||||
|  | ||||
|   gdk_error_trap_push (); | ||||
|   actual_type = None; | ||||
|   buffer = NULL; | ||||
|   if (XGetWindowProperty (display, rootwin, xrootpmap, | ||||
|                           0, G_MAXLONG, | ||||
|                           False, XA_PIXMAP, &actual_type, &actual_format, | ||||
|                           &n_items, | ||||
|                           &bytes_after, | ||||
|                           &buffer) != Success || | ||||
|       actual_type == None) | ||||
|     { | ||||
|       if (buffer) | ||||
|         XFree (buffer); | ||||
|       gdk_error_trap_pop_ignored (); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   if (gdk_error_trap_pop () != Success || | ||||
|       n_items == 0 || | ||||
|       actual_type != XA_PIXMAP || | ||||
|       actual_format != 32) | ||||
|     { | ||||
|       if (buffer) | ||||
|         XFree (buffer); | ||||
|       return FALSE; | ||||
|     } | ||||
|  | ||||
|   pixmap = *((Pixmap*) buffer); | ||||
|  | ||||
|   XFree (buffer); | ||||
|   return pixmap; | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include <clutter/clutter.h> | ||||
| #include <libsoup/soup.h> | ||||
| #include <gdk-pixbuf/gdk-pixbuf.h> | ||||
| #include <gdk/gdkx.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| @@ -46,6 +47,8 @@ GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar      *data, | ||||
|                                                int                height, | ||||
|                                                int                rowstride); | ||||
|  | ||||
| Pixmap  shell_util_get_root_background        (void); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
| #endif /* __SHELL_UTIL_H__ */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user