Merge lp:~3v1n0/gnome-shell/bionic-patches-picks into lp:~ubuntu-desktop/gnome-shell/ubuntu
- bionic-patches-picks
- Merge into ubuntu
Status: | Merged |
---|---|
Merged at revision: | 143 |
Proposed branch: | lp:~3v1n0/gnome-shell/bionic-patches-picks |
Merge into: | lp:~ubuntu-desktop/gnome-shell/ubuntu |
Diff against target: |
1534 lines (+1455/-1) 13 files modified
debian/changelog (+26/-0) debian/patches/StIcon-only-compute-shadow-pipeline-when-the-texture-is-p.patch (+134/-0) debian/patches/js-fix-invalid-access-errors.patch (+564/-0) debian/patches/popupMenu-Fix-wrong-call-to-clutter_actor_add_child.patch (+28/-0) debian/patches/series (+12/-1) debian/patches/shell-ignore-invalid-window-monitor-index.patch (+98/-0) debian/patches/st-texture-cache-Cancel-sliced-image-loading-on-target-ac.patch (+118/-0) debian/patches/st-texture-cache-Don-t-add-NULL-textures-to-cache.patch (+92/-0) debian/patches/volume-Add-back-sound-feedback-on-scroll.patch (+106/-0) debian/patches/workspace-fix-repositioned-windows-in-activities.patch (+148/-0) debian/patches/workspaceThumbnail-initialize-porthole-based-on-workArea.patch (+36/-0) debian/patches/workspaceThumbnail-only-update-_porthole-if-the-overview-.patch (+29/-0) debian/patches/workspaceThumbnail-rebuild-thumbnails-if-workareas-size-c.patch (+64/-0) |
To merge this branch: | bzr merge lp:~3v1n0/gnome-shell/bionic-patches-picks |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jeremy Bícha | Approve | ||
Review via email: mp+343423@code.launchpad.net |
Commit message
debian: cherry-pick patches from upstream or proposed
· https:/
· https:/
· https:/
· https:/
· https:/
· https:/
Description of the change
See https:/
Patch-queue git branch: https:/
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
2018-04-17 13:15 GMT-05:00 Jeremy Bicha <email address hidden>:
> I am very concerned with the decision to add 11 more patches to bionic's gnome-shell. I am concerned that this
> could make updating to 3.28.2 difficult (or the 3.30 series) if too much code is changed before these patches
> are accepted in to GNOME.
Considering how the pace at gnome-shell development is currently, I
think this won't be really a problem.
Plus, I've linked the git repo I've used to generate all this, and
using patch-queue, you know that rebasing won't really be an issue.
In any, case I can take care of it. Although I hope some of these
patch will merge (where's it's not already the case).
> You could at least help reduce this number by following up on the patches that have already been applied to upstream master
> to see if they can be pushed to the gnome-3-28 branch.
There's not gnome-3-28 branch yet, thus everything that here has been
cherry-picked from master, will be in 3.28.X.
> Please also try to be more persistent with getting upstream review of the remaining patches.
Eh, true, but I also don't like to bother people :).
> I encourage you to talk to Debian's smcv to see if he would be interested in taking some of these patches in to Debian.
Yeah, I already planned to propose some of them to salsa too.
> One minor note. The patch rename wasn't done in this merge proposal. Maybe that was missed when exporting your work from git.
Oh, well spotted. Thanks.
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2018-04-14 01:50:15 +0000 |
3 | +++ debian/changelog 2018-04-17 10:30:40 +0000 |
4 | @@ -1,10 +1,36 @@ |
5 | gnome-shell (3.28.1-0ubuntu1) UNRELEASED; urgency=medium |
6 | |
7 | + [ Jeremy Bicha ] |
8 | * New upstream release |
9 | * Drop obsolete patches: |
10 | - 27-nm-libexec-path.patch |
11 | - fix-wayland-vbox-crash.patch |
12 | |
13 | + [ Marco Trevisan (Treviño) ] |
14 | + * ui-Theme-lookup-should-respect-XDG_DATA_DIRS.patch: |
15 | + - Renamed from ubuntu_theme_lookup_xdg.patch and cherry-picked from |
16 | + upstream |
17 | + * StIcon-only-compute-shadow-pipeline-when-the-texture-is-p.patch: |
18 | + - Don't try to compute shadows on not allocated icons (LP: #1723378) |
19 | + * js-fix-invalid-access-errors.patch: |
20 | + - Fix javascript errors (LP: #1747566) |
21 | + * popupMenu-Fix-wrong-call-to-clutter_actor_add_child.patch: |
22 | + - Cherry-pick from upstream |
23 | + * shell-ignore-invalid-window-monitor-index.patch: |
24 | + - Fix crash on accessing on invalid monitor windows (LP: #1724439) |
25 | + * volume-Add-back-sound-feedback-on-scroll.patch: |
26 | + - Fix regression causing missing feedback on volume slider scroll |
27 | + * workspace-fix-repositioned-windows-in-activities.patch: |
28 | + - Ensure windows thumbnails coordinates are correct (LP: #1653153) |
29 | + * workspaceThumbnail-initialize-porthole-based-on-workArea.patch: |
30 | + workspaceThumbnail-only-update-_porthole-if-the-overview-.patch: |
31 | + workspaceThumbnail-rebuild-thumbnails-if-workareas-size-c.patch: |
32 | + - Cherry-picks from upstream, avoid unneeded computations in activities |
33 | + * st-texture-cache-Cancel-sliced-image-loading-on-target-ac.patch: |
34 | + - Fix possible crash on cache loading |
35 | + * st-texture-cache-Don-t-add-NULL-textures-to-cache.patch: |
36 | + - Fix crash when deleting NULL textures from cash (LP: #1754445) |
37 | + |
38 | -- Jeremy Bicha <jbicha@ubuntu.com> Fri, 13 Apr 2018 21:40:17 -0400 |
39 | |
40 | gnome-shell (3.28.0-0ubuntu5) bionic; urgency=medium |
41 | |
42 | === added file 'debian/patches/StIcon-only-compute-shadow-pipeline-when-the-texture-is-p.patch' |
43 | --- debian/patches/StIcon-only-compute-shadow-pipeline-when-the-texture-is-p.patch 1970-01-01 00:00:00 +0000 |
44 | +++ debian/patches/StIcon-only-compute-shadow-pipeline-when-the-texture-is-p.patch 2018-04-17 10:30:40 +0000 |
45 | @@ -0,0 +1,134 @@ |
46 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
47 | +Date: Wed, 18 Oct 2017 05:32:22 -0500 |
48 | +Subject: StIcon: only compute shadow pipeline when the texture is properly |
49 | + allocated |
50 | + |
51 | +Creating the shadow pipeline requires the actor to be allocated in order |
52 | +to get its dimensions, however in the current state we just compute it |
53 | +even if this is not the case. |
54 | +This causes _st_create_shadow_pipeline_from_actor (when getting the allocation |
55 | +box) to trigger an allocation cycle, which might lead to a convolution to |
56 | +st_icon_finish_update causing breakage on data as soon as we return from it. |
57 | + |
58 | +Generating it at paint if not done before, it's a way for avoiding this. |
59 | + |
60 | +https://bugzilla.gnome.org/show_bug.cgi?id=788908 |
61 | + |
62 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=788908 |
63 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1723378 |
64 | +Forwarded: yes, https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/3 |
65 | +--- |
66 | + src/st/st-icon.c | 48 +++++++++++++++++++++++++++++++++++++----------- |
67 | + 1 file changed, 37 insertions(+), 11 deletions(-) |
68 | + |
69 | +diff --git a/src/st/st-icon.c b/src/st/st-icon.c |
70 | +index 192df60..332e5b2 100644 |
71 | +--- a/src/st/st-icon.c |
72 | ++++ b/src/st/st-icon.c |
73 | +@@ -56,12 +56,15 @@ struct _StIconPrivate |
74 | + |
75 | + CoglPipeline *shadow_pipeline; |
76 | + StShadow *shadow_spec; |
77 | ++ ClutterSize shadow_size; |
78 | + }; |
79 | + |
80 | + G_DEFINE_TYPE_WITH_PRIVATE (StIcon, st_icon, ST_TYPE_WIDGET) |
81 | + |
82 | + static void st_icon_update (StIcon *icon); |
83 | + static gboolean st_icon_update_icon_size (StIcon *icon); |
84 | ++static void st_icon_update_shadow_pipeline (StIcon *icon); |
85 | ++static void st_icon_clean_shadow_pipeline (StIcon *icon); |
86 | + |
87 | + #define DEFAULT_ICON_SIZE 48 |
88 | + |
89 | +@@ -164,18 +167,31 @@ st_icon_paint (ClutterActor *actor) |
90 | + |
91 | + if (priv->icon_texture) |
92 | + { |
93 | +- if (priv->shadow_pipeline) |
94 | +- { |
95 | ++ if (priv->shadow_spec) |
96 | ++ { |
97 | + ClutterActorBox allocation; |
98 | + float width, height; |
99 | + |
100 | + clutter_actor_get_allocation_box (priv->icon_texture, &allocation); |
101 | + clutter_actor_box_get_size (&allocation, &width, &height); |
102 | + |
103 | +- _st_paint_shadow_with_opacity (priv->shadow_spec, |
104 | +- priv->shadow_pipeline, |
105 | +- &allocation, |
106 | +- clutter_actor_get_paint_opacity (priv->icon_texture)); |
107 | ++ if (priv->shadow_pipeline == NULL || |
108 | ++ priv->shadow_size.width != width || |
109 | ++ priv->shadow_size.height != height) |
110 | ++ { |
111 | ++ st_icon_update_shadow_pipeline (ST_ICON (actor)); |
112 | ++ |
113 | ++ if (priv->shadow_pipeline) |
114 | ++ clutter_size_init (&priv->shadow_size, width, height); |
115 | ++ } |
116 | ++ |
117 | ++ if (priv->shadow_pipeline) |
118 | ++ { |
119 | ++ _st_paint_shadow_with_opacity (priv->shadow_spec, |
120 | ++ priv->shadow_pipeline, |
121 | ++ &allocation, |
122 | ++ clutter_actor_get_paint_opacity (priv->icon_texture)); |
123 | ++ } |
124 | + } |
125 | + |
126 | + clutter_actor_paint (priv->icon_texture); |
127 | +@@ -189,7 +205,7 @@ st_icon_style_changed (StWidget *widget) |
128 | + StThemeNode *theme_node = st_widget_get_theme_node (widget); |
129 | + StIconPrivate *priv = self->priv; |
130 | + |
131 | +- g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref); |
132 | ++ st_icon_clean_shadow_pipeline (self); |
133 | + g_clear_pointer (&priv->shadow_spec, st_shadow_unref); |
134 | + |
135 | + priv->shadow_spec = st_theme_node_get_shadow (theme_node, "icon-shadow"); |
136 | +@@ -268,21 +284,31 @@ st_icon_init (StIcon *self) |
137 | + } |
138 | + |
139 | + static void |
140 | +-st_icon_update_shadow_pipeline (StIcon *icon) |
141 | ++st_icon_clean_shadow_pipeline (StIcon *icon) |
142 | + { |
143 | + StIconPrivate *priv = icon->priv; |
144 | + |
145 | + g_clear_pointer (&priv->shadow_pipeline, cogl_object_unref); |
146 | ++ clutter_size_init (&priv->shadow_size, 0, 0); |
147 | ++} |
148 | ++ |
149 | ++static void |
150 | ++st_icon_update_shadow_pipeline (StIcon *icon) |
151 | ++{ |
152 | ++ StIconPrivate *priv = icon->priv; |
153 | ++ |
154 | ++ st_icon_clean_shadow_pipeline (icon); |
155 | + |
156 | + if (priv->shadow_spec) |
157 | +- priv->shadow_pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, priv->icon_texture); |
158 | ++ priv->shadow_pipeline = _st_create_shadow_pipeline_from_actor (priv->shadow_spec, priv->icon_texture); |
159 | + } |
160 | + |
161 | + static void |
162 | + on_pixbuf_changed (ClutterTexture *texture, |
163 | + StIcon *icon) |
164 | + { |
165 | +- st_icon_update_shadow_pipeline (icon); |
166 | ++ st_icon_clean_shadow_pipeline (icon); |
167 | ++ clutter_actor_queue_redraw (CLUTTER_ACTOR (icon)); |
168 | + } |
169 | + |
170 | + static void |
171 | +@@ -307,7 +333,7 @@ st_icon_finish_update (StIcon *icon) |
172 | + /* Remove the temporary ref we added */ |
173 | + g_object_unref (priv->icon_texture); |
174 | + |
175 | +- st_icon_update_shadow_pipeline (icon); |
176 | ++ st_icon_clean_shadow_pipeline (icon); |
177 | + |
178 | + /* "pixbuf-change" is actually a misnomer for "texture-changed" */ |
179 | + g_signal_connect_object (priv->icon_texture, "pixbuf-change", |
180 | |
181 | === added file 'debian/patches/js-fix-invalid-access-errors.patch' |
182 | --- debian/patches/js-fix-invalid-access-errors.patch 1970-01-01 00:00:00 +0000 |
183 | +++ debian/patches/js-fix-invalid-access-errors.patch 2018-04-17 10:30:40 +0000 |
184 | @@ -0,0 +1,564 @@ |
185 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
186 | +Date: Mon, 4 Dec 2017 19:41:50 -0600 |
187 | +Subject: js: fix invalid-access errors |
188 | + |
189 | +tweener: Save handlers on target and remove them on destroy |
190 | + |
191 | +Saving handlers we had using the wrapper as a property of the object and delete |
192 | +them when resetting the object state. |
193 | +Without doing this an handler could be called on a destroyed target when this |
194 | +happens on the onComplete callback. |
195 | + |
196 | +https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
197 | + |
198 | +dnd: Nullify _dragActor after we've destroyed it, and avoid invalid access |
199 | + |
200 | +We need to avoid that we use the _dragActor instance after that it has |
201 | +been destroyed or we'll get errors. We now set it to null when this |
202 | +happens, protecting any access to that. |
203 | + |
204 | +Add a DragState enum-like object to keep track of the state |
205 | +instead of using booleans. |
206 | + |
207 | +Remove duplicated handler on 'destroy' and just use a generic one. |
208 | + |
209 | +https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
210 | + |
211 | +workspaceThumbnail: Disconnect from window signals on destruction |
212 | + |
213 | +Avoid to try to destroy the window clone content more than once |
214 | +when a window is destroyed, and do it in proper order. |
215 | + |
216 | +https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
217 | + |
218 | +workspaceThumbnail: Remove WindowClone's from _windows when destroyed |
219 | + |
220 | +A WindowClone might be destroyed earlier than its MetaWindow counterpart |
221 | +as its WindowActor could be destroyed earlier, thus when happens it's safer |
222 | +to remove the clone from the windows list, without waiting for the workspace |
223 | +to request to do so. |
224 | + |
225 | +WindowClone now emits a 'destroy' signals earlier enough and this now |
226 | +triggers a _doRemoveWindow on WorkspaceThumbnail which will lead |
227 | +to the proper cleanup; keeping track of the signal connections, in |
228 | +order to avoid callback loops (not really harmful in this case, but |
229 | +good practice). |
230 | + |
231 | +https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
232 | + |
233 | +workspace: Disconnect from window signals on destruction |
234 | + |
235 | +Avoid to try to destroy the window clone content more than once |
236 | +when a window is destroyed, and do it in proper order. |
237 | + |
238 | +https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
239 | + |
240 | +workspace: Remove WindowClone's from _windows when destroyed |
241 | + |
242 | +A WindowClone might be destroyed earlier than its MetaWindow counterpart |
243 | +as its WindowActor could be destroyed earlier, thus when happens it's safer |
244 | +to remove the clone from the windows list, without waiting for the workspace |
245 | +to request to do so. |
246 | + |
247 | +WindowClone now emits a 'destroy' signals earlier enough and this now |
248 | +triggers a _doRemoveWindow on WorkspaceThumbnail which will lead |
249 | +to the proper cleanup; keeping track of the signal connections, in |
250 | +order to avoid callback loops (not really harmful in this case, but |
251 | +good practice). |
252 | + |
253 | +https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
254 | + |
255 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=791233 |
256 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/bionic/+source/gnome-shell/+bug/1747566 |
257 | +Forwarded: yes, https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/4 |
258 | +--- |
259 | + js/ui/dnd.js | 65 +++++++++++++++++++++++++++------------------ |
260 | + js/ui/tweener.js | 64 +++++++++++++++++++++++++++++++++++--------- |
261 | + js/ui/workspace.js | 35 +++++++++++++++++------- |
262 | + js/ui/workspaceThumbnail.js | 33 +++++++++++++++++------ |
263 | + 4 files changed, 140 insertions(+), 57 deletions(-) |
264 | + |
265 | +diff --git a/js/ui/dnd.js b/js/ui/dnd.js |
266 | +index a38607c..431c60d 100644 |
267 | +--- a/js/ui/dnd.js |
268 | ++++ b/js/ui/dnd.js |
269 | +@@ -27,6 +27,12 @@ var DragMotionResult = { |
270 | + CONTINUE: 3 |
271 | + }; |
272 | + |
273 | ++var DragState = { |
274 | ++ INIT: 0, |
275 | ++ DRAGGING: 1, |
276 | ++ CANCELLED: 2, |
277 | ++}; |
278 | ++ |
279 | + var DRAG_CURSOR_MAP = { |
280 | + 0: Meta.Cursor.DND_UNSUPPORTED_TARGET, |
281 | + 1: Meta.Cursor.DND_COPY, |
282 | +@@ -78,6 +84,8 @@ var _Draggable = new Lang.Class({ |
283 | + dragActorOpacity: undefined }); |
284 | + |
285 | + this.actor = actor; |
286 | ++ this._dragState = DragState.INIT; |
287 | ++ |
288 | + if (!params.manualMode) { |
289 | + this.actor.connect('button-press-event', |
290 | + this._onButtonPress.bind(this)); |
291 | +@@ -88,7 +96,7 @@ var _Draggable = new Lang.Class({ |
292 | + this.actor.connect('destroy', () => { |
293 | + this._actorDestroyed = true; |
294 | + |
295 | +- if (this._dragInProgress && this._dragCancellable) |
296 | ++ if (this._dragState == DragState.DRAGGING && this._dragCancellable) |
297 | + this._cancelDrag(global.get_current_time()); |
298 | + this.disconnectAll(); |
299 | + }); |
300 | +@@ -100,7 +108,6 @@ var _Draggable = new Lang.Class({ |
301 | + this._dragActorOpacity = params.dragActorOpacity; |
302 | + |
303 | + this._buttonDown = false; // The mouse button has been pressed and has not yet been released. |
304 | +- this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet. |
305 | + this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting). |
306 | + this._dragCancellable = true; |
307 | + |
308 | +@@ -206,9 +213,10 @@ var _Draggable = new Lang.Class({ |
309 | + (event.type() == Clutter.EventType.TOUCH_END && |
310 | + global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { |
311 | + this._buttonDown = false; |
312 | +- if (this._dragInProgress) { |
313 | ++ if (this._dragState == DragState.DRAGGING) { |
314 | + return this._dragActorDropped(event); |
315 | +- } else if (this._dragActor != null && !this._animationInProgress) { |
316 | ++ } else if ((this._dragActor != null || this._dragState == DragState.CANCELLED) && |
317 | ++ !this._animationInProgress) { |
318 | + // Drag must have been cancelled with Esc. |
319 | + this._dragComplete(); |
320 | + return Clutter.EVENT_STOP; |
321 | +@@ -222,14 +230,14 @@ var _Draggable = new Lang.Class({ |
322 | + } else if (event.type() == Clutter.EventType.MOTION || |
323 | + (event.type() == Clutter.EventType.TOUCH_UPDATE && |
324 | + global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) { |
325 | +- if (this._dragInProgress) { |
326 | ++ if (this._dragActor && this._dragState == DragState.DRAGGING) { |
327 | + return this._updateDragPosition(event); |
328 | +- } else if (this._dragActor == null) { |
329 | ++ } else if (this._dragActor == null && this._dragState != DragState.CANCELLED) { |
330 | + return this._maybeStartDrag(event); |
331 | + } |
332 | + // We intercept KEY_PRESS event so that we can process Esc key press to cancel |
333 | + // dragging and ignore all other key presses. |
334 | +- } else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragInProgress) { |
335 | ++ } else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragState == DragState.DRAGGING) { |
336 | + let symbol = event.get_key_symbol(); |
337 | + if (symbol == Clutter.Escape) { |
338 | + this._cancelDrag(event.get_time()); |
339 | +@@ -265,7 +273,7 @@ var _Draggable = new Lang.Class({ |
340 | + */ |
341 | + startDrag(stageX, stageY, time, sequence) { |
342 | + currentDraggable = this; |
343 | +- this._dragInProgress = true; |
344 | ++ this._dragState = DragState.DRAGGING; |
345 | + |
346 | + // Special-case St.Button: the pointer grab messes with the internal |
347 | + // state, so force a reset to a reasonable state here |
348 | +@@ -342,6 +350,13 @@ var _Draggable = new Lang.Class({ |
349 | + Shell.util_set_hidden_from_pick(this._dragActor, true); |
350 | + } |
351 | + |
352 | ++ this._dragActorDestroyId = this._dragActor.connect('destroy', () => { |
353 | ++ // Cancel ongoing animation (if any) |
354 | ++ this._finishAnimation(); |
355 | ++ |
356 | ++ this._dragActor = null; |
357 | ++ this._dragState = DragState.CANCELLED; |
358 | ++ }); |
359 | + this._dragOrigOpacity = this._dragActor.opacity; |
360 | + if (this._dragActorOpacity != undefined) |
361 | + this._dragActor.opacity = this._dragActorOpacity; |
362 | +@@ -500,7 +515,7 @@ var _Draggable = new Lang.Class({ |
363 | + event.get_time())) { |
364 | + // If it accepted the drop without taking the actor, |
365 | + // handle it ourselves. |
366 | +- if (this._dragActor.get_parent() == Main.uiGroup) { |
367 | ++ if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) { |
368 | + if (this._restoreOnSuccess) { |
369 | + this._restoreDragActor(event.get_time()); |
370 | + return true; |
371 | +@@ -508,7 +523,7 @@ var _Draggable = new Lang.Class({ |
372 | + this._dragActor.destroy(); |
373 | + } |
374 | + |
375 | +- this._dragInProgress = false; |
376 | ++ this._dragState = DragState.INIT; |
377 | + global.screen.set_cursor(Meta.Cursor.DEFAULT); |
378 | + this.emit('drag-end', event.get_time(), true); |
379 | + this._dragComplete(); |
380 | +@@ -557,20 +572,22 @@ var _Draggable = new Lang.Class({ |
381 | + |
382 | + _cancelDrag(eventTime) { |
383 | + this.emit('drag-cancelled', eventTime); |
384 | +- this._dragInProgress = false; |
385 | +- let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation(); |
386 | ++ let wasCancelled = (this._dragState == DragState.CANCELLED); |
387 | ++ this._dragState = DragState.CANCELLED; |
388 | + |
389 | +- if (this._actorDestroyed) { |
390 | ++ if (this._actorDestroyed || wasCancelled) { |
391 | + global.screen.set_cursor(Meta.Cursor.DEFAULT); |
392 | + if (!this._buttonDown) |
393 | + this._dragComplete(); |
394 | + this.emit('drag-end', eventTime, false); |
395 | +- if (!this._dragOrigParent) |
396 | ++ if (!this._dragOrigParent && this._dragActor) |
397 | + this._dragActor.destroy(); |
398 | + |
399 | + return; |
400 | + } |
401 | + |
402 | ++ let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation(); |
403 | ++ |
404 | + this._animateDragEnd(eventTime, |
405 | + { x: snapBackX, |
406 | + y: snapBackY, |
407 | +@@ -581,7 +598,7 @@ var _Draggable = new Lang.Class({ |
408 | + }, |
409 | + |
410 | + _restoreDragActor(eventTime) { |
411 | +- this._dragInProgress = false; |
412 | ++ this._dragState = DragState.INIT; |
413 | + let [restoreX, restoreY, restoreScale] = this._getRestoreLocation(); |
414 | + |
415 | + // fade the actor back in at its original location |
416 | +@@ -596,12 +613,6 @@ var _Draggable = new Lang.Class({ |
417 | + _animateDragEnd(eventTime, params) { |
418 | + this._animationInProgress = true; |
419 | + |
420 | +- // finish animation if the actor gets destroyed |
421 | +- // during it |
422 | +- this._dragActorDestroyId = |
423 | +- this._dragActor.connect('destroy', |
424 | +- this._finishAnimation.bind(this)); |
425 | +- |
426 | + params['opacity'] = this._dragOrigOpacity; |
427 | + params['transition'] = 'easeOutQuad'; |
428 | + params['onComplete'] = this._onAnimationComplete; |
429 | +@@ -624,9 +635,6 @@ var _Draggable = new Lang.Class({ |
430 | + }, |
431 | + |
432 | + _onAnimationComplete(dragActor, eventTime) { |
433 | +- dragActor.disconnect(this._dragActorDestroyId); |
434 | +- this._dragActorDestroyId = 0; |
435 | +- |
436 | + if (this._dragOrigParent) { |
437 | + Main.uiGroup.remove_child(this._dragActor); |
438 | + this._dragOrigParent.add_actor(this._dragActor); |
439 | +@@ -641,7 +649,7 @@ var _Draggable = new Lang.Class({ |
440 | + }, |
441 | + |
442 | + _dragComplete() { |
443 | +- if (!this._actorDestroyed) |
444 | ++ if (!this._actorDestroyed && this._dragActor) |
445 | + Shell.util_set_hidden_from_pick(this._dragActor, false); |
446 | + |
447 | + this._ungrabEvents(); |
448 | +@@ -652,7 +660,12 @@ var _Draggable = new Lang.Class({ |
449 | + this._updateHoverId = 0; |
450 | + } |
451 | + |
452 | +- this._dragActor = undefined; |
453 | ++ if (this._dragActor) { |
454 | ++ this._dragActor.disconnect(this._dragActorDestroyId); |
455 | ++ this._dragActor = null; |
456 | ++ } |
457 | ++ |
458 | ++ this._dragState = DragState.INIT; |
459 | + currentDraggable = null; |
460 | + } |
461 | + }); |
462 | +diff --git a/js/ui/tweener.js b/js/ui/tweener.js |
463 | +index 1a85e2f..663b97b 100644 |
464 | +--- a/js/ui/tweener.js |
465 | ++++ b/js/ui/tweener.js |
466 | +@@ -69,30 +69,68 @@ function _getTweenState(target) { |
467 | + return target.__ShellTweenerState; |
468 | + } |
469 | + |
470 | ++function _ensureHandlers(target) { |
471 | ++ if (!target.__ShellTweenerHandlers) |
472 | ++ target.__ShellTweenerHandlers = {}; |
473 | ++ return target.__ShellTweenerHandlers; |
474 | ++} |
475 | ++ |
476 | + function _resetTweenState(target) { |
477 | + let state = target.__ShellTweenerState; |
478 | + |
479 | + if (state) { |
480 | +- if (state.destroyedId) |
481 | ++ if (state.destroyedId) { |
482 | + state.actor.disconnect(state.destroyedId); |
483 | ++ delete state.destroyedId; |
484 | ++ } |
485 | + } |
486 | + |
487 | ++ _removeHandler(target, 'onComplete', _tweenCompleted); |
488 | + target.__ShellTweenerState = {}; |
489 | + } |
490 | + |
491 | + function _addHandler(target, params, name, handler) { |
492 | +- if (params[name]) { |
493 | +- let oldHandler = params[name]; |
494 | +- let oldScope = params[name + 'Scope']; |
495 | +- let oldParams = params[name + 'Params']; |
496 | +- let eventScope = oldScope ? oldScope : target; |
497 | +- |
498 | +- params[name] = () => { |
499 | +- oldHandler.apply(eventScope, oldParams); |
500 | +- handler(target); |
501 | +- }; |
502 | +- } else |
503 | +- params[name] = () => { handler(target); }; |
504 | ++ let wrapperNeeded = false; |
505 | ++ let tweenerHandlers = _ensureHandlers(target); |
506 | ++ |
507 | ++ if (!(name in tweenerHandlers)) |
508 | ++ { |
509 | ++ tweenerHandlers[name] = []; |
510 | ++ wrapperNeeded = true; |
511 | ++ } |
512 | ++ |
513 | ++ let handlers = tweenerHandlers[name]; |
514 | ++ handlers.push(handler); |
515 | ++ |
516 | ++ if (wrapperNeeded) { |
517 | ++ if (params[name]) { |
518 | ++ let oldHandler = params[name]; |
519 | ++ let oldScope = params[name + 'Scope']; |
520 | ++ let oldParams = params[name + 'Params']; |
521 | ++ let eventScope = oldScope ? oldScope : target; |
522 | ++ |
523 | ++ params[name] = () => { |
524 | ++ oldHandler.apply(eventScope, oldParams); |
525 | ++ handlers.forEach((h) => h(target)); |
526 | ++ }; |
527 | ++ } else { |
528 | ++ params[name] = () => { handlers.forEach((h) => h(target)); }; |
529 | ++ } |
530 | ++ } |
531 | ++} |
532 | ++ |
533 | ++function _removeHandler(target, name, handler) { |
534 | ++ let tweenerHandlers = _ensureHandlers(target); |
535 | ++ |
536 | ++ if (name in tweenerHandlers) { |
537 | ++ let handlers = tweenerHandlers[name]; |
538 | ++ let handlerIndex = handlers.indexOf(handler); |
539 | ++ |
540 | ++ while (handlerIndex > -1) { |
541 | ++ handlers.splice(handlerIndex, 1); |
542 | ++ handlerIndex = handlers.indexOf(handler); |
543 | ++ } |
544 | ++ } |
545 | + } |
546 | + |
547 | + function _actorDestroyed(target) { |
548 | +diff --git a/js/ui/workspace.js b/js/ui/workspace.js |
549 | +index 1e121b7..8836537 100644 |
550 | +--- a/js/ui/workspace.js |
551 | ++++ b/js/ui/workspace.js |
552 | +@@ -139,14 +139,8 @@ var WindowClone = new Lang.Class({ |
553 | + |
554 | + this._windowClone._updateId = this.metaWindow.connect('size-changed', |
555 | + this._onRealWindowSizeChanged.bind(this)); |
556 | +- this._windowClone._destroyId = |
557 | +- this.realWindow.connect('destroy', () => { |
558 | +- // First destroy the clone and then destroy everything |
559 | +- // This will ensure that we never see it in the |
560 | +- // _disconnectSignals loop |
561 | +- this._windowClone.destroy(); |
562 | +- this.destroy(); |
563 | +- }); |
564 | ++ this._windowClone._destroyId = this.realWindow.connect('destroy', |
565 | ++ this.destroy.bind(this)); |
566 | + |
567 | + this._updateAttachedDialogs(); |
568 | + this._computeBoundingBox(); |
569 | +@@ -310,6 +304,14 @@ var WindowClone = new Lang.Class({ |
570 | + }, |
571 | + |
572 | + destroy() { |
573 | ++ this.emit('destroy'); |
574 | ++ |
575 | ++ // First destroy the clone and then destroy everything |
576 | ++ // This will ensure that we never see it in the _disconnectSignals loop |
577 | ++ this.metaWindow.disconnect(this._windowClone._updateId); |
578 | ++ this.realWindow.disconnect(this._windowClone._destroyId); |
579 | ++ this._windowClone.destroy(); |
580 | ++ |
581 | + this.actor.destroy(); |
582 | + }, |
583 | + |
584 | +@@ -1131,6 +1133,7 @@ var Workspace = new Lang.Class({ |
585 | + // Create clones for windows that should be |
586 | + // visible in the Overview |
587 | + this._windows = []; |
588 | ++ this._windowsDestroyedIds = []; |
589 | + this._windowOverlays = []; |
590 | + for (let i = 0; i < windows.length; i++) { |
591 | + if (this._isOverviewWindow(windows[i])) { |
592 | +@@ -1428,7 +1431,7 @@ var Workspace = new Lang.Class({ |
593 | + return GLib.SOURCE_REMOVE; |
594 | + }, |
595 | + |
596 | +- _doRemoveWindow(metaWin) { |
597 | ++ _doRemoveWindow(metaWin, {cloneDestroy}={cloneDestroy: true}) { |
598 | + let win = metaWin.get_compositor_private(); |
599 | + |
600 | + // find the position of the window in our list |
601 | +@@ -1438,8 +1441,10 @@ var Workspace = new Lang.Class({ |
602 | + return; |
603 | + |
604 | + let clone = this._windows[index]; |
605 | ++ clone.disconnect(this._windowsDestroyedIds[index]); |
606 | + |
607 | + this._windows.splice(index, 1); |
608 | ++ this._windowsDestroyedIds.splice(index, 1); |
609 | + this._windowOverlays.splice(index, 1); |
610 | + |
611 | + // If metaWin.get_compositor_private() returned non-NULL, that |
612 | +@@ -1457,7 +1462,9 @@ var Workspace = new Lang.Class({ |
613 | + scale: stageWidth / clone.actor.width |
614 | + }; |
615 | + } |
616 | +- clone.destroy(); |
617 | ++ |
618 | ++ if (cloneDestroy) |
619 | ++ clone.destroy(); |
620 | + |
621 | + |
622 | + // We need to reposition the windows; to avoid shuffling windows |
623 | +@@ -1800,7 +1807,11 @@ var Workspace = new Lang.Class({ |
624 | + this._actualGeometryLater = 0; |
625 | + } |
626 | + |
627 | ++ for (let index = 0; index < this._windows.length; ++index) |
628 | ++ this._windows[index].disconnect(this._windowsDestroyedIds[index]); |
629 | ++ |
630 | + this._windows = []; |
631 | ++ this._windowsDestroyedIds = []; |
632 | + }, |
633 | + |
634 | + // Sets this.leavingOverview flag to false. |
635 | +@@ -1848,6 +1859,9 @@ var Workspace = new Lang.Class({ |
636 | + clone.connect('size-changed', () => { |
637 | + this._recalculateWindowPositions(WindowPositionFlags.NONE); |
638 | + }); |
639 | ++ let cloneDestroyedId = clone.connect('destroy', () => { |
640 | ++ this._doRemoveWindow(clone.metaWindow, {cloneDestroy: false}); |
641 | ++ }); |
642 | + |
643 | + this.actor.add_actor(clone.actor); |
644 | + |
645 | +@@ -1864,6 +1878,7 @@ var Workspace = new Lang.Class({ |
646 | + clone.setStackAbove(this._windows[this._windows.length - 1].actor); |
647 | + |
648 | + this._windows.push(clone); |
649 | ++ this._windowsDestroyedIds.push(cloneDestroyedId); |
650 | + this._windowOverlays.push(overlay); |
651 | + |
652 | + return [clone, overlay]; |
653 | +diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js |
654 | +index c1b4bdd..0c72e74 100644 |
655 | +--- a/js/ui/workspaceThumbnail.js |
656 | ++++ b/js/ui/workspaceThumbnail.js |
657 | +@@ -70,12 +70,7 @@ var WindowClone = new Lang.Class({ |
658 | + |
659 | + this.clone._updateId = this.metaWindow.connect('position-changed', |
660 | + this._onPositionChanged.bind(this)); |
661 | +- this.clone._destroyId = this.realWindow.connect('destroy', () => { |
662 | +- // First destroy the clone and then destroy everything |
663 | +- // This will ensure that we never see it in the _disconnectSignals loop |
664 | +- this.clone.destroy(); |
665 | +- this.destroy(); |
666 | +- }); |
667 | ++ this.clone._destroyId = this.realWindow.connect('destroy', this.destroy.bind(this)); |
668 | + this._onPositionChanged(); |
669 | + |
670 | + this.actor.connect('button-release-event', |
671 | +@@ -142,6 +137,14 @@ var WindowClone = new Lang.Class({ |
672 | + }, |
673 | + |
674 | + destroy() { |
675 | ++ this.emit('destroy'); |
676 | ++ |
677 | ++ // First destroy the clone and then destroy everything |
678 | ++ // This will ensure that we never see it in the _disconnectSignals loop |
679 | ++ this.metaWindow.disconnect(this.clone._updateId); |
680 | ++ this.realWindow.disconnect(this.clone._destroyId); |
681 | ++ this.clone.destroy(); |
682 | ++ |
683 | + this.actor.destroy(); |
684 | + }, |
685 | + |
686 | +@@ -285,6 +288,7 @@ var WorkspaceThumbnail = new Lang.Class({ |
687 | + |
688 | + // Create clones for windows that should be visible in the Overview |
689 | + this._windows = []; |
690 | ++ this._windowsDestroyedIds = []; |
691 | + this._allWindows = []; |
692 | + this._minimizedChangedIds = []; |
693 | + for (let i = 0; i < windows.length; i++) { |
694 | +@@ -371,7 +375,7 @@ var WorkspaceThumbnail = new Lang.Class({ |
695 | + return this._collapseFraction; |
696 | + }, |
697 | + |
698 | +- _doRemoveWindow(metaWin) { |
699 | ++ _doRemoveWindow(metaWin, {cloneDestroy}={cloneDestroy: true}) { |
700 | + let win = metaWin.get_compositor_private(); |
701 | + |
702 | + // find the position of the window in our list |
703 | +@@ -381,9 +385,13 @@ var WorkspaceThumbnail = new Lang.Class({ |
704 | + return; |
705 | + |
706 | + let clone = this._windows[index]; |
707 | ++ clone.disconnect(this._windowsDestroyedIds[index]); |
708 | ++ |
709 | + this._windows.splice(index, 1); |
710 | ++ this._windowsDestroyedIds.splice(index, 1); |
711 | + |
712 | +- clone.destroy(); |
713 | ++ if (cloneDestroy) |
714 | ++ clone.destroy(); |
715 | + }, |
716 | + |
717 | + _doAddWindow(metaWin) { |
718 | +@@ -502,7 +510,11 @@ var WorkspaceThumbnail = new Lang.Class({ |
719 | + this._bgManager = null; |
720 | + } |
721 | + |
722 | ++ for (let index = 0; index < this._windows.length; ++index) |
723 | ++ this._windows[index].disconnect(this._windowsDestroyedIds[index]); |
724 | ++ |
725 | + this._windows = []; |
726 | ++ this._windowsDestroyedIds = []; |
727 | + this.actor = null; |
728 | + }, |
729 | + |
730 | +@@ -535,6 +547,10 @@ var WorkspaceThumbnail = new Lang.Class({ |
731 | + clone.connect('drag-end', () => { |
732 | + Main.overview.endWindowDrag(clone.metaWindow); |
733 | + }); |
734 | ++ let cloneDestroyedId = clone.connect('destroy', () => { |
735 | ++ this._doRemoveWindow(clone.metaWindow, {cloneDestroy: false}); |
736 | ++ }); |
737 | ++ |
738 | + this._contents.add_actor(clone.actor); |
739 | + |
740 | + if (this._windows.length == 0) |
741 | +@@ -543,6 +559,7 @@ var WorkspaceThumbnail = new Lang.Class({ |
742 | + clone.setStackAbove(this._windows[this._windows.length - 1].actor); |
743 | + |
744 | + this._windows.push(clone); |
745 | ++ this._windowsDestroyedIds.push(cloneDestroyedId); |
746 | + |
747 | + return clone; |
748 | + }, |
749 | |
750 | === added file 'debian/patches/popupMenu-Fix-wrong-call-to-clutter_actor_add_child.patch' |
751 | --- debian/patches/popupMenu-Fix-wrong-call-to-clutter_actor_add_child.patch 1970-01-01 00:00:00 +0000 |
752 | +++ debian/patches/popupMenu-Fix-wrong-call-to-clutter_actor_add_child.patch 2018-04-17 10:30:40 +0000 |
753 | @@ -0,0 +1,28 @@ |
754 | +From: Mario Sanchez Prada <mario@endlessm.com> |
755 | +Date: Mon, 16 Apr 2018 05:47:57 -0500 |
756 | +Subject: popupMenu: Fix wrong call to clutter_actor_add_child() |
757 | + |
758 | +Specify the horizontal alignment via the x_align property when creating |
759 | +the StIcon, since this function expects one argument, not two. |
760 | + |
761 | +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/commit/cdbc99e |
762 | +--- |
763 | + js/ui/popupMenu.js | 5 +++-- |
764 | + 1 file changed, 3 insertions(+), 2 deletions(-) |
765 | + |
766 | +diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js |
767 | +index 67b928c..83194d7 100644 |
768 | +--- a/js/ui/popupMenu.js |
769 | ++++ b/js/ui/popupMenu.js |
770 | +@@ -394,8 +394,9 @@ var PopupImageMenuItem = new Lang.Class({ |
771 | + _init(text, icon, params) { |
772 | + this.parent(params); |
773 | + |
774 | +- this._icon = new St.Icon({ style_class: 'popup-menu-icon' }); |
775 | +- this.actor.add_child(this._icon, { align: St.Align.END }); |
776 | ++ this._icon = new St.Icon({ style_class: 'popup-menu-icon', |
777 | ++ x_align: Clutter.ActorAlign.END }); |
778 | ++ this.actor.add_child(this._icon); |
779 | + this.label = new St.Label({ text: text }); |
780 | + this.actor.add_child(this.label); |
781 | + this.actor.label_actor = this.label; |
782 | |
783 | === modified file 'debian/patches/series' |
784 | --- debian/patches/series 2018-04-14 01:50:15 +0000 |
785 | +++ debian/patches/series 2018-04-17 10:30:40 +0000 |
786 | @@ -11,5 +11,16 @@ |
787 | ubuntu_background_login.patch |
788 | ubuntu_gdm_alternatives.patch |
789 | ubuntu_block_mode_extension_update.patch |
790 | -ubuntu_theme_lookup_xdg.patch |
791 | +ui-Theme-lookup-should-respect-XDG_DATA_DIRS.patch |
792 | workaround_crasher_fractional_scaling.patch |
793 | +shell-ignore-invalid-window-monitor-index.patch |
794 | +workspaceThumbnail-only-update-_porthole-if-the-overview-.patch |
795 | +workspaceThumbnail-rebuild-thumbnails-if-workareas-size-c.patch |
796 | +workspaceThumbnail-initialize-porthole-based-on-workArea.patch |
797 | +popupMenu-Fix-wrong-call-to-clutter_actor_add_child.patch |
798 | +StIcon-only-compute-shadow-pipeline-when-the-texture-is-p.patch |
799 | +volume-Add-back-sound-feedback-on-scroll.patch |
800 | +js-fix-invalid-access-errors.patch |
801 | +workspace-fix-repositioned-windows-in-activities.patch |
802 | +st-texture-cache-Cancel-sliced-image-loading-on-target-ac.patch |
803 | +st-texture-cache-Don-t-add-NULL-textures-to-cache.patch |
804 | |
805 | === added file 'debian/patches/shell-ignore-invalid-window-monitor-index.patch' |
806 | --- debian/patches/shell-ignore-invalid-window-monitor-index.patch 1970-01-01 00:00:00 +0000 |
807 | +++ debian/patches/shell-ignore-invalid-window-monitor-index.patch 2018-04-17 10:30:40 +0000 |
808 | @@ -0,0 +1,98 @@ |
809 | +From: Sam Spilsbury <sam@endlessm.com> |
810 | +Date: Wed, 11 Oct 2017 05:42:04 -0500 |
811 | +Subject: shell: ignore invalid window monitor index |
812 | + |
813 | +windowMenu: Check if monitorIndex is valid before using it |
814 | + |
815 | +Calling meta_window_get_monitor on an unmanaged window may return |
816 | +-1, so we need to check the return value. |
817 | + |
818 | +Fixes https://bugzilla.gnome.org/show_bug.cgi?id=788882 |
819 | + |
820 | +keyboard: Handle case where keyboardMonitor is unset |
821 | + |
822 | +This may be the case where keyboardIndex is -1, which may be the |
823 | +case where either the keyboard monitor hasn't been set yet, or |
824 | +the keyboard is being unmanaged and meta_window_get_monitor |
825 | +returns -1 |
826 | + |
827 | +https://bugzilla.gnome.org/show_bug.cgi?id=788882 |
828 | + |
829 | +layout: Remove focusMonitor, as it is unused |
830 | + |
831 | +It also uses focusIndex to determine which monitor to |
832 | +return and may occassionally return undefined if focusIndex |
833 | +was -1. |
834 | + |
835 | +https://bugzilla.gnome.org/show_bug.cgi?id=788882 |
836 | + |
837 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=788882 |
838 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1724439 |
839 | +Forwarded: yes |
840 | +--- |
841 | + js/ui/keyboard.js | 8 ++++++++ |
842 | + js/ui/layout.js | 4 ---- |
843 | + js/ui/windowMenu.js | 7 ++++--- |
844 | + 3 files changed, 12 insertions(+), 7 deletions(-) |
845 | + |
846 | +diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js |
847 | +index e13c7b7..14f6e7b 100644 |
848 | +--- a/js/ui/keyboard.js |
849 | ++++ b/js/ui/keyboard.js |
850 | +@@ -939,6 +939,12 @@ var Keyboard = new Lang.Class({ |
851 | + if (this.actor == null) |
852 | + return; |
853 | + let monitor = Main.layoutManager.keyboardMonitor; |
854 | ++ |
855 | ++ // monitor may be null here if the underlying keyboard monitor |
856 | ++ // index was still unset. |
857 | ++ if (!monitor) |
858 | ++ return; |
859 | ++ |
860 | + let maxHeight = monitor.height / 3; |
861 | + this.actor.width = monitor.width; |
862 | + this.actor.height = maxHeight; |
863 | +@@ -1001,6 +1007,8 @@ var Keyboard = new Lang.Class({ |
864 | + if (!this._enabled) |
865 | + return; |
866 | + |
867 | ++ |
868 | ++ |
869 | + this._clearShowIdle(); |
870 | + this._keyboardRequested = true; |
871 | + |
872 | +diff --git a/js/ui/layout.js b/js/ui/layout.js |
873 | +index 3d53bd4..cf0dad0 100644 |
874 | +--- a/js/ui/layout.js |
875 | ++++ b/js/ui/layout.js |
876 | +@@ -564,10 +564,6 @@ var LayoutManager = new Lang.Class({ |
877 | + return i; |
878 | + }, |
879 | + |
880 | +- get focusMonitor() { |
881 | +- return this.monitors[this.focusIndex]; |
882 | +- }, |
883 | +- |
884 | + set keyboardIndex(v) { |
885 | + this._keyboardIndex = v; |
886 | + this._updateKeyboardBox(); |
887 | +diff --git a/js/ui/windowMenu.js b/js/ui/windowMenu.js |
888 | +index f0e564b..9bd7d19 100644 |
889 | +--- a/js/ui/windowMenu.js |
890 | ++++ b/js/ui/windowMenu.js |
891 | +@@ -128,11 +128,12 @@ var WindowMenu = new Lang.Class({ |
892 | + |
893 | + let screen = global.screen; |
894 | + let nMonitors = screen.get_n_monitors(); |
895 | +- if (nMonitors > 1) { |
896 | ++ let monitorIndex = window.get_monitor(); |
897 | ++ // meta_window_get_monitor can return -1, so handle that case |
898 | ++ // appropriately. |
899 | ++ if (nMonitors > 1 && monitorIndex >= 0) { |
900 | + this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); |
901 | + |
902 | +- let monitorIndex = window.get_monitor(); |
903 | +- |
904 | + let dir = Meta.ScreenDirection.UP; |
905 | + let upMonitorIndex = |
906 | + screen.get_monitor_neighbor_index(monitorIndex, dir); |
907 | |
908 | === added file 'debian/patches/st-texture-cache-Cancel-sliced-image-loading-on-target-ac.patch' |
909 | --- debian/patches/st-texture-cache-Cancel-sliced-image-loading-on-target-ac.patch 1970-01-01 00:00:00 +0000 |
910 | +++ debian/patches/st-texture-cache-Cancel-sliced-image-loading-on-target-ac.patch 2018-04-17 10:30:40 +0000 |
911 | @@ -0,0 +1,118 @@ |
912 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
913 | +Date: Wed, 29 Nov 2017 19:48:02 -0600 |
914 | +Subject: st-texture-cache: Cancel sliced image loading on target actor |
915 | + destroy |
916 | + |
917 | +It might happen that the target clutter actor that we return on call |
918 | +of st_texture_cache_load_sliced_image might be destroyed while the |
919 | +loading task is still running. To protect from this, let's connect |
920 | +to "destroy" signal and when this happens we use a cancellable to |
921 | +stop the task. |
922 | + |
923 | +This allows to safely reuse the return value of this function to |
924 | +cancel the execution and avoiding that load_callback is called |
925 | +even for a request that is not anymore under our control. |
926 | + |
927 | +Forwarded: yes, https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/5 |
928 | +--- |
929 | + src/st/st-texture-cache.c | 30 ++++++++++++++++++++++++++---- |
930 | + 1 file changed, 26 insertions(+), 4 deletions(-) |
931 | + |
932 | +diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c |
933 | +index e8a832d..13b019e 100644 |
934 | +--- a/src/st/st-texture-cache.c |
935 | ++++ b/src/st/st-texture-cache.c |
936 | +@@ -1019,6 +1019,7 @@ typedef struct { |
937 | + gint grid_width, grid_height; |
938 | + gint scale_factor; |
939 | + ClutterActor *actor; |
940 | ++ GCancellable *cancellable; |
941 | + GFunc load_callback; |
942 | + gpointer load_callback_data; |
943 | + } AsyncImageData; |
944 | +@@ -1029,10 +1030,21 @@ on_data_destroy (gpointer data) |
945 | + AsyncImageData *d = (AsyncImageData *)data; |
946 | + g_object_unref (d->gfile); |
947 | + g_object_unref (d->actor); |
948 | ++ g_object_unref (d->cancellable); |
949 | + g_free (d); |
950 | + } |
951 | + |
952 | + static void |
953 | ++on_sliced_image_actor_destroyed (ClutterActor *actor, |
954 | ++ gpointer data) |
955 | ++{ |
956 | ++ GTask *task = data; |
957 | ++ GCancellable *cancellable = g_task_get_cancellable (task); |
958 | ++ |
959 | ++ g_cancellable_cancel (cancellable); |
960 | ++} |
961 | ++ |
962 | ++static void |
963 | + on_sliced_image_loaded (GObject *source_object, |
964 | + GAsyncResult *res, |
965 | + gpointer user_data) |
966 | +@@ -1042,7 +1054,7 @@ on_sliced_image_loaded (GObject *source_object, |
967 | + GTask *task = G_TASK (res); |
968 | + GList *list, *pixbufs; |
969 | + |
970 | +- if (g_task_had_error (task)) |
971 | ++ if (g_task_had_error (task) || g_cancellable_is_cancelled (data->cancellable)) |
972 | + return; |
973 | + |
974 | + pixbufs = g_task_propagate_pointer (task, NULL); |
975 | +@@ -1056,6 +1068,10 @@ on_sliced_image_loaded (GObject *source_object, |
976 | + |
977 | + g_list_free_full (pixbufs, g_object_unref); |
978 | + |
979 | ++ g_signal_handlers_disconnect_by_func (data->actor, |
980 | ++ on_sliced_image_actor_destroyed, |
981 | ++ task); |
982 | ++ |
983 | + if (data->load_callback != NULL) |
984 | + data->load_callback (cache, data->load_callback_data); |
985 | + } |
986 | +@@ -1093,7 +1109,7 @@ load_sliced_image (GTask *result, |
987 | + gchar *buffer = NULL; |
988 | + gsize length; |
989 | + |
990 | +- g_assert (!cancellable); |
991 | ++ g_assert (cancellable); |
992 | + |
993 | + data = task_data; |
994 | + g_assert (data); |
995 | +@@ -1101,7 +1117,7 @@ load_sliced_image (GTask *result, |
996 | + loader = gdk_pixbuf_loader_new (); |
997 | + g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data); |
998 | + |
999 | +- if (!g_file_load_contents (data->gfile, NULL, &buffer, &length, NULL, &error)) |
1000 | ++ if (!g_file_load_contents (data->gfile, cancellable, &buffer, &length, NULL, &error)) |
1001 | + { |
1002 | + g_warning ("Failed to open sliced image: %s", error->message); |
1003 | + goto out; |
1004 | +@@ -1169,6 +1185,7 @@ st_texture_cache_load_sliced_image (StTextureCache *cache, |
1005 | + AsyncImageData *data; |
1006 | + GTask *result; |
1007 | + ClutterActor *actor = clutter_actor_new (); |
1008 | ++ GCancellable *cancellable = g_cancellable_new (); |
1009 | + |
1010 | + data = g_new0 (AsyncImageData, 1); |
1011 | + data->grid_width = grid_width; |
1012 | +@@ -1176,11 +1193,16 @@ st_texture_cache_load_sliced_image (StTextureCache *cache, |
1013 | + data->scale_factor = scale; |
1014 | + data->gfile = g_object_ref (file); |
1015 | + data->actor = actor; |
1016 | ++ data->cancellable = cancellable; |
1017 | + data->load_callback = load_callback; |
1018 | + data->load_callback_data = user_data; |
1019 | + g_object_ref (G_OBJECT (actor)); |
1020 | + |
1021 | +- result = g_task_new (cache, NULL, on_sliced_image_loaded, data); |
1022 | ++ result = g_task_new (cache, cancellable, on_sliced_image_loaded, data); |
1023 | ++ |
1024 | ++ g_signal_connect (actor, "destroy", |
1025 | ++ G_CALLBACK (on_sliced_image_actor_destroyed), result); |
1026 | ++ |
1027 | + g_task_set_task_data (result, data, on_data_destroy); |
1028 | + g_task_run_in_thread (result, load_sliced_image); |
1029 | + |
1030 | |
1031 | === added file 'debian/patches/st-texture-cache-Don-t-add-NULL-textures-to-cache.patch' |
1032 | --- debian/patches/st-texture-cache-Don-t-add-NULL-textures-to-cache.patch 1970-01-01 00:00:00 +0000 |
1033 | +++ debian/patches/st-texture-cache-Don-t-add-NULL-textures-to-cache.patch 2018-04-17 10:30:40 +0000 |
1034 | @@ -0,0 +1,92 @@ |
1035 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1036 | +Date: Tue, 17 Apr 2018 04:43:34 -0500 |
1037 | +Subject: st-texture-cache: Don't add NULL textures to cache |
1038 | + |
1039 | +This might cause a crash when cleaning up the cache as the hash table has |
1040 | +cogl_object_unref as DestroyNotify function but that assumes that |
1041 | +the passed object is a valid CoglObject. |
1042 | + |
1043 | +st-texture-cache: Save cairo surfaces to a different map |
1044 | + |
1045 | +The default keyed_surface is meant to handle CoglTextures thus we can't |
1046 | +add cairo surfaces to it, as the DestroyNotify function won't handle them. |
1047 | + |
1048 | +Then the quicker way is to just add another Hash table for handling |
1049 | +such types of textures, with proper destroy function. |
1050 | + |
1051 | +Forwarded: yes, https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/79 |
1052 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/210 |
1053 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1754445 |
1054 | +--- |
1055 | + src/st/st-texture-cache.c | 16 ++++++++++++++-- |
1056 | + 1 file changed, 14 insertions(+), 2 deletions(-) |
1057 | + |
1058 | +diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c |
1059 | +index 13b019e..168473b 100644 |
1060 | +--- a/src/st/st-texture-cache.c |
1061 | ++++ b/src/st/st-texture-cache.c |
1062 | +@@ -37,6 +37,7 @@ struct _StTextureCachePrivate |
1063 | + |
1064 | + /* Things that were loaded with a cache policy != NONE */ |
1065 | + GHashTable *keyed_cache; /* char * -> CoglTexture* */ |
1066 | ++ GHashTable *surfaces_keyed_cache; /* char * -> cairo_surface_t* */ |
1067 | + |
1068 | + /* Presently this is used to de-duplicate requests for GIcons and async URIs. */ |
1069 | + GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */ |
1070 | +@@ -145,6 +146,10 @@ st_texture_cache_init (StTextureCache *self) |
1071 | + |
1072 | + self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal, |
1073 | + g_free, cogl_object_unref); |
1074 | ++ self->priv->surfaces_keyed_cache = g_hash_table_new_full (g_str_hash, |
1075 | ++ g_str_equal, |
1076 | ++ g_free, |
1077 | ++ (GDestroyNotify) cairo_surface_destroy); |
1078 | + self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal, |
1079 | + g_free, NULL); |
1080 | + self->priv->file_monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, |
1081 | +@@ -166,6 +171,7 @@ st_texture_cache_dispose (GObject *object) |
1082 | + } |
1083 | + |
1084 | + g_clear_pointer (&self->priv->keyed_cache, g_hash_table_destroy); |
1085 | ++ g_clear_pointer (&self->priv->surfaces_keyed_cache, g_hash_table_destroy); |
1086 | + g_clear_pointer (&self->priv->outstanding_requests, g_hash_table_destroy); |
1087 | + g_clear_pointer (&self->priv->file_monitors, g_hash_table_destroy); |
1088 | + |
1089 | +@@ -520,6 +526,8 @@ finish_texture_load (AsyncTextureLoadData *data, |
1090 | + goto out; |
1091 | + |
1092 | + texdata = pixbuf_to_cogl_texture (pixbuf); |
1093 | ++ if (!texdata) |
1094 | ++ goto out; |
1095 | + |
1096 | + if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE) |
1097 | + { |
1098 | +@@ -1295,6 +1303,9 @@ st_texture_cache_load_file_sync_to_cogl_texture (StTextureCache *cache, |
1099 | + texdata = pixbuf_to_cogl_texture (pixbuf); |
1100 | + g_object_unref (pixbuf); |
1101 | + |
1102 | ++ if (!texdata) |
1103 | ++ goto out; |
1104 | ++ |
1105 | + if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER) |
1106 | + { |
1107 | + cogl_object_ref (texdata); |
1108 | +@@ -1326,7 +1337,7 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache, |
1109 | + |
1110 | + key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file)); |
1111 | + |
1112 | +- surface = g_hash_table_lookup (cache->priv->keyed_cache, key); |
1113 | ++ surface = g_hash_table_lookup (cache->priv->surfaces_keyed_cache, key); |
1114 | + |
1115 | + if (surface == NULL) |
1116 | + { |
1117 | +@@ -1340,7 +1351,8 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache, |
1118 | + if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER) |
1119 | + { |
1120 | + cairo_surface_reference (surface); |
1121 | +- g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface); |
1122 | ++ g_hash_table_insert (cache->priv->surfaces_keyed_cache, |
1123 | ++ g_strdup (key), surface); |
1124 | + } |
1125 | + } |
1126 | + else |
1127 | |
1128 | === added file 'debian/patches/volume-Add-back-sound-feedback-on-scroll.patch' |
1129 | --- debian/patches/volume-Add-back-sound-feedback-on-scroll.patch 1970-01-01 00:00:00 +0000 |
1130 | +++ debian/patches/volume-Add-back-sound-feedback-on-scroll.patch 2018-04-17 10:30:40 +0000 |
1131 | @@ -0,0 +1,106 @@ |
1132 | +From: =?utf-8?q?Florian_M=C3=BCllner?= <fmuellner@gnome.org> |
1133 | +Date: Fri, 23 Feb 2018 16:58:22 -0600 |
1134 | +Subject: volume: Add back sound feedback on scroll |
1135 | + |
1136 | +Commit 8d4855f1008 accidentally removed the volume change feedback |
1137 | +for scroll events. Add it back to be consistent again with moving |
1138 | +the slider via arrow keys, slider drags/clicks and gsd's media keys |
1139 | +handling. |
1140 | + |
1141 | +https://gitlab.gnome.org/GNOME/gnome-shell/issues/53 |
1142 | + |
1143 | +volume: Only emit sound feedback after volume changes |
1144 | + |
1145 | +gnome-settings-daemon doesn't play the volume change sound when |
1146 | +the volume stayed the same (that is, it is already at its maximum |
1147 | +or minimum). This looks like the right thing to do, so copy its |
1148 | +behavior. |
1149 | + |
1150 | +https://gitlab.gnome.org/GNOME/gnome-shell/issues/53 |
1151 | + |
1152 | +slider: Stop emulating drags in key handling |
1153 | + |
1154 | +Emitting ::drag-end after changing the slider value via arrow keys |
1155 | +was a cheap way to make the sound feedback work for keyboard input. |
1156 | +But now that the volume indicator plays the sound on ::value-changed |
1157 | +as well, we can stop doing that - after all, key presses aren't drags. |
1158 | + |
1159 | +Besides that, this will make the limiting of feedback to actual volume |
1160 | +changes from the previous commit work for key events as well. |
1161 | + |
1162 | +https://gitlab.gnome.org/GNOME/gnome-shell/issues/53 |
1163 | + |
1164 | +Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/53 |
1165 | +Forwarded: yes, https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/51 |
1166 | +--- |
1167 | + js/ui/slider.js | 2 -- |
1168 | + js/ui/status/volume.js | 19 ++++++++++++++++++- |
1169 | + 2 files changed, 18 insertions(+), 3 deletions(-) |
1170 | + |
1171 | +diff --git a/js/ui/slider.js b/js/ui/slider.js |
1172 | +index 9853929..30295b4 100644 |
1173 | +--- a/js/ui/slider.js |
1174 | ++++ b/js/ui/slider.js |
1175 | +@@ -232,9 +232,7 @@ var Slider = new Lang.Class({ |
1176 | + let delta = key == Clutter.KEY_Right ? 0.1 : -0.1; |
1177 | + this._value = Math.max(0, Math.min(this._value + delta, 1)); |
1178 | + this.actor.queue_repaint(); |
1179 | +- this.emit('drag-begin'); |
1180 | + this.emit('value-changed', this._value); |
1181 | +- this.emit('drag-end'); |
1182 | + return Clutter.EVENT_STOP; |
1183 | + } |
1184 | + return Clutter.EVENT_PROPAGATE; |
1185 | +diff --git a/js/ui/status/volume.js b/js/ui/status/volume.js |
1186 | +index 65c4c42..c0f9cf3 100644 |
1187 | +--- a/js/ui/status/volume.js |
1188 | ++++ b/js/ui/status/volume.js |
1189 | +@@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter; |
1190 | + const Lang = imports.lang; |
1191 | + const Gio = imports.gi.Gio; |
1192 | + const Gvc = imports.gi.Gvc; |
1193 | ++const Mainloop = imports.mainloop; |
1194 | + const St = imports.gi.St; |
1195 | + const Signals = imports.signals; |
1196 | + |
1197 | +@@ -36,9 +37,16 @@ var StreamSlider = new Lang.Class({ |
1198 | + |
1199 | + this.item = new PopupMenu.PopupBaseMenuItem({ activate: false }); |
1200 | + |
1201 | ++ this._inDrag = false; |
1202 | ++ this._notifyVolumeChangeId = 0; |
1203 | ++ |
1204 | + this._slider = new Slider.Slider(0); |
1205 | ++ this._slider.connect('drag-begin', () => { this._inDrag = true; }); |
1206 | + this._slider.connect('value-changed', this._sliderChanged.bind(this)); |
1207 | +- this._slider.connect('drag-end', this._notifyVolumeChange.bind(this)); |
1208 | ++ this._slider.connect('drag-end', () => { |
1209 | ++ this._inDrag = false; |
1210 | ++ this._notifyVolumeChange(); |
1211 | ++ }); |
1212 | + |
1213 | + this._icon = new St.Icon({ style_class: 'popup-menu-icon' }); |
1214 | + this.item.actor.add(this._icon); |
1215 | +@@ -135,6 +143,7 @@ var StreamSlider = new Lang.Class({ |
1216 | + |
1217 | + let volume = value * this._get_control_max_volume(); |
1218 | + let prevMuted = this._stream.is_muted; |
1219 | ++ let prevVolume = this._stream.volume; |
1220 | + if (volume < 1) { |
1221 | + this._stream.volume = 0; |
1222 | + if (!prevMuted) |
1223 | +@@ -145,6 +154,14 @@ var StreamSlider = new Lang.Class({ |
1224 | + this._stream.change_is_muted(false); |
1225 | + } |
1226 | + this._stream.push_volume(); |
1227 | ++ |
1228 | ++ let volumeChanged = this._stream.volume != prevVolume; |
1229 | ++ if (volumeChanged && !this._notifyVolumeChangeId && !this._inDrag) |
1230 | ++ this._notifyVolumeChangeId = Mainloop.timeout_add(30, () => { |
1231 | ++ this._notifyVolumeChange(); |
1232 | ++ this._notifyVolumeChangeId = 0; |
1233 | ++ return GLib.SOURCE_REMOVE; |
1234 | ++ }); |
1235 | + }, |
1236 | + |
1237 | + _notifyVolumeChange() { |
1238 | |
1239 | === added file 'debian/patches/workspace-fix-repositioned-windows-in-activities.patch' |
1240 | --- debian/patches/workspace-fix-repositioned-windows-in-activities.patch 1970-01-01 00:00:00 +0000 |
1241 | +++ debian/patches/workspace-fix-repositioned-windows-in-activities.patch 2018-04-17 10:30:40 +0000 |
1242 | @@ -0,0 +1,148 @@ |
1243 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1244 | +Date: Fri, 19 Jan 2018 08:00:10 -0600 |
1245 | +Subject: workspace: fix repositioned windows in activities |
1246 | + |
1247 | +workspace: Recompute bounding box on window 'position-changed' |
1248 | + |
1249 | +We need to update the clone position if window size changed |
1250 | +also, rename meta window 'size-changed' callback accordingly. |
1251 | + |
1252 | +https://bugzilla.gnome.org/show_bug.cgi?id=792681 |
1253 | + |
1254 | +workspaceThumbnail: Sync clone position changes with actor |
1255 | + |
1256 | +We need to update the clone position if window actor (not the meta window) |
1257 | +position changed. |
1258 | + |
1259 | +https://bugzilla.gnome.org/show_bug.cgi?id=792681 |
1260 | + |
1261 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=776588 |
1262 | +Bug-Ubuntu: https://bugs.launchpad.net/gnome-shell/+bug/1653153 |
1263 | +Forwarded: yes, https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/8 |
1264 | +--- |
1265 | + js/ui/workspace.js | 28 +++++++++++++++------------- |
1266 | + js/ui/workspaceThumbnail.js | 9 ++++----- |
1267 | + 2 files changed, 19 insertions(+), 18 deletions(-) |
1268 | + |
1269 | +diff --git a/js/ui/workspace.js b/js/ui/workspace.js |
1270 | +index 8836537..f06b78e 100644 |
1271 | +--- a/js/ui/workspace.js |
1272 | ++++ b/js/ui/workspace.js |
1273 | +@@ -137,8 +137,10 @@ var WindowClone = new Lang.Class({ |
1274 | + this._dragSlot = [0, 0, 0, 0]; |
1275 | + this._stackAbove = null; |
1276 | + |
1277 | +- this._windowClone._updateId = this.metaWindow.connect('size-changed', |
1278 | +- this._onRealWindowSizeChanged.bind(this)); |
1279 | ++ this._windowClone._sizeChangedId = this.metaWindow.connect('size-changed', |
1280 | ++ this._onMetaWindowSizeChanged.bind(this)); |
1281 | ++ this._windowClone._posChangedId = this.metaWindow.connect('position-changed', |
1282 | ++ this._computeBoundingBox.bind(this)); |
1283 | + this._windowClone._destroyId = this.realWindow.connect('destroy', |
1284 | + this.destroy.bind(this)); |
1285 | + |
1286 | +@@ -200,8 +202,7 @@ var WindowClone = new Lang.Class({ |
1287 | + |
1288 | + addAttachedDialog(win) { |
1289 | + this._doAddAttachedDialog(win, win.get_compositor_private()); |
1290 | +- this._computeBoundingBox(); |
1291 | +- this.emit('size-changed'); |
1292 | ++ this._onMetaWindowSizeChanged(); |
1293 | + }, |
1294 | + |
1295 | + hasAttachedDialogs() { |
1296 | +@@ -210,15 +211,14 @@ var WindowClone = new Lang.Class({ |
1297 | + |
1298 | + _doAddAttachedDialog(metaWin, realWin) { |
1299 | + let clone = new Clutter.Clone({ source: realWin }); |
1300 | +- clone._updateId = metaWin.connect('size-changed', () => { |
1301 | +- this._computeBoundingBox(); |
1302 | +- this.emit('size-changed'); |
1303 | +- }); |
1304 | ++ clone._sizeChangedId = metaWin.connect('size-changed', |
1305 | ++ this._onMetaWindowSizeChanged.bind(this)); |
1306 | ++ clone._posChangedId = metaWin.connect('position-changed', |
1307 | ++ this._onMetaWindowSizeChanged.bind(this)); |
1308 | + clone._destroyId = realWin.connect('destroy', () => { |
1309 | + clone.destroy(); |
1310 | + |
1311 | +- this._computeBoundingBox(); |
1312 | +- this.emit('size-changed'); |
1313 | ++ this._onMetaWindowSizeChanged.bind(this); |
1314 | + }); |
1315 | + this.actor.add_child(clone); |
1316 | + }, |
1317 | +@@ -308,7 +308,8 @@ var WindowClone = new Lang.Class({ |
1318 | + |
1319 | + // First destroy the clone and then destroy everything |
1320 | + // This will ensure that we never see it in the _disconnectSignals loop |
1321 | +- this.metaWindow.disconnect(this._windowClone._updateId); |
1322 | ++ this.metaWindow.disconnect(this._windowClone._sizeChangedId); |
1323 | ++ this.metaWindow.disconnect(this._windowClone._posChangedId); |
1324 | + this.realWindow.disconnect(this._windowClone._destroyId); |
1325 | + this._windowClone.destroy(); |
1326 | + |
1327 | +@@ -323,12 +324,13 @@ var WindowClone = new Lang.Class({ |
1328 | + else |
1329 | + realWindow = child.source; |
1330 | + |
1331 | +- realWindow.meta_window.disconnect(child._updateId); |
1332 | ++ realWindow.meta_window.disconnect(child._sizeChangedId); |
1333 | ++ realWindow.meta_window.disconnect(child._posChangedId); |
1334 | + realWindow.disconnect(child._destroyId); |
1335 | + }); |
1336 | + }, |
1337 | + |
1338 | +- _onRealWindowSizeChanged() { |
1339 | ++ _onMetaWindowSizeChanged() { |
1340 | + this._computeBoundingBox(); |
1341 | + this.emit('size-changed'); |
1342 | + }, |
1343 | +diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js |
1344 | +index 0c72e74..4db8c19 100644 |
1345 | +--- a/js/ui/workspaceThumbnail.js |
1346 | ++++ b/js/ui/workspaceThumbnail.js |
1347 | +@@ -68,7 +68,7 @@ var WindowClone = new Lang.Class({ |
1348 | + this.realWindow = realWindow; |
1349 | + this.metaWindow = realWindow.meta_window; |
1350 | + |
1351 | +- this.clone._updateId = this.metaWindow.connect('position-changed', |
1352 | ++ this.clone._updateId = this.realWindow.connect('notify::position', |
1353 | + this._onPositionChanged.bind(this)); |
1354 | + this.clone._destroyId = this.realWindow.connect('destroy', this.destroy.bind(this)); |
1355 | + this._onPositionChanged(); |
1356 | +@@ -141,7 +141,7 @@ var WindowClone = new Lang.Class({ |
1357 | + |
1358 | + // First destroy the clone and then destroy everything |
1359 | + // This will ensure that we never see it in the _disconnectSignals loop |
1360 | +- this.metaWindow.disconnect(this.clone._updateId); |
1361 | ++ this.realWindow.disconnect(this.clone._updateId); |
1362 | + this.realWindow.disconnect(this.clone._destroyId); |
1363 | + this.clone.destroy(); |
1364 | + |
1365 | +@@ -156,7 +156,7 @@ var WindowClone = new Lang.Class({ |
1366 | + let clone = new Clutter.Clone({ source: realDialog }); |
1367 | + this._updateDialogPosition(realDialog, clone); |
1368 | + |
1369 | +- clone._updateId = metaDialog.connect('position-changed', dialog => { |
1370 | ++ clone._updateId = metaDialog.connect('notify::position', dialog => { |
1371 | + this._updateDialogPosition(dialog, clone); |
1372 | + }); |
1373 | + clone._destroyId = realDialog.connect('destroy', () => { |
1374 | +@@ -174,7 +174,6 @@ var WindowClone = new Lang.Class({ |
1375 | + }, |
1376 | + |
1377 | + _onPositionChanged() { |
1378 | +- let rect = this.metaWindow.get_frame_rect(); |
1379 | + this.actor.set_position(this.realWindow.x, this.realWindow.y); |
1380 | + }, |
1381 | + |
1382 | +@@ -182,7 +181,7 @@ var WindowClone = new Lang.Class({ |
1383 | + this.actor.get_children().forEach(child => { |
1384 | + let realWindow = child.source; |
1385 | + |
1386 | +- realWindow.meta_window.disconnect(child._updateId); |
1387 | ++ realWindow.disconnect(child._updateId); |
1388 | + realWindow.disconnect(child._destroyId); |
1389 | + }); |
1390 | + }, |
1391 | |
1392 | === added file 'debian/patches/workspaceThumbnail-initialize-porthole-based-on-workArea.patch' |
1393 | --- debian/patches/workspaceThumbnail-initialize-porthole-based-on-workArea.patch 1970-01-01 00:00:00 +0000 |
1394 | +++ debian/patches/workspaceThumbnail-initialize-porthole-based-on-workArea.patch 2018-04-17 10:30:40 +0000 |
1395 | @@ -0,0 +1,36 @@ |
1396 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1397 | +Date: Fri, 19 Jan 2018 10:37:20 -0600 |
1398 | +Subject: workspaceThumbnail: initialize porthole based on workArea |
1399 | + |
1400 | +https://bugzilla.gnome.org/show_bug.cgi?id=792687 |
1401 | + |
1402 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=792687 |
1403 | +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/commit/b99e304 |
1404 | +--- |
1405 | + js/ui/workspaceThumbnail.js | 6 ++---- |
1406 | + 1 file changed, 2 insertions(+), 4 deletions(-) |
1407 | + |
1408 | +diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js |
1409 | +index 3dffd12..c1b4bdd 100644 |
1410 | +--- a/js/ui/workspaceThumbnail.js |
1411 | ++++ b/js/ui/workspaceThumbnail.js |
1412 | +@@ -275,8 +275,8 @@ var WorkspaceThumbnail = new Lang.Class({ |
1413 | + |
1414 | + this._createBackground(); |
1415 | + |
1416 | +- let monitor = Main.layoutManager.primaryMonitor; |
1417 | +- this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height); |
1418 | ++ let workArea = Main.layoutManager.getWorkAreaForMonitor(this.monitorIndex); |
1419 | ++ this.setPorthole(workArea.x, workArea.y, workArea.width, workArea.height); |
1420 | + |
1421 | + let windows = global.get_window_actors().filter(actor => { |
1422 | + let win = actor.meta_window; |
1423 | +@@ -321,8 +321,6 @@ var WorkspaceThumbnail = new Lang.Class({ |
1424 | + }, |
1425 | + |
1426 | + setPorthole(x, y, width, height) { |
1427 | +- this._portholeX = x; |
1428 | +- this._portholeY = y; |
1429 | + this.actor.set_size(width, height); |
1430 | + this._contents.set_position(-x, -y); |
1431 | + }, |
1432 | |
1433 | === added file 'debian/patches/workspaceThumbnail-only-update-_porthole-if-the-overview-.patch' |
1434 | --- debian/patches/workspaceThumbnail-only-update-_porthole-if-the-overview-.patch 1970-01-01 00:00:00 +0000 |
1435 | +++ debian/patches/workspaceThumbnail-only-update-_porthole-if-the-overview-.patch 2018-04-17 10:30:40 +0000 |
1436 | @@ -0,0 +1,29 @@ |
1437 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1438 | +Date: Fri, 19 Jan 2018 09:31:01 -0600 |
1439 | +Subject: workspaceThumbnail: only update _porthole if the overview is visible |
1440 | + |
1441 | +Otherwise it happens that porthole is computed again after that the |
1442 | +overlay is hidden (triggered by a layout reallocation) and thus not |
1443 | +regenerated again afterwards. |
1444 | + |
1445 | +https://bugzilla.gnome.org/show_bug.cgi?id=792687 |
1446 | + |
1447 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=792687 |
1448 | +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/commit/5fcf40b |
1449 | +--- |
1450 | + js/ui/workspaceThumbnail.js | 2 +- |
1451 | + 1 file changed, 1 insertion(+), 1 deletion(-) |
1452 | + |
1453 | +diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js |
1454 | +index 7d5d2c0..5565a1e 100644 |
1455 | +--- a/js/ui/workspaceThumbnail.js |
1456 | ++++ b/js/ui/workspaceThumbnail.js |
1457 | +@@ -1159,7 +1159,7 @@ var ThumbnailsBox = new Lang.Class({ |
1458 | + // The "porthole" is the portion of the screen that we show in the |
1459 | + // workspaces |
1460 | + _ensurePorthole() { |
1461 | +- if (!Main.layoutManager.primaryMonitor) |
1462 | ++ if (!Main.layoutManager.primaryMonitor || !Main.overview.visible) |
1463 | + return false; |
1464 | + |
1465 | + if (!this._porthole) |
1466 | |
1467 | === added file 'debian/patches/workspaceThumbnail-rebuild-thumbnails-if-workareas-size-c.patch' |
1468 | --- debian/patches/workspaceThumbnail-rebuild-thumbnails-if-workareas-size-c.patch 1970-01-01 00:00:00 +0000 |
1469 | +++ debian/patches/workspaceThumbnail-rebuild-thumbnails-if-workareas-size-c.patch 2018-04-17 10:30:40 +0000 |
1470 | @@ -0,0 +1,64 @@ |
1471 | +From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> |
1472 | +Date: Fri, 19 Jan 2018 09:39:13 -0600 |
1473 | +Subject: workspaceThumbnail: rebuild thumbnails if workareas size changed |
1474 | + |
1475 | +https://bugzilla.gnome.org/show_bug.cgi?id=792687 |
1476 | + |
1477 | +Origin: https://gitlab.gnome.org/GNOME/gnome-shell/commit/c29bd46 |
1478 | +Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=792687 |
1479 | +--- |
1480 | + js/ui/workspaceThumbnail.js | 21 ++++++++++++++++----- |
1481 | + 1 file changed, 16 insertions(+), 5 deletions(-) |
1482 | + |
1483 | +diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js |
1484 | +index 5565a1e..3dffd12 100644 |
1485 | +--- a/js/ui/workspaceThumbnail.js |
1486 | ++++ b/js/ui/workspaceThumbnail.js |
1487 | +@@ -675,11 +675,7 @@ var ThumbnailsBox = new Lang.Class({ |
1488 | + this._settings.connect('changed::dynamic-workspaces', |
1489 | + this._updateSwitcherVisibility.bind(this)); |
1490 | + |
1491 | +- Main.layoutManager.connect('monitors-changed', () => { |
1492 | +- this._destroyThumbnails(); |
1493 | +- if (Main.overview.visible) |
1494 | +- this._createThumbnails(); |
1495 | +- }); |
1496 | ++ Main.layoutManager.connect('monitors-changed', this._rebuildThumbnails.bind(this)); |
1497 | + }, |
1498 | + |
1499 | + _updateSwitcherVisibility() { |
1500 | +@@ -872,6 +868,9 @@ var ThumbnailsBox = new Lang.Class({ |
1501 | + Main.overview.connect('windows-restacked', |
1502 | + this._syncStacking.bind(this)); |
1503 | + |
1504 | ++ this._workareasChangedId = |
1505 | ++ global.screen.connect('workareas-changed', this._rebuildThumbnails.bind(this)); |
1506 | ++ |
1507 | + this._targetScale = 0; |
1508 | + this._scale = 0; |
1509 | + this._pendingScaleUpdate = false; |
1510 | +@@ -901,12 +900,24 @@ var ThumbnailsBox = new Lang.Class({ |
1511 | + this._syncStackingId = 0; |
1512 | + } |
1513 | + |
1514 | ++ if (this._workareasChangedId > 0) { |
1515 | ++ global.screen.disconnect(this._workareasChangedId); |
1516 | ++ this._workareasChangedId = 0; |
1517 | ++ } |
1518 | ++ |
1519 | + for (let w = 0; w < this._thumbnails.length; w++) |
1520 | + this._thumbnails[w].destroy(); |
1521 | + this._thumbnails = []; |
1522 | + this._porthole = null; |
1523 | + }, |
1524 | + |
1525 | ++ _rebuildThumbnails() { |
1526 | ++ this._destroyThumbnails(); |
1527 | ++ |
1528 | ++ if (Main.overview.visible) |
1529 | ++ this._createThumbnails(); |
1530 | ++ }, |
1531 | ++ |
1532 | + _workspacesChanged() { |
1533 | + let validThumbnails = |
1534 | + this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL); |
I am very concerned with the decision to add 11 more patches to bionic's gnome-shell. I am concerned that this could make updating to 3.28.2 difficult (or the 3.30 series) if too much code is changed before these patches are accepted in to GNOME.
You could at least help reduce this number by following up on the patches that have already been applied to upstream master to see if they can be pushed to the gnome-3-28 branch.
Please also try to be more persistent with getting upstream review of the remaining patches.
I encourage you to talk to Debian's smcv to see if he would be interested in taking some of these patches in to Debian.
One minor note. The patch rename wasn't done in this merge proposal. Maybe that was missed when exporting your work from git.