@@ -2000,13 +2000,19 @@ private void registerAndroidInputHandlers(GameHost host)
20002000 gameActivity . MouseHandler = mouseHandler ;
20012001 gameActivity . KeyboardHandler = keyboardHandler ;
20022002
2003- // Match the screen / digitiser dimensions for tablet area mapping.
2004- applyStylusDisplaySize ( stylusHandler ) ;
2005-
20062003 // Initialize each handler the same way the framework would in
20072004 // CreateAvailableInputHandlers — sets the protected Host field on the base
20082005 // class and runs handler-specific bindable wiring. Skip-on-failure: a single
20092006 // misbehaving handler must not knock out the other two.
2007+ //
2008+ // NOTE: applyStylusDisplaySize is called AFTER Initialize so that:
2009+ // 1. base.Initialize(host) has finished setting up the Host field and any
2010+ // framework config bindings, avoiding a race where config-loaded values
2011+ // overwrite the display size we push in SetDisplaySize.
2012+ // 2. The OutputAreaSize BindValueChanged guard installed in Initialize is
2013+ // already in place before SetDisplaySize fires the first write, ensuring
2014+ // the normalised-sentinel detector can intercept subsequent ScalingContainer
2015+ // writes on the very first updateSize() call.
20102016 var newHandlers = new osu . Framework . Input . Handlers . InputHandler [ ] { stylusHandler , mouseHandler , keyboardHandler } ;
20112017
20122018 foreach ( var h in newHandlers )
@@ -2022,6 +2028,11 @@ private void registerAndroidInputHandlers(GameHost host)
20222028 }
20232029 }
20242030
2031+ // Match the screen / digitiser dimensions for tablet area mapping.
2032+ // Called after Initialize so the display-size write lands on top of any
2033+ // framework config-restore and the OutputAreaSize guard is already armed.
2034+ applyStylusDisplaySize ( stylusHandler ) ;
2035+
20252036 // Reflectively replace AvailableInputHandlers with the union of the host's
20262037 // existing immutable array and our three handlers. The property has a private
20272038 // setter; we use reflection because the framework does not expose a public
@@ -2105,10 +2116,13 @@ private void registerAndroidInputHandlers(GameHost host)
21052116 /// </para>
21062117 ///
21072118 /// <para>
2108- /// As a final defensive guard the resolved bounds are normalised to landscape
2109- /// (<c>max(W,H) × min(W,H)</c>) since the activity is landscape-locked on phones —
2119+ /// As a final defensive guard on phones, the resolved bounds are normalised to landscape
2120+ /// (<c>max(W,H) × min(W,H)</c>) since the activity is landscape-locked there —
21102121 /// this neutralises the residual case where an OEM still hands back portrait
2111- /// bounds for the current metrics on certain Android skins.
2122+ /// bounds for the current metrics on certain Android skins. Tablets and DeX are
2123+ /// excluded because they run in <see cref="ScreenOrientation.FullUser"/> / external
2124+ /// display orientation, where forcing landscape makes portrait tablet S Pen
2125+ /// coordinates divide by the wrong axis and pins the pointer near the origin.
21122126 /// </para>
21132127 /// </summary>
21142128 private void applyStylusDisplaySize ( AndroidStylusHandler handler )
@@ -2178,13 +2192,18 @@ private void applyStylusDisplaySize(AndroidStylusHandler handler)
21782192 if ( width <= 0 || height <= 0 )
21792193 return ;
21802194
2181- // Canonicalise to landscape since the phone activity is landscape-locked
2195+ // Canonicalise to landscape only when the activity is actually landscape-locked
21822196 // (see [Activity(ScreenOrientation = ScreenOrientation.Landscape)] on
2183- // OsuGameActivity). Tablets / DeX run in FullUser orientation so the
2184- // canonicalisation is harmless — we still get a (W, H) pair whose major
2185- // axis matches MotionEvent.GetX's range.
2186- int w = Math . Max ( width , height ) ;
2187- int h = Math . Min ( width , height ) ;
2197+ // OsuGameActivity). Tablets / DeX run in FullUser / external-display
2198+ // orientation, so preserve the current window metrics exactly there.
2199+ int w = width ;
2200+ int h = height ;
2201+
2202+ if ( ! gameActivity . IsTablet && ! gameActivity . IsDeX )
2203+ {
2204+ w = Math . Max ( width , height ) ;
2205+ h = Math . Min ( width , height ) ;
2206+ }
21882207
21892208 handler . SetDisplaySize ( w , h ) ;
21902209 }
0 commit comments