Merge pull request #1 from Abbion/BorderlessForWindows

Focus gained when l mouse clicked
This commit is contained in:
Abbion 2023-02-27 18:31:01 +01:00 committed by GitHub
commit db61958bc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 490 additions and 15 deletions

View File

@ -27,6 +27,7 @@ set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
add_executable(boing WIN32 MACOSX_BUNDLE boing.c ${ICON} ${GLAD_GL}) add_executable(boing WIN32 MACOSX_BUNDLE boing.c ${ICON} ${GLAD_GL})
add_executable(gears WIN32 MACOSX_BUNDLE gears.c ${ICON} ${GLAD_GL}) add_executable(gears WIN32 MACOSX_BUNDLE gears.c ${ICON} ${GLAD_GL})
add_executable(areoBorderless WIN32 MACOSX_BUNDLE areoBorderless.c ${ICON} ${GLAD_GL})
add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD_GL}) add_executable(heightmap WIN32 MACOSX_BUNDLE heightmap.c ${ICON} ${GLAD_GL})
add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL}) add_executable(offscreen offscreen.c ${ICON} ${GLAD_GL})
add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL}) add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD_GL})
@ -42,7 +43,7 @@ if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}") target_link_libraries(particles "${RT_LIBRARY}")
endif() endif()
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview set(GUI_ONLY_BINARIES boing gears areoBorderless heightmap particles sharing splitview
triangle-opengl triangle-opengles wave windows) triangle-opengl triangle-opengles wave windows)
set(CONSOLE_BINARIES offscreen) set(CONSOLE_BINARIES offscreen)
@ -63,6 +64,7 @@ endif()
if (APPLE) if (APPLE)
set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing") set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
set_target_properties(areoBorderless PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "WindowsOnly!!!")
set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap") set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles") set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")

234
examples/areoBorderless.c Normal file
View File

@ -0,0 +1,234 @@
#if defined(_MSC_VER)
// Make MS math.h define M_PI
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define GLAD_GL_IMPLEMENTATION
#include <glad/gl.h>
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <Windows.h>
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void button_callback(GLFWwindow* window, int button, int action, int mods);
int leftMousePressed = 0;
int leftMouseClicked = 0;
int lestMouseReleased = 0;
void moveWindow(GLFWwindow* window)
{
int resizeFrameSize = 5;
int grabBarSize = 20;
int windowWidth;
int windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
int windowPosX;
int windowPosY;
glfwGetWindowPos(window, &windowPosX, &windowPosY);
double mousePositionInWindowX;
double mousePositionInWindowY;
glfwGetCursorPos(window, &mousePositionInWindowX, &mousePositionInWindowY);
static double lastMousePositionInWindowX = 0;
static double lastMousePositionInWindowY = 0;
int mouseUpdated = 0;
if (lastMousePositionInWindowX != mousePositionInWindowX || lastMousePositionInWindowY != mousePositionInWindowY)
{
lastMousePositionInWindowX = mousePositionInWindowX;
lastMousePositionInWindowY = mousePositionInWindowY;
mouseUpdated = 1;
}
static int lockX = 0;
static int lockY = 0;
static int grabActive = 0;
if (leftMouseClicked)
{
if (mousePositionInWindowX > resizeFrameSize && mousePositionInWindowX < windowWidth - resizeFrameSize &&
mousePositionInWindowY > resizeFrameSize && mousePositionInWindowY < grabBarSize + resizeFrameSize)
{
lockX = mousePositionInWindowX;
lockY = mousePositionInWindowY;
grabActive = 1;
}
}
if (lestMouseReleased)
{
grabActive = 0;
}
if (grabActive && mouseUpdated)
{
int currentX = windowPosX + mousePositionInWindowX - lockX;
int currentY = windowPosY + mousePositionInWindowY - lockY;
glfwSetWindowPos(window, currentX, currentY);
}
}
void resizeWidnow(GLFWwindow* window)
{
int resizeFrameSize = 4;
int grabBarSize = 20;
int windowWidth;
int windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
int windowPosX;
int windowPosY;
glfwGetWindowPos(window, &windowPosX, &windowPosY);
double mousePositionInWindowX;
double mousePositionInWindowY;
glfwGetCursorPos(window, &mousePositionInWindowX, &mousePositionInWindowY);
static double lastMousePositionInWindowX = 0;
static double lastMousePositionInWindowY = 0;
int mouseUpdated = 0;
enum resizeType {
LEFT_TOP = 1 << 0,
RIGHT_TOP = 1 << 1,
LEFT_BOTTOM = 1 << 2,
RIGHT_BOTTOM = 1 << 3,
LEFT = 1 << 4,
RIGHT = 1 << 5,
TOP = 1 << 6,
BOTTOM = 1 << 7
};
enum resizeType type = 0;
if (mousePositionInWindowX >= 0 && mousePositionInWindowX < resizeFrameSize)
{
type |= LEFT;
}
if (mousePositionInWindowX <= windowWidth && mousePositionInWindowX > windowWidth - resizeFrameSize)
{
type |= RIGHT;
}
if (mousePositionInWindowY >= 0 && mousePositionInWindowY < resizeFrameSize)
{
type |= TOP;
}
if (mousePositionInWindowY <= windowHeight && mousePositionInWindowY > windowHeight - resizeFrameSize)
{
type |= BOTTOM;
}
if (type == (LEFT & TOP))
{
type = LEFT_TOP;
}
else if (type == (RIGHT & TOP))
{
type = RIGHT_TOP;
}
else if (type == (LEFT & BOTTOM))
{
type = LEFT_BOTTOM;
}
else if (type == (RIGHT & BOTTOM))
{
type = RIGHT_BOTTOM;
}
//printf("%d", type);
}
/* program entry */
int main(int argc, char* argv[])
{
GLFWwindow* window;
int width, height;
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_BORDERLESS_AREO, GLFW_TRUE);
window = glfwCreateWindow(800, 600, "areoBorderless", NULL, NULL);
if (!window)
{
fprintf(stderr, "Failed to open GLFW window\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, button_callback);
glfwSetWindowPos(window, 300, 200);
glfwSetWindowBorderlessResizeBorderSize(window, 8);
glfwSetWindowTitle(window, "Hello");
while (!glfwWindowShouldClose(window))
{
int w, h;
glfwGetWindowSize(window, &w, &h);
// printf("%d, %d\n", w, h);
leftMouseClicked = 0;
lestMouseReleased = 0;
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
exit(EXIT_SUCCESS);
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_E && action == GLFW_PRESS)
glfwIconifyWindow(window);
if (key == GLFW_KEY_W && action == GLFW_PRESS)
glfwMaximizeWindow(window);
if (key == GLFW_KEY_Q && action == GLFW_PRESS)
glfwRestoreWindow(window);
}
void button_callback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS)
{
leftMouseClicked = 1;
leftMousePressed = 1;
}
else if (button == GLFW_MOUSE_BUTTON_1 && action == GLFW_RELEASE)
{
leftMousePressed = 0;
lestMouseReleased = 1;
}
}

View File

@ -878,8 +878,16 @@ extern "C" {
* [window attribute](@ref GLFW_DECORATED_attrib). * [window attribute](@ref GLFW_DECORATED_attrib).
*/ */
#define GLFW_DECORATED 0x00020005 #define GLFW_DECORATED 0x00020005
/*! @brief Window borderless areo window hint and attribute
*
* This hint works only for windows!
*
* Window borderless areo [window hint](@ref GLFW_BORDERLESS_AREO_hint) and
* [window attribute](@ref GLFW_BORDERLESS_AREO_attrib).
*/
#define GLFW_BORDERLESS_AREO 0x00020015
/*! @brief Window auto-iconification window hint and attribute /*! @brief Window auto-iconification window hint and attribute
* *
* Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and * Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and
* [window attribute](@ref GLFW_AUTO_ICONIFY_attrib). * [window attribute](@ref GLFW_AUTO_ICONIFY_attrib).
*/ */
@ -3229,7 +3237,40 @@ GLFWAPI int glfwWindowShouldClose(GLFWwindow* window);
* *
* @ingroup window * @ingroup window
*/ */
GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int height);
/*! @brief Sets the resize border size of the window when the window is borderless with areao(WINDOWS)
*
* This function sets the window resize border size when the window is in broderles-areo mode.
*
* @param[in] window The window whose title to change.
* @param[in] resize border size.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*/
GLFWAPI void glfwSetWindowBorderlessResizeBorderSize(GLFWwindow* window, int size);
/*! @brief Sets the grab area of the window when the window is borderless with areao(WINDOWS)
*
* This function sets the window grab area when the window is in broderles-areo mode.
*
* @param[in] window The window whose title to change.
* @param[in] x position of the grab area.
* @param[in] y position of the grab area.
* @param[in] width of the grab area.
* @param[in] height of the grab area.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*/
GLFWAPI void glfwSetWindowBorderlessGrabArea(GLFWwindow* window, int xpos, int ypos, int width, int height);
/*! @brief Sets the title of the specified window. /*! @brief Sets the title of the specified window.
* *
@ -3254,6 +3295,7 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
* *
* @ingroup window * @ingroup window
*/ */
GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
/*! @brief Sets the icon for the specified window. /*! @brief Sets the icon for the specified window.

View File

@ -397,6 +397,7 @@ struct _GLFWwndconfig
GLFWbool resizable; GLFWbool resizable;
GLFWbool visible; GLFWbool visible;
GLFWbool decorated; GLFWbool decorated;
GLFWbool borderlessAreo;
GLFWbool focused; GLFWbool focused;
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
@ -524,6 +525,7 @@ struct _GLFWwindow
// Window settings and state // Window settings and state
GLFWbool resizable; GLFWbool resizable;
GLFWbool decorated; GLFWbool decorated;
GLFWbool borderLessAreo;
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
GLFWbool focusOnShow; GLFWbool focusOnShow;
@ -704,6 +706,8 @@ struct _GLFWplatform
// window // window
GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*); GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*);
void (*destroyWindow)(_GLFWwindow*); void (*destroyWindow)(_GLFWwindow*);
void (*setWindowBorderlessResizeBorderSize)(_GLFWwindow*, int);
void (*setWindowBorderlessGrabArea)(_GLFWwindow*, int, int, int, int);
void (*setWindowTitle)(_GLFWwindow*,const char*); void (*setWindowTitle)(_GLFWwindow*,const char*);
void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*); void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*);
void (*getWindowPos)(_GLFWwindow*,int*,int*); void (*getWindowPos)(_GLFWwindow*,int*,int*);

View File

@ -71,6 +71,8 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwSetGammaRampNull, _glfwSetGammaRampNull,
_glfwCreateWindowNull, _glfwCreateWindowNull,
_glfwDestroyWindowNull, _glfwDestroyWindowNull,
_glfwSetWindowBorderlessResizeBorderSizeNull,
_glfwSetWindowBorderlessGrabAreaNull,
_glfwSetWindowTitleNull, _glfwSetWindowTitleNull,
_glfwSetWindowIconNull, _glfwSetWindowIconNull,
_glfwGetWindowPosNull, _glfwGetWindowPosNull,

View File

@ -87,6 +87,8 @@ void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowNull(_GLFWwindow* window); void _glfwDestroyWindowNull(_GLFWwindow* window);
void _glfwSetWindowBorderlessResizeBorderSizeNull(_GLFWwindow* window, int size);
void _glfwSetWindowBorderlessGrabAreaNull(_GLFWwindow* window, int xpos, int ypos, int width, int height);
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);

View File

@ -179,6 +179,14 @@ void _glfwDestroyWindowNull(_GLFWwindow* window)
window->context.destroy(window); window->context.destroy(window);
} }
void _glfwSetWindowBorderlessResizeBorderSizeNull(_GLFWwindow* window, int size)
{
}
void _glfwSetWindowBorderlessGrabAreaNull(_GLFWwindow* window, int xpos, int ypos, int width, int height)
{
}
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title) void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title)
{ {
} }

View File

@ -636,6 +636,8 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
_glfwSetGammaRampWin32, _glfwSetGammaRampWin32,
_glfwCreateWindowWin32, _glfwCreateWindowWin32,
_glfwDestroyWindowWin32, _glfwDestroyWindowWin32,
_glfwSetWindowBorderlessResizeBorderSizeWin32,
_glfwSetWindowBorderlessGrabAreaWin32,
_glfwSetWindowTitleWin32, _glfwSetWindowTitleWin32,
_glfwSetWindowIconWin32, _glfwSetWindowIconWin32,
_glfwGetWindowPosWin32, _glfwGetWindowPosWin32,

View File

@ -432,6 +432,15 @@ typedef struct _GLFWwindowWin32
int lastCursorPosX, lastCursorPosY; int lastCursorPosX, lastCursorPosY;
// The last received high surrogate when decoding pairs of UTF-16 messages // The last received high surrogate when decoding pairs of UTF-16 messages
WCHAR highSurrogate; WCHAR highSurrogate;
struct grabAreaStruct {
int x;
int y;
int width;
int height;
} grabArea;
int resizeBorderSize;
} _GLFWwindowWin32; } _GLFWwindowWin32;
// Win32-specific global data // Win32-specific global data
@ -541,6 +550,8 @@ void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* ys
GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowWin32(_GLFWwindow* window); void _glfwDestroyWindowWin32(_GLFWwindow* window);
void _glfwSetWindowBorderlessResizeBorderSizeWin32(_GLFWwindow* window, int size);
void _glfwSetWindowBorderlessGrabAreaWin32(_GLFWwindow* window, int xpos, int ypos, int width, int height);
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title); void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images); void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos); void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos);

View File

@ -49,7 +49,11 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
{ {
style |= WS_SYSMENU | WS_MINIMIZEBOX; style |= WS_SYSMENU | WS_MINIMIZEBOX;
if (window->decorated) if (window->borderLessAreo)
{
style |= WS_POPUP | WS_THICKFRAME | WS_CAPTION | WS_MAXIMIZEBOX;
}
else if (window->decorated)
{ {
style |= WS_CAPTION; style |= WS_CAPTION;
@ -63,6 +67,78 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
return style; return style;
} }
LRESULT hit_test(_GLFWwindow* window, int posX, int posY)
{
RECT windowRect;
if (!GetWindowRect(window->win32.handle, &windowRect)) {
return HTNOWHERE;
}
enum region_mask {
non = 0b00000,
left = 0b0001,
right = 0b0010,
top = 0b0100,
bottom = 0b1000,
};
enum region_mask result =
left * (posX < (windowRect.left + window->win32.resizeBorderSize)) |
right * (posX >= (windowRect.right - window->win32.resizeBorderSize)) |
top * (posY < (windowRect.top + window->win32.resizeBorderSize)) |
bottom * (posY >= (windowRect.bottom - window->win32.resizeBorderSize));
if (result == non)
{
if ((posX >= (windowRect.left + window->win32.grabArea.x)) &&
posX <= (windowRect.left + window->win32.grabArea.x + window->win32.grabArea.width) &&
posY >= (windowRect.top + window->win32.grabArea.y) &&
posY <= (windowRect.top + window->win32.grabArea.y + window->win32.grabArea.height))
{
return HTCAPTION;
}
else
{
return HTCLIENT;
}
}
switch (result) {
case left: return HTLEFT;
case right: return HTRIGHT;
case top: return HTTOP;
case bottom: return HTBOTTOM;
case top | left: return HTTOPLEFT;
case top | right: return HTTOPRIGHT;
case bottom | left: return HTBOTTOMLEFT;
case bottom | right: return HTBOTTOMRIGHT;
default: return HTCLIENT;
}
}
int adjust_maximized_client_rect(_GLFWwindow* window, RECT* rect){
WINDOWPLACEMENT placement;
if (!GetWindowPlacement(window->win32.handle, &placement))
return 0;
if (placement.showCmd != SW_MAXIMIZE)
return 0;
auto monitor = MonitorFromWindow(window->win32.handle, MONITOR_DEFAULTTONULL);
if (!monitor)
return 0;
MONITORINFO monitor_info;
monitor_info.cbSize = sizeof(monitor_info);
if (!GetMonitorInfoW(monitor, &monitor_info))
return 0;
(*rect) = monitor_info.rcWork;
return 1;
}
// Returns the extended window style for the specified window // Returns the extended window style for the specified window
// //
static DWORD getWindowExStyle(const _GLFWwindow* window) static DWORD getWindowExStyle(const _GLFWwindow* window)
@ -553,6 +629,27 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
switch (uMsg) switch (uMsg)
{ {
case WM_NCCALCSIZE:
{
if (window->borderLessAreo == GLFW_TRUE)
{
NCCALCSIZE_PARAMS* pParams = (NCCALCSIZE_PARAMS*)lParam;
if(!adjust_maximized_client_rect(window, &pParams->rgrc[0]))
pParams->rgrc[0].top -= 1;
return 0;
}
break;
}
case WM_NCHITTEST: {
if (window->borderLessAreo) {
return hit_test(window, GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
}
break;
}
case WM_MOUSEACTIVATE: case WM_MOUSEACTIVATE:
{ {
// HACK: Postpone cursor disabling when the window was activated by // HACK: Postpone cursor disabling when the window was activated by
@ -1133,11 +1230,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
// Prevent title bar from being drawn after restoring a minimized // Prevent title bar from being drawn after restoring a minimized
// undecorated window // undecorated window
if (!window->decorated) if (!window->decorated)
return TRUE; return TRUE;
break; break;
} }
case WM_DWMCOMPOSITIONCHANGED: case WM_DWMCOMPOSITIONCHANGED:
case WM_DWMCOLORIZATIONCOLORCHANGED: case WM_DWMCOLORIZATIONCOLORCHANGED:
{ {
@ -1325,8 +1420,18 @@ static int createNativeWindow(_GLFWwindow* window,
frameY = wndconfig->ypos + rect.top; frameY = wndconfig->ypos + rect.top;
} }
frameWidth = rect.right - rect.left; if (window->borderLessAreo)
frameHeight = rect.bottom - rect.top; {
frameX = (rect.right - rect.left - wndconfig->width) / 2;
frameY = (rect.bottom - rect.top - wndconfig->height) - frameX;
frameWidth = wndconfig->width;
frameHeight = wndconfig->height;
}
else
{
frameWidth = rect.right - rect.left;
frameHeight = rect.bottom - rect.top;
}
} }
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title); wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
@ -1354,7 +1459,7 @@ static int createNativeWindow(_GLFWwindow* window,
} }
SetPropW(window->win32.handle, L"GLFW", window); SetPropW(window->win32.handle, L"GLFW", window);
if (IsWindows7OrGreater()) if (IsWindows7OrGreater())
{ {
ChangeWindowMessageFilterEx(window->win32.handle, ChangeWindowMessageFilterEx(window->win32.handle,
@ -1434,6 +1539,14 @@ static int createNativeWindow(_GLFWwindow* window,
window->win32.transparent = GLFW_TRUE; window->win32.transparent = GLFW_TRUE;
} }
if (window->borderLessAreo)
{
updateWindowStyles(window);
_glfwSetWindowSizeWin32(window, frameWidth, frameHeight);
_glfwSetWindowBorderlessGrabAreaWin32(window, 0, 0, frameWidth, GetSystemMetrics(SM_CYSIZE));
window->win32.resizeBorderSize = GetSystemMetrics(SM_CXFRAME);
}
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height); _glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
return GLFW_TRUE; return GLFW_TRUE;
@ -1529,6 +1642,19 @@ void _glfwDestroyWindowWin32(_GLFWwindow* window)
DestroyIcon(window->win32.smallIcon); DestroyIcon(window->win32.smallIcon);
} }
void _glfwSetWindowBorderlessResizeBorderSizeWin32(_GLFWwindow* window, int size)
{
window->win32.resizeBorderSize = size;
}
void _glfwSetWindowBorderlessGrabAreaWin32(_GLFWwindow* window, int xpos, int ypos, int width, int height)
{
window->win32.grabArea.x = xpos;
window->win32.grabArea.y = ypos;
window->win32.grabArea.width = width;
window->win32.grabArea.height = height;
}
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title) void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title)
{ {
WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title); WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
@ -1604,7 +1730,16 @@ void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos)
FALSE, getWindowExStyle(window)); FALSE, getWindowExStyle(window));
} }
SetWindowPos(window->win32.handle, NULL, rect.left, rect.top, 0, 0, int windowPosX = rect.left;
int windowPosY = rect.top;
if (window->borderLessAreo)
{
windowPosX = xpos;
windowPosY = ypos;
}
SetWindowPos(window->win32.handle, NULL, windowPosX, windowPosY, 0, 0,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
} }
@ -1617,6 +1752,9 @@ void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height)
*width = area.right; *width = area.right;
if (height) if (height)
*height = area.bottom; *height = area.bottom;
if(window->borderLessAreo && !window->win32.maximized)
(*height) -= 1;
} }
void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height) void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height)
@ -1645,9 +1783,18 @@ void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height)
FALSE, getWindowExStyle(window)); FALSE, getWindowExStyle(window));
} }
int windowWidth = rect.right - rect.left;
int windowHeight = rect.bottom - rect.top;
if (window->borderLessAreo)
{
windowWidth = width;
windowHeight = height;
}
SetWindowPos(window->win32.handle, HWND_TOP, SetWindowPos(window->win32.handle, HWND_TOP,
0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, windowWidth, windowHeight,
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER); SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER);
} }
} }
@ -2500,5 +2647,4 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
return window->win32.handle; return window->win32.handle;
} }
#endif // _GLFW_WIN32 #endif // _GLFW_WIN32

View File

@ -230,6 +230,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->borderLessAreo = wndconfig.borderlessAreo;
window->autoIconify = wndconfig.autoIconify; window->autoIconify = wndconfig.autoIconify;
window->floating = wndconfig.floating; window->floating = wndconfig.floating;
window->focusOnShow = wndconfig.focusOnShow; window->focusOnShow = wndconfig.focusOnShow;
@ -355,6 +356,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_BORDERLESS_AREO:
_glfw.hints.window.borderlessAreo = 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;
@ -515,6 +519,24 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value)
window->shouldClose = value; window->shouldClose = value;
} }
GLFWAPI void glfwSetWindowBorderlessResizeBorderSize(GLFWwindow* handle, int size)
{
_GLFWwindow* window = (_GLFWwindow*)handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.setWindowBorderlessResizeBorderSize(window, size);
}
GLFWAPI void glfwSetWindowBorderlessGrabArea(GLFWwindow* handle, int xpos, int ypos, int width, int height)
{
_GLFWwindow* window = (_GLFWwindow*)handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.setWindowBorderlessGrabArea(window, xpos, ypos, width, height);
}
GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;