Compare commits
	
		
			2 Commits
		
	
	
		
			gbsneto/ne
			...
			wip/gcampa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 6d4ca1fcc8 | ||
|   | 93b1af401f | 
| @@ -174,15 +174,6 @@ const WindowManager = new Lang.Class({ | ||||
|                            Meta.KeyBindingFlags.NONE, | ||||
|                            Shell.KeyBindingMode.NORMAL, | ||||
|                            Lang.bind(this, this._openAppMenu)); | ||||
|  | ||||
|         Main.overview.connect('showing', Lang.bind(this, function() { | ||||
|             for (let i = 0; i < this._dimmedWindows.length; i++) | ||||
|                 this._undimWindow(this._dimmedWindows[i]); | ||||
|         })); | ||||
|         Main.overview.connect('hiding', Lang.bind(this, function() { | ||||
|             for (let i = 0; i < this._dimmedWindows.length; i++) | ||||
|                 this._dimWindow(this._dimmedWindows[i]); | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     setCustomKeybindingHandler: function(name, modes, handler) { | ||||
| @@ -342,15 +333,13 @@ const WindowManager = new Lang.Class({ | ||||
|         if (shouldDim && !window._dimmed) { | ||||
|             window._dimmed = true; | ||||
|             this._dimmedWindows.push(window); | ||||
|             if (!Main.overview.visible) | ||||
|                 this._dimWindow(window); | ||||
|             this._dimWindow(window); | ||||
|         } else if (!shouldDim && window._dimmed) { | ||||
|             window._dimmed = false; | ||||
|             this._dimmedWindows = this._dimmedWindows.filter(function(win) { | ||||
|                                                                  return win != window; | ||||
|                                                              }); | ||||
|             if (!Main.overview.visible) | ||||
|                 this._undimWindow(window); | ||||
|             this._undimWindow(window); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,7 @@ const Main = imports.ui.main; | ||||
| const Overview = imports.ui.overview; | ||||
| const Panel = imports.ui.panel; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const WindowManager = imports.ui.windowManager; | ||||
|  | ||||
| const FOCUS_ANIMATION_TIME = 0.15; | ||||
|  | ||||
| @@ -41,6 +42,68 @@ function _interpolate(start, end, step) { | ||||
|     return start + (end - start) * step; | ||||
| } | ||||
|  | ||||
| const WindowCloneLayout = new Lang.Class({ | ||||
|     Name: 'WindowCloneLayout', | ||||
|     Extends: Clutter.LayoutManager, | ||||
|  | ||||
|     _init: function(boundingBox) { | ||||
|         this.parent(); | ||||
|  | ||||
|         this._boundingBox = boundingBox; | ||||
|     }, | ||||
|  | ||||
|     get boundingBox() { | ||||
|         return this._boundingBox; | ||||
|     }, | ||||
|  | ||||
|     set boundingBox(b) { | ||||
|         this._boundingBox = b; | ||||
|         this.layout_changed(); | ||||
|     }, | ||||
|  | ||||
|     _makeBoxForWindow: function(window) { | ||||
|         // We need to adjust the position of the actor because of the | ||||
|         // consequences of invisible borders -- in reality, the texture | ||||
|         // has an extra set of "padding" around it that we need to trim | ||||
|         // down. | ||||
|  | ||||
|         // The outer rect (from which we compute the bounding box) | ||||
|         // paradoxically is the smaller rectangle, containing the positions | ||||
|         // of the visible frame. The input rect contains everything, | ||||
|         // including the invisible border padding. | ||||
|         let inputRect = window.get_input_rect(); | ||||
|  | ||||
|         let box = new Clutter.ActorBox(); | ||||
|  | ||||
|         box.set_origin(inputRect.x - this._boundingBox.x, | ||||
|                        inputRect.y - this._boundingBox.y); | ||||
|         box.set_size(inputRect.width, inputRect.height); | ||||
|  | ||||
|         return box; | ||||
|     }, | ||||
|  | ||||
|     vfunc_get_preferred_height: function(container, forWidth) { | ||||
|         return [this._boundingBox.height, this._boundingBox.height]; | ||||
|     }, | ||||
|  | ||||
|     vfunc_get_preferred_width: function(container, forHeight) { | ||||
|         return [this._boundingBox.width, this._boundingBox.width]; | ||||
|     }, | ||||
|  | ||||
|     vfunc_allocate: function(container, box, flags) { | ||||
|         let clone = container.get_children().forEach(function (child) { | ||||
|             let realWindow; | ||||
|             if (child == container._delegate._windowClone) | ||||
|                 realWindow = container._delegate.realWindow; | ||||
|             else | ||||
|                 realWindow = child.source; | ||||
|  | ||||
|             child.allocate(this._makeBoxForWindow(realWindow.meta_window), | ||||
|                            flags); | ||||
|         }, this); | ||||
|     }, | ||||
| }); | ||||
|  | ||||
| const WindowClone = new Lang.Class({ | ||||
|     Name: 'WindowClone', | ||||
|  | ||||
| @@ -50,10 +113,7 @@ const WindowClone = new Lang.Class({ | ||||
|         this.metaWindow._delegate = this; | ||||
|         this._workspace = workspace; | ||||
|  | ||||
|         let [borderX, borderY] = this._getInvisibleBorderPadding(); | ||||
|         this._windowClone = new Clutter.Clone({ source: realWindow.get_texture(), | ||||
|                                                 x: -borderX, | ||||
|                                                 y: -borderY }); | ||||
|         this._windowClone = new Clutter.Clone({ source: realWindow.get_texture() }); | ||||
|         // We expect this.actor to be used for all interaction rather than | ||||
|         // this._windowClone; as the former is reactive and the latter | ||||
|         // is not, this just works for most cases. However, for DND all | ||||
| @@ -61,20 +121,15 @@ const WindowClone = new Lang.Class({ | ||||
|         // To avoid this, we hide it from pick. | ||||
|         Shell.util_set_hidden_from_pick(this._windowClone, true); | ||||
|  | ||||
|         this.origX = realWindow.x + borderX; | ||||
|         this.origY = realWindow.y + borderY; | ||||
|  | ||||
|         let outerRect = realWindow.meta_window.get_outer_rect(); | ||||
|  | ||||
|         // The MetaShapedTexture that we clone has a size that includes | ||||
|         // the invisible border; this is inconvenient; rather than trying | ||||
|         // to compensate all over the place we insert a ClutterActor into | ||||
|         // to compensate all over the place we insert a custom container into | ||||
|         // the hierarchy that is sized to only the visible portion. | ||||
|         // As usual, we cannot use a ShellGenericContainer or StWidget here, | ||||
|         // because Workspace plays dirty tricks with reparenting to do DNDs | ||||
|         // and scroll-to-zoom. | ||||
|         this.actor = new Clutter.Actor({ reactive: true, | ||||
|                                          x: this.origX, | ||||
|                                          y: this.origY, | ||||
|                                          width: outerRect.width, | ||||
|                                          height: outerRect.height }); | ||||
|                                          layout_manager: new WindowCloneLayout() }); | ||||
|  | ||||
|         this.actor.add_child(this._windowClone); | ||||
|  | ||||
| @@ -84,10 +139,19 @@ const WindowClone = new Lang.Class({ | ||||
|         this._dragSlot = [0, 0, 0, 0]; | ||||
|         this._stackAbove = null; | ||||
|  | ||||
|         this._sizeChangedId = this.realWindow.connect('size-changed', | ||||
|         this._windowClone._updateId = this.realWindow.connect('size-changed', | ||||
|             Lang.bind(this, this._onRealWindowSizeChanged)); | ||||
|         this._realWindowDestroyId = this.realWindow.connect('destroy', | ||||
|             Lang.bind(this, this._disconnectRealWindowSignals)); | ||||
|         this._windowClone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() { | ||||
|             // First destroy the clone and then destroy everything | ||||
|             // This will ensure that we never see it in the _disconnectSignals loop | ||||
|             this._windowClone.destroy(); | ||||
|             this.destroy(); | ||||
|         })); | ||||
|  | ||||
|         this._updateAttachedDialogs(); | ||||
|         this._computeBoundingBox(); | ||||
|         this.actor.x = this._boundingBox.x; | ||||
|         this.actor.y = this._boundingBox.y; | ||||
|  | ||||
|         let clickAction = new Clutter.ClickAction(); | ||||
|         clickAction.connect('clicked', Lang.bind(this, this._onClicked)); | ||||
| @@ -121,6 +185,97 @@ const WindowClone = new Lang.Class({ | ||||
|             return this._slot; | ||||
|     }, | ||||
|  | ||||
|     deleteAll: function() { | ||||
|         // Delete all windows, starting from the bottom-most (most-modal) one | ||||
|  | ||||
|         let windows = this.actor.get_children(); | ||||
|         for (let i = windows.length - 1; i >= 1; i--) { | ||||
|             let realWindow = windows[i].source; | ||||
|             let metaWindow = realWindow.meta_window; | ||||
|  | ||||
|             metaWindow.delete(global.get_current_time()); | ||||
|         } | ||||
|  | ||||
|         this.metaWindow.delete(global.get_current_time()); | ||||
|     }, | ||||
|  | ||||
|     addAttachedDialog: function(win) { | ||||
|         this._doAddAttachedDialog(win, win.get_compositor_private()); | ||||
|         this._computeBoundingBox(); | ||||
|         this._updateDimmer(); | ||||
|         this.emit('size-changed'); | ||||
|     }, | ||||
|  | ||||
|     _doAddAttachedDialog: function(metaWin, realWin) { | ||||
|         let clone = new Clutter.Clone({ source: realWin }); | ||||
|         clone._updateId = realWin.connect('size-changed', Lang.bind(this, function() { | ||||
|             this._computeBoundingBox(); | ||||
|             this.emit('size-changed'); | ||||
|         })); | ||||
|         clone._destroyId = realWin.connect('destroy', Lang.bind(this, function() { | ||||
|             clone.destroy(); | ||||
|  | ||||
|             this._computeBoundingBox(); | ||||
|             this._updateDimmer(); | ||||
|             this.emit('size-changed'); | ||||
|         })); | ||||
|         this.actor.add_child(clone); | ||||
|     }, | ||||
|  | ||||
|     _updateAttachedDialogs: function() { | ||||
|         let iter = Lang.bind(this, function(win) { | ||||
|             let actor = win.get_compositor_private(); | ||||
|  | ||||
|             if (!actor) | ||||
|                 return false; | ||||
|             if (!win.is_attached_dialog()) | ||||
|                 return false; | ||||
|  | ||||
|             this._doAddAttachedDialog(win, actor); | ||||
|             win.foreach_transient(iter); | ||||
|             return true; | ||||
|         }); | ||||
|         this.metaWindow.foreach_transient(iter); | ||||
|  | ||||
|         this._dimmer = new WindowManager.WindowDimmer(this._windowClone); | ||||
|         this._updateDimmer(); | ||||
|     }, | ||||
|  | ||||
|     _updateDimmer: function() { | ||||
|         if (this.actor.get_n_children() > 1) { | ||||
|             this._dimmer.setEnabled(true); | ||||
|             this._dimmer.dimFactor = 1.0; | ||||
|         } else { | ||||
|             this._dimmer.setEnabled(false); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     get boundingBox() { | ||||
|         return this._boundingBox; | ||||
|     }, | ||||
|  | ||||
|     getOriginalPosition: function() { | ||||
|         return [this._boundingBox.x, this._boundingBox.y]; | ||||
|     }, | ||||
|  | ||||
|     _computeBoundingBox: function() { | ||||
|         let rect = this.metaWindow.get_outer_rect(); | ||||
|  | ||||
|         this.actor.get_children().forEach(function (child) { | ||||
|             let realWindow; | ||||
|             if (child == this._windowClone) | ||||
|                 realWindow = this.realWindow; | ||||
|             else | ||||
|                 realWindow = child.source; | ||||
|  | ||||
|             let metaWindow = realWindow.meta_window; | ||||
|             rect = rect.union(metaWindow.get_outer_rect()); | ||||
|         }, this); | ||||
|  | ||||
|         this._boundingBox = rect; | ||||
|         this.actor.layout_manager.boundingBox = rect; | ||||
|     }, | ||||
|  | ||||
|     setStackAbove: function (actor) { | ||||
|         this._stackAbove = actor; | ||||
|         if (this.inDrag) | ||||
| @@ -136,44 +291,26 @@ const WindowClone = new Lang.Class({ | ||||
|         this.actor.destroy(); | ||||
|     }, | ||||
|  | ||||
|     _disconnectRealWindowSignals: function() { | ||||
|         if (this._sizeChangedId > 0) | ||||
|             this.realWindow.disconnect(this._sizeChangedId); | ||||
|         this._sizeChangedId = 0; | ||||
|     _disconnectSignals: function() { | ||||
|         this.actor.get_children().forEach(Lang.bind(this, function (child) { | ||||
|             let realWindow; | ||||
|             if (child == this._windowClone) | ||||
|                 realWindow = this.realWindow; | ||||
|             else | ||||
|                 realWindow = child.source; | ||||
|  | ||||
|         if (this._realWindowDestroyId > 0) | ||||
|             this.realWindow.disconnect(this._realWindowDestroyId); | ||||
|         this._realWindowDestroyId = 0; | ||||
|     }, | ||||
|  | ||||
|     _getInvisibleBorderPadding: function() { | ||||
|         // We need to adjust the position of the actor because of the | ||||
|         // consequences of invisible borders -- in reality, the texture | ||||
|         // has an extra set of "padding" around it that we need to trim | ||||
|         // down. | ||||
|  | ||||
|         // The outer rect paradoxically is the smaller rectangle, | ||||
|         // containing the positions of the visible frame. The input | ||||
|         // rect contains everything, including the invisible border | ||||
|         // padding. | ||||
|         let outerRect = this.metaWindow.get_outer_rect(); | ||||
|         let inputRect = this.metaWindow.get_input_rect(); | ||||
|         let [borderX, borderY] = [outerRect.x - inputRect.x, | ||||
|                                   outerRect.y - inputRect.y]; | ||||
|  | ||||
|         return [borderX, borderY]; | ||||
|             realWindow.disconnect(child._updateId); | ||||
|             realWindow.disconnect(child._destroyId); | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _onRealWindowSizeChanged: function() { | ||||
|         let [borderX, borderY] = this._getInvisibleBorderPadding(); | ||||
|         let outerRect = this.metaWindow.get_outer_rect(); | ||||
|         this.actor.set_size(outerRect.width, outerRect.height); | ||||
|         this._windowClone.set_position(-borderX, -borderY); | ||||
|         this._computeBoundingBox(); | ||||
|         this.emit('size-changed'); | ||||
|     }, | ||||
|  | ||||
|     _onDestroy: function() { | ||||
|         this._disconnectRealWindowSignals(); | ||||
|         this._disconnectSignals(); | ||||
|  | ||||
|         this.metaWindow._delegate = null; | ||||
|         this.actor._delegate = null; | ||||
| @@ -432,7 +569,7 @@ const WindowOverlay = new Lang.Class({ | ||||
|                                                       Lang.bind(this, | ||||
|                                                                 this._onWindowAdded)); | ||||
|  | ||||
|         metaWindow.delete(global.get_current_time()); | ||||
|         this._windowClone.deleteAll(); | ||||
|     }, | ||||
|  | ||||
|     _onWindowAdded: function(workspace, win) { | ||||
| @@ -1220,9 +1357,29 @@ const Workspace = new Lang.Class({ | ||||
|         if (this._lookupIndex (metaWin) != -1) | ||||
|             return; | ||||
|  | ||||
|         if (!this._isMyWindow(win) || !this._isOverviewWindow(win)) | ||||
|         if (!this._isMyWindow(win)) | ||||
|             return; | ||||
|  | ||||
|         if (!this._isOverviewWindow(win)) { | ||||
|             if (metaWin.is_attached_dialog()) { | ||||
|                 let parent = metaWin.get_transient_for(); | ||||
|                 while (parent.is_attached_dialog()) | ||||
|                     parent = metaWin.get_transient_for(); | ||||
|  | ||||
|                 let idx = this._lookupIndex (parent); | ||||
|                 if (idx < 0) { | ||||
|                     // parent was not created yet, it will take care | ||||
|                     // of the dialog when created | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 let clone = this._windows[idx]; | ||||
|                 clone.addAttachedDialog(metaWin); | ||||
|             } | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         let [clone, overlay] = this._addWindowClone(win); | ||||
|  | ||||
|         if (win._overviewHint) { | ||||
| @@ -1321,9 +1478,11 @@ const Workspace = new Lang.Class({ | ||||
|                 overlay.hide(); | ||||
|  | ||||
|             if (clone.metaWindow.showing_on_its_workspace()) { | ||||
|                 let [origX, origY] = clone.getOriginalPosition(); | ||||
|  | ||||
|                 Tweener.addTween(clone.actor, | ||||
|                                  { x: clone.origX, | ||||
|                                    y: clone.origY, | ||||
|                                  { x: origX, | ||||
|                                    y: origY, | ||||
|                                    scale_x: 1.0, | ||||
|                                    scale_y: 1.0, | ||||
|                                    time: Overview.ANIMATION_TIME, | ||||
|   | ||||
| @@ -13,6 +13,7 @@ const Background = imports.ui.background; | ||||
| const DND = imports.ui.dnd; | ||||
| const Main = imports.ui.main; | ||||
| const Tweener = imports.ui.tweener; | ||||
| const WindowManager = imports.ui.windowManager; | ||||
| const Workspace = imports.ui.workspace; | ||||
| const WorkspacesView = imports.ui.workspacesView; | ||||
|  | ||||
| @@ -31,20 +32,49 @@ const WORKSPACE_KEEP_ALIVE_TIME = 100; | ||||
|  | ||||
| const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides'; | ||||
|  | ||||
| /* A layout manager that requests size only for primary_actor, but then allocates | ||||
|    all using a fixed layout */ | ||||
| const PrimaryActorLayout = new Lang.Class({ | ||||
|     Name: 'PrimaryActorLayout', | ||||
|     Extends: Clutter.FixedLayout, | ||||
|  | ||||
|     _init: function(primaryActor) { | ||||
|         this.parent(); | ||||
|  | ||||
|         this.primaryActor = primaryActor; | ||||
|     }, | ||||
|  | ||||
|     vfunc_get_preferred_width: function(forHeight) { | ||||
|         return this.primaryActor.get_preferred_width(forHeight); | ||||
|     }, | ||||
|  | ||||
|     vfunc_get_preferred_height: function(forWidth) { | ||||
|         return this.primaryActor.get_preferred_height(forWidth); | ||||
|     }, | ||||
| }); | ||||
|  | ||||
| const WindowClone = new Lang.Class({ | ||||
|     Name: 'WindowClone', | ||||
|  | ||||
|     _init : function(realWindow) { | ||||
|         this.actor = new Clutter.Clone({ source: realWindow.get_texture(), | ||||
|         this.clone = new Clutter.Clone({ source: realWindow }); | ||||
|  | ||||
|         /* Can't use a Shell.GenericContainer because of DND and reparenting... */ | ||||
|         this.actor = new Clutter.Actor({ layout_manager: new PrimaryActorLayout(this.clone), | ||||
|                                          reactive: true }); | ||||
|         this.actor._delegate = this; | ||||
|         this.actor.add_child(this.clone); | ||||
|         this.realWindow = realWindow; | ||||
|         this.metaWindow = realWindow.meta_window; | ||||
|  | ||||
|         this._positionChangedId = this.realWindow.connect('position-changed', | ||||
|                                                           Lang.bind(this, this._onPositionChanged)); | ||||
|         this._realWindowDestroyedId = this.realWindow.connect('destroy', | ||||
|                                                               Lang.bind(this, this._disconnectRealWindowSignals)); | ||||
|         this.clone._updateId = this.realWindow.connect('position-changed', | ||||
|                                                        Lang.bind(this, this._onPositionChanged)); | ||||
|         this.clone._destroyId = this.realWindow.connect('destroy', Lang.bind(this, function() { | ||||
|             // First destroy the clone and then destroy everything | ||||
|             // This will ensure that we never see it in the _disconnectSignals loop | ||||
|             this.clone.destroy(); | ||||
|             this.destroy(); | ||||
|         })); | ||||
|         this._onPositionChanged(); | ||||
|  | ||||
|         this.actor.connect('button-release-event', | ||||
| @@ -60,6 +90,24 @@ const WindowClone = new Lang.Class({ | ||||
|         this._draggable.connect('drag-cancelled', Lang.bind(this, this._onDragCancelled)); | ||||
|         this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd)); | ||||
|         this.inDrag = false; | ||||
|  | ||||
|         let iter = Lang.bind(this, function(win) { | ||||
|             let actor = win.get_compositor_private(); | ||||
|  | ||||
|             if (!actor) | ||||
|                 return false; | ||||
|             if (!win.is_attached_dialog()) | ||||
|                 return false; | ||||
|  | ||||
|             this._doAddAttachedDialog(win, actor); | ||||
|             win.foreach_transient(iter); | ||||
|  | ||||
|             return true; | ||||
|         }); | ||||
|         this.metaWindow.foreach_transient(iter); | ||||
|  | ||||
|         this._dimmer = new WindowManager.WindowDimmer(this.clone); | ||||
|         this._updateDimmer(); | ||||
|     }, | ||||
|  | ||||
|     setStackAbove: function (actor) { | ||||
| @@ -74,25 +122,57 @@ const WindowClone = new Lang.Class({ | ||||
|         this.actor.destroy(); | ||||
|     }, | ||||
|  | ||||
|     addAttachedDialog: function(win) { | ||||
|         this._doAddAttachedDialog(win, win.get_compositor_private()); | ||||
|         this._updateDimmer(); | ||||
|     }, | ||||
|  | ||||
|     _doAddAttachedDialog: function(metaDialog, realDialog) { | ||||
|         let clone = new Clutter.Clone({ source: realDialog }); | ||||
|         this._updateDialogPosition(realDialog, clone); | ||||
|  | ||||
|         clone._updateId = realDialog.connect('position-changed', | ||||
|                                              Lang.bind(this, this._updateDialogPosition, clone)); | ||||
|         clone._destroyId = realDialog.connect('destroy', Lang.bind(this, function() { | ||||
|             clone.destroy(); | ||||
|             this._updateDimmer(); | ||||
|         })); | ||||
|         this.actor.add_child(clone); | ||||
|     }, | ||||
|  | ||||
|     _updateDimmer: function() { | ||||
|         if (this.actor.get_n_children() > 1) { | ||||
|             this._dimmer.setEnabled(true); | ||||
|             this._dimmer.dimFactor = 1.0; | ||||
|         } else { | ||||
|             this._dimmer.setEnabled(false); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _updateDialogPosition: function(realDialog, cloneDialog) { | ||||
|         let metaDialog = realDialog.meta_window; | ||||
|         let dialogRect = metaDialog.get_outer_rect(); | ||||
|         let rect = this.metaWindow.get_outer_rect(); | ||||
|  | ||||
|         cloneDialog.set_position(dialogRect.x - rect.x, dialogRect.y - rect.y); | ||||
|     }, | ||||
|  | ||||
|     _onPositionChanged: function() { | ||||
|         let rect = this.metaWindow.get_outer_rect(); | ||||
|         this.actor.set_position(this.realWindow.x, this.realWindow.y); | ||||
|     }, | ||||
|  | ||||
|     _disconnectRealWindowSignals: function() { | ||||
|         if (this._positionChangedId != 0) { | ||||
|             this.realWindow.disconnect(this._positionChangedId); | ||||
|             this._positionChangedId = 0; | ||||
|         } | ||||
|     _disconnectSignals: function() { | ||||
|         this.actor.get_children().forEach(function(child) { | ||||
|             let realWindow = child.source; | ||||
|  | ||||
|         if (this._realWindowDestroyedId != 0) { | ||||
|             this.realWindow.disconnect(this._realWindowDestroyedId); | ||||
|             this._realWindowDestroyedId = 0; | ||||
|         } | ||||
|             realWindow.disconnect(child._updateId); | ||||
|             realWindow.disconnect(child._destroyId); | ||||
|         }); | ||||
|     }, | ||||
|  | ||||
|     _onDestroy: function() { | ||||
|         this._disconnectRealWindowSignals(); | ||||
|         this._disconnectSignals(); | ||||
|  | ||||
|         this.actor._delegate = null; | ||||
|  | ||||
| @@ -320,10 +400,26 @@ const WorkspaceThumbnail = new Lang.Class({ | ||||
|         if (this._lookupIndex (metaWin) != -1) | ||||
|             return; | ||||
|  | ||||
|         if (!this._isMyWindow(win) || !this._isOverviewWindow(win)) | ||||
|         if (!this._isMyWindow(win)) | ||||
|             return; | ||||
|  | ||||
|         let clone = this._addWindowClone(win); | ||||
|         if (this._isOverviewWindow(win)) { | ||||
|             this._addWindowClone(win); | ||||
|         } else if (metaWin.is_attached_dialog()) { | ||||
|             let parent = metaWin.get_transient_for(); | ||||
|             while (parent.is_attached_dialog()) | ||||
|                 parent = metaWin.get_transient_for(); | ||||
|  | ||||
|             let idx = this._lookupIndex (parent); | ||||
|             if (idx < 0) { | ||||
|                 // parent was not created yet, it will take care | ||||
|                 // of the dialog when created | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             let clone = this._windows[idx]; | ||||
|             clone.addAttachedDialog(metaWin); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _windowAdded : function(metaWorkspace, metaWin) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user