mirror of
https://github.com/glfw/glfw.git
synced 2024-11-14 18:34:34 +00:00
Partially merged from MohitSethi99/glfw with modifications
- Still some problems and not super happy with this partially decorated frame - Tested on Win 10 and 11, client area top + resize handle is not perfect - Also client area seems to be different on frame 0
This commit is contained in:
commit
c186bef662
10
premake5.lua
10
premake5.lua
@ -2,6 +2,7 @@ project "GLFW"
|
||||
kind "StaticLib"
|
||||
language "C"
|
||||
staticruntime "off"
|
||||
warnings "off"
|
||||
|
||||
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
|
||||
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
|
||||
@ -37,6 +38,7 @@ project "GLFW"
|
||||
"src/x11_monitor.c",
|
||||
"src/x11_window.c",
|
||||
"src/xkb_unicode.c",
|
||||
"src/posix_module.c",
|
||||
"src/posix_time.c",
|
||||
"src/posix_thread.c",
|
||||
"src/posix_module.c",
|
||||
@ -102,9 +104,9 @@ project "GLFW"
|
||||
|
||||
filter "configurations:Release"
|
||||
runtime "Release"
|
||||
optimize "on"
|
||||
optimize "speed"
|
||||
|
||||
filter "configurations:Dist"
|
||||
filter "configurations:Dist"
|
||||
runtime "Release"
|
||||
optimize "on"
|
||||
symbols "off"
|
||||
optimize "speed"
|
||||
symbols "off"
|
||||
|
@ -490,7 +490,8 @@ static void releaseMonitor(_GLFWwindow* window)
|
||||
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static RECT border_thickness;
|
||||
static RECT border_thickness = { 4, 4, 4, 4 };
|
||||
BOOL hasThickFrame = GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME;
|
||||
|
||||
_GLFWwindow* window = GetPropW(hWnd, L"GLFW");
|
||||
if (!window)
|
||||
@ -548,22 +549,21 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (_glfw.hints.window.titlebar)
|
||||
break;
|
||||
|
||||
//find border thickness
|
||||
SetRectEmpty(&border_thickness);
|
||||
if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME)
|
||||
if (hasThickFrame)
|
||||
{
|
||||
AdjustWindowRectEx(&border_thickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, 0);
|
||||
border_thickness.left *= -1;
|
||||
border_thickness.top *= -1;
|
||||
}
|
||||
else// if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_BORDER)
|
||||
{
|
||||
SetRect(&border_thickness, 4, 4, 4, 4);
|
||||
}
|
||||
RECT size_rect;
|
||||
GetWindowRect(hWnd, &size_rect);
|
||||
|
||||
MARGINS margins = { 0 };
|
||||
DwmExtendFrameIntoClientArea(hWnd, &margins);
|
||||
SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
|
||||
// Inform the application of the frame change to force redrawing with the new
|
||||
// client area that is extended into the title bar
|
||||
SetWindowPos(
|
||||
hWnd, NULL,
|
||||
size_rect.left, size_rect.top,
|
||||
size_rect.right - size_rect.left, size_rect.bottom - size_rect.top,
|
||||
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -573,15 +573,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (_glfw.hints.window.titlebar)
|
||||
break;
|
||||
|
||||
// Extend the frame into the client area.
|
||||
MARGINS margins = { 0 };
|
||||
auto hr = DwmExtendFrameIntoClientArea(hWnd, &margins);
|
||||
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
// Handle the error.
|
||||
}
|
||||
|
||||
RECT title_bar_rect = {0};
|
||||
InvalidateRect(hWnd, &title_bar_rect, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1013,16 +1006,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
if (_glfw.hints.window.titlebar)
|
||||
break;
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
if (_glfw.hints.window.titlebar || !hasThickFrame || !wParam)
|
||||
break;
|
||||
|
||||
if (lParam)
|
||||
return 0;
|
||||
// For custom frames
|
||||
|
||||
// Shrink client area by border thickness so we can
|
||||
// resize window and see borders
|
||||
const int resizeBorderX = GetSystemMetrics(SM_CXFRAME);
|
||||
const int resizeBorderY = GetSystemMetrics(SM_CYFRAME);
|
||||
|
||||
NCCALCSIZE_PARAMS* params = (NCCALCSIZE_PARAMS*)lParam;
|
||||
RECT* requestedClientRect = params->rgrc;
|
||||
|
||||
requestedClientRect->right -= resizeBorderX;
|
||||
requestedClientRect->left += resizeBorderX;
|
||||
requestedClientRect->bottom -= resizeBorderY;
|
||||
|
||||
//
|
||||
// NOTE(Yan):
|
||||
//
|
||||
// Top borders seem to be handled differently.
|
||||
//
|
||||
// Contracting by 1 on Win 11 seems to give a small area
|
||||
// for resizing whilst not showing a white border.
|
||||
//
|
||||
// But this doesn't seem to work on Win 10, instead showing
|
||||
// a general white titlebar on top of the custom one...
|
||||
// to be continued.
|
||||
//
|
||||
// Not changing the top (i.e. 0) means we don't see the
|
||||
// mouse icon change to a resize handle, but resizing still
|
||||
// works once you click and drag. This works on both
|
||||
// Windows 10 & 11, so we'll keep that for now.
|
||||
requestedClientRect->top += 0;
|
||||
|
||||
// NOTE(Yan): seems to make no difference what we return here,
|
||||
// was originally 0
|
||||
return WVR_ALIGNTOP | WVR_ALIGNLEFT;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_SIZE:
|
||||
{
|
||||
const int width = LOWORD(lParam);
|
||||
@ -1063,6 +1088,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
|
||||
window->win32.iconified = iconified;
|
||||
window->win32.maximized = maximized;
|
||||
|
||||
RECT size_rect;
|
||||
GetWindowRect(hWnd, &size_rect);
|
||||
|
||||
// Inform the application of the frame change to force redrawing with the new
|
||||
// client area that is extended into the title bar
|
||||
SetWindowPos(
|
||||
hWnd, NULL,
|
||||
size_rect.left, size_rect.top,
|
||||
size_rect.right - size_rect.left, size_rect.bottom - size_rect.top,
|
||||
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1271,54 +1308,57 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
if (_glfw.hints.window.titlebar)
|
||||
break;
|
||||
|
||||
// Extend the frame into the client area.
|
||||
MARGINS margins = { 0 };
|
||||
auto hr = DwmExtendFrameIntoClientArea(hWnd, &margins);
|
||||
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
// Handle the error.
|
||||
}
|
||||
|
||||
break;
|
||||
RECT title_bar_rect = { 0 };
|
||||
InvalidateRect(hWnd, &title_bar_rect, FALSE);
|
||||
}
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
if (_glfw.hints.window.titlebar)
|
||||
if (_glfw.hints.window.titlebar || !hasThickFrame)
|
||||
break;
|
||||
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
ScreenToClient(hWnd, &pt);
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
//
|
||||
// Hit test for custom frames
|
||||
//
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
ScreenToClient(hWnd, &pt);
|
||||
|
||||
int titlebarHittest = 0;
|
||||
_glfwInputTitleBarHitTest(window, pt.x, pt.y, &titlebarHittest);
|
||||
// Check borders first
|
||||
if (!window->win32.maximized)
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
|
||||
if (titlebarHittest)
|
||||
{
|
||||
return HTCAPTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
enum { left = 1, top = 2, right = 4, bottom = 8 };
|
||||
int hit = 0;
|
||||
if (pt.x < border_thickness.left) hit |= left;
|
||||
if (pt.x > rc.right - border_thickness.right) hit |= right;
|
||||
if (pt.y < border_thickness.top) hit |= top;
|
||||
if (pt.y > rc.bottom - border_thickness.bottom) hit |= bottom;
|
||||
const int verticalBorderSize = GetSystemMetrics(SM_CYFRAME);
|
||||
|
||||
if (hit & top && hit & left) return HTTOPLEFT;
|
||||
if (hit & top && hit & right) return HTTOPRIGHT;
|
||||
if (hit & bottom && hit & left) return HTBOTTOMLEFT;
|
||||
if (hit & bottom && hit & right) return HTBOTTOMRIGHT;
|
||||
if (hit & left) return HTLEFT;
|
||||
enum { left = 1, top = 2, right = 4, bottom = 8 };
|
||||
int hit = 0;
|
||||
if (pt.x <= border_thickness.left)
|
||||
hit |= left;
|
||||
if (pt.x >= rc.right - border_thickness.right)
|
||||
hit |= right;
|
||||
if (pt.y <= border_thickness.top || pt.y < verticalBorderSize)
|
||||
hit |= top;
|
||||
if (pt.y >= rc.bottom - border_thickness.bottom)
|
||||
hit |= bottom;
|
||||
|
||||
if (hit & top && hit & left) return HTTOPLEFT;
|
||||
if (hit & top && hit & right) return HTTOPRIGHT;
|
||||
if (hit & bottom && hit & left) return HTBOTTOMLEFT;
|
||||
if (hit & bottom && hit & right) return HTBOTTOMRIGHT;
|
||||
if (hit & left) return HTLEFT;
|
||||
if (hit & top) return HTTOP;
|
||||
if (hit & right) return HTRIGHT;
|
||||
if (hit & bottom) return HTBOTTOM;
|
||||
if (hit & right) return HTRIGHT;
|
||||
if (hit & bottom) return HTBOTTOM;
|
||||
}
|
||||
|
||||
return HTCLIENT;
|
||||
}
|
||||
// Then do client-side test which should determine titlebar bounds
|
||||
int titlebarHittest = 0;
|
||||
_glfwInputTitleBarHitTest(window, pt.x, pt.y, &titlebarHittest);
|
||||
if (titlebarHittest)
|
||||
return HTCAPTION;
|
||||
|
||||
// In client area
|
||||
return HTCLIENT;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user