glfw: Window hints rework #71
No reviewers
Labels
No labels
CI
all
basisu
blog
bug
build
contributor-friendly
core
correctness
deferred
dev
direct3d-headers
docs
driver-os-issue
duplicate
dxcompiler
editor
examples
experiment
feature-idea
feedback
flac
freetype
gamemode
gkurve
glfw
gpu
gpu-dawn
harfbuzz
help welcome
in-progress
infrastructure
invalid
libmach
linux-audio-headers
long-term
mach
mach.gfx
mach.math
mach.physics
mach.testing
model3d
needs-triage
object
opengl-headers
opus
os/linux
os/macos
os/wasm
os/windows
package-manager
priority
proposal
proposal-accepted
question
roadmap
slipped
stability
sysaudio
sysgpu
sysjs
validating-fix
vulkan-zig-generated
wayland-headers
website
wontfix
wrench
www
x11-headers
xcode-frameworks
zig-update
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
hexops/mach!71
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "window-hints-rework"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I took a different approach to the one used for initialization hints, because I realized that it would probably a lot of overhead to callWindow.hintfor every possible hint, compared to how status quo allows one to avoid that overhead; as well, it would probably be a lot harder to maintain, given that, unlikeInitHint, window initialization hints are of more types than just booleans.This approach is (quite a bit) more verbose, but avoids the overhead, and probably makes it easier to maintain.Also, I found that
context_revisionandcontext_no_errorare listed inWindow.Hint, but are not listed as hints in the docs, only as attributes; I commented them out to make what I have pass tests - is this intentional and I'm missing something, or is this the result of some mishap?Edit:
it should also be noted that unlike the change made to initialization hints, I didn't completely re-use the in-place API, because I ran into some issues regarding the type-inference in theWindow.hintfunction, so you'll see I ended up re-implementing the code forWindow.hintinHintValue.set(whereHintValueis a tagged union, with a tag type ofHint).Edit: as pointed out by @silversquirl, there isn't actually a lot of overhead involved in the struct approach, so now the union slice is no more.
Now just to address the other components of this problem, such asWindow.hint, which seems to have some some type inference issues which caused compilation to fail under this new model. Should we try and rework it, or discard it in favor ofHints.set(private function)?Edit: Closes #65
I had this thought initially too, but if you look at the GLFW source, it's probably about the same as calling
glfwDefaultWindowHints. I'd say have a hints struct with default values, and just set all of them unconditionally.If you do want to avoid setting hints that don't need changed though, I'd still recommend going the struct route, and just check if the value is different than the default. This is easy to do by just looping over
std.meta.fields, since the typeinfo gives you default values.A struct results in a nicer API than an array of hints - the latter still feels very much like a C API, not a Zig one.
@silversquirl Good point. I don't know why I didn't actually check the source; guess that's what I get for starting this on my laptop at a café. And I guess that's also why I made this a draft.
@silversquirl Do you have any thoughts on what to do with the currently unused
Window.hintfunction?Either move the type conversion logic in
setinto it, or delete it. Not much point in keeping it if it's not used@ -258,0 +268,4 @@OpenGLProfile,=> c.glfwWindowHint(hint_tag, @enumToInt(hint_value)),[:0]const u8 => c.glfwWindowHintString(hint_tag, hint_value.ptr),Any particular reason for these parens? Personally I find it more readable without them
@ -258,0 +268,4 @@OpenGLProfile,=> c.glfwWindowHint(hint_tag, @enumToInt(hint_value)),[:0]const u8 => c.glfwWindowHintString(hint_tag, hint_value.ptr),My personal reason for it is that I don't like "mixing" whitespace "scopes" (the obligatory space between 'const' and 'u8', and the optional whitespace between 'u8' and '=>'), if that makes any sense. Though, I have no particular attachment to it either, just a sort of typing habit. I can go ahead and change it whenever I get on my laptop.
Excuse my fumbling with git, trying to make the history not look messy.
@ -230,0 +160,4 @@center_cursor: bool = true,transparent_framebuffer: bool = false,focus_on_show: bool = true,scale_to_monitor: bool = false,The source backs you up here. GLFW_CONTEXT_REVISION is not a hint
@ -230,0 +160,4 @@center_cursor: bool = true,transparent_framebuffer: bool = false,focus_on_show: bool = true,scale_to_monitor: bool = false,@silversquirl Is that the same case for
context_no_error = c.GLFW_CONTEXT_NO_ERROR?@ -258,0 +180,4 @@/// Monitor refresh raterefresh_rate: c_int = glfw.dont_care,This one is a hint, and is actually listed in the docs
@ -258,0 +207,4 @@opengl_debug_context: bool = false,opengl_profile: OpenGLProfile = .opengl_any_profile,Personally I'd remove these constants from consts and inline them here. They don't need to be publicly accessible any more, so there's probably no reason for them to be in consts.
@ -258,0 +207,4 @@opengl_debug_context: bool = false,opengl_profile: OpenGLProfile = .opengl_any_profile,@silversquirl I was thinking the same thing, but was unsure whether to do so being that something like this wasn't done in #56 already.
@ -258,0 +180,4 @@/// Monitor refresh raterefresh_rate: c_int = glfw.dont_care,@silversquirl Right, I didn't see that. I was looking at this list, which lists hints, their default values and possible values. It's not in that list, and I can't see anywhere else that would specify a default value for it; maybe it could default to
!std.debug.runtime_safety? (set to true in release modes).@ -258,0 +180,4 @@/// Monitor refresh raterefresh_rate: c_int = glfw.dont_care,Since we handle errors through Zig error unions, I'd say definitely default it to false. Possibly even remove it from the struct altogether, since it's quite an unsafe option to use - at the very least put a doc comment informing about the dangers.
@ -258,0 +180,4 @@/// Monitor refresh raterefresh_rate: c_int = glfw.dont_care,@silversquirl Alright, I suppose that makes sense. I'll amend it now and leave this as resolved.
@ -258,0 +207,4 @@opengl_debug_context: bool = false,opengl_profile: OpenGLProfile = .opengl_any_profile,@silversquirl I went ahead with the change; the only constant in consts.zig now is
dont_care.Thanks for all your work on this! It'll probably be a few days before I have a chance to review (at handmade Seattle and then to a wedding) so apologies for the delayed review!
I had an idea to maybe add a test that compares the attribute values of a window created with
Window.from(c.glfwCreateWindow(...)), to the attribute values of a window created withWindow.create(...)(in that order), to check that, for any attribute whose value is initialized viaWindow.Hints.set, its value is the same as what would be set by GLFW itself (maybe excluding context_no_error). This wouldn't be full-coverage, but it would be something. Thoughts?@ -258,0 +268,4 @@OpenGLProfile,=> c.glfwWindowHint(hint_tag, @enumToInt(hint_value)),[:0]const u8 => c.glfwWindowHintString(hint_tag, hint_value.ptr),Happy to have this as-is and let
zig fmtformally sort it out later.@InKryption regarding:
This sounds like an obvious win to me, so yes, please do! I won't block this PR on this, please send another PR for it if I merge before you get to it.
One thing to be mindful of: if we want the test to pass on any OS, be sure to choose hints that work on all OS/platforms.
@slimsag Roger roger, I'll set this as ready for merging then, in the absence of any notes you may have.
@ -266,3 +283,2 @@try getError();}};The reason I had this here was that it is listed in the source as being both a hint and attribute:
github.com/glfw/glfw@fb0f2f92a3/include/GLFW/glfw3.h (L1031-L1036)However, indeed, I can confirm from looking at the GLFW source that comment in their header seems incorrect. I will send a PR upstream to fix the comment.
@ -266,3 +283,2 @@try getError();}};Sent https://github.com/glfw/glfw/pull/1992
Adding this note so that others will know how to verify if these values are correct or not and how to update them in the future
Because these are the only public hints exposed by the API, I think that we need to move all the docstrings from the current
const Hint = enum(c_int) {into the fields here. Otherwise, once a Zig documentation generator exists (or even if you're just looking at this code for usage) you would not find any docstrings on these fields.@ -258,0 +200,4 @@context_release_behavior: ContextReleaseBehavior = .any_release_behavior,/// Note: disables the context creating errors,/// instead turning them into undefined behavior.From https://ziglang.org/documentation/master/#Names
I would guess
OpenGLProfileis more correct thanOpenGlProfile@ -258,0 +200,4 @@context_release_behavior: ContextReleaseBehavior = .any_release_behavior,/// Note: disables the context creating errors,/// instead turning them into undefined behavior.@ -258,0 +200,4 @@context_release_behavior: ContextReleaseBehavior = .any_release_behavior,/// Note: disables the context creating errors,/// instead turning them into undefined behavior.And same thing for
ClientApiandContextCreationApiI think (useAPI)I believe that this is wrong? It would set the user-specified hints, then overwrite them with the defaults?
Maybe delete this whole file now and just move this constant into
main.zig, since we already do ausingnamespaceimport of this file:github.com/hexops/mach@d5913c3e49/glfw/src/main.zig (L8)Looks really great, thanks for sending this. Once my comments are addressed and tests pass I'll merge. Feel free to send the test in this PR or a separate one, whichever you prefer.
You are correct, that code is wrong. That probably explains why I was getting some strange results prototyping those hint-attribute tests I mentioned.
Ah, I see your intent now is to "cleanup" the hints so-to-speak by changing them back to the default. This makes sense.
However, if window creation fails we would not clean up. Maybe instead
deferand ignore the error? I thinkdefer _ = Window.defaultHints();would do the trick (but I might have the exact syntax wrong)In my original thinking, a
deferwouldn't have worked, as you can'ttryin adeferstatement; but looking at it closer, the only possible error forWindow.defaultHintsisError.NotInitialized, which should already have been caught inHints.set, so an error should never be thrown there, a lacatch unreachable.@slimsag Here, I'm actually unsure if all of the comments in
Hintare totally necessary. They about double the length of the struct's declaration, and don't (in my opinion) add that much information. All of them follow the pattern:Save for a few, like
center_cursorandfocus_on_show, and the framebuffer bits hints, which follow their own pattern.But if you feel strongly about it, I can add the changes.
Edit: gentle ping
Makes sense to me! I agree having comments just for the sake of it is bad practice, we should remove all such instances. They probably just ended up there as I didn't notice it. I should've checked the comments were actually useful before asking you to do this, sorry 😛
All's good. I'll sort through them for a bit, and grab the ones that are meaningful, and polish them up.
@ -68,126 +69,67 @@ pub const InternalUserPointer = struct {/// @thread_safety This function must only be called from the main thread.I think this became public again by accident / due to merge conflict
Looks good to me, let me know when you're finished and I'll merge. I will need to squash merge due to non-linear history, unless you want to rebase everything (I'm happy either way)
I've done the sorting; give it a quick look and see if there's anything amiss. If that looks good, then I feel confident about saying this is locked and loaded. I'll look at making a PR for that test/those tests concerning hints/attributes at some point in the near-ish future.
Edit:
give me a second to figure out the rebasing, it actually doesn't seem as complicated as I thought.LGTM, thanks a ton again!
Closes #65