GraphicsDevice Viewport changes when Game is started and after resume from background [Monogame on Android ]

I have been looking into this for some time and can’t get my head around it. On certain Android devices my game gets a vertical bar of “dead” space on the right when the game is started and if I send the game to the background and re-activate it I then get an additional one on the right. I have added two GIFS to the post to help show this.

When I check GraphicsDevice.Viewport.X it is not equal to zero, I can set this back to zero, but if I put the game to the background and bring it back, the X value changes again. I can use the below code to correct it, but struggling to find where I should place it so as to avoid the need to call it every update. Similarly the width of the viewport changes at the same times.

if (GraphicsDevice != null && (GraphicsDevice.Viewport.X != 0 ||
GraphicsDevice.Viewport.Width != GraphicsDevice.Adapter.CurrentDisplayMode.Width ||
GraphicsDevice.Viewport.Width != GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width))
{
Viewport view = GraphicsDevice.Viewport;
view.X = 0;
view.Width = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsDevice.Viewport = view;
}

I have been looking into this for some time and can’t get my head around it. On certain Android devices my game gets a vertical bar of “dead” space on the right when the game is started and if I send the game to the background and re-activate it I then get an additional one on the right. I have added two GIFS to the post to help show this.

When I check GraphicsDevice.Viewport.X it is not equal to zero, I can set this back to zero, but if I put the game to the background and bring it back, the X value changes again. I can use the below code to correct it, but struggling to find where I should place it so as to avoid the need to call it every update. Similarly the width of the viewport changes at the same times.

if (GraphicsDevice != null && (GraphicsDevice.Viewport.X != 0 ||
GraphicsDevice.Viewport.Width != GraphicsDevice.Adapter.CurrentDisplayMode.Width ||
GraphicsDevice.Viewport.Width != GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width))
{
Viewport view = GraphicsDevice.Viewport;
view.X = 0;
view.Width = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsDevice.Viewport = view;
}
I have placed this code within the Update() method of the screen and it fixes the issue - but seems overkill to call it in every update. I have also tried to call it in overrides of the Activity and Game OnResume() & OnActivate(), it changes the viewport as required, but doesn’t hold and ends up getting set back to the values that cause the bars ‘instantly’.

Also worth noting the game is running in full screen mode.

Any advice that you can offer would be greatly appreciated.

Videos:
When Game Starts
When game resumes from background

Note: in the videos I am moving the blue marker with touch.

This is a cross post of one I placed on StackOverflow two weeks ago, when I had trouble signing up to Monogame Community.

Yes I had a similar issue and found a solution via googling around. It was several years ago though, so I’ve lost the original reference.

For me, the solution was to put the following in my Game’s Initialize method:

this.Window.ClientSizeChanged +=
    (sender, e) =>
    {
        _screenManager.Screen = new Point(_graphics.GraphicsDevice.Viewport.Width, _graphics.GraphicsDevice.Viewport.Height);
        _screenManager.ApplySettings(_graphics);
    };

Hopefully it helps you out also!

@Trinith Thank you for the suggestion and code snippet. Unfortunately the event is only triggered once when the game is started and the bands still appear. I’ve been struggling to find an event that is triggered when the GraphicsDevice.Viewport is changed as this appears to be the issue.

I welcome any further thoughts you may have. Regardless I’ll keep searching and if I come up with something I will post it here for reference.

See my previous reply here

Thanks @nkast, I played around with the Activity config but it didn’t solve the issue.

However, it did lead me to look at the SystemUiFlags which I set during the OnWindowFocusChanged event to hide the navigation bar and set full screen and the issue has gone away.

Thanks both @Trinith and @nkast for your assistance, a combination of the two replies has sorted my issue.

I was just coming back here to post that very thing, haha. It occurred to me as I was going to bed last night, for no reason. Glad you got there on your own :slight_smile:

For historical purposes, here’s some code, complete with my exasperated comment from when I first found it (and original link). Also, I call this from OnResume instead of OnWindowFocusChanged. I’m not sure if it matters…

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;
    }
}
1 Like