@@ -245,21 +245,26 @@ private static void SnapPositionToGameWindowThread(object processArg)
245
245
if ( ! _mainForm . Visible && ! temporarilyHidden )
246
246
continue ;
247
247
248
- if ( gameProcess . MainWindowHandle == IntPtr . Zero ||
248
+ var gameWindowHandle = gameProcess . MainWindowHandle ;
249
+ var gameWindowTitle = gameProcess . MainWindowTitle ;
250
+
251
+ if ( gameWindowHandle == IntPtr . Zero ||
249
252
// Ignore console window
250
- gameProcess . MainWindowTitle . StartsWith ( "BepInEx" ) ||
251
- gameProcess . MainWindowTitle . StartsWith ( "Select BepInEx" ) )
253
+ gameWindowTitle . StartsWith ( "BepInEx" ) ||
254
+ gameWindowTitle . StartsWith ( "Select BepInEx" ) )
252
255
{
253
256
// Need to refresh the process if the window handle is not yet valid or it will keep grabbing the old one
257
+ _mainForm . TopMost = false ;
254
258
gameProcess . Refresh ( ) ;
255
259
continue ;
256
260
}
257
261
258
262
// Detect Unity's pre-launch resoultion and hotkey configuration window and hide the splash until it is closed
259
263
// It seems like it's not possible to localize this window so the title check should be fine? Hopefully?
260
- if ( gameProcess . MainWindowTitle . EndsWith ( " Configuration" ) )
264
+ if ( gameWindowTitle . EndsWith ( " Configuration" ) )
261
265
{
262
266
_mainForm . Visible = false ;
267
+ _mainForm . TopMost = false ;
263
268
temporarilyHidden = true ;
264
269
gameProcess . Refresh ( ) ;
265
270
continue ;
@@ -271,13 +276,13 @@ private static void SnapPositionToGameWindowThread(object processArg)
271
276
_mainForm . Visible = true ;
272
277
}
273
278
274
- if ( ! NativeMethods . GetWindowRect ( new HandleRef ( _mainForm , gameProcess . MainWindowHandle ) , out var rct ) )
279
+ if ( ! NativeMethods . GetWindowRect ( new HandleRef ( _mainForm , gameWindowHandle ) , out var rct ) )
275
280
throw new InvalidOperationException ( "GetWindowRect failed :(" ) ;
276
281
277
282
var foregroundWindow = NativeMethods . GetForegroundWindow ( ) ;
278
283
// The main game window is not responding most of the time, which prevents it from being recognized as the foreground window
279
284
// To work around this, check if the currently focused window is the splash window, as it will most likely be the last focused window after user clicks on the game window
280
- _mainForm . TopMost = gameProcess . MainWindowHandle == foregroundWindow || _mainForm . Handle == foregroundWindow ;
285
+ _mainForm . TopMost = gameWindowHandle == foregroundWindow || NativeMethods . IsBorderless ( gameWindowHandle ) ;
281
286
282
287
// Just in case, don't want to mangle the splash
283
288
if ( default ( NativeMethods . RECT ) . Equals ( rct ) )
@@ -327,6 +332,22 @@ public struct RECT
327
332
328
333
[ DllImport ( "user32.dll" , CharSet = CharSet . Auto , ExactSpelling = true ) ]
329
334
public static extern IntPtr GetForegroundWindow ( ) ;
335
+
336
+ [ DllImport ( "user32.dll" ) ]
337
+ private static extern int GetWindowLong ( IntPtr hWnd , int nIndex ) ;
338
+
339
+ private static int GWL_STYLE = - 16 ;
340
+ private static int WS_BORDER = 0x00800000 ; //window with border
341
+ private static int WS_DLGFRAME = 0x00400000 ; //window with double border but no title
342
+ private static int WS_CAPTION = WS_BORDER | WS_DLGFRAME ; //window with a title bar
343
+ private static int WS_SYSMENU = 0x00080000 ; //window menu
344
+
345
+ public static bool IsBorderless ( IntPtr windowPtr )
346
+ {
347
+ int style = GetWindowLong ( windowPtr , GWL_STYLE ) ;
348
+
349
+ return ( style & WS_CAPTION ) == 0 && ( style & WS_SYSMENU ) == 0 ;
350
+ }
330
351
}
331
352
332
353
#endregion
0 commit comments