From 0a7f7e8e23ee1dfc89b9d721a17e30c8b14706f7 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 30 Jan 2025 09:06:11 +0100 Subject: [PATCH 1/3] dev: Improve BMS compatibility --- src/manager/event_manager.ts | 17 +++++++++++++---- src/manager/utils.ts | 9 ++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/manager/event_manager.ts b/src/manager/event_manager.ts index e707049..f01ed8e 100644 --- a/src/manager/event_manager.ts +++ b/src/manager/event_manager.ts @@ -135,10 +135,19 @@ function applyEffectTo(actor: RoundedWindowActor) { // In wayland sessions, the surface actor of XWayland clients is sometimes // not ready when the window is created. In this case, we wait until it is // ready before applying the effect. - if (!actor.firstChild) { - const id = actor.connect('notify::first-child', () => { - applyEffectTo(actor); - actor.disconnect(id); + // For Blur My Shell compatibility, we have to make sure that the actor is + // not a bms-application-blurred-widget. This actor is created by BMS and + // is not the actual window actor. + const bmsActorName = 'bms-application-blurred-widget'; + const actorReady = (actor.firstChild && actor.firstChild.name !== bmsActorName) || + (actor.lastChild && actor.lastChild.name !== bmsActorName); + + if (!actorReady) { + const id = actor.connect('child-added', (actor, child) => { + if (child.name !== bmsActorName) { + applyEffectTo(actor); + actor.disconnect(id); + } }); return; diff --git a/src/manager/utils.ts b/src/manager/utils.ts index b570626..ebdd104 100644 --- a/src/manager/utils.ts +++ b/src/manager/utils.ts @@ -21,14 +21,17 @@ import type {Bounds, RoundedCornerSettings} from '../utils/types.js'; /** * Get the actor that rounded corners should be applied to. * In Wayland, the effect is applied to WindowActor, but in X11, it is applied - * to WindowActor.first_child. + * to WindowActor.last_child. Usually, there is only one child but to improve the + * compatibility with Blur My Shell, we use the last child. With Blur My Shell's + * application blur effect, the first child is actually the blur effect and the + * second child is the actual window actor. * * @param actor - The window actor to unwrap. * @returns The correct actor that the effect should be applied to. */ export function unwrapActor(actor: Meta.WindowActor): Clutter.Actor | null { const type = actor.metaWindow.get_client_type(); - return type === Meta.WindowClientType.X11 ? actor.get_first_child() : actor; + return type === Meta.WindowClientType.X11 ? actor.get_last_child() : actor; } /** @@ -70,7 +73,7 @@ export function getRoundedCornersEffect( const win = actor.metaWindow; const name = ROUNDED_CORNERS_EFFECT; return win.get_client_type() === Meta.WindowClientType.X11 - ? (actor.firstChild.get_effect(name) as RoundedCornersEffectType) + ? (actor.lastChild.get_effect(name) as RoundedCornersEffectType) : (actor.get_effect(name) as RoundedCornersEffectType); } From 38d6ae453d7b5b0900ead46c3033f182e0eecaaa Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 30 Jan 2025 15:52:52 +0100 Subject: [PATCH 2/3] dev: add the effect to the surface actor also on wayland --- src/manager/event_handlers.ts | 5 ++--- src/manager/utils.ts | 21 +-------------------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/manager/event_handlers.ts b/src/manager/event_handlers.ts index 1f20e35..f8b1c8d 100644 --- a/src/manager/event_handlers.ts +++ b/src/manager/event_handlers.ts @@ -24,7 +24,6 @@ import { getRoundedCornersCfg, getRoundedCornersEffect, shouldEnableEffect, - unwrapActor, updateShadowActorStyle, windowScaleFactor, } from './utils.js'; @@ -43,7 +42,7 @@ export function onAddEffect(actor: RoundedWindowActor) { return; } - unwrapActor(actor)?.add_effect_with_name( + actor.get_last_child()?.add_effect_with_name( ROUNDED_CORNERS_EFFECT, new RoundedCornersEffect(), ); @@ -80,7 +79,7 @@ export function onAddEffect(actor: RoundedWindowActor) { export function onRemoveEffect(actor: RoundedWindowActor): void { const name = ROUNDED_CORNERS_EFFECT; - unwrapActor(actor)?.remove_effect_by_name(name); + actor.get_last_child()?.remove_effect_by_name(name); // Remove shadow actor const shadow = actor.rwcCustomData?.shadow; diff --git a/src/manager/utils.ts b/src/manager/utils.ts index ebdd104..2e193f4 100644 --- a/src/manager/utils.ts +++ b/src/manager/utils.ts @@ -18,22 +18,6 @@ import type Clutter from 'gi://Clutter'; import type {RoundedCornersEffect} from '../effect/rounded_corners_effect.js'; import type {Bounds, RoundedCornerSettings} from '../utils/types.js'; -/** - * Get the actor that rounded corners should be applied to. - * In Wayland, the effect is applied to WindowActor, but in X11, it is applied - * to WindowActor.last_child. Usually, there is only one child but to improve the - * compatibility with Blur My Shell, we use the last child. With Blur My Shell's - * application blur effect, the first child is actually the blur effect and the - * second child is the actual window actor. - * - * @param actor - The window actor to unwrap. - * @returns The correct actor that the effect should be applied to. - */ -export function unwrapActor(actor: Meta.WindowActor): Clutter.Actor | null { - const type = actor.metaWindow.get_client_type(); - return type === Meta.WindowClientType.X11 ? actor.get_last_child() : actor; -} - /** * Get the correct rounded corner setting for a window (custom settings if a * window has custom overrides, global settings otherwise). @@ -70,11 +54,8 @@ type RoundedCornersEffectType = InstanceType; export function getRoundedCornersEffect( actor: Meta.WindowActor, ): RoundedCornersEffectType | null { - const win = actor.metaWindow; const name = ROUNDED_CORNERS_EFFECT; - return win.get_client_type() === Meta.WindowClientType.X11 - ? (actor.lastChild.get_effect(name) as RoundedCornersEffectType) - : (actor.get_effect(name) as RoundedCornersEffectType); + return (actor.lastChild.get_effect(name) as RoundedCornersEffectType); } /** From 9f100c8682820803d55aa8bdc1c20cb3dad32234 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 30 Jan 2025 15:54:39 +0100 Subject: [PATCH 3/3] chore: fix linting issues --- src/manager/event_handlers.ts | 10 ++++++---- src/manager/event_manager.ts | 5 +++-- src/manager/utils.ts | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/manager/event_handlers.ts b/src/manager/event_handlers.ts index f8b1c8d..b229b42 100644 --- a/src/manager/event_handlers.ts +++ b/src/manager/event_handlers.ts @@ -42,10 +42,12 @@ export function onAddEffect(actor: RoundedWindowActor) { return; } - actor.get_last_child()?.add_effect_with_name( - ROUNDED_CORNERS_EFFECT, - new RoundedCornersEffect(), - ); + actor + .get_last_child() + ?.add_effect_with_name( + ROUNDED_CORNERS_EFFECT, + new RoundedCornersEffect(), + ); const shadow = createShadow(actor); diff --git a/src/manager/event_manager.ts b/src/manager/event_manager.ts index f01ed8e..df92df5 100644 --- a/src/manager/event_manager.ts +++ b/src/manager/event_manager.ts @@ -139,8 +139,9 @@ function applyEffectTo(actor: RoundedWindowActor) { // not a bms-application-blurred-widget. This actor is created by BMS and // is not the actual window actor. const bmsActorName = 'bms-application-blurred-widget'; - const actorReady = (actor.firstChild && actor.firstChild.name !== bmsActorName) || - (actor.lastChild && actor.lastChild.name !== bmsActorName); + const actorReady = + (actor.firstChild && actor.firstChild.name !== bmsActorName) || + (actor.lastChild && actor.lastChild.name !== bmsActorName); if (!actorReady) { const id = actor.connect('child-added', (actor, child) => { diff --git a/src/manager/utils.ts b/src/manager/utils.ts index 2e193f4..4fda923 100644 --- a/src/manager/utils.ts +++ b/src/manager/utils.ts @@ -55,7 +55,7 @@ export function getRoundedCornersEffect( actor: Meta.WindowActor, ): RoundedCornersEffectType | null { const name = ROUNDED_CORNERS_EFFECT; - return (actor.lastChild.get_effect(name) as RoundedCornersEffectType); + return actor.lastChild.get_effect(name) as RoundedCornersEffectType; } /**