diff --git a/.gitignore b/.gitignore index 9d2d504b2..c3bfa687d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ -# The canonical out-of-tree build subdirectory -build -build-* -# Visual Studio clutter _ReSharper* +*.opensdf *.sdf *.suo *.dir @@ -28,19 +25,9 @@ GLFW.xcodeproj # Makefile generator clutter Makefile - -# Ninja generator clutter -build.ninja -rules.ninja -.ninja_deps -.ninja_log - -# CMake clutter CMakeCache.txt CMakeFiles CMakeScripts -CMakeDoxyfile.in -CMakeDoxygenDefaults.cmake cmake_install.cmake cmake_uninstall.cmake @@ -102,3 +89,6 @@ tests/triangle-vulkan tests/window tests/windows +# Hazel-specific +bin +bin-int diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 5e6fad426..f35980cad 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -921,6 +921,14 @@ extern "C" { * [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib). */ #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 * @@ -1576,6 +1584,27 @@ typedef void (* GLFWerrorfun)(int error_code, const char* description); */ 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. * * 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); +/*! @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. * * This function sets the size callback of the specified window, which is diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 000000000..b0e66cb2e --- /dev/null +++ b/premake5.lua @@ -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" diff --git a/src/cocoa_init.m b/src/cocoa_init.m index b3831df15..5e3c4ec42 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -554,13 +554,17 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform) _glfwGetWindowOpacityCocoa, _glfwSetWindowResizableCocoa, _glfwSetWindowDecoratedCocoa, - _glfwSetWindowFloatingCocoa, + _glfwSetWindowFloatingNull, _glfwSetWindowOpacityCocoa, _glfwSetWindowMousePassthroughCocoa, _glfwPollEventsCocoa, _glfwWaitEventsCocoa, _glfwWaitEventsTimeoutCocoa, _glfwPostEmptyEventCocoa, + + // Hazel + _glfwSetWindowTitlebarNull, + _glfwGetEGLPlatformCocoa, _glfwGetEGLNativeDisplayCocoa, _glfwGetEGLNativeWindowCocoa, diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 9d7949405..7ae9fbc58 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1473,7 +1473,14 @@ void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled) } // 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 { if (enabled) diff --git a/src/internal.h b/src/internal.h index fe0369aaf..d72a09583 100644 --- a/src/internal.h +++ b/src/internal.h @@ -400,6 +400,7 @@ struct _GLFWwndconfig GLFWbool resizable; GLFWbool visible; GLFWbool decorated; + GLFWbool titlebar; GLFWbool focused; GLFWbool autoIconify; GLFWbool floating; @@ -555,14 +556,15 @@ struct _GLFWwindow _GLFWcontext context; struct { - GLFWwindowposfun pos; - GLFWwindowsizefun size; - GLFWwindowclosefun close; - GLFWwindowrefreshfun refresh; - GLFWwindowfocusfun focus; - GLFWwindowiconifyfun iconify; - GLFWwindowmaximizefun maximize; - GLFWframebuffersizefun fbsize; + GLFWwindowposfun pos; + GLFWtitlebarhittestfun tbhittest; + GLFWwindowsizefun size; + GLFWwindowclosefun close; + GLFWwindowrefreshfun refresh; + GLFWwindowfocusfun focus; + GLFWwindowiconifyfun iconify; + GLFWwindowmaximizefun maximize; + GLFWframebuffersizefun fbsize; GLFWwindowcontentscalefun scale; GLFWmousebuttonfun mouseButton; GLFWcursorposfun cursorPos; @@ -742,6 +744,10 @@ struct _GLFWplatform void (*waitEvents)(void); void (*waitEventsTimeout)(double); void (*postEmptyEvent)(void); + + // Hazel + void (*setWindowTitleBar)(_GLFWwindow*,GLFWbool); + // EGL EGLenum (*getEGLPlatform)(EGLint**); EGLNativeDisplayType (*getEGLNativeDisplay)(void); @@ -887,6 +893,65 @@ void _glfwPlatformInitTimer(void); uint64_t _glfwPlatformGetTimerValue(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); void _glfwPlatformDestroyTls(_GLFWtls* tls); void* _glfwPlatformGetTls(_GLFWtls* tls); @@ -909,6 +974,7 @@ GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name); void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused); void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos); 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 _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscale); diff --git a/src/null_init.c b/src/null_init.c index 34ddc04af..3d955b713 100644 --- a/src/null_init.c +++ b/src/null_init.c @@ -105,6 +105,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) _glfwWaitEventsNull, _glfwWaitEventsTimeoutNull, _glfwPostEmptyEventNull, + _glfwSetWindowTitlebarNull, _glfwGetEGLPlatformNull, _glfwGetEGLNativeDisplayNull, _glfwGetEGLNativeWindowNull, diff --git a/src/null_platform.h b/src/null_platform.h index fb9374b43..9618a24ba 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -170,6 +170,7 @@ typedef struct _GLFWwindowNull GLFWbool maximized; GLFWbool resizable; GLFWbool decorated; + GLFWbool titlebar; GLFWbool floating; GLFWbool transparent; float opacity; @@ -248,6 +249,10 @@ void _glfwPollEventsNull(void); void _glfwWaitEventsNull(void); void _glfwWaitEventsTimeoutNull(double timeout); void _glfwPostEmptyEventNull(void); + +// Hazel +void _glfwSetWindowTitlebarNull(_GLFWwindow* window, GLFWbool enabled); + void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos); void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y); void _glfwSetCursorModeNull(_GLFWwindow* window, int mode); diff --git a/src/null_window.c b/src/null_window.c index c2aafbadf..21c91cd50 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -397,6 +397,11 @@ void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled) window->null.decorated = enabled; } +void _glfwSetWindowTitlebarNull(_GLFWwindow* window, GLFWbool enabled) +{ + window->null.titlebar = enabled; +} + void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled) { window->null.floating = enabled; diff --git a/src/win32_init.c b/src/win32_init.c index 4cb01adbd..4a6362db1 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -669,6 +669,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform) _glfwWaitEventsWin32, _glfwWaitEventsTimeoutWin32, _glfwPostEmptyEventWin32, + _glfwSetWindowTitlebarWin32, _glfwGetEGLPlatformWin32, _glfwGetEGLNativeDisplayWin32, _glfwGetEGLNativeWindowWin32, diff --git a/src/win32_platform.h b/src/win32_platform.h index 82b34bb9d..958162933 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -581,6 +581,9 @@ void _glfwWaitEventsWin32(void); void _glfwWaitEventsTimeoutWin32(double timeout); void _glfwPostEmptyEventWin32(void); +// Hazel +void _glfwSetWindowTitlebarWin32(_GLFWwindow* window, GLFWbool enabled); + void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos); void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos); void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode); diff --git a/src/win32_window.c b/src/win32_window.c index f7feb32d9..c659ff4db 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -34,6 +34,7 @@ #include #include #include +#include // 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 RECT border_thickness = { 4, 4, 4, 4 }; + BOOL hasThickFrame = GetWindowLongPtr(hWnd, GWL_STYLE) & WS_THICKFRAME; + _GLFWwindow* window = GetPropW(hWnd, L"GLFW"); if (!window) { @@ -544,6 +548,40 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l if (wndconfig && wndconfig->scaleToMonitor) 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); @@ -995,6 +1033,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l 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: { 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.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; } @@ -1240,6 +1332,64 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l DragFinish(drop); 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); @@ -1939,6 +2089,11 @@ void _glfwSetWindowDecoratedWin32(_GLFWwindow* window, GLFWbool enabled) updateWindowStyles(window); } +void _glfwSetWindowTitlebarWin32(_GLFWwindow* window, GLFWbool enabled) +{ + updateWindowStyles(window); +} + void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled) { const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST; diff --git a/src/window.c b/src/window.c index 1117df2f0..55ef9b57c 100644 --- a/src/window.c +++ b/src/window.c @@ -93,6 +93,14 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int 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 // void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) @@ -268,6 +276,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.window.resizable = GLFW_TRUE; _glfw.hints.window.visible = GLFW_TRUE; _glfw.hints.window.decorated = GLFW_TRUE; + _glfw.hints.window.titlebar = GLFW_TRUE; _glfw.hints.window.focused = GLFW_TRUE; _glfw.hints.window.autoIconify = GLFW_TRUE; _glfw.hints.window.centerCursor = GLFW_TRUE; @@ -353,6 +362,9 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_DECORATED: _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_TITLEBAR: + _glfw.hints.window.titlebar = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_FOCUSED: _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE; return; @@ -872,6 +884,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->resizable; case GLFW_DECORATED: return window->decorated; + case GLFW_TITLEBAR: + return _glfw.hints.window.titlebar; case GLFW_FLOATING: return window->floating; case GLFW_AUTO_ICONIFY: @@ -931,8 +945,14 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) window->decorated = value; if (!window->monitor) _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: window->floating = value; if (!window->monitor) @@ -1029,6 +1049,16 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, 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, GLFWwindowsizefun cbfun) { diff --git a/src/wl_window.c b/src/wl_window.c index 76c6a7637..0048ccb9c 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -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) { _glfwInputError(GLFW_FEATURE_UNAVAILABLE, diff --git a/src/x11_init.c b/src/x11_init.c index c90b593cb..f8ebf642d 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -1240,6 +1240,10 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) _glfwWaitEventsX11, _glfwWaitEventsTimeoutX11, _glfwPostEmptyEventX11, + + // Hazel + _glfwSetWindowTitlebarNull, + _glfwGetEGLPlatformX11, _glfwGetEGLNativeDisplayX11, _glfwGetEGLNativeWindowX11, diff --git a/src/x11_window.c b/src/x11_window.c index 3c76d3a9d..df7d4f252 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2641,6 +2641,13 @@ void _glfwSetWindowDecoratedX11(_GLFWwindow* window, GLFWbool enabled) 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) { if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)