diff --git a/0001-dnd-Nullify-_dragActor-after-we-ve-destroyed-it-and-.patch b/0001-dnd-Nullify-_dragActor-after-we-ve-destroyed-it-and-.patch new file mode 100644 index 0000000..61e1e89 --- /dev/null +++ b/0001-dnd-Nullify-_dragActor-after-we-ve-destroyed-it-and-.patch @@ -0,0 +1,220 @@ +From 3033506f2c266115a00ff43daaad14e59e3215c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 5 Dec 2017 22:41:17 +0100 +Subject: [PATCH 1/4] dnd: Nullify _dragActor after we've destroyed it, and + avoid invalid access + +We need to avoid that we use the _dragActor instance after that it has +been destroyed or we'll get errors. We now set it to null when this +happens, protecting any access to that. + +Add a DragState enum-like object to keep track of the state +instead of using booleans. + +Remove duplicated handler on 'destroy' and just use a generic one. + +https://bugzilla.gnome.org/show_bug.cgi?id=791233 +--- + js/ui/dnd.js | 65 +++++++++++++++++++++++++++++++--------------------- + 1 file changed, 39 insertions(+), 26 deletions(-) + +diff --git a/js/ui/dnd.js b/js/ui/dnd.js +index 634a7d6d7..8483e89fc 100644 +--- a/js/ui/dnd.js ++++ b/js/ui/dnd.js +@@ -27,6 +27,12 @@ var DragMotionResult = { + CONTINUE: 3 + }; + ++var DragState = { ++ INIT: 0, ++ DRAGGING: 1, ++ CANCELLED: 2, ++}; ++ + var DRAG_CURSOR_MAP = { + 0: Meta.Cursor.DND_UNSUPPORTED_TARGET, + 1: Meta.Cursor.DND_COPY, +@@ -78,6 +84,8 @@ var _Draggable = new Lang.Class({ + dragActorOpacity: undefined }); + + this.actor = actor; ++ this._dragState = DragState.INIT; ++ + if (!params.manualMode) { + this.actor.connect('button-press-event', + this._onButtonPress.bind(this)); +@@ -88,7 +96,7 @@ var _Draggable = new Lang.Class({ + this.actor.connect('destroy', () => { + this._actorDestroyed = true; + +- if (this._dragInProgress && this._dragCancellable) ++ if (this._dragState == DragState.DRAGGING && this._dragCancellable) + this._cancelDrag(global.get_current_time()); + this.disconnectAll(); + }); +@@ -100,7 +108,6 @@ var _Draggable = new Lang.Class({ + this._dragActorOpacity = params.dragActorOpacity; + + this._buttonDown = false; // The mouse button has been pressed and has not yet been released. +- this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet. + this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting). + this._dragCancellable = true; + +@@ -206,9 +213,10 @@ var _Draggable = new Lang.Class({ + (event.type() == Clutter.EventType.TOUCH_END && + global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { + this._buttonDown = false; +- if (this._dragInProgress) { ++ if (this._dragState == DragState.DRAGGING) { + return this._dragActorDropped(event); +- } else if (this._dragActor != null && !this._animationInProgress) { ++ } else if ((this._dragActor != null || this._dragState == DragState.CANCELLED) && ++ !this._animationInProgress) { + // Drag must have been cancelled with Esc. + this._dragComplete(); + return Clutter.EVENT_STOP; +@@ -222,14 +230,14 @@ var _Draggable = new Lang.Class({ + } else if (event.type() == Clutter.EventType.MOTION || + (event.type() == Clutter.EventType.TOUCH_UPDATE && + global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { +- if (this._dragInProgress) { ++ if (this._dragActor && this._dragState == DragState.DRAGGING) { + return this._updateDragPosition(event); +- } else if (this._dragActor == null) { ++ } else if (this._dragActor == null && this._dragState != DragState.CANCELLED) { + return this._maybeStartDrag(event); + } + // We intercept KEY_PRESS event so that we can process Esc key press to cancel + // dragging and ignore all other key presses. +- } else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragInProgress) { ++ } else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragState == DragState.DRAGGING) { + let symbol = event.get_key_symbol(); + if (symbol == Clutter.Escape) { + this._cancelDrag(event.get_time()); +@@ -265,7 +273,7 @@ var _Draggable = new Lang.Class({ + */ + startDrag(stageX, stageY, time, sequence) { + currentDraggable = this; +- this._dragInProgress = true; ++ this._dragState = DragState.DRAGGING; + + // Special-case St.Button: the pointer grab messes with the internal + // state, so force a reset to a reasonable state here +@@ -342,6 +350,13 @@ var _Draggable = new Lang.Class({ + Shell.util_set_hidden_from_pick(this._dragActor, true); + } + ++ this._dragActorDestroyId = this._dragActor.connect('destroy', () => { ++ // Cancel ongoing animation (if any) ++ this._finishAnimation(); ++ ++ this._dragActor = null; ++ this._dragState = DragState.CANCELLED; ++ }); + this._dragOrigOpacity = this._dragActor.opacity; + if (this._dragActorOpacity != undefined) + this._dragActor.opacity = this._dragActorOpacity; +@@ -500,7 +515,7 @@ var _Draggable = new Lang.Class({ + event.get_time())) { + // If it accepted the drop without taking the actor, + // handle it ourselves. +- if (this._dragActor.get_parent() == Main.uiGroup) { ++ if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) { + if (this._restoreOnSuccess) { + this._restoreDragActor(event.get_time()); + return true; +@@ -508,7 +523,7 @@ var _Draggable = new Lang.Class({ + this._dragActor.destroy(); + } + +- this._dragInProgress = false; ++ this._dragState = DragState.INIT; + global.display.set_cursor(Meta.Cursor.DEFAULT); + this.emit('drag-end', event.get_time(), true); + this._dragComplete(); +@@ -557,20 +572,22 @@ var _Draggable = new Lang.Class({ + + _cancelDrag(eventTime) { + this.emit('drag-cancelled', eventTime); +- this._dragInProgress = false; +- let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation(); ++ let wasCancelled = (this._dragState == DragState.CANCELLED); ++ this._dragState = DragState.CANCELLED; + +- if (this._actorDestroyed) { ++ if (this._actorDestroyed || wasCancelled) { + global.display.set_cursor(Meta.Cursor.DEFAULT); + if (!this._buttonDown) + this._dragComplete(); + this.emit('drag-end', eventTime, false); +- if (!this._dragOrigParent) ++ if (!this._dragOrigParent && this._dragActor) + this._dragActor.destroy(); + + return; + } + ++ let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation(); ++ + this._animateDragEnd(eventTime, + { x: snapBackX, + y: snapBackY, +@@ -581,7 +598,7 @@ var _Draggable = new Lang.Class({ + }, + + _restoreDragActor(eventTime) { +- this._dragInProgress = false; ++ this._dragState = DragState.INIT; + let [restoreX, restoreY, restoreScale] = this._getRestoreLocation(); + + // fade the actor back in at its original location +@@ -596,12 +613,6 @@ var _Draggable = new Lang.Class({ + _animateDragEnd(eventTime, params) { + this._animationInProgress = true; + +- // finish animation if the actor gets destroyed +- // during it +- this._dragActorDestroyId = +- this._dragActor.connect('destroy', +- this._finishAnimation.bind(this)); +- + params['opacity'] = this._dragOrigOpacity; + params['transition'] = 'easeOutQuad'; + params['onComplete'] = this._onAnimationComplete; +@@ -624,9 +635,6 @@ var _Draggable = new Lang.Class({ + }, + + _onAnimationComplete(dragActor, eventTime) { +- dragActor.disconnect(this._dragActorDestroyId); +- this._dragActorDestroyId = 0; +- + if (this._dragOrigParent) { + Main.uiGroup.remove_child(this._dragActor); + this._dragOrigParent.add_actor(this._dragActor); +@@ -641,7 +649,7 @@ var _Draggable = new Lang.Class({ + }, + + _dragComplete() { +- if (!this._actorDestroyed) ++ if (!this._actorDestroyed && this._dragActor) + Shell.util_set_hidden_from_pick(this._dragActor, false); + + this._ungrabEvents(); +@@ -652,7 +660,12 @@ var _Draggable = new Lang.Class({ + this._updateHoverId = 0; + } + +- this._dragActor = undefined; ++ if (this._dragActor) { ++ this._dragActor.disconnect(this._dragActorDestroyId); ++ this._dragActor = null; ++ } ++ ++ this._dragState = DragState.INIT; + currentDraggable = null; + } + }); +-- +2.19.0 + diff --git a/0001-dnd-don-t-try-to-access-destroyed-dragActor.patch b/0001-dnd-don-t-try-to-access-destroyed-dragActor.patch deleted file mode 100644 index e6a0ad8..0000000 --- a/0001-dnd-don-t-try-to-access-destroyed-dragActor.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 82c72f377a91cfa75fed1102f92ff4685c7e74da Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 19 Sep 2018 11:47:35 -0400 -Subject: [PATCH] dnd: don't try to access destroyed dragActor - -The dragComplete handler incorrectly checks -this._actorDestroyed to see if the drag actor -is destroyed. The drag actor may not be the same -as the main actor. - -The end result is an exception in drop handling, -leading to a shell lockup. - -This commit changes the code to always set -this._dragActor to undefined when it's destroyed, -and check for that condition instead of -this._actorDestroyed in the dragComplete handler. - -Closes https://gitlab.gnome.org/GNOME/gnome-shell/issues/577 ---- - js/ui/dnd.js | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/js/ui/dnd.js b/js/ui/dnd.js -index 634a7d6d7..6c563a3ba 100644 ---- a/js/ui/dnd.js -+++ b/js/ui/dnd.js -@@ -479,121 +479,124 @@ var _Draggable = new Lang.Class({ - switch (dropFunc(dropEvent)) { - case DragDropResult.FAILURE: - case DragDropResult.SUCCESS: - return true; - case DragDropResult.CONTINUE: - continue; - } - } - - // At this point it is too late to cancel a drag by destroying - // the actor, the fate of which is decided by acceptDrop and its - // side-effects - this._dragCancellable = false; - - while (target) { - if (target._delegate && target._delegate.acceptDrop) { - let [r, targX, targY] = target.transform_stage_point(dropX, dropY); - if (target._delegate.acceptDrop(this.actor._delegate, - this._dragActor, - targX, - targY, - event.get_time())) { - // If it accepted the drop without taking the actor, - // handle it ourselves. - if (this._dragActor.get_parent() == Main.uiGroup) { - if (this._restoreOnSuccess) { - this._restoreDragActor(event.get_time()); - return true; - } else - this._dragActor.destroy(); -+ this._dragActor = undefined; - } - - this._dragInProgress = false; - global.display.set_cursor(Meta.Cursor.DEFAULT); - this.emit('drag-end', event.get_time(), true); - this._dragComplete(); - return true; - } - } - target = target.get_parent(); - } - - this._cancelDrag(event.get_time()); - - return true; - }, - - _getRestoreLocation() { - let x, y, scale; - - if (this._dragActorSource && this._dragActorSource.visible) { - // Snap the clone back to its source - [x, y] = this._dragActorSource.get_transformed_position(); - let [sourceScaledWidth, sourceScaledHeight] = this._dragActorSource.get_transformed_size(); - scale = sourceScaledWidth ? this._dragActor.width / sourceScaledWidth : 0; - } else if (this._dragOrigParent) { - // Snap the actor back to its original position within - // its parent, adjusting for the fact that the parent - // may have been moved or scaled - let [parentX, parentY] = this._dragOrigParent.get_transformed_position(); - let [parentWidth, parentHeight] = this._dragOrigParent.get_size(); - let [parentScaledWidth, parentScaledHeight] = this._dragOrigParent.get_transformed_size(); - let parentScale = 1.0; - if (parentWidth != 0) - parentScale = parentScaledWidth / parentWidth; - - x = parentX + parentScale * this._dragOrigX; - y = parentY + parentScale * this._dragOrigY; - scale = this._dragOrigScale * parentScale; - } else { - // Snap back actor to its original stage position - x = this._snapBackX; - y = this._snapBackY; - scale = this._snapBackScale; - } - - return [x, y, scale]; - }, - - _cancelDrag(eventTime) { - this.emit('drag-cancelled', eventTime); - this._dragInProgress = false; - let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation(); - - if (this._actorDestroyed) { - global.display.set_cursor(Meta.Cursor.DEFAULT); - if (!this._buttonDown) - this._dragComplete(); - this.emit('drag-end', eventTime, false); -- if (!this._dragOrigParent) -+ if (!this._dragOrigParent) { - this._dragActor.destroy(); -+ this._dragActor = undefined; -+ } - - return; - } - - this._animateDragEnd(eventTime, - { x: snapBackX, - y: snapBackY, - scale_x: snapBackScale, - scale_y: snapBackScale, - time: SNAP_BACK_ANIMATION_TIME, - }); - }, - - _restoreDragActor(eventTime) { - this._dragInProgress = false; - let [restoreX, restoreY, restoreScale] = this._getRestoreLocation(); - - // fade the actor back in at its original location - this._dragActor.set_position(restoreX, restoreY); - this._dragActor.set_scale(restoreScale, restoreScale); - this._dragActor.opacity = 0; - - this._animateDragEnd(eventTime, - { time: REVERT_ANIMATION_TIME }); - }, - - _animateDragEnd(eventTime, params) { - this._animationInProgress = true; - - // finish animation if the actor gets destroyed -@@ -607,68 +610,69 @@ var _Draggable = new Lang.Class({ - params['onComplete'] = this._onAnimationComplete; - params['onCompleteScope'] = this; - params['onCompleteParams'] = [this._dragActor, eventTime]; - - // start the animation - Tweener.addTween(this._dragActor, params) - }, - - _finishAnimation() { - if (!this._animationInProgress) - return - - this._animationInProgress = false; - if (!this._buttonDown) - this._dragComplete(); - - global.display.set_cursor(Meta.Cursor.DEFAULT); - }, - - _onAnimationComplete(dragActor, eventTime) { - dragActor.disconnect(this._dragActorDestroyId); - this._dragActorDestroyId = 0; - - if (this._dragOrigParent) { - Main.uiGroup.remove_child(this._dragActor); - this._dragOrigParent.add_actor(this._dragActor); - dragActor.set_scale(this._dragOrigScale, this._dragOrigScale); - dragActor.set_position(this._dragOrigX, this._dragOrigY); - } else { - dragActor.destroy(); -+ this._dragActor = undefined; - } - - this.emit('drag-end', eventTime, false); - this._finishAnimation(); - }, - - _dragComplete() { -- if (!this._actorDestroyed) -+ if (this._dragActor) - Shell.util_set_hidden_from_pick(this._dragActor, false); - - this._ungrabEvents(); - global.sync_pointer(); - - if (this._updateHoverId) { - GLib.source_remove(this._updateHoverId); - this._updateHoverId = 0; - } - - this._dragActor = undefined; - currentDraggable = null; - } - }); - - Signals.addSignalMethods(_Draggable.prototype); - - /** - * makeDraggable: - * @actor: Source actor - * @params: (optional) Additional parameters - * - * Create an object which controls drag and drop for the given actor. - * - * If %manualMode is %true in @params, do not automatically start - * drag and drop on click - * - * If %dragActorMaxSize is present in @params, the drag actor will - * be scaled down to be no larger than that size in pixels. - * --- -2.17.1 - diff --git a/0001-theme-define-proper-hover-and-active-states.patch b/0001-theme-define-proper-hover-and-active-states.patch new file mode 100644 index 0000000..edd5f08 --- /dev/null +++ b/0001-theme-define-proper-hover-and-active-states.patch @@ -0,0 +1,74 @@ +From 22531384f1737090cf6a72a35bebb6fef4d0b4ac Mon Sep 17 00:00:00 2001 +From: Jakub Steiner +Date: Wed, 5 Sep 2018 20:33:56 +0200 +Subject: [PATCH] theme: define proper :hover and :active states + +- buttons didn't actually have these properly defined + +fixes issue #523 +--- + data/theme/gnome-shell-sass/_common.scss | 5 +++-- + data/theme/gnome-shell-sass/_drawing.scss | 8 ++++---- + 2 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss +index 64f9b0264..37ac36231 100644 +--- a/data/theme/gnome-shell-sass/_common.scss ++++ b/data/theme/gnome-shell-sass/_common.scss +@@ -48,17 +48,18 @@ stage { + padding: 4px 32px; + @include button(normal); + &:focus { @include button(focus); } ++ &:hover { @include button(hover); } + &:insensitive { @include button(insensitive); } + &:active { @include button(active); } +- + } + + .modal-dialog-linked-button { + border-right-width: 1px; + @include button(normal); + &:insensitive { @include button(insensitive); } +- &:active { @include button(active); } + &:focus { @include button(focus); } ++ &:hover { @include button(hover); } ++ &:active { @include button(active); } + padding: 12px; + + &:first-child { +diff --git a/data/theme/gnome-shell-sass/_drawing.scss b/data/theme/gnome-shell-sass/_drawing.scss +index 66d5adab6..7ac18b1bb 100644 +--- a/data/theme/gnome-shell-sass/_drawing.scss ++++ b/data/theme/gnome-shell-sass/_drawing.scss +@@ -150,8 +150,8 @@ + // + // focused button + // +- $_bg: if($c!=$osd_bg_color, transparentize($c, 0.5), +- $osd_bg_color); ++ $_bg: if($c!=$osd_bg_color, transparentize($c, 0.3), ++ lighten($osd_bg_color,3%)); + + color: $osd_fg_color; + text-shadow: 0 1px black; +@@ -164,7 +164,7 @@ + // active osd button + // + $_bg: if($c!=$osd_bg_color, transparentize($c, 0.3), +- lighten($osd_bg_color,10%)); ++ lighten($osd_bg_color,3%)); + + color: white; + border-color: $osd_borders_color; +@@ -182,7 +182,7 @@ + + color: white; + border-color: $osd_borders_color; +- background-color: darken($_bg,5%); ++ background-color: $selected_bg_color; + // This should be none, but it's creating some issues with borders, so to + // workaround it for now, use inset wich goes through a different code path. + // see https://bugzilla.gnome.org/show_bug.cgi?id=752934 +-- +2.19.0 + diff --git a/0001-windowManager-listen-actively-to-windows-being-destr.patch b/0001-windowManager-listen-actively-to-windows-being-destr.patch new file mode 100644 index 0000000..0b788e7 --- /dev/null +++ b/0001-windowManager-listen-actively-to-windows-being-destr.patch @@ -0,0 +1,46 @@ +From b087752b5539a8cbb1d61979cb069aef8a3475be Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 6 Sep 2018 21:50:21 +0200 +Subject: [PATCH] windowManager: listen actively to windows being destroyed + during WS switch + +Prevents gjs from dealing with already dispose()d objects. + +Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/539 +--- + js/ui/windowManager.js | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js +index b6627e253..2295e3010 100644 +--- a/js/ui/windowManager.js ++++ b/js/ui/windowManager.js +@@ -1910,6 +1910,14 @@ var WindowManager = new Lang.Class({ + actor.visible = visible; + } + } ++ ++ for (let i = 0; i < switchData.windows.length; i++) { ++ let w = switchData.windows[i]; ++ ++ w.windowDestroyId = w.window.connect('destroy', () => { ++ switchData.windows.splice(switchData.windows.indexOf(w), 1); ++ }); ++ } + }, + + _finishWorkspaceSwitch(switchData) { +@@ -1917,9 +1925,8 @@ var WindowManager = new Lang.Class({ + + for (let i = 0; i < switchData.windows.length; i++) { + let w = switchData.windows[i]; +- if (w.window.is_destroyed()) // Window gone +- continue; + ++ w.window.disconnect(w.windowDestroyId); + w.window.reparent(w.parent); + + if (w.window.get_meta_window().get_workspace() != +-- +2.19.0 + diff --git a/0001-windowMenu-Port-from-Meta.ScreenDirection-to-Meta.Di.patch b/0001-windowMenu-Port-from-Meta.ScreenDirection-to-Meta.Di.patch new file mode 100644 index 0000000..e7c47b1 --- /dev/null +++ b/0001-windowMenu-Port-from-Meta.ScreenDirection-to-Meta.Di.patch @@ -0,0 +1,58 @@ +From 2d791a51c0f4ec445cf52cdb0ac6a0bf39cef452 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=BCrg=20Billeter?= +Date: Tue, 11 Sep 2018 12:55:55 +0200 +Subject: [PATCH] windowMenu: Port from Meta.ScreenDirection to + Meta.DisplayDirection + +Meta.ScreenDirection no longer exists. This fixes window menus on +multi-monitor systems. + + JS ERROR: TypeError: Meta.ScreenDirection is undefined + _buildMenu@resource:///org/gnome/shell/ui/windowMenu.js:135:17 +--- + js/ui/windowMenu.js | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/js/ui/windowMenu.js b/js/ui/windowMenu.js +index 32e3be698..11d4f17b6 100644 +--- a/js/ui/windowMenu.js ++++ b/js/ui/windowMenu.js +@@ -132,7 +132,7 @@ var WindowMenu = new Lang.Class({ + if (nMonitors > 1 && monitorIndex >= 0) { + this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + +- let dir = Meta.ScreenDirection.UP; ++ let dir = Meta.DisplayDirection.UP; + let upMonitorIndex = + display.get_monitor_neighbor_index(monitorIndex, dir); + if (upMonitorIndex != -1) { +@@ -141,7 +141,7 @@ var WindowMenu = new Lang.Class({ + }); + } + +- dir = Meta.ScreenDirection.DOWN; ++ dir = Meta.DisplayDirection.DOWN; + let downMonitorIndex = + display.get_monitor_neighbor_index(monitorIndex, dir); + if (downMonitorIndex != -1) { +@@ -150,7 +150,7 @@ var WindowMenu = new Lang.Class({ + }); + } + +- dir = Meta.ScreenDirection.LEFT; ++ dir = Meta.DisplayDirection.LEFT; + let leftMonitorIndex = + display.get_monitor_neighbor_index(monitorIndex, dir); + if (leftMonitorIndex != -1) { +@@ -159,7 +159,7 @@ var WindowMenu = new Lang.Class({ + }); + } + +- dir = Meta.ScreenDirection.RIGHT; ++ dir = Meta.DisplayDirection.RIGHT; + let rightMonitorIndex = + display.get_monitor_neighbor_index(monitorIndex, dir); + if (rightMonitorIndex != -1) { +-- +2.19.0 + diff --git a/0002-messageList-stop-syncing-if-closeButton-has-been-des.patch b/0002-messageList-stop-syncing-if-closeButton-has-been-des.patch new file mode 100644 index 0000000..8a20f3d --- /dev/null +++ b/0002-messageList-stop-syncing-if-closeButton-has-been-des.patch @@ -0,0 +1,32 @@ +From 87da623d86323a0744b8723e1991f053586defaf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Wed, 4 Jul 2018 15:56:25 +0200 +Subject: [PATCH 2/4] messageList: stop syncing if closeButton has been + destroyed + +The _sync function for Message only updates the close button visibility, +so we can safely stop doing that if the close button get get destroyed earlier +(as it happens when clicking on it). + +https://bugzilla.gnome.org/show_bug.cgi?id=791233 +--- + js/ui/messageList.js | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/js/ui/messageList.js b/js/ui/messageList.js +index 3b3c2b6df..547135a1f 100644 +--- a/js/ui/messageList.js ++++ b/js/ui/messageList.js +@@ -363,7 +363,8 @@ var Message = new Lang.Class({ + this.setBody(body); + + this._closeButton.connect('clicked', this.close.bind(this)); +- this.actor.connect('notify::hover', this._sync.bind(this)); ++ let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this)); ++ this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId)); + this.actor.connect('clicked', this._onClicked.bind(this)); + this.actor.connect('destroy', this._onDestroy.bind(this)); + this._sync(); +-- +2.19.0 + diff --git a/0003-automountManager-remove-allowAutorun-expire-timeout-.patch b/0003-automountManager-remove-allowAutorun-expire-timeout-.patch new file mode 100644 index 0000000..a0ee633 --- /dev/null +++ b/0003-automountManager-remove-allowAutorun-expire-timeout-.patch @@ -0,0 +1,44 @@ +From 9c41736a813354fd9291177b12f6c4f85bd1c5f7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Wed, 4 Jul 2018 16:55:28 +0200 +Subject: [PATCH 3/4] automountManager: remove allowAutorun expire timeout on + volume removal + +If the volume is removed before AUTORUN_EXPIRE_TIMEOUT_SECS seconds, we can stop +the timeout earlier as there's nothing to unset, while the volume instance +won't be valid anymore. + +https://bugzilla.gnome.org/show_bug.cgi?id=791233 +--- + js/ui/components/automountManager.js | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/js/ui/components/automountManager.js b/js/ui/components/automountManager.js +index 2d8f3f8fb..a6cd85792 100644 +--- a/js/ui/components/automountManager.js ++++ b/js/ui/components/automountManager.js +@@ -210,6 +210,10 @@ var AutomountManager = new Lang.Class({ + }, + + _onVolumeRemoved(monitor, volume) { ++ if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) { ++ Mainloop.source_remove(volume._allowAutorunExpireId); ++ delete volume._allowAutorunExpireId; ++ } + this._volumeQueue = + this._volumeQueue.filter(element => (element != volume)); + }, +@@ -234,8 +238,10 @@ var AutomountManager = new Lang.Class({ + _allowAutorunExpire(volume) { + let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => { + volume.allowAutorun = false; ++ delete volume._allowAutorunExpireId; + return GLib.SOURCE_REMOVE; + }); ++ volume._allowAutorunExpireId = id; + GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun'); + } + }); +-- +2.19.0 + diff --git a/0004-calendar-chain-up-to-parent-on-_onDestroy.patch b/0004-calendar-chain-up-to-parent-on-_onDestroy.patch new file mode 100644 index 0000000..05d7dde --- /dev/null +++ b/0004-calendar-chain-up-to-parent-on-_onDestroy.patch @@ -0,0 +1,25 @@ +From 5bca4a884e8f02441a89d7b44490339d869e5966 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 9 Jul 2018 13:31:26 +0200 +Subject: [PATCH 4/4] calendar: chain up to parent on _onDestroy + +--- + js/ui/calendar.js | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/js/ui/calendar.js b/js/ui/calendar.js +index 990cac243..815c9f9c9 100644 +--- a/js/ui/calendar.js ++++ b/js/ui/calendar.js +@@ -803,6 +803,8 @@ var NotificationMessage = new Lang.Class({ + }, + + _onDestroy() { ++ this.parent(); ++ + if (this._updatedId) + this.notification.disconnect(this._updatedId); + this._updatedId = 0; +-- +2.19.0 + diff --git a/gnome-shell.spec b/gnome-shell.spec index a9afe43..b9795be 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -1,6 +1,6 @@ Name: gnome-shell Version: 3.30.0 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Window management and application launching for GNOME Group: User Interface/Desktops @@ -20,16 +20,33 @@ Patch2: 0001-network-Don-t-assume-the-active-connection-has-been-.patch # https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/240 Patch3: 0001-Fix-connection-to-wifi-APs-from-user-menu-RH-1628263.patch -# Fixes crash on Overview app icon drag-and-drop +# Fixes crash on Overview app icon drag-and-drop, along with some other +# JS invalid access fixes # https://gitlab.gnome.org/GNOME/gnome-shell/issues/577 # https://bugzilla.redhat.com/show_bug.cgi?id=1630134 -# https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/241 -Patch4: 0001-dnd-don-t-try-to-access-destroyed-dragActor.patch +# https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/209 +Patch4: 0001-dnd-Nullify-_dragActor-after-we-ve-destroyed-it-and-.patch +Patch5: 0002-messageList-stop-syncing-if-closeButton-has-been-des.patch +Patch6: 0003-automountManager-remove-allowAutorun-expire-timeout-.patch +Patch7: 0004-calendar-chain-up-to-parent-on-_onDestroy.patch # Fixes lack of text identifying the key on ssh key unlock prompt # https://gitlab.gnome.org/GNOME/gnome-shell/issues/574 # https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/234 -Patch5: 234.patch +Patch8: 234.patch + +# Fixes a workspace switch / window destroy crash with gjs 1.54.0 +# https://gitlab.gnome.org/GNOME/gnome-shell/issues/539 +Patch9: 0001-windowManager-listen-actively-to-windows-being-destr.patch + +# Fixes an issue with window menus on multi-monitor systems +# https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/227 +Patch10: 0001-windowMenu-Port-from-Meta.ScreenDirection-to-Meta.Di.patch + +# Fixes hover and active state for some buttons (e.g. Power Off dialog) +# https://gitlab.gnome.org/GNOME/gnome-shell/issues/523 +# https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/221 +Patch11: 0001-theme-define-proper-hover-and-active-states.patch %define libcroco_version 0.6.8 %define eds_version 3.17.2 @@ -226,6 +243,12 @@ glib-compile-schemas --allow-any-name %{_datadir}/glib-2.0/schemas &> /dev/null %{_mandir}/man1/%{name}.1.gz %changelog +* Wed Sep 19 2018 Adam Williamson - 3.30.0-7 +- Replace dnd fix from -5 with upstream version (GGO MR #209) +- Fix a window destroy crash which can occur with new gjs (GGO #539) +- Fix a window menu issue on multi-monitor systems (GGO MR #227) +- Fix hover and active states for some buttons (GGO #523) + * Wed Sep 19 2018 Adam Williamson - 3.30.0-6 - Fix missing key description in ssh key unlock prompt (GGO #574)