Simplify borderless window code and improve resizing behavior and style (e.g. dropshadow);

This commit is contained in:
alektron
2024-12-01 08:21:58 -08:00
committed by Ryan Fleury
parent 19fac9b1aa
commit b4cbaa0171
+75 -89
View File
@@ -642,37 +642,32 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_NCCALCSIZE: case WM_NCCALCSIZE:
{ {
if(os_w32_new_window_custom_border || (window && window->custom_border)) if(os_w32_new_window_custom_border || (window && window->custom_border))
{
DWORD window_style = GetWindowLong(hwnd, GWL_STYLE);
B32 window_is_fullscreen = !(window_style & WS_OVERLAPPEDWINDOW);
if(IsZoomed(hwnd) && !window_is_fullscreen)
{ {
F32 dpi = w32_GetDpiForWindow_func ? (F32)w32_GetDpiForWindow_func(hwnd) : 96.f; F32 dpi = w32_GetDpiForWindow_func ? (F32)w32_GetDpiForWindow_func(hwnd) : 96.f;
S32 title_bar_size = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CYCAPTION, dpi) : 0; S32 frame_x = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXFRAME, dpi) : GetSystemMetrics(SM_CXFRAME);
S32 border_lr_size = 0;//w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : 0; S32 frame_y = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME);
S32 border_b_size = 0;//w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : 0; S32 padding = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER);
if(wParam == 1) if (wParam)
{ {
NCCALCSIZE_PARAMS *pncsp = (NCCALCSIZE_PARAMS *)lParam; NCCALCSIZE_PARAMS* params = (NCCALCSIZE_PARAMS*)lParam;
pncsp->rgrc[0].top -= title_bar_size; RECT* rect = params->rgrc;
pncsp->rgrc[0].left += border_lr_size; rect->right -= frame_x + padding;
pncsp->rgrc[0].right -= border_lr_size; rect->left += frame_x + padding;
pncsp->rgrc[0].bottom -= border_b_size; rect->bottom -= frame_y + padding;
if (IsMaximized(hwnd))
{
rect->top += frame_y + padding;
// If we do not do this hidden taskbar can not be unhidden on mouse hover
// Unfortunately it can create an ugly bottom border when maximized...
rect->bottom -= 1;
}
} }
else else
{ {
RECT *rect = (RECT *)lParam; RECT* rect = (RECT*)lParam;
rect->top -= title_bar_size; rect->right -= frame_x + padding;
rect->left += border_lr_size; rect->left += frame_x + padding;
rect->right -= border_lr_size; rect->bottom -= frame_y + padding;
rect->bottom -= border_b_size;
}
result = DefWindowProc(hwnd, uMsg, wParam, lParam);
}
else if(wParam == 1)
{
NCCALCSIZE_PARAMS *pncsp = (NCCALCSIZE_PARAMS *)lParam;
pncsp->rgrc[0].right += 1;
} }
} }
else else
@@ -691,6 +686,27 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
result = DefWindowProcW(hwnd, uMsg, wParam, lParam); result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
} }
else else
{
B32 is_default_handled = 0;
// Let the default procedure handle resizing areas
result = DefWindowProc(hwnd, uMsg, wParam, lParam);
switch (result)
{
case HTNOWHERE:
case HTRIGHT:
case HTLEFT:
case HTTOPLEFT:
case HTTOPRIGHT:
case HTBOTTOMRIGHT:
case HTBOTTOM:
case HTBOTTOMLEFT:
{
is_default_handled = 1;
} break;
}
if (!is_default_handled)
{ {
POINT pos_monitor; POINT pos_monitor;
pos_monitor.x = GET_X_LPARAM(lParam); pos_monitor.x = GET_X_LPARAM(lParam);
@@ -698,49 +714,14 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
POINT pos_client = pos_monitor; POINT pos_client = pos_monitor;
ScreenToClient(hwnd, &pos_client); ScreenToClient(hwnd, &pos_client);
//- rjf: check against window boundaries // Adjustments happening in NCCALCSIZE are messing with the detection
RECT frame_rect; // of the top hit area so manually checking that.
GetWindowRect(hwnd, &frame_rect); F32 dpi = w32_GetDpiForWindow_func ? (F32)w32_GetDpiForWindow_func(hwnd) : 96.f;
B32 is_over_window = (frame_rect.left <= pos_monitor.x && pos_monitor.x < frame_rect.right && S32 frame_y = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME);
frame_rect.top <= pos_monitor.y && pos_monitor.y < frame_rect.bottom); S32 padding = w32_GetSystemMetricsForDpi_func ? w32_GetSystemMetricsForDpi_func(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER);
//- rjf: check against borders B32 is_over_top_resize = pos_client.y >= 0 && pos_client.y < frame_y + padding;
B32 is_over_left = 0; B32 is_over_title_bar = pos_client.y >= 0 && pos_client.y < window->custom_border_title_thickness;
B32 is_over_right = 0;
B32 is_over_top = 0;
B32 is_over_bottom = 0;
{
RECT rect;
GetClientRect(hwnd, &rect);
if(!IsZoomed(hwnd))
{
if(rect.left <= pos_client.x && pos_client.x < rect.left + window->custom_border_edge_thickness)
{
is_over_left = 1;
}
if(rect.right - window->custom_border_edge_thickness <= pos_client.x && pos_client.x < rect.right)
{
is_over_right = 1;
}
if(rect.bottom - window->custom_border_edge_thickness <= pos_client.y && pos_client.y < rect.bottom)
{
is_over_bottom = 1;
}
if(rect.top <= pos_client.y && pos_client.y < rect.top + window->custom_border_edge_thickness)
{
is_over_top = 1;
}
}
}
//- rjf: check against title bar
B32 is_over_title_bar = 0;
{
RECT rect;
GetClientRect(hwnd, &rect);
is_over_title_bar = (rect.left <= pos_client.x && pos_client.x < rect.right &&
rect.top <= pos_client.y && pos_client.y < rect.top + window->custom_border_title_thickness);
}
//- rjf: check against title bar client areas //- rjf: check against title bar client areas
B32 is_over_title_bar_client_area = 0; B32 is_over_title_bar_client_area = 0;
@@ -757,37 +738,42 @@ os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} }
} }
//- rjf: resolve hovering to result if (IsMaximized(hwnd))
result = HTNOWHERE; {
if(is_over_window) if (is_over_title_bar_client_area)
{ {
// rjf: default to client area
result = HTCLIENT; result = HTCLIENT;
}
// rjf: title bar else if (is_over_title_bar)
if(is_over_title_bar)
{ {
result = HTCAPTION; result = HTCAPTION;
} }
else
// rjf: normal edges
if(is_over_left) { result = HTLEFT; }
if(is_over_right) { result = HTRIGHT; }
if(is_over_top) { result = HTTOP; }
if(is_over_bottom) { result = HTBOTTOM; }
// rjf: corners
if(is_over_left && is_over_top) { result = HTTOPLEFT; }
if(is_over_left && is_over_bottom) { result = HTBOTTOMLEFT; }
if(is_over_right && is_over_top) { result = HTTOPRIGHT; }
if(is_over_right && is_over_bottom) { result = HTBOTTOMRIGHT; }
// rjf: title bar client area
if(is_over_title_bar_client_area)
{ {
result = HTCLIENT; result = HTCLIENT;
} }
} }
else
{
//Swap the first two conditions to choose if hovering the top border
//should prioritize resize or title bar buttons.
if (is_over_title_bar_client_area)
{
result = HTCLIENT;
}
else if (is_over_top_resize)
{
result = HTTOP;
}
else if (is_over_title_bar)
{
result = HTCAPTION;
}
else {
result = HTCLIENT;
}
}
}
} }
}break; }break;
} }