Skip to content

The Game.Window.Resizable setter on Android causes unexpected screen rotation #6577

@Frederisk

Description

@Frederisk

Through this issue, we already know that when SDL3Window initializes, it reads the SDL_HINT_ORIENTATIONS instead of RequestedOrientation, which can cause problems.

So, a possible solution is to use SDL.SDL3.SDL_SetHint to pre-assign the orientation we need.

However, this still doesn't avoid another problem: besides during initialization, the Window.Resizable property will call this setOrientationBis method again when its value changes. And I think users might not expect this. For example:

  • A user might initially, similar to osu!, not assign a hint and use RequestedOrientation to set the screen orientation to a specific value. Then, some method (perhaps a cross-platform settings option) tries to change the value of Resizable: Window.Resizable = !Window.Resizable. Then, RequestedOrientation will suddenly be changed to FullUser. And what's stranger is that executing Window.Resizable = !Window.Resizable again will not restore the screen orientation, but will fix the screen to landscape or portrait.
    class MyGame : Game {
      [Reslove]
      AndroidGameActivity activity;
      [BackgroundDependencyLoader]
      load() => this.activity.RequestedOrientation = ScreenOrientation.Landscape;
    
      // By this action, RequestedOrientation may become `FullUser`, or `SensorLandscape`, or `SensorLandscape`
      override OnClick() => Window.Resizable = !Window.Resizable;
    }
  • Alternatively, a user might use a hint to make the screen display in landscape for things like loading screens. Then, there's an in-game setting to force the program into portrait mode. At this point, RequestedOrientation must be used, as SDL_HINT_ORIENTATIONS does not notify Android that its status has changed. Then, if an attempt is made to change the Resizable value while in portrait mode, the SDL_HINT_ORIENTATIONS takes effect again, forcing the screen back to landscape. And changing Resizable back to its original value has no effect. I believe users who haven't seen any comments about this would be very confused.
    class AndroidGameActivity {
      override OnCreate() => SDL.SDL3.SDL_SetHint(SDL.SDL3.SDL_HINT_ORIENTATIONS, "LandscapeRight"u8);
    }
    class MyGame : Game {
      [Reslove]
      AndroidGameActivity activity;
      [BackgroundDependencyLoader]
      load() => this.activity.RequestedOrientation = ScreenOrientation.Landscape;
    
      // By this action, RequestedOrientation will become `ReverseLandscape`
      override OnClick() => Window.Resizable = !Window.Resizable;
    }

Here's a sample program. Just install the compiled SampleGame.Android project on your device. You can try clicking some buttons and observe how the screen orientation changes.

So, do we also need additional wiki documentation or comments for Resizable to inform users about this unusual issue? For example, mentioning that changing Resizable in Android can cause unexpected orientation changes, or reminding users to record the value of RequestedOrientation before modifying Resizable in Android and restore it after the call is complete.

By the way, I have a potentially viable solution for the three related issues, which is to override the SetOrientationBis method in AndroidGameActivity. I have already checked the complete call chain. But after asking for others' opinions on Discord, I received the reply, "If it works, then don't touch it." So, whether to solve these problems, or to consider them not to be problems, is entirely up to you guys. I have no other ideas.😕

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions