Skip to content

gTile@shuairan: Resolve transparency and UI unresponsiveness after sleep (#512)#994

Open
RiaanBurger wants to merge 9 commits intolinuxmint:masterfrom
RiaanBurger:fix/512-transparency-after-sleep
Open

gTile@shuairan: Resolve transparency and UI unresponsiveness after sleep (#512)#994
RiaanBurger wants to merge 9 commits intolinuxmint:masterfrom
RiaanBurger:fix/512-transparency-after-sleep

Conversation

@RiaanBurger
Copy link
Copy Markdown

Description

This Pull Request addresses Issue #512, where the gTile GUI becomes transparent, "ghosted," or fails to accept input after the system resumes from a suspend/sleep state. This behavior is most prevalent on NVIDIA hardware using the proprietary driver.

Root Cause: The issue appears to be twofold:

  • GPU Texture Staling: Cinnamon (via Clutter) sometimes fails to refresh the GPU memory buffers for UI actors when the display driver re-initializes after wake-up.
  • Race Condition: The extension's monitors-changed logic was triggering before the compositor and video memory were fully stable, leading to corrupted rendering of the grid.

Changes Made

  • Explicit Actor Destruction: Updated src/base/ui/Grid.ts to explicitly call .destroy() on the main BoxLayout actor. This forces the underlying graphics toolkit to purge the stale GPU textures.
  • Re-initialization Delay: Introduced a 750ms GLib.timeout_add delay in src/base/app.ts during the ReInitialize cycle. This provides the necessary buffer for the display driver to settle before the extension attempts to redraw UI elements.
  • Signal Management: Added tracking for the monitors-changed signal ID and implemented explicit disconnection in the App destruction lifecycle to prevent "zombie" listeners and memory leaks.
  • Cleanup Optimization: Updated src/5_4/extension.ts to nullify the App reference upon disabling, ensuring a cleaner memory state during extension reloads.

While the 750ms delay does the trick, I did look into "fancier" ways to handle this, like listening for system power signals via DBus or using a "heartbeat" timer to detect time-drifts after wake-up. I decided to stick with the timeout because it's simple and effective and comes with minimal edits.

Testing Performed

  • Verified the fix on Linux Mint 22.2.
  • Performed multiple Suspend/Resume cycles with gTile active.
  • Verified that the extension no longer exhibits transparency or "click-through" bugs after waking the system.

Fixes #512

Clean up trailing whitespace, add dictionary words to cSpell, and ensure blank lines at EOF.

Prepares the codebase for fix linuxmint#512.
This commit addresses the issue where the gTile GUI becomes transparent or unresponsive after the system resumes from sleep, particularly on NVIDIA hardware.

Key changes include:
- Explicitly calling .destroy() on the main BoxLayout actor in Grid.ts to force the release of GPU-side textures.
- Introducing a 750ms delay in app.ts during ReInitialize to allow the display driver and compositor to settle before redrawing.
- Implementing proper signal management by tracking and disconnecting the 'monitors-changed' signal in the App lifecycle.
- Cleaning up the extension state in extension.ts by nullifying the App reference upon disabling.

Fixes linuxmint#512
@t3k4y
Copy link
Copy Markdown

t3k4y commented Jan 8, 2026

Great that you worked on this, thank you!
Hope it will get merged soon :-)

@rcalixte
Copy link
Copy Markdown
Member

rcalixte commented Jan 8, 2026

@RiaanBurger Have you actually tested this? Without updating the JavaScript, I'm not seeing how this makes any changes to the extension after it's loaded.

@RiaanBurger
Copy link
Copy Markdown
Author

I have tested this on my local machine (Linux Mint 22.2 with NVIDIA hardware). Although the extension is compiled to JavaScript, these changes to the TypeScript source address the root cause of the transparency issue in three ways:

  • Explicit Cleanup: Adding this.actor.destroy(); in Grid.ts ensures that stale GPU graphics buffers are purged rather than just hidden, which prevents the 'ghosting' effect.
  • Timing Resilience: The 750ms GLib.timeout_add delay in app.ts allows (hopefully, I mean it should and I tested once) the NVIDIA driver and window manager to fully re-initialize after wake-up before the UI attempts to draw.
  • Memory Management: Disconnecting the monitors-changed signal in app.ts via global.screen.disconnect
  • prevents multiple 'zombie' instances of the extension logic from running simultaneously.

@rcalixte
Copy link
Copy Markdown
Member

Although the extension is compiled to JavaScript, these changes to the TypeScript source address the root cause of the transparency issue in three ways

It's not just compiled to JavaScript, as I understand it, the JavaScript is what is executing the extension. Or am I incorrect and the TypeScript is being executed directly? Otherwise, the bugs aren't addressed without re-compiling the JavaScript with the code changes in the TypeScript.

@RiaanBurger
Copy link
Copy Markdown
Author

😳 Thank you for your patient and kind understanding... I'm on it...

@RiaanBurger
Copy link
Copy Markdown
Author

I see there were several merged code contributions altering the transpiled JavaScript files. Also that this is the only spice using TypeScript. I propose affecting my fix to the JavaScript instead and removing the TypeScript tooling. But if your preference is to have a TypeScript example of the project I can implement the changes that were made to the JS in TS and clean up the TS implementation?

@rcalixte
Copy link
Copy Markdown
Member

I see there were several merged code contributions altering the transpiled JavaScript files. Also that this is the only spice using TypeScript. I propose affecting my fix to the JavaScript instead and removing the TypeScript tooling. But if your preference is to have a TypeScript example of the project I can implement the changes that were made to the JS in TS and clean up the TS implementation?

The original author chose the code structure for this Spice. There is a well-known and widely-used Spice that does use TypeScript and is actively maintained: it is the Weather applet. This extension and that applet are what come to mind when it comes to TypeScript being used for Spices. Would converting the code at this point be the easier option than running the transpiling steps? Especially if you've already implemented the changes in TypeScript.

@RiaanBurger
Copy link
Copy Markdown
Author

Ah, so there is a value to stick with TypeScript as an example implementation.

Thank you for pointing out the weather applet, I just searched the github.com/linuxmint/cinnamon-spices-extensions code base.

After reviewing the history I see that this commit 4abcc01 is the only one that I'll have to backport to TS. Doing so will add fragility, if course, but I can test to see if all is well. I was hoping to make this a surgical fix for the issue only, but I can take my time a bit more and go the TS and backport route and clean the TS up a bit more.

The fastest options is to go JS and clean up by removing the TS tooling.

The better example which will take a bit longer is to backport the JS changes to TS and clean up and update the TS tooling.

Do you have a preference?

@RiaanBurger
Copy link
Copy Markdown
Author

Maybe just a surgical JS fix and a new TS project cTile?

@fredcw
Copy link
Copy Markdown
Contributor

fredcw commented Jan 12, 2026

The radio@driglu4it applet is also in Typescript btw. I don't see any advantage to keeping any applets (that don't currently have a maintainer) in Typescript, it just means far fewer people are able to help fix bugs or make minor changes themselves. The inconvenience of the compilation step and installing the toolchain far outweighs any advantage of the language IMO.

@RiaanBurger
Copy link
Copy Markdown
Author

I left the updates I made in TS but didn't transpile. I updated the JS and tested it.

@RiaanBurger
Copy link
Copy Markdown
Author

Three of us have been using this for two weeks now at my worksplace with no problems reported.

@rcalixte
Copy link
Copy Markdown
Member

Three of us have been using this for two weeks now at my worksplace with no problems reported.

Was this rebuilt? My primary concern is maintainability. If this is modified again by someone else who rebuilds it and the changes are not properly recorded, they would be lost.

@RiaanBurger
Copy link
Copy Markdown
Author

Indeed, we have two code bases now, the original TypeScript and the rendered and then manually updated JavaScript. If anyone were to transpile the TypeScript now it would undo some of the existing work: This previous Pull Request:

Which was only applied to the JS.

Either removing TS or redoing that Pull Request and mine (though mine already includes the TS work too) should be the job of another valuable Pull Request for this extension.

We can leave this one open and re-roll it if another is made and merged first? I'd have volunteered, but the year's really kicked off at work and my time is a little more limited now.

@rcalixte
Copy link
Copy Markdown
Member

This was a mistake that should not have been merged, exactly for the problem that it caused. That work is going to be lost. Once this is merged, maybe we can engage the author of that to do it again correctly.

Longer-term, it would be great to have the maintainability (or lack thereof) addressed but agreed that it is out of scope right now and should be done in a targeted future effort. For now, it's best to focus on getting this landed correctly, even if it means lost work for a previous author where their changes should not have been merged.

@RiaanBurger
Copy link
Copy Markdown
Author

If you merge my latest 84cfc6a won't be lost. I affected changes to the TS, but instead of transpiling it I also manually affected changes to the JS. The only gap now is that if someone in future makes changes to the TS then only will 84cfc6a be lost.

@rcalixte
Copy link
Copy Markdown
Member

If you merge my latest 84cfc6a won't be lost. I affected changes to the TS, but instead of transpiling it I also manually affected changes to the JS. The only gap now is that if someone in future makes changes to the TS then only will 84cfc6a be lost.

Correct. That merged commit is a mistake. Breaking the transpiling should be intentional if/when the TypeScript is removed. As it is now, the structure will impede future development. Leaving a land mine in maintenance never ends well. Best to transpile it now, merge that, and then have the other fix re-applied correctly. What's the point of the automation if everything is done by hand? Carrying forward previous mistakes only begets further mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gTile@shuairan: transparency in extension GUI after sleep

4 participants