airsdk / Adobe-Runtime-Support

Report, track and discuss issues in Adobe AIR. Monitored by Adobe - and HARMAN - and maintained by the AIR community.
201 stars 11 forks source link

`NativeWindow::resizeToScreen()` cause deformated fullscreen #3241

Open itlancer opened 4 months ago

itlancer commented 4 months ago

Problem Description

NativeWindow::resizeToScreen() call cause deformated fullscreen afterward. It critical when you try to turn AIR application window to fullscreen on specific Screen.

Reproduced with multiple AIR versions, even with AIR 50.2.4.4, 50.2.4.5, 50.2.5.1 and latest 51.0.1.1 with multiple different Windows devices with different applications. Same issue in all cases. Adding timeout after NativeWindow::resizeToScreen() didn't help. Didn't test with macOS and Linux.

Related issues: https://github.com/airsdk/Adobe-Runtime-Support/issues/3239 https://github.com/airsdk/Adobe-Runtime-Support/issues/3203 https://github.com/airsdk/Adobe-Runtime-Support/issues/3177 https://github.com/airsdk/Adobe-Runtime-Support/issues/3176 https://github.com/airsdk/Adobe-Runtime-Support/issues/2549 https://github.com/airsdk/Adobe-Runtime-Support/issues/2497 https://github.com/airsdk/Adobe-Runtime-Support/issues/2495 https://github.com/airsdk/Adobe-Runtime-Support/issues/2241 https://github.com/airsdk/Adobe-Runtime-Support/issues/1840 https://github.com/airsdk/Adobe-Runtime-Support/issues/1669 https://github.com/airsdk/Adobe-Runtime-Support/issues/1425 https://github.com/airsdk/Adobe-Runtime-Support/issues/1200 https://github.com/airsdk/Adobe-Runtime-Support/issues/1123 https://github.com/airsdk/Adobe-Runtime-Support/issues/528

Steps to Reproduce

Launch application with code below. It just set stage color to green, draw red rectangle little smaller than fullscreen Stage (just to better show issue), resize application window to main Screen and change display state to fullscreen.

Application example with sources attached. resizetoscreen_fullscreen_bug.zip

package {
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display.Shape;
    import flash.display.StageDisplayState;
    import flash.display.Screen;
    import flash.events.Event;
    import flash.display.NativeWindow;
    import flash.events.NativeWindowDisplayStateEvent;
    import flash.display.NativeWindowDisplayState;

    public class ResizeToScreenFullscreenBug extends Sprite {
        private var window:NativeWindow;

        public function ResizeToScreenFullscreenBug() {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.color = 0x00ff00;//Set stage color to green

            //Draw red rectangle little smaller than whole fullscreen stage
            var shape:Shape = new Shape();
            shape.graphics.beginFill(0xff0000);
            shape.graphics.drawRect(0, 0, stage.fullScreenWidth - 10, stage.fullScreenHeight - 10);
            shape.graphics.endFill();
            addChild(shape);

            addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        }

        private function addedToStage(e:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStage);

            window = stage.nativeWindow;
            if (window.active){
                //Main window is active
                window_activate();
            } else {
                //Wait for window to be activated
                window.addEventListener(Event.ACTIVATE, window_activate);
            }
        }

        private function window_activate(e:Event = null):void {
            window.removeEventListener(Event.ACTIVATE, window_activate);

            window.resizeToScreen(Screen.mainScreen);//Fit (resize) window to whole main screen

            stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;

            //For workaround comment line above and uncomment 2 lines below
            //window.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, window_displayStateChange);
            //window.maximize();
        }

        private function window_displayStateChange(e:NativeWindowDisplayStateEvent):void {
            trace("window_displayStateChange");
            if (e.afterDisplayState == NativeWindowDisplayState.MAXIMIZED){//Window maximized
                window.removeEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, window_displayStateChange);

                stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
            }
        }
    }
}

Actual Result: All stage looks red (without green borders). In real complex applications also you can see that content inside stage deformed (aspect ratio wrong). image

Expected Result: You can see green border at right and bottom. No content deformation. image

Known Workarounds

After NativeWindow::resizeToScreen() call NativeWindow::maximize(). See code above.

ajwfrost commented 4 months ago

Seems like this is related to the render mode i.e. in CPU rendering, it works, but with Direct mode, it doesn't.

Testing here:

We can try to investigate this one...