3
3
using Android . Runtime ;
4
4
using Android . Util ;
5
5
using Android . Views ;
6
- using AndroidX . AppCompat . App ;
7
6
using AndroidX . Core . View ;
8
7
using Uno . Disposables ;
9
8
using Uno . Foundation . Logging ;
10
9
using Uno . UI . Extensions ;
11
10
using Windows . ApplicationModel . Core ;
12
11
using Windows . Foundation ;
13
- using Windows . Graphics ;
14
12
using Windows . Graphics . Display ;
15
13
using Windows . UI . Core ;
16
14
using Windows . UI . ViewManagement ;
@@ -78,6 +76,7 @@ internal void RaiseNativeSizeChanged()
78
76
Bounds = new Rect ( default , windowSize ) ;
79
77
VisibleBounds = visibleBounds ;
80
78
Size = new ( ( int ) ( windowSize . Width * RasterizationScale ) , ( int ) ( windowSize . Height * RasterizationScale ) ) ;
79
+ ApplySystemOverlaysTheming ( ) ;
81
80
82
81
if ( _previousTrueVisibleBounds != visibleBounds )
83
82
{
@@ -88,7 +87,11 @@ internal void RaiseNativeSizeChanged()
88
87
}
89
88
}
90
89
91
- protected override void ShowCore ( ) => RemovePreDrawListener ( ) ;
90
+ protected override void ShowCore ( )
91
+ {
92
+ ApplySystemOverlaysTheming ( ) ;
93
+ RemovePreDrawListener ( ) ;
94
+ }
92
95
93
96
private ( Size windowSize , Rect visibleBounds ) GetVisualBounds ( )
94
97
{
@@ -103,6 +106,9 @@ internal void RaiseNativeSizeChanged()
103
106
Rect windowBounds ;
104
107
Rect visibleBounds ;
105
108
109
+ var decorView = activity . Window . DecorView ;
110
+ var fitsSystemWindows = decorView . FitsSystemWindows ;
111
+
106
112
if ( ( int ) Android . OS . Build . VERSION . SdkInt < 35 )
107
113
{
108
114
var opaqueInsetsTypes = insetsTypes ;
@@ -134,9 +140,19 @@ internal void RaiseNativeSizeChanged()
134
140
this . Log ( ) . LogDebug ( $ "Insets: { insets } ") ;
135
141
}
136
142
137
- // Edge-to-edge is default on Android 15 and above
138
- windowBounds = new Rect ( default , GetWindowSize ( ) ) ;
139
- visibleBounds = windowBounds . DeflateBy ( insets ) ;
143
+ if ( fitsSystemWindows )
144
+ {
145
+ // The window bounds are the same as the display size, as the system insets are already taken into account by the layout
146
+ windowBounds = new Rect ( default , GetWindowSize ( ) . Subtract ( insets ) ) ;
147
+ visibleBounds = windowBounds ;
148
+ }
149
+ else
150
+ {
151
+ // Edge-to-edge is default on Android 15 and above
152
+ windowBounds = new Rect ( default , GetWindowSize ( ) ) ;
153
+ visibleBounds = windowBounds . DeflateBy ( insets ) ;
154
+ }
155
+
140
156
}
141
157
142
158
if ( this . Log ( ) . IsEnabled ( LogLevel . Debug ) )
@@ -178,6 +194,25 @@ private WindowInsetsCompat GetWindowInsets(Activity activity)
178
194
return null ;
179
195
}
180
196
197
+ internal void ApplySystemOverlaysTheming ( )
198
+ {
199
+ if ( ( int ) Android . OS . Build . VERSION . SdkInt >= 35 )
200
+ {
201
+ // In edge-to-edge experience we want to adjust the theming of status bar to match the app theme.
202
+ if ( ( ContextHelper . TryGetCurrent ( out var context ) ) &&
203
+ context is Activity activity &&
204
+ activity . Window ? . DecorView is { FitsSystemWindows : false } decorView )
205
+ {
206
+ var requestedTheme = Microsoft . UI . Xaml . Application . Current . RequestedTheme ;
207
+
208
+ var insetsController = WindowCompat . GetInsetsController ( activity . Window , decorView ) ;
209
+
210
+ // "appearance light" refers to status bar set to light theme == dark foreground
211
+ insetsController . AppearanceLightStatusBars = requestedTheme == Microsoft . UI . Xaml . ApplicationTheme . Light ;
212
+ }
213
+ }
214
+ }
215
+
181
216
private Size GetWindowSize ( )
182
217
{
183
218
if ( ContextHelper . Current is not Activity activity )
0 commit comments