Skip to content

Commit a635736

Browse files
committed
Overview: allocate shadow actor when position & size of window changed
1 parent 7324572 commit a635736

File tree

2 files changed

+78
-78
lines changed

2 files changed

+78
-78
lines changed

src/extension.ts

Lines changed: 78 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { MonitorManager } from '@gi/Meta'
88
import { WindowPreview } from '@imports/ui/windowPreview'
99
import { WorkspaceGroup } from '@imports/ui/workspaceAnimation'
1010
import { WindowManager } from '@imports/ui/windowManager'
11-
import { WorkspacesView } from '@imports/ui/workspacesView'
1211
import BackgroundMenu from '@imports/ui/backgroundMenu'
1312
import { sessionMode, layoutManager } from '@imports/ui/main'
1413

@@ -27,15 +26,16 @@ import { WM } from '@gi/Shell'
2726
import { RoundedCornersCfg } from '@me/utils/types'
2827
import { Window, WindowActor } from '@gi/Meta'
2928
import { global } from '@global'
29+
import { registerClass } from '@gi/GObject'
3030

3131
// --------------------------------------------------------------- [end imports]
32+
3233
export class Extension {
3334
// The methods of gnome-shell to monkey patch
34-
private _orig_add_window !: (_: Window) => void
35-
private _orig_create_windows !: () => void
36-
private _orig_size_changed !: (wm: WM, actor: WindowActor) => void
37-
private _orig_scroll_to_active !: () => void
38-
private _add_background_menu !: typeof BackgroundMenu.addBackgroundMenu
35+
private _orig_add_window !: (_: Window) => void
36+
private _orig_create_windows !: () => void
37+
private _orig_size_changed !: (wm: WM, actor: WindowActor) => void
38+
private _add_background_menu !: typeof BackgroundMenu.addBackgroundMenu
3939

4040
private _services: Services | null = null
4141
private _rounded_corners_manager: RoundedCornersManager | null = null
@@ -54,7 +54,6 @@ export class Extension {
5454
this._orig_add_window = WindowPreview.prototype._addWindow
5555
this._orig_create_windows = WorkspaceGroup.prototype._createWindows
5656
this._orig_size_changed = WindowManager.prototype._sizeChangeWindowDone
57-
this._orig_scroll_to_active = WorkspacesView.prototype._scrollToActive
5857
this._add_background_menu = BackgroundMenu.addBackgroundMenu
5958

6059
this._services = new Services ()
@@ -121,11 +120,16 @@ export class Extension {
121120

122121
const self = this
123122

123+
// WindowPreview is a widgets that show content of window in overview.
124+
// this widget also contain a St.Label (show title of window), icon and
125+
// close button for window.
126+
//
124127
// When there is new window added into overview, this function will be
125128
// called. We need add our shadow actor and blur actor of rounded
126129
// corners window into overview.
127130
//
128131
WindowPreview.prototype._addWindow = function (window) {
132+
// call original method from gnome-shell
129133
self._orig_add_window.apply (this, [window])
130134

131135
// Make sure patched method only be called in _init() of
@@ -161,63 +165,29 @@ export class Extension {
161165

162166
_log (`Add shadow for ${window.title} in overview`)
163167

168+
// WindowPreview.window_container used to show content of window
164169
const window_container = this.window_container
165170
let first_child: Clutter.Actor | null = window_container.first_child
166171

167-
// Set linear filter to window preview in overview
168-
first_child.add_effect (new LinearFilterEffect ())
172+
// Set linear filter to make it looks like better
173+
first_child?.add_effect (new LinearFilterEffect ())
169174

170-
const shadow_clone = new Clutter.Clone ({
171-
source: shadow,
172-
pivot_point: new Point ({ x: 0.5, y: 0.5 }),
173-
name: constants.OVERVIEW_SHADOW_ACTOR,
174-
})
175+
// Add a clone of shadow to overview
176+
const shadow_clone = new OverviewShadowActor (shadow, this)
175177
for (const prop of ['scale-x', 'scale-y']) {
176-
window_container.bind_property (prop, shadow_clone, prop, 2)
178+
window_container.bind_property (prop, shadow_clone, prop, 1)
177179
}
178-
179180
this.insert_child_below (shadow_clone, window_container)
180181

181-
UI.UpdateShadowOfWindowPreview (this)
182-
183-
const c = connections.get ()
184-
c.connect (this, 'notify::width', () =>
185-
UI.UpdateShadowOfWindowPreview (this)
186-
)
187-
c.connect (this, 'drag-end', () =>
188-
UI.UpdateShadowOfWindowPreview (this)
189-
)
190-
191182
// Disconnect all signals when Window preview in overview is destroy
183+
const c = connections.get ()
192184
c.connect (this, 'destroy', () => {
193185
first_child?.clear_effects ()
194186
first_child = null
195187
c.disconnect_all (this)
196188
})
197189
}
198190

199-
// When we change workspace in overview, this method will be called.
200-
// Need to recompute the Clutter.BindConstraint for shadow actor
201-
// in overview.
202-
//
203-
// Relative to #39
204-
WorkspacesView.prototype._scrollToActive = function () {
205-
self._orig_scroll_to_active.apply (this, [])
206-
207-
if (self._shadow_timeout_id != 0) {
208-
GLib.Source.remove (self._shadow_timeout_id)
209-
self._shadow_timeout_id = 0
210-
}
211-
self._shadow_timeout_id = GLib.timeout_add (0, 100, () => {
212-
for (const ws of this._workspaces) {
213-
for (const win of ws._windows) {
214-
UI.UpdateShadowOfWindowPreview (win)
215-
}
216-
}
217-
return false
218-
})
219-
}
220-
221191
// Just Like the monkey patch when enter overview, need to add shadow
222192
// actor and blur actor into WorkspaceGroup to see them when switching
223193
// workspace
@@ -306,7 +276,6 @@ export class Extension {
306276
WindowPreview.prototype._addWindow = this._orig_add_window
307277
WorkspaceGroup.prototype._createWindows = this._orig_create_windows
308278
WindowManager.prototype._sizeChangeWindowDone = this._orig_size_changed
309-
WorkspacesView.prototype._scrollToActive = this._orig_scroll_to_active
310279
BackgroundMenu.addBackgroundMenu = this._add_background_menu
311280

312281
// Remove main loop sources
@@ -348,3 +317,63 @@ export class Extension {
348317
export function init () {
349318
return new Extension ()
350319
}
320+
321+
/**
322+
* Copy shadow of rounded corners window and show it in overview.
323+
* This actor will be created when window preview has created for overview
324+
*/
325+
const OverviewShadowActor = registerClass (
326+
{},
327+
class extends Clutter.Clone {
328+
_window_preview !: WindowPreview
329+
330+
/**
331+
* Create shadow actor for WindowPreview in overview
332+
* @param source the shadow actor create for rounded corners shadow
333+
* @param window_preview the window preview has shown in overview
334+
*/
335+
_init (source: Clutter.Actor, window_preview: WindowPreview): void {
336+
super._init ({
337+
source, // the source shadow actor shown in desktop
338+
name: constants.OVERVIEW_SHADOW_ACTOR,
339+
pivot_point: new Point ({ x: 0.5, y: 0.5 }),
340+
})
341+
342+
this._window_preview = window_preview
343+
}
344+
345+
/**
346+
* Recompute the position and size of shadow in overview
347+
* This virtual function will be called when we:
348+
* - entering/closing overview
349+
* - dragging window
350+
* - position and size of window preview in overview changed
351+
* @param box The bound box of shadow actor
352+
*/
353+
vfunc_allocate (box: Clutter.ActorBox): void {
354+
// The window container that shown in overview
355+
const window_container = this._window_preview.window_container
356+
357+
// Meta.Window contain the all information about a window
358+
const meta_win = this._window_preview._windowActor.meta_window
359+
360+
// As we known, preview shown in overview has been scaled
361+
// in overview
362+
const container_scaled =
363+
window_container.width / meta_win.get_frame_rect ().width
364+
const paddings =
365+
constants.SHADOW_PADDING *
366+
container_scaled *
367+
UI.WindowScaleFactor (meta_win)
368+
369+
// Setup bounds box of shadow actor
370+
box.x1 = -paddings
371+
box.y1 = -paddings
372+
box.x2 = window_container.width + paddings
373+
box.y2 = window_container.height + paddings
374+
375+
// Make bounds box effect actor
376+
super.vfunc_allocate (box)
377+
}
378+
}
379+
)

src/utils/ui.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -179,32 +179,3 @@ export function ShouldHasRoundedCorners (
179179

180180
return should_has_rounded_corners
181181
}
182-
183-
/** Compute size & position of shadow actor for window in overview */
184-
export function UpdateShadowOfWindowPreview (win_preview: WindowPreview) {
185-
const win = win_preview._windowActor.meta_window
186-
const shadow_clone = win_preview.get_child_at_index (0)
187-
188-
if (shadow_clone?.get_name () != constants.OVERVIEW_SHADOW_ACTOR) {
189-
return
190-
}
191-
192-
shadow_clone.get_constraints ().forEach ((c) => {
193-
shadow_clone.remove_constraint (c)
194-
})
195-
196-
const paddings =
197-
constants.SHADOW_PADDING *
198-
(win_preview.window_container.width / win.get_frame_rect ().width) *
199-
WindowScaleFactor (win)
200-
201-
for (let i = 0; i < 4; i++) {
202-
shadow_clone.add_constraint (
203-
new Clutter.BindConstraint ({
204-
coordinate: i,
205-
source: win_preview.window_container,
206-
offset: i < 2 ? -paddings : paddings * 2,
207-
})
208-
)
209-
}
210-
}

0 commit comments

Comments
 (0)