From 5846a07226dec78e96a48684e6f102f8235dd338 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Mon, 14 Apr 2014 23:15:12 +0200 Subject: [PATCH] gnome-shell: maybe fix the background corruption bug --- .../gnome-3/core/gnome-shell/default.nix | 2 + .../fix_background_corruption.patch | 147 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 pkgs/desktops/gnome-3/core/gnome-shell/fix_background_corruption.patch diff --git a/pkgs/desktops/gnome-3/core/gnome-shell/default.nix b/pkgs/desktops/gnome-3/core/gnome-shell/default.nix index be25c615d97..554b09a1e59 100644 --- a/pkgs/desktops/gnome-3/core/gnome-shell/default.nix +++ b/pkgs/desktops/gnome-3/core/gnome-shell/default.nix @@ -39,6 +39,8 @@ stdenv.mkDerivation rec { --prefix XDG_DATA_DIRS : "${evolution_data_server}/share:$out/share:$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH" ''; + patches = [ ./fix_background_corruption.patch ]; + meta = with stdenv.lib; { platforms = platforms.linux; }; diff --git a/pkgs/desktops/gnome-3/core/gnome-shell/fix_background_corruption.patch b/pkgs/desktops/gnome-3/core/gnome-shell/fix_background_corruption.patch new file mode 100644 index 00000000000..9cb041bcce2 --- /dev/null +++ b/pkgs/desktops/gnome-3/core/gnome-shell/fix_background_corruption.patch @@ -0,0 +1,147 @@ +commit 831bd07b0d6b7055fea8317f2cdf8fd4a408c36d +Author: Jasper St. Pierre +Date: Thu Nov 7 17:14:47 2013 -0500 + + layout: Fix several issues with the background management code + + If monitor-changed fires at startup, it will destroy all of the + backgrounds, but since this._isStartup is true, won't recreate any + of them. Additionally, since _bgManagers is indexed by monitor index, + if the primary index is not 0, it could become a sparse array (e.g. + [undefined, undefined, primaryBackground]), and our for loop will + crash trying to access properties of undefined. + + Fix both of these issues by always creating background managers for + every monitor, hiding them on startup but only showing them after + the startup animation is complete. + + One thing we need to watch out for is that while LayoutManager is + constructing, Main.uiGroup / Main.layoutManager will be undefined, + so addBackgroundMenu will fail. Fix this by passing down the uiGroup + to the background menu code. + + https://bugzilla.gnome.org/show_bug.cgi?id=709313 + +diff --git a/js/ui/backgroundMenu.js b/js/ui/backgroundMenu.js +index 06e698c..dcbbb39 100644 +--- a/js/ui/backgroundMenu.js ++++ b/js/ui/backgroundMenu.js +@@ -13,7 +13,7 @@ const BackgroundMenu = new Lang.Class({ + Name: 'BackgroundMenu', + Extends: PopupMenu.PopupMenu, + +- _init: function(source) { ++ _init: function(source, layoutManager) { + this.parent(source, 0, St.Side.TOP); + + this.addSettingsAction(_("Settings"), 'gnome-control-center.desktop'); +@@ -22,17 +22,17 @@ const BackgroundMenu = new Lang.Class({ + + this.actor.add_style_class_name('background-menu'); + +- Main.uiGroup.add_actor(this.actor); ++ layoutManager.uiGroup.add_actor(this.actor); + this.actor.hide(); + } + }); + +-function addBackgroundMenu(actor) { ++function addBackgroundMenu(actor, layoutManager) { + let cursor = new St.Bin({ opacity: 0 }); +- Main.uiGroup.add_actor(cursor); ++ layoutManager.uiGroup.add_actor(cursor); + + actor.reactive = true; +- actor._backgroundMenu = new BackgroundMenu(cursor); ++ actor._backgroundMenu = new BackgroundMenu(cursor, layoutManager); + actor._backgroundManager = new PopupMenu.PopupMenuManager({ actor: actor }); + actor._backgroundManager.addMenu(actor._backgroundMenu); + +diff --git a/js/ui/layout.js b/js/ui/layout.js +index 17073a6..80bae9d 100644 +--- a/js/ui/layout.js ++++ b/js/ui/layout.js +@@ -352,26 +352,26 @@ const LayoutManager = new Lang.Class({ + this.emit('hot-corners-changed'); + }, + +- _createBackground: function(monitorIndex) { ++ _addBackgroundMenu: function(bgManager) { ++ BackgroundMenu.addBackgroundMenu(bgManager.background.actor, this); ++ }, ++ ++ _createBackgroundManager: function(monitorIndex) { + let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup, + layoutManager: this, + monitorIndex: monitorIndex }); +- BackgroundMenu.addBackgroundMenu(bgManager.background.actor); +- +- bgManager.connect('changed', Lang.bind(this, function() { +- BackgroundMenu.addBackgroundMenu(bgManager.background.actor); +- })); + +- this._bgManagers[monitorIndex] = bgManager; ++ bgManager.connect('changed', Lang.bind(this, this._addBackgroundMenu)); ++ this._addBackgroundMenu(bgManager); + +- return bgManager.background; ++ return bgManager; + }, + +- _createSecondaryBackgrounds: function() { ++ _showSecondaryBackgrounds: function() { + for (let i = 0; i < this.monitors.length; i++) { + if (i != this.primaryIndex) { +- let background = this._createBackground(i); +- ++ let background = this._bgManagers[i].background; ++ background.actor.show(); + background.actor.opacity = 0; + Tweener.addTween(background.actor, + { opacity: 255, +@@ -381,10 +381,6 @@ const LayoutManager = new Lang.Class({ + } + }, + +- _createPrimaryBackground: function() { +- this._createBackground(this.primaryIndex); +- }, +- + _updateBackgrounds: function() { + let i; + for (i = 0; i < this._bgManagers.length; i++) +@@ -395,11 +391,12 @@ const LayoutManager = new Lang.Class({ + if (Main.sessionMode.isGreeter) + return; + +- if (this._startingUp) +- return; +- + for (let i = 0; i < this.monitors.length; i++) { +- this._createBackground(i); ++ let bgManager = this._createBackgroundManager(i); ++ this._bgManagers.push(bgManager); ++ ++ if (i != this.primaryIndex && this._startingUp) ++ bgManager.background.actor.hide(); + } + }, + +@@ -595,7 +592,7 @@ const LayoutManager = new Lang.Class({ + if (Main.sessionMode.isGreeter) { + this.panelBox.translation_y = -this.panelBox.height; + } else { +- this._createPrimaryBackground(); ++ this._updateBackgrounds(); + + // We need to force an update of the regions now before we scale + // the UI group to get the coorect allocation for the struts. +@@ -673,7 +670,7 @@ const LayoutManager = new Lang.Class({ + this.keyboardBox.show(); + + if (!Main.sessionMode.isGreeter) { +- this._createSecondaryBackgrounds(); ++ this._showSecondaryBackgrounds(); + global.window_group.remove_clip(); + } +