goxjs / glfw

Go cross-platform glfw library for creating an OpenGL context and receiving events.
MIT License
82 stars 26 forks source link

Entering fullscreen has to happen during user event, cannot happen at CreateWindow time. #3

Open dmitshur opened 9 years ago

dmitshur commented 9 years ago

Summary

Because of browser limitations (to avoid websites abusing the Fullscreen API), requesting to enter fullscreen mode can only be done successfully during user input event handlers.

Therefore, when glfw.CreateWindow is called with fullscreen mode, we can only "schedule" the enter fullscreen request to occur at the next viable moment, which is when the user performs the next input event (mouse down, mouse up, keyboard down, or keyboard up events).

I'm not sure what can be done to improve this situation...

Details

Relevant excerpt from #gopherjs channel on Gophers Slack:

[3:20 AM] shurcool: So I was working on https://github.com/google/gxui/pull/86 just now, rebased it against latest master, etc. I saw there was a new sample demo, a fullscreen/windowed switcher

[3:21 AM] shurcool: I tried to implement it for the browser-side GLFW using Fullscreen API (https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode)

Mozilla Developer Network
Using fullscreen mode
The fullscreen API provides an easy way for web content to be presented using the user's entire screen. This article provides information about using this API.

[3:21 AM] shurcool: but the problem is that browsers allow requesting to enter fullscreen mode only in user input callbacks.

[3:22 AM] shurcool: Now, the code to do that actually happens when the user clicks. But the problem is that due to goroutines, etc. it ends up being indirected and in reality it does not happen from the user click callback directly, and the browser fails the request. (edited)

[3:23 AM]
shurcool uploaded a file: 
Pasted image at 2015-05-28, 3:23 AM  
15KB PNG file • in #gopherjs  • Add comment • Open original

[3:43 AM] shurcool: I wonder what's a good way to go about solving this.

[3:46 AM] neelance: you’ll need to call it directly inside of the click handler, without wrapping it into a goroutine

[3:48 AM] neelance: this is similar to the `event.preventDefault()` problem

[3:48 AM] neelance: you also can’t do that inside of a new goroutine, because then it’s too late

[11:23 AM] shurcool: Yeah, I have an idea now. When doing `glfw.CreateWindow(..., fullscreen)` it can just set a boolean flag "requestedFullscreen" to true and the very next user input handler can actually perform the browser request.

[11:53 AM] neelance: gl :simple_smile:

----- Today May 29th, 2015 -----

[9:55 PM] shurcool: Okay, partial success (and the success part is _really_ cool!)

[9:56 PM] shurcool: The sample I'm testing this with has a big button "make fullscreen". When you press it, it goes fullscreen, and then the button becomes "make windowed".

[9:56 PM] shurcool: There are 2 ways to press the button. Focus it and press Enter or Space.

[9:56 PM] shurcool: When that key is pressed down (keydown event), it triggers.

[9:57 PM] shurcool: I've added my `if requestedFullscreen` checks into "keydown" and "keyup" listener events, and when you **release the key**, it catches that and goes fullscreen.

[9:57 PM] shurcool: So that part works, and it's awesome!

[9:57 PM] shurcool: But sadly, clicking with mouse is problematic.

[9:57 PM] shurcool: To trigger the button with mouse in gxui, you need to press mouse button and release the mouse button. It triggers on mouse button release event.

[9:58 PM] shurcool: The problem is that the browser "mouseup" event triggers event processing in gxui via goroutines, etc. and by the time it does glfw.CreateWindow(fullscreen) - "mouseup" has already finished earlier.

[9:59 PM] shurcool: So if the user presses the gxui button with mouse and waits - nothing happens. It will only go fullscreen the next time they click mouse or press key or do any "user event".

[9:59 PM] shurcool: :confused:

[10:01 PM]
shurcool uploaded a file: 
Fullscreen gxui sample working in browser via GopherJS and Fullscreen API.  
10KB PNG file • in #gopherjs  • Add comment • Open original

[10:19 PM] shurcool: I think this is the best I can do for now, so that's how it'll be... if anyone can think of a way to improve it (or if I think of something later), that'd be great!