[Solved] Screen Resolution : Detect when the user flip his device







Hello, for my first time I execute a Monogame Android project on my phone, it was just suppose to display a grass square block at the top left corner.

So first I try with this scripts : screenshot n°5 ( note, I wrote the number of the screenshot myself with a software ), and I get this result : screenshot n°1 . It a little weird because the unused space between the top screen and the texture correspond to the barre notification. If it turn my device, I got the screenshot n°2, and if I turn it again, I got the screenshot n°3 .

I also try this program : screenshot n°6 ( not very optimized I know ), and I get the screenshot n°1, If it turn my device, I got the screenshot n°2, and if I turn it again, I got the screenshot n°4.

I want to know how I can “remove” the unused space between the top screen and the texture, I don’t want turn twice my device each time to have the good display, and also how I can detect when the user turn his device

Are you setting the backbuffer width/height correctly when the app starts up or changes resolution/aspect-ratio?

To give you an idea (this was writen in the browser, not my code editor ;))…

int previous_width = -1;
int previous_height = -1;
protected override void Update(GameTime gameTime) {
    if (Window.ClientBounds.Width!=previous_width||Window.ClientBounds.Height!=previous_height) {
        graphics.PreferredBackBufferWidth = Window.ClientBounds.Width;
        graphics.PreferredBackBufferHeight = Window.ClientBounds.Height;
        previous_width = Window.ClientBounds.Width;
        previous_height = Window.ClientBounds.Height;
        graphics.ApplyChanges();
    }
}
1 Like

I think the backbuffer is width/height correctly when the app starts up :

    public MainGame()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        previous_width = -1;
        previous_height = -1;

        graphics.IsFullScreen = true;
        graphics.PreferredBackBufferWidth = 800;
        graphics.PreferredBackBufferHeight = 480;
        graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
        graphics.ApplyChanges();

    }

I try your scripts (in the Update method):

if (Window.ClientBounds.Width != previous_width || Window.ClientBounds.Height != previous_height)
{
graphics.PreferredBackBufferWidth = Window.ClientBounds.Width;
graphics.PreferredBackBufferHeight = Window.ClientBounds.Height;
previous_width = Window.ClientBounds.Width;
previous_height = Window.ClientBounds.Height;
graphics.ApplyChanges();
Debug.WriteLine(“Initialise first time. unused space” + Window.ClientBounds.Y);
}

but the result is the same as my first try in my first post (screenshot n°1,2,3)
Note, I also try do to it in an emulator, same result, except this I don’t get the “unused space”.

I also try with GraphicsDevice.Viewport.Width/Height instead of Window.ClientBounds.X/Y, same result again ( with the unused space).

I found an solution, but it is not working well :

        if (Window.ClientBounds.Width != previous_width || Window.ClientBounds.Height != previous_height || Window.ClientBounds.Y != 0 || Window.ClientBounds.X != 0)
        {
            graphics.PreferredBackBufferWidth = Window.ClientBounds.Width + Window.ClientBounds.X;
            graphics.PreferredBackBufferHeight = Window.ClientBounds.Height + Window.ClientBounds.Y;
            previous_width = Window.ClientBounds.Width;
            previous_height = Window.ClientBounds.Height;

            graphics.ApplyChanges();
            Debug.WriteLine("initialise first time. unused space" + Window.ClientBounds.Y);
        }

this time, the project is well initialize, I get the screenshot n°4 ( it’s okay), if I flip my device I get the screenshot n°2 ( it’s okay again :slight_smile: ) , and if I flip it again I get …the screenshot n°1 ( the wrong case ).

I can patch it by doing an “graphics.ApplyChanges();” each time in the Update method, but that will no be otpimised…

Do there is a way to detect when the user flip his device ?

This is the problem. The backbuffer should under normal circumstances always be the same size as the window/screen.

Just check Window.ClientBounds.<Width/Height> on each frame. Or check GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.<Width/Height> which should be the whole display… This might work for fullscreen devices such as Android, but for windowed devices like Pc & Mac you need the check the window.

Adding X&Y to the size of the backbuffer is not a good idea! This defines the location of the window on the screen and should not be added to the dimensions.

Try it like this!

#if WINDOWS || WINDOWS_UAP || LINUX || __MACOS__
graphics.PreferredBackBufferWidth = Window.ClientBounds.Width;
graphics.PreferredBackBufferHeight = Window.ClientBounds.Height;
#else
graphics.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
graphics.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
#endif
graphics.ApplyChanges();
2 Likes

Thank you very much !
It’s work, I use the “GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.” to detect when the user flip his phone.


        if (GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width != lastWidth || GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height != lastHeight)
        {
            graphics.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
            graphics.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
            lastWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
            lastHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
            graphics.ApplyChanges();
            Debug.WriteLine("Switch !");
        }

Everything work well now, thank again for the (quick) answer :smile:

1 Like

Glad you got it working :slight_smile:

I had similar issues on my Android version. I used the ClientSizeChanged event on the Game class. When this event occurs, I pass the info along to my screen manager, which then sets it the usual MonoGame way (as you have above).

        protected override void Initialize()
        {
            _graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
            this.Window.ClientSizeChanged += (sender, e) =>
            {
                _engine.ScreenManager.Screen = new Point(_graphics.GraphicsDevice.Viewport.Width, _graphics.GraphicsDevice.Viewport.Height);
                _engine.ScreenManager.ApplySettings(_engine.Graphics);
            };

          ...

One other thing of note, for Android, they have this system UI thing that takes up a portion of your resolution. You can hide it and set a full screen mode. I put it in a method and call it from my AndroidGameActivity.OnResume method.

        private void HideSystemUI()
        {
            // Apparently for Android OS Kitkat and higher, you can set a full screen mode. Why this isn't on by default, or some kind
            // of simple switch, is beyond me.
            // Got this from the following forum post: http://community.monogame.net/t/blocking-the-menu-bar-from-appearing/1021/2
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
            {
                View decorView = Window.DecorView;
                var uiOptions = (int)decorView.SystemUiVisibility;
                var newUiOptions = (int)uiOptions;

                newUiOptions |= (int)SystemUiFlags.LowProfile;
                newUiOptions |= (int)SystemUiFlags.Fullscreen;
                newUiOptions |= (int)SystemUiFlags.HideNavigation;
                newUiOptions |= (int)SystemUiFlags.ImmersiveSticky;

                decorView.SystemUiVisibility = (StatusBarVisibility)newUiOptions;

                this.Immersive = true;
            }
        }

This is only Android though… I haven’t gotten into iOS yet. You can thank Apple for that… it’s silly that they require an Apple computer on the network to build. My iPhone apparently isn’t enough >.<

1 Like