Skip to content

Complete GLFW v3.4 integration and fix TODOs (supersedes #400)#414

Open
alexballas wants to merge 26 commits intogo-gl:masterfrom
alexballas:master
Open

Complete GLFW v3.4 integration and fix TODOs (supersedes #400)#414
alexballas wants to merge 26 commits intogo-gl:masterfrom
alexballas:master

Conversation

@alexballas
Copy link
Copy Markdown

@alexballas alexballas commented Feb 26, 2026

This PR finalizes the migration to GLFW v3.4. It resolves the long-standing blockers from #400 and completes the remaining tasks required for a stable release.

This PR completes the GLFW v3.4 integration. It resolves the build failures and Wayland-related panics that stalled previous efforts.

Key Updates:

  • Hybrid Linux Build: Both X11 and Wayland are now enabled by default with runtime switching. Use -tags x11 or -tags wayland to force a single backend.
  • Build Fixes: Added missing C files (win32_module.c, posix_module.c, etc.) to fix linker errors on Windows, macOS, and BSD.
  • Panic Prevention: Uses acceptError for FEATURE_UNAVAILABLE codes. This allows functions like SetIcon or SetOpacity to fail gracefully on platforms that don't support them (e.g., Wayland) instead of crashing.
  • New Constants: Added all 3.4 Window Hints and Cursors (MousePassthrough, ResizeNWSE, etc.).
  • Warning Fix: Wrapped _GNU_SOURCE in #ifndef to eliminate the "redefined" compiler warnings.

Thanks to @Geo25rey for the great start on this. I've finished the remaining work, including fixing the Windows/BSD linker errors and implementing the hybrid Linux builds. @Jacalz and @dmitshur, I also resolved the _GNU_SOURCE warnings and added the missing 3.4 hints/error handling to prevent Wayland panics. Ready for review!

@andydotxyz fyi

Geo25rey and others added 11 commits May 4, 2024 08:54
- Adds missing window hints and options added in GLFW v3.4
- Adds standard cursors added in v3.4
- Maps `GLFW_FEATURE_UNAVAILABLE` and `GLFW_FEATURE_UNIMPLEMENTED` ErrorCodes so they cleanly return without panicking the application.
- Fixes C compiler warnings about `_GNU_SOURCE` being redefined by protecting the definition.
@alexballas alexballas mentioned this pull request Feb 27, 2026
43 tasks
@alexballas
Copy link
Copy Markdown
Author

Some more items:

  • Added GLFW 3.4 platform API wrappers: GetPlatform, PlatformSupported, and Platform enum values.
  • Added custom allocator support: Allocator + InitAllocator.
  • Added Vulkan loader/presentation wrappers: InitVulkanLoader and GetPhysicalDevicePresentationSupport.
  • Added direct error query API: GetError and NoError.
  • Added missing GLFW 3.4 error mappings: CursorUnavailable, PlatformUnavailable (and handling in Init / standard cursor creation).
  • Added missing window/input API pieces: Window.GetTitle, CursorCaptured, ContextNoError, AnyPosition, plus new 3.4 hints and hint values (ANGLE, Wayland, Win32, X11 Vulkan surface, etc.).
  • Updated README to be in sync with v3.4 usage and changelog (including note that GLFW_UNLIMITED_MOUSE_BUTTONS is not in the vendored GLFW revision).

@alexballas
Copy link
Copy Markdown
Author

Brought this PR up to date with the latest go-gl commits. Everything should be in place now.

@hackbar
Copy link
Copy Markdown

hackbar commented Mar 21, 2026

I tested this on my wayland system (KDE, debian 13.4) with opengl ES 3.2. It seems to work fine, but I noticed the window doesn't actually render until the first SwapBuffers call. With x11, it just shows a black window, but in wayland there's no actual window, just the app's icon in the taskbar. Not a huge issue, since I can just add a SwapBuffers call right after I make the window.

Also, I see the window isn't the size I asked for, but about 30% bigger in each dimension. Is this some hidpi thing? I am on a 4k 32" monitor

@alexballas
Copy link
Copy Markdown
Author

Hello @hackbar
Thanks for testing this :)

What you describe matches typical Wayland behavior: unlike X11, a compositor may not show the toplevel until the client has attached and committed a real buffer, so seeing only the app icon until the first SwapBuffers is not surprising.

This is also reflected in the vendored GLFW 3.4 Wayland code. In v3.4/glfw/glfw/src/egl_context.c:283, there is even a note:

// NOTE: Swapping buffers on a hidden window on Wayland makes it visible

The size difference is most likely HiDPI / compositor scaling. In GLFW 3.4, window size and framebuffer size are separate: the window size is in screen coordinates, while the framebuffer size can be scaled for HiDPI.

Could you check what GLFW reports on your setup?

w, h := window.GetSize()
fbw, fbh := window.GetFramebufferSize()
xscale, yscale := window.GetContentScale()
fmt.Printf("window=%dx%d framebuffer=%dx%d scale=%.2fx%.2f\n", w, h, fbw, fbh, xscale, yscale)

If GetSize() matches the requested size, but GetFramebufferSize() is larger and GetContentScale() is above 1.0, then this is most likely HiDPI / compositor scaling on Wayland. If GetSize() itself is larger than requested, that would point to an actual sizing issue.

Thanks,
Alex

@hackbar
Copy link
Copy Markdown

hackbar commented Mar 22, 2026

Hmm, it looks my GetSize and GetFramebuffer size match what I requested, and ContentScale is 1 in both dimensions.

This doesn't seem to match the window size I'm getting, which is 1.25 times larger. This does match the scale I set in kde's settings. Setting that to 100% does give me the same windows size as I requested.

So it seems like wayland is doing some kind of scaling for me automatically? Is this a thing, or is there any way to change the setting?

@alexballas
Copy link
Copy Markdown
Author

Could you check one more thing on top of the previous printout: what does glfw.GetPlatform() report after Init()?
It would also help to print the same values once more after the window is actually mapped, i.e. after one initial SwapBuffers() + PollEvents().

If native Wayland still reports window == framebuffer and scale == 1.0 even after the first frame, while KDE at 125% still makes the window appear larger, then this points to upstream GLFW / compositor scaling behavior rather than go-gl itself.

@hackbar
Copy link
Copy Markdown

hackbar commented Mar 22, 2026

GetPlatforms return 0x60003.

Even after the first buffer swap it's showing the framebuffer and window are the same size (what I requested) and the scale is 1.0.

I'll try to see how KDE scaling works. I'd imagine the kwin compositor does things the standard wayland way, but maybe it's doing something weird.

@alexballas
Copy link
Copy Markdown
Author

alexballas commented Mar 23, 2026

Could you check whether the compositor is advertising the needed protocols?
wayland-info | grep -E 'wp_fractional_scale_manager_v1|wp_viewporter'
and one step deeper
WAYLAND_DEBUG=1 ./app 2>&1 | grep -E 'wp_fractional_scale|preferred_scale|wp_viewporter'

@hackbar
Copy link
Copy Markdown

hackbar commented Mar 23, 2026 via email

@alexballas
Copy link
Copy Markdown
Author

A good next check is whether KWin is actually sending the fractional-scale callback for the window (the second grep I sent). GLFW should request it, but GetContentScale() will stay at 1.0 unless the compositor replies with preferred_scale. If you run the test with WAYLAND_DEBUG=1, we can check whether GLFW sends get_fractional_scale and whether KWin sends preferred_scale back.

@hackbar
Copy link
Copy Markdown

hackbar commented Mar 24, 2026

Which tests? just printing out the window/framebuffer/scaling sizes?

@hackbar
Copy link
Copy Markdown

hackbar commented Mar 24, 2026

here's the logs for printing the sizes etc: https://pastebin.com/zP2gYkZt

@hackbar
Copy link
Copy Markdown

hackbar commented Apr 2, 2026

Is there anything else I can do to help test this? Other than than the scaling, which I don't really mind once I figured out what was happening (my app is primarily fullscreen), it's working well for me.

@Jacalz
Copy link
Copy Markdown
Collaborator

Jacalz commented Apr 2, 2026

I have been meaning to review this but I'm afraid that I have very little time for open source at the moment due to writing my Master's thesis.

@rcoreilly
Copy link
Copy Markdown

FWIW, I have been using this PR in https://cogentcore.org apps for a week or so without any issues on my macbook. Given how difficult it is to actually use the PR code from another package (because 3.4 doesn't exist in any package that go modules know about), I haven't tested on other platforms. And also given that using this requires changing the import paths, perhaps it makes sense at this point to fast-track the approval, and then plan to address any issues that come up later?

@alexballas
Copy link
Copy Markdown
Author

Agree. Since this requires explicit import changes, it won’t break existing integrations by default. We can address edge cases as they arise.

@hackbar
Copy link
Copy Markdown

hackbar commented Apr 3, 2026

Yeah, I think that makes a lot of sense.

@Jacalz
Copy link
Copy Markdown
Collaborator

Jacalz commented Apr 4, 2026

Perhaps @dmitshur has more time to look at it?

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.

5 participants