Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composite template support for Vala, Rust, Python + "Custom Widget" demo #823

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

theCapypara
Copy link
Contributor

@theCapypara theCapypara commented Nov 18, 2023

This is my attempt to get composite templates working for the other langs.

I say attempt, because it doesn't actually work. There are a lot of reasons, and it boils down to that this probably would require approaching the external previewers completely different.

The main remaining/blocking issue is the fact that the class names need to be counted up to avoid collisions. but Python, Vala and Rust expect the class name to match exactly what's in the demo while the current GJS demo doesn't seem to mind the mismatch.
I worked around that for Python by getting the gtype name from the Workbench API, but for the others this is much more complicated due to the fact that it needs to be compiled. I'm not sure how to get the modified class name in there. Maybe we need to just not add a number to it for those two and restart the previewer every time.
The Python code currently launches once. After that it doesn't anymore, since it tries to re-register the object. Modification would probably be needed to always count up on launch, not just when the XML changes, or the previewer would just also need to be restarted every time. In that case we should just get rid of the number for all external demos and restart the previewer on every launch if templates are involved.

Another issue is that the Vala/Rust code would need to modify the internal state of the previewer to set the "target", but since they are linked in as shared objects there's no easy way to communicate back here.

And I needed to change how the dummy target is handled, replacing it just with an empty box so that the Python and Vala previewers don't crash trying to initialize it's signal handlers. Weirdly this kinda breaks Blueprint, it's trying to display the internal previewer now for non-JS demos. But maybe that's not related.

@theCapypara
Copy link
Contributor Author

theCapypara commented Nov 19, 2023

Some solution ideas we had:

  • Unregister the template type before the demo starts if it's already registered. This also means: Do not count up the class name for external previewer.
  • Instead of having a "workbench.preview" API, expose the target widget as "workbench.target". Have that be an empty GtkBox for template demos. For regular demos have it just be the normal target.

Edit:
Also AdwBin would probably be much better, since with GtkBox we would also need to make sure to empty it every time. only downside is that all demos would need Adw loaded.

@sonnyp
Copy link
Contributor

sonnyp commented Nov 19, 2023

Thanks for sharing your work and documenting.

the current GJS demo doesn't seem to mind the mismatch.

That's because I implemented a hack.

// GTypeName must be unique globally
// there is no unregister equivalent to registerClass and
// this is what GNOME Shell does too according to Verdre
// https://github.com/workbenchdev/Workbench/issues/50
// https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1011#note_451228
// https://gitlab.gnome.org/GNOME/glib/-/issues/282#note_662735
// https://gitlab.gnome.org/GNOME/glib/-/issues/2336
// https://gitlab.gnome.org/GNOME/glib/-/issues/667
GObject.registerClass = function registerWorkbenchClass(...args) {

restart the previewer every time.

If that means closing and reopening the preview window then it's probably a no go


If the goal is to avoid connecting signals manually and using get_object - I have a proposal

The idea is to add a new API. In Workbench first, as experimental and upstream relevant bits into GJS/Vala/Rust/PyGObject/...


Regarding composite widgets, if we can make it work that'd be great.
That said I think there are other reasonable options:

  • Support them in Code only for GJS and PyGObject
  • Remove support for GJS in code
  • Only support composite template preview and explain why

@theCapypara
Copy link
Contributor Author

theCapypara commented Nov 19, 2023

there is no unregister equivalent to registerClass

Ah shame, that makes unregistering impossible then, shame. If we also don't want to restart then we have to come up with another solution. For Python we could probably monkey-patch Gtk.Template, but for the other two it wouldn't be so simple...

@sonnyp
Copy link
Contributor

sonnyp commented Jan 7, 2024

I wonder if there could be a way to restart the previewer in a seamless way.
Without closing and reopening the window.

This would be useful for all bindings as we could get rid of our complicated GModule setup.

Something GDK surfaces?

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

Successfully merging this pull request may close these issues.

2 participants