Feat/unfocus window effects - #299
Conversation
- Implemented a registry for unfocus effects allowing plugins to register their own effects via `wp.desktop.registerUnfocusEffect()`. - Created a server-sync module to manage the loading and unloading of unfocus effects based on server-side registrations. - Developed an unfocus engine that applies the selected unfocus effect to all unfocused windows, responding to window lifecycle events and OS settings changes. - Added a settings section for users to select their preferred unfocus effect, including a built-in 'darken' effect. - Introduced unit tests for the new functionality, covering registration, synchronization, and effect application logic.
…and off-desktop windows
|
@claude can you review this? |
|
Claude finished @AllTerrainDeveloper's task in 4m 8s —— View job PR Review: Feat/unfocus window effectsTodo list:
This is a well-structured addition that follows the repo's established patterns closely (mirrors the commands/title-bar-buttons/wallpapers registry shape, uses Bug: stale CSS class after an effect is unregistered while appliedFile: When a plugin deactivates mid-session, The code comment says "Remove the class…even if that def has since been unregistered" — but that's not what the code actually does. // current code — className is NOT removed when def is gone
const prior = getUnfocusEffect( priorId ); // → undefined after unregister
if ( prior?.className ) { // → skipped
el.classList.remove( prior.className );
}Fix: store the applied class in a second data attribute at const EFFECT_CLASS_ATTR = 'data-desktop-unfocus-effect-class';
const apply = ( el: HTMLElement, def: UnfocusEffectDef ): void => {
if ( def.className ) {
el.classList.add( def.className );
el.setAttribute( EFFECT_CLASS_ATTR, def.className ); // ← persist
}
el.setAttribute( EFFECT_ATTR, def.id );
def.apply?.( el );
};
const clear = ( el: HTMLElement ): void => {
// Stored class always removes correctly — even if def was unregistered.
const storedClass = el.getAttribute( EFFECT_CLASS_ATTR );
if ( storedClass ) {
el.classList.remove( storedClass );
el.removeAttribute( EFFECT_CLASS_ATTR );
}
const priorId = el.getAttribute( EFFECT_ATTR );
if ( priorId ) {
getUnfocusEffect( priorId )?.clear?.( el ); // callback still guarded
}
// Defensive sweep for any still-registered effects.
for ( const def of listUnfocusEffects() ) {
if ( def.className ) el.classList.remove( def.className );
}
el.removeAttribute( EFFECT_ATTR );
};No double-init guard in
|
wp.desktop.registerUnfocusEffect().