Skip to content

Conversation

HTechHQ
Copy link

@HTechHQ HTechHQ commented Sep 25, 2025

On Linux with Wayland (KWin) the customdeco example is not working.

This implements calls to Wayland to set the decoration as configured in the Gio application.

cnf.apply(cfg, options)
w.config.decoHeight = cnf.decoHeight

if w.decor != nil && (prev.Decorated != cnf.Decorated || !w.configured) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why set the mode when !w.configured? It seems to me the initial Decorated should be set to whatever the display server tells us.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking a look.
My goal is to have custom decoration show immediately if I start the app with:

window.Option(
    app.Decorated(false),
)

I am still trying to understand the full live-cycle and how the app interacts with the server. My best guess right now:

  1. Configure is called
  2. The server always decorates the window and thus the server selected decoration is set in gio_onToplevelDecorationConfigure
  3. gio_onXdgSurfaceConfigure is called and w.configured is set BUT the options are not applied any more, because they were processed in step 1

With the !w.configured I got it to work.

Please let me know, if you have more insights into this. It's the first time I interact with Wayland at all.

Also: because I don't understand the full live-cycle yet, I tried to be defensive. If you know and can confirm that the w.decor is never nil this condition could go.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been too long for me to say what the correct change would be. All I know is that the w.configured smells fishy to me, and that the prev.Decorated != cnf.Decorated check ought to be enough. Note that the action happens in the callback gio_onToplevelDecorationConfigure.

w.decor is nil if the server doesn't support the decoration manager extension, so its nil check is appropriate.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use case is to start the Gio app and have custom decorations immediately applied without any explicit user interaction

The order of function execution is:
Configure
gio_onToplevelDecorationConfigure

If Configure already sets the option then wayland responds with them in the first call to gio_onToplevelDecorationConfigure
Otherwise wayland chooses to decorate the window itself.

The issue is with the zero value of the config: On the first call with app.Decorated(false) the condition prev.Decorated != cnf.Decorated does not catch this.
I've added an explicit variable to track the initial call

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'm still not convinced another bool is necessary. It seems to me the issue is that prev.Decorated is not initialized. Does the following patch make any difference?

diff --git a/app/os_wayland.go b/app/os_wayland.go
index b020c6d173..55fd0f2166 100644
--- a/app/os_wayland.go
+++ b/app/os_wayland.go
@@ -354,6 +354,8 @@
                wakeups:   make(chan struct{}, 1),
                clipReads: make(chan transfer.DataEvent, 1),
        }
+       // Wayland windows are server-side decorated by default.
+       w.config.Decorated = true
        w.surf = C.wl_compositor_create_surface(d.compositor)
        if w.surf == nil {
                w.destroy()

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.

2 participants