Merge pull request #88852 from bruvzg/borderless_hack

[Windows] Remove visible WINDOW_MODE_FULLSCREEN border by setting window region.
This commit is contained in:
Thaddeus Crews 2025-03-11 16:54:08 -05:00
commit 1aefcf77af
No known key found for this signature in database
GPG key ID: 62181B86FE9E5D84
2 changed files with 83 additions and 78 deletions

View file

@ -2126,7 +2126,6 @@
Full screen mode with full multi-window support. Full screen mode with full multi-window support.
Full screen window covers the entire display area of a screen and has no decorations. The display's video mode is not changed. Full screen window covers the entire display area of a screen and has no decorations. The display's video mode is not changed.
[b]On Android:[/b] This enables immersive mode. [b]On Android:[/b] This enables immersive mode.
[b]On Windows:[/b] Multi-window full-screen mode has a 1px border of the [member ProjectSettings.rendering/environment/defaults/default_clear_color] color.
[b]On macOS:[/b] A new desktop is used to display the running project. [b]On macOS:[/b] A new desktop is used to display the running project.
[b]Note:[/b] Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode. [b]Note:[/b] Regardless of the platform, enabling full screen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling full screen mode.
</constant> </constant>

View file

@ -32,6 +32,7 @@
#include "drop_target_windows.h" #include "drop_target_windows.h"
#include "os_windows.h" #include "os_windows.h"
#include "scene/main/window.h"
#include "wgl_detect_version.h" #include "wgl_detect_version.h"
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
@ -83,6 +84,8 @@
#define WM_INDICATOR_CALLBACK_MESSAGE (WM_USER + 1) #define WM_INDICATOR_CALLBACK_MESSAGE (WM_USER + 1)
int constexpr FS_TRANSP_BORDER = 2;
static String format_error_message(DWORD id) { static String format_error_message(DWORD id) {
LPWSTR messageBuffer = nullptr; LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
@ -167,8 +170,11 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
WindowData &wd = windows[window_id]; WindowData &wd = windows[window_id];
int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
RECT clipRect; RECT clipRect;
GetClientRect(wd.hWnd, &clipRect); GetClientRect(wd.hWnd, &clipRect);
clipRect.right -= off_x;
ClientToScreen(wd.hWnd, (POINT *)&clipRect.left); ClientToScreen(wd.hWnd, (POINT *)&clipRect.left);
ClientToScreen(wd.hWnd, (POINT *)&clipRect.right); ClientToScreen(wd.hWnd, (POINT *)&clipRect.right);
ClipCursor(&clipRect); ClipCursor(&clipRect);
@ -1925,23 +1931,37 @@ void DisplayServerWindows::window_set_mouse_passthrough(const Vector<Vector2> &p
void DisplayServerWindows::_update_window_mouse_passthrough(WindowID p_window) { void DisplayServerWindows::_update_window_mouse_passthrough(WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window)); ERR_FAIL_COND(!windows.has(p_window));
if (windows[p_window].mpass || windows[p_window].mpath.size() == 0) {
SetWindowRgn(windows[p_window].hWnd, nullptr, FALSE);
} else {
POINT *points = (POINT *)memalloc(sizeof(POINT) * windows[p_window].mpath.size());
for (int i = 0; i < windows[p_window].mpath.size(); i++) {
if (windows[p_window].borderless) {
points[i].x = windows[p_window].mpath[i].x;
points[i].y = windows[p_window].mpath[i].y;
} else {
points[i].x = windows[p_window].mpath[i].x + GetSystemMetrics(SM_CXSIZEFRAME);
points[i].y = windows[p_window].mpath[i].y + GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
}
}
HRGN region = CreatePolygonRgn(points, windows[p_window].mpath.size(), ALTERNATE); const WindowData &wd = windows[p_window];
SetWindowRgn(windows[p_window].hWnd, region, FALSE); bool clip_pixel = (wd.multiwindow_fs || (wd.borderless && wd.maximized));
memfree(points); bool pass_set = (wd.mpath.size() > 0);
if (!clip_pixel && !pass_set) {
SetWindowRgn(wd.hWnd, nullptr, TRUE);
} else {
HRGN region = nullptr;
if (pass_set) {
Vector<POINT> points;
points.resize(wd.mpath.size());
POINT *points_ptr = points.ptrw();
for (int i = 0; i < wd.mpath.size(); i++) {
if (wd.borderless) {
points_ptr[i].x = wd.mpath[i].x;
points_ptr[i].y = wd.mpath[i].y;
} else {
points_ptr[i].x = wd.mpath[i].x + GetSystemMetrics(SM_CXSIZEFRAME);
points_ptr[i].y = wd.mpath[i].y + GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
}
}
region = CreatePolygonRgn(points.ptr(), points.size(), ALTERNATE);
} else {
region = CreateRectRgn(0, 0, wd.width, wd.height);
}
if (clip_pixel) {
HRGN region_clip = CreateRectRgn(0, 0, wd.width, wd.height);
CombineRgn(region, region, region_clip, RGN_AND);
DeleteObject(region_clip);
}
SetWindowRgn(wd.hWnd, region, FALSE);
} }
} }
@ -1972,14 +1992,16 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
if (wd.fullscreen) { if (wd.fullscreen) {
Point2 pos = screen_get_position(p_screen) + _get_screens_origin(); Point2 pos = screen_get_position(p_screen) + _get_screens_origin();
Size2 size = screen_get_size(p_screen); Size2 size = screen_get_size(p_screen);
int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); MoveWindow(wd.hWnd, pos.x, pos.y, size.width + off_x, size.height, TRUE);
} else if (wd.maximized) { } else if (wd.maximized) {
Point2 pos = screen_get_position(p_screen) + _get_screens_origin(); Point2 pos = screen_get_position(p_screen) + _get_screens_origin();
Size2 size = screen_get_size(p_screen); Size2 size = screen_get_size(p_screen);
int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
ShowWindow(wd.hWnd, SW_RESTORE); ShowWindow(wd.hWnd, SW_RESTORE);
MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); MoveWindow(wd.hWnd, pos.x, pos.y, size.width + off_x, size.height, TRUE);
ShowWindow(wd.hWnd, SW_MAXIMIZE); ShowWindow(wd.hWnd, SW_MAXIMIZE);
} else { } else {
Rect2i srect = screen_get_usable_rect(p_screen); Rect2i srect = screen_get_usable_rect(p_screen);
@ -2228,7 +2250,8 @@ Size2i DisplayServerWindows::window_get_size(WindowID p_window) const {
RECT r; RECT r;
if (GetClientRect(wd.hWnd, &r)) { // Retrieves area inside of window border, including decoration. if (GetClientRect(wd.hWnd, &r)) { // Retrieves area inside of window border, including decoration.
return Size2(r.right - r.left, r.bottom - r.top); int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
return Size2(r.right - r.left - off_x, r.bottom - r.top);
} }
return Size2(); return Size2();
} }
@ -2241,7 +2264,8 @@ Size2i DisplayServerWindows::window_get_size_with_decorations(WindowID p_window)
RECT r; RECT r;
if (GetWindowRect(wd.hWnd, &r)) { // Retrieves area inside of window border, including decoration. if (GetWindowRect(wd.hWnd, &r)) { // Retrieves area inside of window border, including decoration.
return Size2(r.right - r.left, r.bottom - r.top); int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
return Size2(r.right - r.left - off_x, r.bottom - r.top);
} }
return Size2(); return Size2();
} }
@ -2280,9 +2304,6 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_initiali
r_style |= WS_MAXIMIZEBOX; r_style |= WS_MAXIMIZEBOX;
} }
} }
if ((p_fullscreen && p_multiwindow_fs) || p_maximized_fs) {
r_style |= WS_BORDER; // Allows child windows to be displayed on top of full screen.
}
} else { } else {
if (p_resizable) { if (p_resizable) {
if (p_minimized) { if (p_minimized) {
@ -2340,8 +2361,8 @@ void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repain
if (p_repaint) { if (p_repaint) {
RECT rect; RECT rect;
GetWindowRect(wd.hWnd, &rect); GetWindowRect(wd.hWnd, &rect);
int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left + off_x, rect.bottom - rect.top, TRUE);
} }
} }
@ -2359,6 +2380,10 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
bool was_fullscreen = wd.fullscreen; bool was_fullscreen = wd.fullscreen;
wd.was_fullscreen_pre_min = false; wd.was_fullscreen_pre_min = false;
if (p_mode == WINDOW_MODE_MAXIMIZED && wd.borderless) {
p_mode = WINDOW_MODE_FULLSCREEN;
}
if (wd.fullscreen && p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { if (wd.fullscreen && p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
RECT rect; RECT rect;
@ -2410,11 +2435,10 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
if (p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { if (p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
wd.multiwindow_fs = false; wd.multiwindow_fs = false;
_update_window_style(p_window, false); } else if (p_mode == WINDOW_MODE_FULLSCREEN) {
} else {
wd.multiwindow_fs = true; wd.multiwindow_fs = true;
_update_window_style(p_window, false);
} }
_update_window_style(p_window, false);
if ((p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) && !wd.fullscreen) { if ((p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) && !wd.fullscreen) {
if (wd.minimized || wd.maximized) { if (wd.minimized || wd.maximized) {
@ -2440,7 +2464,8 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
_update_window_style(p_window, false); _update_window_style(p_window, false);
MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); int off_x = (wd.multiwindow_fs || (!wd.fullscreen && wd.borderless && wd.maximized)) ? FS_TRANSP_BORDER : 0;
MoveWindow(wd.hWnd, pos.x, pos.y, size.width + off_x, size.height, TRUE);
// If the user has mouse trails enabled in windows, then sometimes the cursor disappears in fullscreen mode. // If the user has mouse trails enabled in windows, then sometimes the cursor disappears in fullscreen mode.
// Save number of trails so we can restore when exiting, then turn off mouse trails // Save number of trails so we can restore when exiting, then turn off mouse trails
@ -2449,6 +2474,7 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, nullptr, 0); SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, nullptr, 0);
} }
} }
_update_window_mouse_passthrough(p_window);
} }
DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_window) const { DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_window) const {
@ -2498,8 +2524,8 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
} break; } break;
case WINDOW_FLAG_BORDERLESS: { case WINDOW_FLAG_BORDERLESS: {
wd.borderless = p_enabled; wd.borderless = p_enabled;
_update_window_style(p_window);
_update_window_mouse_passthrough(p_window); _update_window_mouse_passthrough(p_window);
_update_window_style(p_window);
ShowWindow(wd.hWnd, (wd.no_focus || wd.is_popup) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show the window. ShowWindow(wd.hWnd, (wd.no_focus || wd.is_popup) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show the window.
} break; } break;
case WINDOW_FLAG_ALWAYS_ON_TOP: { case WINDOW_FLAG_ALWAYS_ON_TOP: {
@ -2550,7 +2576,6 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
} break; } break;
case WINDOW_FLAG_MOUSE_PASSTHROUGH: { case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
wd.mpass = p_enabled; wd.mpass = p_enabled;
_update_window_mouse_passthrough(p_window);
} break; } break;
case WINDOW_FLAG_EXCLUDE_FROM_CAPTURE: { case WINDOW_FLAG_EXCLUDE_FROM_CAPTURE: {
wd.hide_from_capture = p_enabled; wd.hide_from_capture = p_enabled;
@ -4529,30 +4554,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
SendMessageW(windows[window_id].hWnd, WM_PAINT, 0, 0); SendMessageW(windows[window_id].hWnd, WM_PAINT, 0, 0);
} }
} break; } break;
case WM_NCPAINT: {
if (RenderingServer::get_singleton() && (windows[window_id].borderless || (windows[window_id].fullscreen && windows[window_id].multiwindow_fs))) {
Color color = RenderingServer::get_singleton()->get_default_clear_color();
HDC hdc = GetWindowDC(hWnd);
if (hdc) {
HPEN pen = CreatePen(PS_SOLID, 1, RGB(color.r * 255.f, color.g * 255.f, color.b * 255.f));
if (pen) {
HGDIOBJ prev_pen = SelectObject(hdc, pen);
HGDIOBJ prev_brush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
RECT rc;
GetWindowRect(hWnd, &rc);
OffsetRect(&rc, -rc.left, -rc.top);
Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(hdc, prev_pen);
SelectObject(hdc, prev_brush);
DeleteObject(pen);
}
ReleaseDC(hWnd, hdc);
}
return 0;
}
} break;
case WM_NCHITTEST: { case WM_NCHITTEST: {
if (windows[window_id].mpass) { if (windows[window_id].mpass) {
return HTTRANSPARENT; return HTTRANSPARENT;
@ -5558,6 +5559,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break; } break;
case WM_WINDOWPOSCHANGED: { case WM_WINDOWPOSCHANGED: {
WindowData &window = windows[window_id];
int off_x = (window.multiwindow_fs || (!window.fullscreen && window.borderless && IsZoomed(hWnd))) ? FS_TRANSP_BORDER : 0;
Rect2i window_client_rect; Rect2i window_client_rect;
Rect2i window_rect; Rect2i window_rect;
{ {
@ -5565,17 +5569,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
GetClientRect(hWnd, &rect); GetClientRect(hWnd, &rect);
ClientToScreen(hWnd, (POINT *)&rect.left); ClientToScreen(hWnd, (POINT *)&rect.left);
ClientToScreen(hWnd, (POINT *)&rect.right); ClientToScreen(hWnd, (POINT *)&rect.right);
window_client_rect = Rect2i(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); window_client_rect = Rect2i(rect.left, rect.top, rect.right - rect.left - off_x, rect.bottom - rect.top);
window_client_rect.position -= _get_screens_origin(); window_client_rect.position -= _get_screens_origin();
RECT wrect; RECT wrect;
GetWindowRect(hWnd, &wrect); GetWindowRect(hWnd, &wrect);
window_rect = Rect2i(wrect.left, wrect.top, wrect.right - wrect.left, wrect.bottom - wrect.top); window_rect = Rect2i(wrect.left, wrect.top, wrect.right - wrect.left - off_x, wrect.bottom - wrect.top);
window_rect.position -= _get_screens_origin(); window_rect.position -= _get_screens_origin();
} }
WINDOWPOS *window_pos_params = (WINDOWPOS *)lParam; WINDOWPOS *window_pos_params = (WINDOWPOS *)lParam;
WindowData &window = windows[window_id];
bool rect_changed = false; bool rect_changed = false;
if (!(window_pos_params->flags & SWP_NOSIZE) || window_pos_params->flags & SWP_FRAMECHANGED) { if (!(window_pos_params->flags & SWP_NOSIZE) || window_pos_params->flags & SWP_FRAMECHANGED) {
@ -5644,6 +5647,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
RECT crect; RECT crect;
GetClientRect(window.hWnd, &crect); GetClientRect(window.hWnd, &crect);
crect.right -= off_x;
ClientToScreen(window.hWnd, (POINT *)&crect.left); ClientToScreen(window.hWnd, (POINT *)&crect.left);
ClientToScreen(window.hWnd, (POINT *)&crect.right); ClientToScreen(window.hWnd, (POINT *)&crect.right);
ClipCursor(&crect); ClipCursor(&crect);
@ -6109,26 +6113,29 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
_get_window_style(window_id_counter == MAIN_WINDOW_ID, false, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MINIMIZED, p_mode == WINDOW_MODE_MAXIMIZED, false, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), p_parent_hwnd, dwStyle, dwExStyle); _get_window_style(window_id_counter == MAIN_WINDOW_ID, false, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MINIMIZED, p_mode == WINDOW_MODE_MAXIMIZED, false, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), p_parent_hwnd, dwStyle, dwExStyle);
RECT WindowRect;
WindowRect.left = p_rect.position.x;
WindowRect.right = p_rect.position.x + p_rect.size.x;
WindowRect.top = p_rect.position.y;
WindowRect.bottom = p_rect.position.y + p_rect.size.y;
int rq_screen = get_screen_from_rect(p_rect); int rq_screen = get_screen_from_rect(p_rect);
if (rq_screen < 0) { if (rq_screen < 0) {
rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds. rq_screen = get_primary_screen(); // Requested window rect is outside any screen bounds.
} }
Rect2i usable_rect = screen_get_usable_rect(rq_screen);
Point2i offset = _get_screens_origin(); Point2i offset = _get_screens_origin();
RECT WindowRect;
int off_x = (p_mode == WINDOW_MODE_FULLSCREEN || ((p_flags & WINDOW_FLAG_BORDERLESS_BIT) && p_mode == WINDOW_MODE_MAXIMIZED)) ? FS_TRANSP_BORDER : 0;
WindowRect.left = p_rect.position.x;
WindowRect.right = p_rect.position.x + p_rect.size.x + off_x;
WindowRect.top = p_rect.position.y;
WindowRect.bottom = p_rect.position.y + p_rect.size.y;
if (!p_parent_hwnd) { if (!p_parent_hwnd) {
if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen)); Rect2i screen_rect = Rect2i(screen_get_position(rq_screen), screen_get_size(rq_screen));
WindowRect.left = screen_rect.position.x; WindowRect.left = screen_rect.position.x;
WindowRect.right = screen_rect.position.x + screen_rect.size.x; WindowRect.right = screen_rect.position.x + screen_rect.size.x + off_x;
WindowRect.top = screen_rect.position.y; WindowRect.top = screen_rect.position.y;
WindowRect.bottom = screen_rect.position.y + screen_rect.size.y; WindowRect.bottom = screen_rect.position.y + screen_rect.size.y;
} else { } else {
@ -6139,7 +6146,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
} }
WindowRect.left = wpos.x; WindowRect.left = wpos.x;
WindowRect.right = wpos.x + p_rect.size.x; WindowRect.right = wpos.x + p_rect.size.x + off_x;
WindowRect.top = wpos.y; WindowRect.top = wpos.y;
WindowRect.bottom = wpos.y + p_rect.size.y; WindowRect.bottom = wpos.y + p_rect.size.y;
} }
@ -6277,7 +6284,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
return INVALID_WINDOW_ID; return INVALID_WINDOW_ID;
} }
rendering_context->window_set_size(id, real_client_rect.right - real_client_rect.left, real_client_rect.bottom - real_client_rect.top); rendering_context->window_set_size(id, real_client_rect.right - real_client_rect.left - off_x, real_client_rect.bottom - real_client_rect.top);
rendering_context->window_set_vsync_mode(id, p_vsync_mode); rendering_context->window_set_vsync_mode(id, p_vsync_mode);
wd.context_created = true; wd.context_created = true;
} }
@ -6285,7 +6292,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
#ifdef GLES3_ENABLED #ifdef GLES3_ENABLED
if (gl_manager_native) { if (gl_manager_native) {
if (gl_manager_native->window_create(id, wd.hWnd, hInstance, real_client_rect.right - real_client_rect.left, real_client_rect.bottom - real_client_rect.top) != OK) { if (gl_manager_native->window_create(id, wd.hWnd, hInstance, real_client_rect.right - real_client_rect.left - off_x, real_client_rect.bottom - real_client_rect.top) != OK) {
memdelete(gl_manager_native); memdelete(gl_manager_native);
gl_manager_native = nullptr; gl_manager_native = nullptr;
windows.erase(id); windows.erase(id);
@ -6295,7 +6302,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
} }
if (gl_manager_angle) { if (gl_manager_angle) {
if (gl_manager_angle->window_create(id, nullptr, wd.hWnd, real_client_rect.right - real_client_rect.left, real_client_rect.bottom - real_client_rect.top) != OK) { if (gl_manager_angle->window_create(id, nullptr, wd.hWnd, real_client_rect.right - real_client_rect.left - off_x, real_client_rect.bottom - real_client_rect.top) != OK) {
memdelete(gl_manager_angle); memdelete(gl_manager_angle);
gl_manager_angle = nullptr; gl_manager_angle = nullptr;
windows.erase(id); windows.erase(id);
@ -6390,7 +6397,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
ClientToScreen(wd.hWnd, (POINT *)&r.left); ClientToScreen(wd.hWnd, (POINT *)&r.left);
ClientToScreen(wd.hWnd, (POINT *)&r.right); ClientToScreen(wd.hWnd, (POINT *)&r.right);
wd.last_pos = Point2i(r.left, r.top) - _get_screens_origin(); wd.last_pos = Point2i(r.left, r.top) - _get_screens_origin();
wd.width = r.right - r.left; wd.width = r.right - r.left - off_x;
wd.height = r.bottom - r.top; wd.height = r.bottom - r.top;
} else { } else {
wd.last_pos = p_rect.position; wd.last_pos = p_rect.position;
@ -6398,13 +6405,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
wd.height = p_rect.size.height; wd.height = p_rect.size.height;
} }
// Set size of maximized borderless window (by default it covers the entire screen).
if (p_mode == WINDOW_MODE_MAXIMIZED && (p_flags & WINDOW_FLAG_BORDERLESS_BIT)) {
Rect2i srect = screen_get_usable_rect(rq_screen);
SetWindowPos(wd.hWnd, HWND_TOP, srect.position.x, srect.position.y, srect.size.width, srect.size.height, SWP_NOZORDER | SWP_NOACTIVATE);
}
wd.create_completed = true; wd.create_completed = true;
// Set size of maximized borderless window (by default it covers the entire screen).
if (!p_parent_hwnd && p_mode == WINDOW_MODE_MAXIMIZED && (p_flags & WINDOW_FLAG_BORDERLESS_BIT)) {
SetWindowPos(wd.hWnd, HWND_TOP, usable_rect.position.x - off_x, usable_rect.position.y, usable_rect.size.width + off_x, usable_rect.size.height, SWP_NOZORDER | SWP_NOACTIVATE);
}
_update_window_mouse_passthrough(id);
window_id_counter++; window_id_counter++;
} }