openfl / lime

A foundational Haxe framework for cross-platform development
https://lime.openfl.org/
MIT License
749 stars 359 forks source link

window.fullscreen toggling error on MacOS #1771

Open increpare opened 3 months ago

increpare commented 3 months ago

Code snippet reproducing the issue:

The SimpleImage example with this main.hx file


import lime.ui.KeyModifier;
import lime.app.Application;
import lime.graphics.cairo.CairoImageSurface;
import lime.graphics.opengl.GLBuffer;
import lime.graphics.opengl.GLProgram;
import lime.graphics.opengl.GLTexture;
import lime.graphics.opengl.GLUniformLocation;
import lime.graphics.Image;
import lime.graphics.RenderContext;
import lime.math.Matrix4;
import lime.utils.Assets;
import lime.utils.Float32Array;
import lime.ui.KeyCode;

#if flash
import flash.display.Bitmap;
#end

class Main extends Application {

    private var cairoSurface:CairoImageSurface;
    private var glBuffer:GLBuffer;
    private var glMatrixUniform:GLUniformLocation;
    private var glProgram:GLProgram;
    private var glTexture:GLTexture;
    private var glTextureAttribute:Int;
    private var glVertexAttribute:Int;
    private var image:Image;

    public function new () {

        super ();
    }

    public var fullscreen_cached=false;
    public override function onKeyDown (key:KeyCode, modifier:KeyModifier):Void {

        trace("keydown");
        trace("old fullscreen value is "+window.fullscreen);
        switch (key) {
            case KeyCode.F:
                window.fullscreen = !window.fullscreen;
            case KeyCode.G:
                fullscreen_cached = !fullscreen_cached;
                window.fullscreen = fullscreen_cached;
            default:
                super.onKeyDown (key, modifier);
        }
        trace ("new fullscreen value is "+window.fullscreen);
    }

    public override function render (context:RenderContext):Void {
        super.render (context);
    }

}

Observed behavior: Run the app in cpp/neko builds. The app starts in windowed mode. 1: Press F to toggle fullscreen. The app is now in fullscreen. 2: Press F again. The app remains in fullscreen. 3: Press F again. The app is no longer in fullscreen.

Expected behavior: I expect step 2 to bring me back to windowed mode.

Note the log output:

Source/Main.hx:44: keydown
Source/Main.hx:45: old fullscreen value is false
Source/Main.hx:55: new fullscreen value is true
Source/Main.hx:44: keydown
Source/Main.hx:45: old fullscreen value is false
Source/Main.hx:55: new fullscreen value is true
Source/Main.hx:44: keydown
Source/Main.hx:45: old fullscreen value is true
Source/Main.hx:55: new fullscreen value is false

Note that it seems that FlxG.fullscreen is somehow getting turned back to false sometime between when it's toggled on and I've entered the new frame.

Also note that pressing G, which locally caches the 'fullscreen' value, doesn't have this behaviour.

player-03 commented 3 months ago

Try adding event listeners to each of the following:

How many of them get dispatched, and at what point in the process?

increpare commented 3 months ago

Okay, let's try that (for the record, here's the code with the inserted event handlers - https://gist.github.com/increpare/928e5ee0919d7da56d11ba2ab2c022b7 )

Pressing F three times:

Source/Main.hx:66: keydown Source/Main.hx:67: old fullscreen value is false Source/Main.hx:48: onFullscreen Source/Main.hx:77: new fullscreen value is true Source/Main.hx:52: onMaximize Source/Main.hx:66: keydown Source/Main.hx:67: old fullscreen value is false Source/Main.hx:48: onFullscreen Source/Main.hx:77: new fullscreen value is true Source/Main.hx:66: keydown Source/Main.hx:67: old fullscreen value is true Source/Main.hx:77: new fullscreen value is false Source/Main.hx:62: onRestore

Pressing G twice

Source/Main.hx:66: keydown Source/Main.hx:67: old fullscreen value is false Source/Main.hx:48: onFullscreen Source/Main.hx:77: new fullscreen value is true Source/Main.hx:52: onMaximize Source/Main.hx:66: keydown Source/Main.hx:67: old fullscreen value is false Source/Main.hx:77: new fullscreen value is false Source/Main.hx:62: onRestore

player-03 commented 3 months ago

Well, I think we found the culprit. When we receive a "maximize" window event, we set __fullscreen to false before dispatching onMaximize.

There aren't any other references to onMaximize, so I think it's safe to conclude that's where it's coming from. (Not even references that should exist, like in this list.)

When testing on Linux, I can confirm that there's no onMaximize event, and therefore window.fullscreen behaves as it should, toggling every time F is pressed. And there's also no onRestore event when exiting fullscreen. I don't know why you're getting these extra events on Mac, but they're definitely not what's supposed to happen.

increpare commented 3 months ago

Oho. Maybe it's related to hitting the maximize button on OSX having the same effect as going fullscreen? (At some point years ago macos changed the behaviour of the fullscreen button from a more Windows-style "expand window to fill screen" to actual full-screen).

hoangdung-qbt commented 6 days ago

I've solved this issue by adding "onMaximized()" to native stage. Additionally, you should compare the value of the width or height of the stage with the screen resolution to check your app is already in full screen mode or not. It might be a little trick, "fullscreen" value of SDL library always returns "false" on macOS. The library seems to be outdated. You can also try the developing version of Lime/OpenFL for better results.