_borderless maximize workarounds WIP
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
|
||||
#define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
|
||||
#define BORDERLESS_MAXIMIZE_WORKAROUND 2
|
||||
#if USE_EDITOR
|
||||
#include <oleidl.h>
|
||||
#endif
|
||||
@@ -39,6 +41,9 @@ namespace
|
||||
{
|
||||
SDLWindow* LastEventWindow = nullptr;
|
||||
static SDL_Cursor* Cursors[SDL_SYSTEM_CURSOR_COUNT] = { nullptr };
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 2
|
||||
int SkipMaximizeEventsCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* GetNativeWindowPointer(SDL_Window* window);
|
||||
@@ -548,11 +553,38 @@ void SDLWindow::HandleEvent(SDL_Event& event)
|
||||
_maximized = true;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
// This shouldn't be needed anymore, but maximize blocks any resize operations
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 2
|
||||
if (SkipMaximizeEventsCount > 0)
|
||||
{
|
||||
SkipMaximizeEventsCount--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_settings.HasBorder && _settings.HasSizingFrame)
|
||||
{
|
||||
// Restore the window back to previous state
|
||||
SDL_RestoreWindow(_window);
|
||||
|
||||
// Remove the resizable flags from borderless windows and maximize the window again
|
||||
auto style = ::GetWindowLong((HWND)_handle, GWL_STYLE);
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
SDL_MaximizeWindow(_window);
|
||||
|
||||
// Re-enable the resizable borderless flags
|
||||
style = ::GetWindowLong((HWND)_handle, GWL_STYLE) | STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
// The next SDL_EVENT_WINDOW_RESTORED and SDL_EVENT_WINDOW_MAXIMIZED events should be ignored
|
||||
SkipMaximizeEventsCount = 2;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (false && !_settings.HasBorder && _settings.HasSizingFrame)
|
||||
{
|
||||
// Borderless editor window doesn't maximize properly,
|
||||
// manually force the window into correct location and size.
|
||||
// force the fullscreen window into correct location and size.
|
||||
SDL_Rect rect;
|
||||
SDL_DisplayID display = SDL_GetDisplayForWindow(_window);
|
||||
SDL_GetDisplayUsableBounds(display, &rect); // Excludes taskbar etc.
|
||||
@@ -562,11 +594,9 @@ void SDLWindow::HandleEvent(SDL_Event& event)
|
||||
auto size = GetClientSize();
|
||||
if (pos.X < rect.x || pos.Y < rect.y || size.X > rect.w || size.Y > rect.h)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
|
||||
// Set the internal floating window rectangle to expected position
|
||||
// NOTE: Currently the resize operations are blocked while window is in maximized state
|
||||
SetClientBounds(Rectangle((float)rect.x, (float)rect.y, (float)rect.w, (float)rect.h));
|
||||
_cachedClientRectangle.Size = Float2((float)rect.w, (float)rect.h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -575,6 +605,14 @@ void SDLWindow::HandleEvent(SDL_Event& event)
|
||||
}
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
{
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 2
|
||||
if (SkipMaximizeEventsCount > 0)
|
||||
{
|
||||
SkipMaximizeEventsCount--;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_maximized)
|
||||
{
|
||||
_maximized = false;
|
||||
@@ -786,7 +824,19 @@ void SDLWindow::Maximize()
|
||||
if (!_settings.AllowMaximize)
|
||||
return;
|
||||
|
||||
#if PLATFORM_WINDOWS && BORDERLESS_MAXIMIZE_WORKAROUND == 1
|
||||
// Workaround for "SDL_BORDERLESS_RESIZABLE_STYLE" hint not working as expected when maximizing windows
|
||||
auto style = ::GetWindowLong((HWND)_handle, GWL_STYLE);
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
SDL_MaximizeWindow(_window);
|
||||
|
||||
style = ::GetWindowLong((HWND)_handle, GWL_STYLE) | STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
#else
|
||||
SDL_MaximizeWindow(_window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDLWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
@@ -806,7 +856,9 @@ void SDLWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
{
|
||||
SDL_SetWindowBordered(_window, !isBorderless ? true : false);
|
||||
if (maximized)
|
||||
SDL_MaximizeWindow(_window);
|
||||
{
|
||||
Maximize();
|
||||
}
|
||||
else
|
||||
Focus();
|
||||
}
|
||||
@@ -814,7 +866,9 @@ void SDLWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
{
|
||||
SDL_SetWindowBordered(_window, !isBorderless ? true : false);
|
||||
if (maximized)
|
||||
SDL_MaximizeWindow(_window);
|
||||
{
|
||||
Maximize();
|
||||
}
|
||||
else
|
||||
Focus();
|
||||
}
|
||||
@@ -824,7 +878,19 @@ void SDLWindow::SetBorderless(bool isBorderless, bool maximized)
|
||||
|
||||
void SDLWindow::Restore()
|
||||
{
|
||||
#if PLATFORM_WINDOWS && BORDERLESS_MAXIMIZE_WORKAROUND == 1
|
||||
// Workaround for "SDL_BORDERLESS_RESIZABLE_STYLE" hint not working as expected when maximizing windows
|
||||
auto style = ::GetWindowLong((HWND)_handle, GWL_STYLE);
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
SDL_RestoreWindow(_window);
|
||||
|
||||
style = ::GetWindowLong((HWND)_handle, GWL_STYLE) | STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
#else
|
||||
SDL_RestoreWindow(_window);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SDLWindow::IsClosed() const
|
||||
|
||||
Reference in New Issue
Block a user