|
| 1 | +# Fixes in this fork |
| 2 | + |
| 3 | +This fork carries a set of fixes on top of the [original rounded-window-corners |
| 4 | +extension](https://github.com/flexagoon/rounded-window-corners) that have not |
| 5 | +been integrated upstream (see |
| 6 | +[flexagoon/rounded-window-corners#144](https://github.com/flexagoon/rounded-window-corners/pull/144)). |
| 7 | +They are documented here so users of this fork know exactly what differs from |
| 8 | +upstream and why. |
| 9 | + |
| 10 | +If upstream ever integrates these (or equivalent) fixes, the corresponding |
| 11 | +entry below can be dropped. |
| 12 | + |
| 13 | +## Chromium corner glitch on restore after app-initiated minimize |
| 14 | + |
| 15 | +Chromium-based browsers implement their own title bar and context menu, using |
| 16 | +`xdg_toplevel.set_minimized` to request minimize from the compositor. This is |
| 17 | +distinct from compositor-initiated minimizes (Super+H, Super+D), which do not |
| 18 | +exhibit the issue. When Chromium sends `xdg_toplevel.set_minimized`, the |
| 19 | +compositor acknowledges the minimized state and Chromium stops updating its |
| 20 | +Wayland surface buffer — the last rendered frame is held. On restore, the |
| 21 | +stale surface causes the GLSL rounded corner shader to render with wrong |
| 22 | +bounds, producing a visible glitch until the window receives focus and |
| 23 | +self-corrects. |
| 24 | + |
| 25 | +In `onUnminimize`, Chromium windows outside the magic lamp path are detected |
| 26 | +and a 250ms `refreshRoundedCorners` call is scheduled. This gives Chromium |
| 27 | +time to deliver a fresh post-restore frame before the shader uniforms are |
| 28 | +recomputed. The effect is never disabled during the minimize state, so there |
| 29 | +is no hover delay in the overview and intermediate focus/size change |
| 30 | +callbacks are not blocked. |
| 31 | + |
| 32 | +**Known limitation:** the overview thumbnail for a minimized Chromium window |
| 33 | +shows square corners — the `Shell.GLSLEffect` shader does not apply through |
| 34 | +`Clutter.Clone`, so the raw window surface is rendered. This is a |
| 35 | +compositor-level constraint that cannot be addressed from the extension side. |
| 36 | + |
| 37 | +Commit: [`eba3c9d`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/eba3c9d2b1615077891f6672caf5759ad938c28e) |
| 38 | + |
| 39 | +## Chromium effect reapply after screen lock/unlock |
| 40 | + |
| 41 | +GNOME Shell disables and re-enables extensions during screen lock/unlock. |
| 42 | +When the extension re-enables, Chromium-based browsers (Brave, Chrome, Edge) |
| 43 | +may render stale surfaces for unfocused windows. The compositor skips |
| 44 | +repainting GLSL effects for these windows, resulting in scrambled borders and |
| 45 | +a doubled frame. |
| 46 | + |
| 47 | +After applying effects to existing windows on re-enable, the extension waits |
| 48 | +250ms for surfaces to settle, then briefly focuses each unfocused Chromium |
| 49 | +window (detected by `wm_class`) to force the compositor to repaint the GLSL |
| 50 | +effect, then restores focus to the original window. `onFocusChanged` was also |
| 51 | +promoted from `refreshShadow` to `refreshRoundedCorners` so that any focus |
| 52 | +change recomputes shader bounds, not just the shadow. |
| 53 | + |
| 54 | +Commits: |
| 55 | +[`2503b48`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/2503b485cd2d0a33262375988fba1d64e9b49528), |
| 56 | +[`390b018`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/390b018e4072f9d8b926da9de7bda9f21c036185) |
| 57 | + |
| 58 | +## Overview shadow allocation crash |
| 59 | + |
| 60 | +Guards against zero frame width in `vfunc_allocate` on the overview shadow |
| 61 | +clone, which previously caused `NaN` values in the allocation box and |
| 62 | +triggered Clutter assertion failures. |
| 63 | + |
| 64 | +Commit: [`8af15df`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/8af15df1be5399fbefd8e6d966271ebe525bf88b) |
| 65 | + |
| 66 | +## Silence expected permission errors on `/proc/<pid>/maps` |
| 67 | + |
| 68 | +`getAppType` reads `/proc/<pid>/maps` to detect LibHandy / LibAdwaita |
| 69 | +windows. For processes owned by another user (flatpak sandboxes, root-owned |
| 70 | +apps), the file is unreadable and GIO raises `PERMISSION_DENIED`. The |
| 71 | +existing fallback already handled the outcome, but the error was logged with |
| 72 | +a full stack trace on every such window. `PERMISSION_DENIED` and `NOT_FOUND` |
| 73 | +are now treated as expected and logged at debug level; `logError` is kept |
| 74 | +for everything else. |
| 75 | + |
| 76 | +Commit: [`29f8971`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/29f8971dc8cf14b571ef2a7ca71d23ec3df61722) |
| 77 | + |
| 78 | +## `clutter_actor_node_new` crash on new browser windows (GNOME 50.2) |
| 79 | + |
| 80 | +On mutter 50.2 (Wayland-only), `actor.metaWindow` can be null during window |
| 81 | +actor lifecycle transitions. Previously, `applyEffectTo` connected |
| 82 | +`notify::size` and `size-changed` before checking `actor.metaWindow`. When |
| 83 | +`metaWindow` was null, the resulting TypeError aborted the function |
| 84 | +mid-way, leaving size signals connected but the effect never added. On the |
| 85 | +next `notify::size` (fired during Clutter layout), `onAddEffect` was called |
| 86 | +while the actor was mid-paint, corrupting the effect's actor pointer and |
| 87 | +causing `clutter_actor_node_new(NULL)` → SIGABRT. |
| 88 | + |
| 89 | +`actor.metaWindow` is now guarded before connecting any signals in |
| 90 | +`applyEffectTo`, so the function either completes fully or returns early |
| 91 | +with nothing connected. `actor` from `get_compositor_private()` is also |
| 92 | +null-guarded in the `window-created` handler, and a fresh actor is |
| 93 | +re-fetched in the `wm-class` deferred callback instead of using the |
| 94 | +captured (potentially stale) reference. |
| 95 | + |
| 96 | +Commit: [`9b3c201`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/9b3c201bdb636fc2e513b31eee6337a78a8536be) |
| 97 | + |
| 98 | +## Effect add/remove mid-paint crash (GNOME 50.2, `keepRoundedCorners.maximized = false`) |
| 99 | + |
| 100 | +A second crash path in the same assertion (`clutter_actor_node_new(NULL)`) |
| 101 | +was observed after the null-`metaWindow` fix above was deployed. Root cause: |
| 102 | +Clutter emits `notify::size` and `size-changed` during a layout pass that |
| 103 | +runs inside a paint frame — specifically during |
| 104 | +`meta_window_actor_paint_to_content`, which GNOME Shell calls to capture a |
| 105 | +window snapshot at the start of the maximize animation. |
| 106 | + |
| 107 | +With `keepRoundedCorners.maximized = false` (the default), the `notify::size` |
| 108 | +callback triggered `refreshRoundedCorners` → `onRemoveEffect` for the |
| 109 | +newly-maximized window. `onRemoveEffect` called `actor.remove_effect_by_name()` |
| 110 | +while `CLUTTER_ACTOR_IN_PAINT` was set, which corrupted the |
| 111 | +`RoundedCornersEffect`'s actor pointer via `clutter_actor_meta_set_actor`. |
| 112 | +The subsequent `clutter_actor_continue_paint` call then hit |
| 113 | +`clutter_actor_node_new(NULL)` → SIGABRT. |
| 114 | + |
| 115 | +All seven signal callbacks in `applyEffectTo`, and the two deferred-apply |
| 116 | +callbacks in `enableEffect`, are now wrapped with |
| 117 | +`GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, ...)`. This pushes effect |
| 118 | +add/remove out of any active paint frame into the next GLib main loop |
| 119 | +iteration, where it is safe to modify the actor's effect list. |
| 120 | + |
| 121 | +Commit: [`3f31e0d`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/3f31e0d25d0510bf7b3b56f33137dfe9fcaf9e60) |
| 122 | + |
| 123 | +## Performance improvements |
| 124 | + |
| 125 | +Several hot paths were re-reading GSettings per-frame or per-event. Each |
| 126 | +`getPref()` call deserializes through D-Bus and GLib Variant unpacking, |
| 127 | +which adds up quickly during shader updates and resize/focus events. |
| 128 | + |
| 129 | +- Deserialized pref values are now cached, invalidated automatically via the |
| 130 | + GSettings `changed` signal. This eliminates repeated unpacks for |
| 131 | + `debug-mode` (hit from `logDebug` in every hot-path statement), |
| 132 | + `blacklist`/`whitelist` (read per `shouldEnableEffect`), |
| 133 | + `keep-shadow-for-maximized-fullscreen`, `tweak-kitty-terminal`, and the |
| 134 | + shadow dictionaries. |
| 135 | +- `updateShadowActorStyle` now reads `global-rounded-corner-settings` once |
| 136 | + and derives `borderRadius`, `padding`, and `smoothing` from it, instead of |
| 137 | + 4 separate `getPref` calls. |
| 138 | +- `computeBounds` now compares `wm_class` first, so non-kitty windows skip |
| 139 | + the `getPref` entirely. |
| 140 | + |
| 141 | +Commit: [`4b3dd2c`](https://github.com/GrzegorzKozub/rounded-window-corners-fork/commit/4b3dd2c1526746e17130cd40e84c6ca1fbaffbe7) |
0 commit comments