This commit is contained in:
cats studio 2024-01-20 18:14:42 +00:00 committed by GitHub
commit 662dec2619
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 489 additions and 25 deletions

18
.gitignore vendored
View File

@ -1,9 +1,6 @@
# The canonical out-of-tree build subdirectory
build
build-*
# Visual Studio clutter
_ReSharper* _ReSharper*
*.opensdf
*.sdf *.sdf
*.suo *.suo
*.dir *.dir
@ -28,19 +25,9 @@ GLFW.xcodeproj
# Makefile generator clutter # Makefile generator clutter
Makefile Makefile
# Ninja generator clutter
build.ninja
rules.ninja
.ninja_deps
.ninja_log
# CMake clutter
CMakeCache.txt CMakeCache.txt
CMakeFiles CMakeFiles
CMakeScripts CMakeScripts
CMakeDoxyfile.in
CMakeDoxygenDefaults.cmake
cmake_install.cmake cmake_install.cmake
cmake_uninstall.cmake cmake_uninstall.cmake
@ -102,3 +89,6 @@ tests/triangle-vulkan
tests/window tests/window
tests/windows tests/windows
# Hazel-specific
bin
bin-int

View File

@ -921,6 +921,14 @@ 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).
*
* NOTE: Added by Hazel
*/
#define GLFW_TITLEBAR 0x00C2000D
/*! @brief Mouse input transparency window hint and attribute /*! @brief Mouse input transparency window hint and attribute
* *
@ -1576,6 +1584,27 @@ typedef void (* GLFWerrorfun)(int error_code, const char* description);
*/ */
typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos); typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
/*! @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
@ -4136,6 +4165,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

118
premake5.lua Normal file
View File

@ -0,0 +1,118 @@
project "GLFW"
kind "StaticLib"
language "C"
staticruntime "off"
warnings "off"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"include/GLFW/glfw3.h",
"include/GLFW/glfw3native.h",
"src/glfw_config.h",
"src/context.c",
"src/init.c",
"src/input.c",
"src/monitor.c",
"src/null_init.c",
"src/null_joystick.c",
"src/null_monitor.c",
"src/null_window.c",
"src/platform.c",
"src/vulkan.c",
"src/window.c",
}
filter "system:linux"
pic "On"
systemversion "latest"
files
{
"src/x11_init.c",
"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",
"src/glx_context.c",
"src/egl_context.c",
"src/osmesa_context.c",
"src/linux_joystick.c"
}
defines
{
"_GLFW_X11"
}
filter "system:macosx"
pic "On"
files
{
"src/cocoa_init.m",
"src/cocoa_monitor.m",
"src/cocoa_window.m",
"src/cocoa_joystick.m",
"src/cocoa_time.c",
"src/nsgl_context.m",
"src/posix_thread.c",
"src/posix_module.c",
"src/osmesa_context.c",
"src/egl_context.c"
}
defines
{
"_GLFW_COCOA"
}
filter "system:windows"
systemversion "latest"
files
{
"src/win32_init.c",
"src/win32_joystick.c",
"src/win32_module.c",
"src/win32_monitor.c",
"src/win32_time.c",
"src/win32_thread.c",
"src/win32_window.c",
"src/wgl_context.c",
"src/egl_context.c",
"src/osmesa_context.c"
}
defines
{
"_GLFW_WIN32",
"_CRT_SECURE_NO_WARNINGS"
}
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter { "system:windows", "configurations:Debug-AS" }
runtime "Debug"
symbols "on"
sanitize { "Address" }
flags { "NoRuntimeChecks", "NoIncrementalLink" }
filter "configurations:Release"
runtime "Release"
optimize "speed"
filter "configurations:Dist"
runtime "Release"
optimize "speed"
symbols "off"

View File

@ -554,13 +554,17 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
_glfwGetWindowOpacityCocoa, _glfwGetWindowOpacityCocoa,
_glfwSetWindowResizableCocoa, _glfwSetWindowResizableCocoa,
_glfwSetWindowDecoratedCocoa, _glfwSetWindowDecoratedCocoa,
_glfwSetWindowFloatingCocoa, _glfwSetWindowFloatingNull,
_glfwSetWindowOpacityCocoa, _glfwSetWindowOpacityCocoa,
_glfwSetWindowMousePassthroughCocoa, _glfwSetWindowMousePassthroughCocoa,
_glfwPollEventsCocoa, _glfwPollEventsCocoa,
_glfwWaitEventsCocoa, _glfwWaitEventsCocoa,
_glfwWaitEventsTimeoutCocoa, _glfwWaitEventsTimeoutCocoa,
_glfwPostEmptyEventCocoa, _glfwPostEmptyEventCocoa,
// Hazel
_glfwSetWindowTitlebarNull,
_glfwGetEGLPlatformCocoa, _glfwGetEGLPlatformCocoa,
_glfwGetEGLNativeDisplayCocoa, _glfwGetEGLNativeDisplayCocoa,
_glfwGetEGLNativeWindowCocoa, _glfwGetEGLNativeWindowCocoa,

View File

@ -1473,7 +1473,14 @@ void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled)
} // autoreleasepool } // autoreleasepool
} }
void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Window attribute setting not implemented yet");
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
if (enabled) if (enabled)

View File

@ -400,6 +400,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;
@ -555,14 +556,15 @@ struct _GLFWwindow
_GLFWcontext context; _GLFWcontext context;
struct { struct {
GLFWwindowposfun pos; GLFWwindowposfun pos;
GLFWwindowsizefun size; GLFWtitlebarhittestfun tbhittest;
GLFWwindowclosefun close; GLFWwindowsizefun size;
GLFWwindowrefreshfun refresh; GLFWwindowclosefun close;
GLFWwindowfocusfun focus; GLFWwindowrefreshfun refresh;
GLFWwindowiconifyfun iconify; GLFWwindowfocusfun focus;
GLFWwindowmaximizefun maximize; GLFWwindowiconifyfun iconify;
GLFWframebuffersizefun fbsize; GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize;
GLFWwindowcontentscalefun scale; GLFWwindowcontentscalefun scale;
GLFWmousebuttonfun mouseButton; GLFWmousebuttonfun mouseButton;
GLFWcursorposfun cursorPos; GLFWcursorposfun cursorPos;
@ -742,6 +744,10 @@ struct _GLFWplatform
void (*waitEvents)(void); void (*waitEvents)(void);
void (*waitEventsTimeout)(double); void (*waitEventsTimeout)(double);
void (*postEmptyEvent)(void); void (*postEmptyEvent)(void);
// Hazel
void (*setWindowTitleBar)(_GLFWwindow*,GLFWbool);
// EGL // EGL
EGLenum (*getEGLPlatform)(EGLint**); EGLenum (*getEGLPlatform)(EGLint**);
EGLNativeDisplayType (*getEGLNativeDisplay)(void); EGLNativeDisplayType (*getEGLNativeDisplay)(void);
@ -887,6 +893,65 @@ void _glfwPlatformInitTimer(void);
uint64_t _glfwPlatformGetTimerValue(void); uint64_t _glfwPlatformGetTimerValue(void);
uint64_t _glfwPlatformGetTimerFrequency(void); uint64_t _glfwPlatformGetTimerFrequency(void);
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
int count, const GLFWimage* images);
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom);
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
float* xscale, float* yscale);
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
void _glfwPlatformShowWindow(_GLFWwindow* window);
void _glfwPlatformHideWindow(_GLFWwindow* window);
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
void _glfwPlatformFocusWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
int _glfwPlatformWindowFocused(_GLFWwindow* window);
int _glfwPlatformWindowIconified(_GLFWwindow* window);
int _glfwPlatformWindowVisible(_GLFWwindow* window);
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
int _glfwPlatformWindowHovered(_GLFWwindow* window);
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
void _glfwPlatformPollEvents(void);
void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout);
void _glfwPlatformPostEmptyEvent(void);
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls); GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
void _glfwPlatformDestroyTls(_GLFWtls* tls); void _glfwPlatformDestroyTls(_GLFWtls* tls);
void* _glfwPlatformGetTls(_GLFWtls* tls); void* _glfwPlatformGetTls(_GLFWtls* tls);
@ -909,6 +974,7 @@ GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name);
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

@ -105,6 +105,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwWaitEventsNull, _glfwWaitEventsNull,
_glfwWaitEventsTimeoutNull, _glfwWaitEventsTimeoutNull,
_glfwPostEmptyEventNull, _glfwPostEmptyEventNull,
_glfwSetWindowTitlebarNull,
_glfwGetEGLPlatformNull, _glfwGetEGLPlatformNull,
_glfwGetEGLNativeDisplayNull, _glfwGetEGLNativeDisplayNull,
_glfwGetEGLNativeWindowNull, _glfwGetEGLNativeWindowNull,

View File

@ -170,6 +170,7 @@ typedef struct _GLFWwindowNull
GLFWbool maximized; GLFWbool maximized;
GLFWbool resizable; GLFWbool resizable;
GLFWbool decorated; GLFWbool decorated;
GLFWbool titlebar;
GLFWbool floating; GLFWbool floating;
GLFWbool transparent; GLFWbool transparent;
float opacity; float opacity;
@ -248,6 +249,10 @@ void _glfwPollEventsNull(void);
void _glfwWaitEventsNull(void); void _glfwWaitEventsNull(void);
void _glfwWaitEventsTimeoutNull(double timeout); void _glfwWaitEventsTimeoutNull(double timeout);
void _glfwPostEmptyEventNull(void); void _glfwPostEmptyEventNull(void);
// Hazel
void _glfwSetWindowTitlebarNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos); void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y); void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y);
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode); void _glfwSetCursorModeNull(_GLFWwindow* window, int mode);

View File

@ -397,6 +397,11 @@ void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled)
window->null.decorated = enabled; window->null.decorated = enabled;
} }
void _glfwSetWindowTitlebarNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.titlebar = enabled;
}
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled)
{ {
window->null.floating = enabled; window->null.floating = enabled;

View File

@ -669,6 +669,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
_glfwWaitEventsWin32, _glfwWaitEventsWin32,
_glfwWaitEventsTimeoutWin32, _glfwWaitEventsTimeoutWin32,
_glfwPostEmptyEventWin32, _glfwPostEmptyEventWin32,
_glfwSetWindowTitlebarWin32,
_glfwGetEGLPlatformWin32, _glfwGetEGLPlatformWin32,
_glfwGetEGLNativeDisplayWin32, _glfwGetEGLNativeDisplayWin32,
_glfwGetEGLNativeWindowWin32, _glfwGetEGLNativeWindowWin32,

View File

@ -581,6 +581,9 @@ void _glfwWaitEventsWin32(void);
void _glfwWaitEventsTimeoutWin32(double timeout); void _glfwWaitEventsTimeoutWin32(double timeout);
void _glfwPostEmptyEventWin32(void); void _glfwPostEmptyEventWin32(void);
// Hazel
void _glfwSetWindowTitlebarWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos); void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos); void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode); void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode);

View File

@ -34,6 +34,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
// //
@ -527,6 +528,9 @@ static void maximizeWindowManually(_GLFWwindow* window)
// //
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
static RECT border_thickness = { 4, 4, 4, 4 };
BOOL hasThickFrame = GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME;
_GLFWwindow* window = GetPropW(hWnd, L"GLFW"); _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
if (!window) if (!window)
{ {
@ -544,6 +548,40 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
if (wndconfig && wndconfig->scaleToMonitor) if (wndconfig && wndconfig->scaleToMonitor)
EnableNonClientDpiScaling(hWnd); EnableNonClientDpiScaling(hWnd);
} }
case WM_CREATE:
{
if (_glfw.hints.window.titlebar)
break;
if (hasThickFrame)
{
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
);
break;
}
break;
}
case WM_ACTIVATE:
{
if (_glfw.hints.window.titlebar)
break;
RECT title_bar_rect = {0};
InvalidateRect(hWnd, &title_bar_rect, FALSE);
break;
}
} }
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@ -995,6 +1033,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
break; break;
} }
case WM_NCCALCSIZE:
{
if (_glfw.hints.window.titlebar || !hasThickFrame || !wParam)
break;
// 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;
}
case WM_SIZE: case WM_SIZE:
{ {
const int width = LOWORD(lParam); const int width = LOWORD(lParam);
@ -1035,6 +1115,18 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
window->win32.iconified = iconified; window->win32.iconified = iconified;
window->win32.maximized = maximized; 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; return 0;
} }
@ -1240,6 +1332,64 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
DragFinish(drop); DragFinish(drop);
return 0; return 0;
} }
case WM_ACTIVATE:
{
if (_glfw.hints.window.titlebar)
break;
RECT title_bar_rect = { 0 };
InvalidateRect(hWnd, &title_bar_rect, FALSE);
}
case WM_NCHITTEST:
{
if (_glfw.hints.window.titlebar || !hasThickFrame)
break;
//
// Hit test for custom frames
//
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(hWnd, &pt);
// Check borders first
if (!window->win32.maximized)
{
RECT rc;
GetClientRect(hWnd, &rc);
const int verticalBorderSize = GetSystemMetrics(SM_CYFRAME);
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;
}
// 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;
}
} }
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@ -1939,6 +2089,11 @@ void _glfwSetWindowDecoratedWin32(_GLFWwindow* window, GLFWbool enabled)
updateWindowStyles(window); updateWindowStyles(window);
} }
void _glfwSetWindowTitlebarWin32(_GLFWwindow* window, GLFWbool enabled)
{
updateWindowStyles(window);
}
void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled)
{ {
const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST; const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST;

View File

@ -93,6 +93,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)
@ -268,6 +276,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;
@ -353,6 +362,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;
@ -872,6 +884,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 _glfw.hints.window.titlebar;
case GLFW_FLOATING: case GLFW_FLOATING:
return window->floating; return window->floating;
case GLFW_AUTO_ICONIFY: case GLFW_AUTO_ICONIFY:
@ -931,8 +945,14 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
window->decorated = value; window->decorated = value;
if (!window->monitor) if (!window->monitor)
_glfw.platform.setWindowDecorated(window, value); _glfw.platform.setWindowDecorated(window, value);
return; case GLFW_TITLEBAR:
if (_glfw.hints.window.titlebar == value)
return;
_glfw.hints.window.titlebar = value;
if (!window->monitor)
_glfw.platform.setWindowTitleBar(window, value);
return;
case GLFW_FLOATING: case GLFW_FLOATING:
window->floating = value; window->floating = value;
if (!window->monitor) if (!window->monitor)
@ -1029,6 +1049,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(GLFWtitlebarhittestfun, window->callbacks.tbhittest, tbhtfun);
return tbhtfun;
}
GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
GLFWwindowsizefun cbfun) GLFWwindowsizefun cbfun)
{ {

View File

@ -2463,6 +2463,14 @@ void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled)
} }
} }
void _glfwPlatformSetWindowTitlebar(_GLFWwindow* window, GLFWbool enabled)
{
// TODO
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Window attribute setting not implemented yet");
}
void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled)
{ {
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwInputError(GLFW_FEATURE_UNAVAILABLE,

View File

@ -1240,6 +1240,10 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
_glfwWaitEventsX11, _glfwWaitEventsX11,
_glfwWaitEventsTimeoutX11, _glfwWaitEventsTimeoutX11,
_glfwPostEmptyEventX11, _glfwPostEmptyEventX11,
// Hazel
_glfwSetWindowTitlebarNull,
_glfwGetEGLPlatformX11, _glfwGetEGLPlatformX11,
_glfwGetEGLNativeDisplayX11, _glfwGetEGLNativeDisplayX11,
_glfwGetEGLNativeWindowX11, _glfwGetEGLNativeWindowX11,

View File

@ -2641,6 +2641,13 @@ void _glfwSetWindowDecoratedX11(_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 _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowFloatingX11(_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)