Added window creation hint to disable native OS title-bar

- Disabling title-bar only implemented for win32 window.
This commit is contained in:
Jaytheway 2021-09-28 11:35:27 +03:00
parent 1a3b9eacfc
commit 6d3052e388
9 changed files with 243 additions and 0 deletions

View File

@ -842,6 +842,12 @@ extern "C" {
* [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib). * [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib).
*/ */
#define GLFW_FOCUS_ON_SHOW 0x0002000C #define GLFW_FOCUS_ON_SHOW 0x0002000C
/*! @brief Window has titlebar window hint and attribute
*
* Window has titlebar [window hint](@ref GLFW_TITLEBAR_hint) and
* [window attribute](@ref GLFW_TITLEBAR_attrib).
*/
#define GLFW_TITLEBAR 0x0002000D
/*! @brief Framebuffer bit depth hint. /*! @brief Framebuffer bit depth hint.
* *
@ -1291,8 +1297,30 @@ typedef void (* GLFWerrorfun)(int,const char*);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
/*! @brief The function pointer type for window titlebar hittest callbacks.
*
* This is the function pointer type for window titelebar hittest callbacks.
* A window titlebar hittest callback function has the following signature:
* @code
* void callback_name(GLFWwindow* window, int xpos, int ypos, int* hit)
* @endcode
*
* @param[in] window The window that was moved.
* @param[in] xpos The x-coordinate of mouse, in screen coordinates.
* @param[in] ypos The y-coordinate of mouse, in screen coordinates.
* @param[out] hit 'true' or '1' if mouse hovering titlebar.
*
* @sa @ref window_pos
* @sa @ref glfwSetTitlebarHitTestCallback
*
* @ingroup window
*/
typedef void (*GLFWtitlebarhittestfun)(GLFWwindow*, int, int, int*);
/*! @brief The function pointer type for window size callbacks. /*! @brief The function pointer type for window size callbacks.
* *
* This is the function pointer type for window size callbacks. A window size * This is the function pointer type for window size callbacks. A window size
@ -3688,6 +3716,37 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
*/ */
GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback); GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback);
/*! @brief Sets the titlebar hittest callback for the specified window.
*
* This function sets the titlebar hittest callback of the specified window,
* which is called when the mouse hoveres the window to ask client if it's
* hovering over custom titlebar area which needs to be handles as a native
* titlebar. The callback is provided with the x and y coordinates of the mouse
* cursor in screen coordinates.
*
* @param[in] window The window whose callback to set.
* @param[in] callback The new callback, or `NULL` to remove the currently set
* callback.
* @return The previously set callback, or `NULL` if no callback was set or the
* library had not been [initialized](@ref intro_init).
*
* @callback_signature
* @code
* void function_name(GLFWwindow* window, int xpos, int ypos, int* hit)
* @endcode
* For more information about the callback parameters, see the
* [function pointer type](@ref GLFWtitlebarhittestfun).
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_pos
*
* @ingroup window
*/
GLFWAPI GLFWtitlebarhittestfun glfwSetTitlebarHitTestCallback(GLFWwindow* window, GLFWtitlebarhittestfun callback);
/*! @brief Sets the size callback for the specified window. /*! @brief Sets the size callback for the specified window.
* *
* This function sets the size callback of the specified window, which is * This function sets the size callback of the specified window, which is

View File

@ -64,6 +64,11 @@ project "GLFW"
"_CRT_SECURE_NO_WARNINGS" "_CRT_SECURE_NO_WARNINGS"
} }
links
{
"Dwmapi.lib"
}
filter "configurations:Debug" filter "configurations:Debug"
runtime "Debug" runtime "Debug"
symbols "on" symbols "on"

View File

@ -1337,6 +1337,13 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Window attribute setting not implemented yet");
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {

View File

@ -260,6 +260,7 @@ struct _GLFWwndconfig
GLFWbool resizable; GLFWbool resizable;
GLFWbool visible; GLFWbool visible;
GLFWbool decorated; GLFWbool decorated;
GLFWbool titlebar;
GLFWbool focused; GLFWbool focused;
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
@ -373,6 +374,7 @@ struct _GLFWwindow
// Window settings and state // Window settings and state
GLFWbool resizable; GLFWbool resizable;
GLFWbool decorated; GLFWbool decorated;
GLFWbool titlebar;
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
GLFWbool focusOnShow; GLFWbool focusOnShow;
@ -400,6 +402,7 @@ struct _GLFWwindow
struct { struct {
GLFWwindowposfun pos; GLFWwindowposfun pos;
GLFWtitlebarhittestfun tbhittest;
GLFWwindowsizefun size; GLFWwindowsizefun size;
GLFWwindowclosefun close; GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh; GLFWwindowrefreshfun refresh;
@ -673,6 +676,7 @@ int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window); float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled); void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled); void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled); void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity); void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
@ -708,6 +712,7 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused); void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos); void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height); void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
void _glfwInputTitleBarHitTest(_GLFWwindow* window, int posX, int posY, int* hit);
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height); void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
void _glfwInputWindowContentScale(_GLFWwindow* window, void _glfwInputWindowContentScale(_GLFWwindow* window,
float xscale, float yscale); float xscale, float yscale);

View File

@ -185,6 +185,10 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
{ {
} }
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
} }

View File

@ -35,6 +35,7 @@
#include <string.h> #include <string.h>
#include <windowsx.h> #include <windowsx.h>
#include <shellapi.h> #include <shellapi.h>
#include <uxtheme.h>
// Returns the window style for the specified window // Returns the window style for the specified window
// //
@ -508,6 +509,8 @@ static void releaseMonitor(_GLFWwindow* window)
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam) WPARAM wParam, LPARAM lParam)
{ {
static RECT border_thickness;
_GLFWwindow* window = GetPropW(hWnd, L"GLFW"); _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
if (!window) if (!window)
{ {
@ -545,6 +548,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
break; break;
} }
case WM_CREATE:
{
if (_glfw.hints.window.titlebar)
break;
//find border thickness
SetRectEmpty(&border_thickness);
if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME)
{
AdjustWindowRectEx(&border_thickness, GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION, FALSE, NULL);
border_thickness.left *= -1;
border_thickness.top *= -1;
}
else// if (GetWindowLongPtr(hWnd, GWL_STYLE) & WS_BORDER)
{
SetRect(&border_thickness, 4, 4, 4, 4);
}
MARGINS margins = { 0 };
DwmExtendFrameIntoClientArea(hWnd, &margins);
SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
break;
}
case WM_ACTIVATE:
{
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;
}
} }
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@ -951,6 +996,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
break; break;
} }
case WM_NCCALCSIZE:
{
if (window->titlebar)
break;
if (lParam)
return 0;
break;
}
case WM_SIZE: case WM_SIZE:
{ {
const GLFWbool iconified = wParam == SIZE_MINIMIZED; const GLFWbool iconified = wParam == SIZE_MINIMIZED;
@ -1182,6 +1237,61 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
DragFinish(drop); DragFinish(drop);
return 0; return 0;
} }
case WM_ACTIVATE:
{
if (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;
}
case WM_NCHITTEST:
{
if (window->titlebar)
break;
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(hWnd, &pt);
RECT rc;
GetClientRect(hWnd, &rc);
int titlebarHittest = 0;
_glfwInputTitleBarHitTest(window, pt.x, pt.y, &titlebarHittest);
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;
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;
return HTCLIENT;
}
}
} }
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@ -1828,6 +1938,11 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
updateWindowStyles(window); updateWindowStyles(window);
} }
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
updateWindowStyles(window);
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST; const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST;

View File

@ -86,6 +86,14 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
window->callbacks.size((GLFWwindow*) window, width, height); window->callbacks.size((GLFWwindow*) window, width, height);
} }
// Notifies shared code that mouse hittest needs to be resolved
//
void _glfwInputTitleBarHitTest(_GLFWwindow* window, int posX, int posY, int* hit)
{
if (window->callbacks.tbhittest)
window->callbacks.tbhittest((GLFWwindow*)window, posX, posY, hit);
}
// Notifies shared code that a window has been iconified or restored // Notifies shared code that a window has been iconified or restored
// //
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
@ -200,6 +208,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->monitor = (_GLFWmonitor*) monitor; window->monitor = (_GLFWmonitor*) monitor;
window->resizable = wndconfig.resizable; window->resizable = wndconfig.resizable;
window->decorated = wndconfig.decorated; window->decorated = wndconfig.decorated;
window->titlebar = wndconfig.titlebar;
window->autoIconify = wndconfig.autoIconify; window->autoIconify = wndconfig.autoIconify;
window->floating = wndconfig.floating; window->floating = wndconfig.floating;
window->focusOnShow = wndconfig.focusOnShow; window->focusOnShow = wndconfig.focusOnShow;
@ -262,6 +271,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.window.resizable = GLFW_TRUE; _glfw.hints.window.resizable = GLFW_TRUE;
_glfw.hints.window.visible = GLFW_TRUE; _glfw.hints.window.visible = GLFW_TRUE;
_glfw.hints.window.decorated = GLFW_TRUE; _glfw.hints.window.decorated = GLFW_TRUE;
_glfw.hints.window.titlebar = GLFW_TRUE;
_glfw.hints.window.focused = GLFW_TRUE; _glfw.hints.window.focused = GLFW_TRUE;
_glfw.hints.window.autoIconify = GLFW_TRUE; _glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = GLFW_TRUE; _glfw.hints.window.centerCursor = GLFW_TRUE;
@ -345,6 +355,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_DECORATED: case GLFW_DECORATED:
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_TITLEBAR:
_glfw.hints.window.titlebar = value ? GLFW_TRUE : GLFW_FALSE;
return;
case GLFW_FOCUSED: case GLFW_FOCUSED:
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
@ -828,6 +841,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return window->resizable; return window->resizable;
case GLFW_DECORATED: case GLFW_DECORATED:
return window->decorated; return window->decorated;
case GLFW_TITLEBAR:
return window->titlebar;
case GLFW_FLOATING: case GLFW_FLOATING:
return window->floating; return window->floating;
case GLFW_AUTO_ICONIFY: case GLFW_AUTO_ICONIFY:
@ -889,6 +904,15 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
if (!window->monitor) if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value); _glfwPlatformSetWindowDecorated(window, value);
} }
else if (attrib == GLFW_TITLEBAR)
{
if (window->titlebar == value)
return;
window->titlebar = value;
if (!window->monitor)
_glfwPlatformSetWindowTitlebar(window, value);
}
else if (attrib == GLFW_FLOATING) else if (attrib == GLFW_FLOATING)
{ {
if (window->floating == value) if (window->floating == value)
@ -981,6 +1005,16 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
return cbfun; return cbfun;
} }
GLFWAPI GLFWtitlebarhittestfun glfwSetTitlebarHitTestCallback(GLFWwindow* handle, GLFWtitlebarhittestfun tbhtfun)
{
_GLFWwindow* window = (_GLFWwindow*)handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.tbhittest, tbhtfun);
return tbhtfun;
}
GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWwindowsizefun cbfun) GLFWwindowsizefun cbfun)
{ {

View File

@ -1111,6 +1111,13 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
} }
} }
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Window attribute setting not implemented yet");
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
// TODO // TODO

View File

@ -2658,6 +2658,13 @@ void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
sizeof(hints) / sizeof(long)); sizeof(hints) / sizeof(long));
} }
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Window attribute setting not implemented yet");
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE) if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)