This commit is contained in:
Robbin Marcus 2024-01-15 19:11:06 -08:00 committed by GitHub
commit f41eba80e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 463 additions and 0 deletions

View File

@ -279,6 +279,7 @@ video tutorials.
- Jonas Ådahl
- Lasse Öörni
- Leonard König
- Robbin Marcus
- All the unmentioned and anonymous contributors in the GLFW community, for bug
reports, patches, feedback, testing and encouragement

View File

@ -123,6 +123,9 @@ information on what to include when reporting a bug.
## Changelog
- Added `glfwSetWindowCaptionArea` to define caption for borderless windows (#1420)
- Added `glfwSetWindowResizeBorderSize` to set the resize area on borders for
resizing borderless windows (#1420)
- Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958)
- Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
`GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to

View File

@ -1158,6 +1158,14 @@ extern "C" {
#define GLFW_EGL_CONTEXT_API 0x00036002
#define GLFW_OSMESA_CONTEXT_API 0x00036003
#define GLFW_WINDOW_LEFT 0
#define GLFW_WINDOW_TOP 1
#define GLFW_WINDOW_RIGHT 2
#define GLFW_WINDOW_BOTTOM 3
#define GLFW_WINDOW_TOPLEFT 4
#define GLFW_WINDOW_TOPRIGHT 5
#define GLFW_WINDOW_BOTTOMLEFT 6
#define GLFW_WINDOW_BOTTOMRIGHT 7
#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002
#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003
@ -3873,6 +3881,89 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
*/
GLFWAPI void glfwFocusWindow(GLFWwindow* window);
/*! @brief Starts drag operation to the specified window.
*
* This function starts the drag operation of the specified window.
*
* @param[in] window The window to start the dragging operation.
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_drag
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI void glfwDragWindow(GLFWwindow* window);
/*! @brief Starts a resize operation with the specified window.
*
* This function starts a resize operation on one of the borders of the
* specified window.
*
* this function must be called from a pointer or touch event callback,
* otherwise it risks reacting to a different event.
*
* The borders are [GLFW_WINDOW_LEFT](@ref GLFW_GLFW_WINDOW_LEFT),
* [GLFW_WINDOW_TOP](@ref GLFW_WINDOW_TOP),
* [GLFW_WINDOW_RIGHT](@ref GLFW_WINDOW_RIGHT),
* [GLFW_WINDOW_BOTTOM](@ref GLFW_WINDOW_BOTTOM),
* [GLFW_WINDOW_TOPLEFT](@ref GLFW_WINDOW_TOPLEFT),
* [GLFW_WINDOW_TOPRIGHT](@ref GLFW_WINDOW_TOPRIGHT),
* [GLFW_WINDOW_BOTTOMLEFT](@ref GLFW_WINDOW_BOTTOMLEFT) and
* [GLFW_WINDOW_BOTTOMRIGHT](@ref GLFW_WINDOW_BOTTOMRIGHT).
*
* @param[in] window The window to start the resize operation.
* @param[in] border One of the window borders.
*
* @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.
*
* @sa @ref window_resize
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI void glfwResizeWindow(GLFWwindow* window, int border);
/*! @brief Sets the caption area for the specified window.
*
* This function sets the rectangle for the caption to drag the undecorated window.
*
* @param[in] window The window to set the caption area for.
* @param[in] offsetX The x offset from the top left of the window.
* @param[in] offsetY The y offset from the top left of the window.
* @param[in] sizeX The x size of the caption area.
* @param[in] sizeY The y size of the caption area.
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_caption_area
*
* @since Added in version 3.4.
*
* @ingroup window
*/
GLFWAPI void glfwSetWindowCaptionArea(GLFWwindow* window, int offsetX, int offsetY, int sizeX, int sizeY);
/*! @brief Sets the resize border size for the specified window.
*
* This function sets the size of border where to start the resize operation.
*
* @param[in] window The window to set the caption area for.
* @param[in] size The size of the border.
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_border_size
*
* @since Added in version 3.4.
*
* @ingroup window
*/
GLFWAPI void glfwSetWindowResizeBorderSize(GLFWwindow* window, int size);
/*! @brief Requests user attention to the specified window.
*
* This function requests user attention to the specified window. On

View File

@ -544,6 +544,8 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
_glfwHideWindowCocoa,
_glfwRequestWindowAttentionCocoa,
_glfwFocusWindowCocoa,
_glfwDragWindowCocoa,
_glfwResizeWindowCocoa,
_glfwSetWindowMonitorCocoa,
_glfwWindowFocusedCocoa,
_glfwWindowIconifiedCocoa,

View File

@ -234,6 +234,8 @@ void _glfwShowWindowCocoa(_GLFWwindow* window);
void _glfwHideWindowCocoa(_GLFWwindow* window);
void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window);
void _glfwFocusWindowCocoa(_GLFWwindow* window);
void _glfwDragWindowCocoa(_GLFWwindow* window);
void _glfwResizeWindowCocoa(_GLFWwindow* window, int border);
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window);

View File

@ -1241,6 +1241,15 @@ void _glfwFocusWindowCocoa(_GLFWwindow* window)
} // autoreleasepool
}
void _glfwDragWindowCocoa(_GLFWwindow* window)
{
[window->ns.object performWindowDragWithEvent:[NSApp currentEvent]];
}
void _glfwResizeWindowCocoa(_GLFWwindow* window, int border)
{
}
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,

View File

@ -542,6 +542,11 @@ struct _GLFWwindow
int maxwidth, maxheight;
int numer, denom;
// Caption for undecorated window dragging functionality
int captionOffsetX, captionOffsetY;
int captionSizeX, captionSizeY;
int resizeBorderSize;
GLFWbool stickyKeys;
GLFWbool stickyMouseButtons;
GLFWbool lockKeyMods;
@ -725,6 +730,8 @@ struct _GLFWplatform
void (*hideWindow)(_GLFWwindow*);
void (*requestWindowAttention)(_GLFWwindow*);
void (*focusWindow)(_GLFWwindow*);
void (*dragWindow)(_GLFWwindow*);
void (*resizeWindow)(_GLFWwindow*,int);
void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int);
GLFWbool (*windowFocused)(_GLFWwindow*);
GLFWbool (*windowIconified)(_GLFWwindow*);

View File

@ -88,6 +88,8 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwHideWindowNull,
_glfwRequestWindowAttentionNull,
_glfwFocusWindowNull,
_glfwDragWindowNull,
_glfwResizeWindowNull,
_glfwSetWindowMonitorNull,
_glfwWindowFocusedNull,
_glfwWindowIconifiedNull,

View File

@ -241,6 +241,8 @@ void _glfwShowWindowNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwHideWindowNull(_GLFWwindow* window);
void _glfwFocusWindowNull(_GLFWwindow* window);
void _glfwDragWindowNull(_GLFWwindow* window);
void _glfwResizeWindowNull(_GLFWwindow* window, int border);
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window);

View File

@ -468,6 +468,19 @@ void _glfwFocusWindowNull(_GLFWwindow* window)
_glfwInputWindowFocus(window, GLFW_TRUE);
}
void _glfwDragWindowNull(_GLFWwindow* window)
{
}
void _glfwResizeWindowNull(_GLFWwindow* window, int border)
{
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return _glfw.null.focusedWindow == window;
}
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window)
{
return _glfw.null.focusedWindow == window;

View File

@ -652,6 +652,8 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
_glfwHideWindowWin32,
_glfwRequestWindowAttentionWin32,
_glfwFocusWindowWin32,
_glfwDragWindowWin32,
_glfwResizeWindowWin32,
_glfwSetWindowMonitorWin32,
_glfwWindowFocusedWin32,
_glfwWindowIconifiedWin32,

View File

@ -559,6 +559,8 @@ void _glfwShowWindowWin32(_GLFWwindow* window);
void _glfwHideWindowWin32(_GLFWwindow* window);
void _glfwRequestWindowAttentionWin32(_GLFWwindow* window);
void _glfwFocusWindowWin32(_GLFWwindow* window);
void _glfwDragWindowWin32(_GLFWwindow* window);
void _glfwResizeWindowWin32(_GLFWwindow* window, int border);
void _glfwSetWindowMonitorWin32(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedWin32(_GLFWwindow* window);

View File

@ -34,6 +34,7 @@
#include <string.h>
#include <windowsx.h>
#include <shellapi.h>
#include <assert.h>
// Returns the window style for the specified window
//
@ -55,7 +56,12 @@ static DWORD getWindowStyle(const _GLFWwindow* window)
style |= WS_MAXIMIZEBOX | WS_THICKFRAME;
}
else
{
style |= WS_POPUP;
if (window->resizable)
style |= WS_MAXIMIZEBOX | WS_THICKFRAME;
}
}
return style;
@ -523,6 +529,54 @@ static void maximizeWindowManually(_GLFWwindow* window)
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
static int HitTest(_GLFWwindow* window, RECT windowRect, POINT cursor, POINT border)
{
const int captionOffsetX = window->captionOffsetX != GLFW_DONT_CARE ? window->captionOffsetX : 0;
const int captionOffsetY = window->captionOffsetY != GLFW_DONT_CARE ? window->captionOffsetY : 0;
const int captionSizeX = window->captionSizeX != GLFW_DONT_CARE ? window->captionSizeX : windowRect.right - windowRect.left;
const int captionSizeY = window->captionSizeY;
const int clientAreaLeft = windowRect.left + border.x;
const int clientAreaRight = windowRect.right - border.x;
const int clientAreaTop = windowRect.top + border.y;
const int clientAreaBottom = windowRect.bottom - border.y;
const int cursorInCaption =
cursor.x > clientAreaLeft + captionOffsetX &&
cursor.x < clientAreaLeft + captionOffsetX + captionSizeX &&
cursor.y > clientAreaTop + captionOffsetY &&
cursor.y < clientAreaTop + captionOffsetY + captionSizeY;
enum region_mask
{
client = 0,
left = 1,
right = 2,
top = 4,
bottom = 8,
};
const int result =
left * (cursor.x < clientAreaLeft) |
right * (cursor.x >= clientAreaRight) |
top * (cursor.y < clientAreaTop) |
bottom * (cursor.y >= clientAreaBottom);
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;
case client: return cursorInCaption ? HTCAPTION : HTCLIENT;
default: return HTNOWHERE;
}
}
// Window procedure for user-created windows
//
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@ -1240,6 +1294,38 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
DragFinish(drop);
return 0;
}
case WM_NCCALCSIZE:
{
if (wParam && !window->decorated)
return 0;
break;
}
case WM_NCHITTEST:
{
if (!window->decorated)
{
POINT cursor =
{
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam)
};
POINT border =
{
window->resizable ? window->resizeBorderSize : 0,
window->resizable ? window->resizeBorderSize : 0,
};
RECT rect;
if (!GetWindowRect(hWnd, &rect))
return HTNOWHERE;
return HitTest(window, rect, cursor, border);
}
break;
}
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@ -1767,6 +1853,55 @@ void _glfwFocusWindowWin32(_GLFWwindow* window)
SetFocus(window->win32.handle);
}
void _glfwDragWindowWin32(_GLFWwindow* window)
{
ReleaseCapture();
SendMessage(window->win32.handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
// Mouse button will be released after drag, so prepare released state here already
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_1, GLFW_RELEASE, 0);
}
void _glfwResizeWindowWin32(_GLFWwindow* window, int border)
{
WPARAM wBorder;
switch (border)
{
case GLFW_WINDOW_LEFT:
wBorder = HTLEFT;
break;
case GLFW_WINDOW_TOP:
wBorder = HTTOP;
break;
case GLFW_WINDOW_RIGHT:
wBorder = HTRIGHT;
break;
case GLFW_WINDOW_BOTTOM:
wBorder = HTBOTTOM;
break;
case GLFW_WINDOW_TOPLEFT:
wBorder = HTTOPLEFT;
break;
case GLFW_WINDOW_TOPRIGHT:
wBorder = HTTOPRIGHT;
break;
case GLFW_WINDOW_BOTTOMLEFT:
wBorder = HTBOTTOMLEFT;
break;
case GLFW_WINDOW_BOTTOMRIGHT:
wBorder = HTBOTTOMRIGHT;
break;
default:
assert(GLFW_FALSE);
return;
}
ReleaseCapture();
SendMessage(window->win32.handle, WM_NCLBUTTONDOWN, wBorder, 0);
// Mouse button will be released after drag, so prepare released state here already
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_1, GLFW_RELEASE, 0);
}
void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,

View File

@ -243,6 +243,13 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->numer = GLFW_DONT_CARE;
window->denom = GLFW_DONT_CARE;
window->captionOffsetX = GLFW_DONT_CARE;
window->captionOffsetY = GLFW_DONT_CARE;
window->captionSizeX = GLFW_DONT_CARE;
window->captionSizeY = 16;
window->resizeBorderSize = 4;
if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig))
{
glfwDestroyWindow((GLFWwindow*) window);
@ -843,6 +850,58 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
_glfw.platform.focusWindow(window);
}
GLFWAPI void glfwDragWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.dragWindow(window);
}
GLFWAPI void glfwResizeWindow(GLFWwindow* handle, int border)
{
_GLFWwindow* window = (_GLFWwindow*)handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (border < GLFW_WINDOW_LEFT || border > GLFW_WINDOW_BOTTOMRIGHT)
return;
_glfw.platform.resizeWindow(window, border);
}
GLFWAPI void glfwSetWindowCaptionArea(GLFWwindow* handle, int offsetX, int offsetY, int sizeX, int sizeY)
{
_GLFWwindow* window = (_GLFWwindow*)handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (offsetX < 0 || offsetY < 0 || sizeX < 1 || sizeY < 1)
return;
window->captionOffsetX = offsetX;
window->captionOffsetY = offsetY;
window->captionSizeX = sizeX;
window->captionSizeY = sizeY;
}
GLFWAPI void glfwSetWindowResizeBorderSize(GLFWwindow* handle, int size)
{
_GLFWwindow* window = (_GLFWwindow*)handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (size < 1)
return;
window->resizeBorderSize = size;
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{
_GLFWwindow* window = (_GLFWwindow*) handle;

View File

@ -462,6 +462,8 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
_glfwHideWindowWayland,
_glfwRequestWindowAttentionWayland,
_glfwFocusWindowWayland,
_glfwDragWindowWayland,
_glfwResizeWindowWayland,
_glfwSetWindowMonitorWayland,
_glfwWindowFocusedWayland,
_glfwWindowIconifiedWayland,

View File

@ -629,6 +629,8 @@ void _glfwShowWindowWayland(_GLFWwindow* window);
void _glfwHideWindowWayland(_GLFWwindow* window);
void _glfwRequestWindowAttentionWayland(_GLFWwindow* window);
void _glfwFocusWindowWayland(_GLFWwindow* window);
void _glfwDragWindowWayland(_GLFWwindow* window);
void _glfwResizeWindowWayland(_GLFWwindow* window, int border);
void _glfwSetWindowMonitorWayland(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window);

View File

@ -40,6 +40,7 @@
#include <sys/mman.h>
#include <sys/timerfd.h>
#include <poll.h>
#include <assert.h>
#include "wayland-client-protocol.h"
#include "xdg-shell-client-protocol.h"
@ -2357,6 +2358,49 @@ void _glfwFocusWindowWayland(_GLFWwindow* window)
"Wayland: The platform does not support setting the input focus");
}
void _glfwDragWindowWayland(_GLFWwindow* window)
{
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, _glfw.wl.serial);
}
void _glfwResizeWindowWayland(_GLFWwindow* window, int border)
{
int wlBorder;
switch (border)
{
case GLFW_WINDOW_LEFT:
wlBorder = WL_SHELL_SURFACE_RESIZE_LEFT;
break;
case GLFW_WINDOW_TOP:
wlBorder = WL_SHELL_SURFACE_RESIZE_TOP;
break;
case GLFW_WINDOW_RIGHT:
wlBorder = WL_SHELL_SURFACE_RESIZE_RIGHT;
break;
case GLFW_WINDOW_BOTTOM:
wlBorder = WL_SHELL_SURFACE_RESIZE_BOTTOM;
break;
case GLFW_WINDOW_TOPLEFT:
wlBorder = WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
break;
case GLFW_WINDOW_TOPRIGHT:
wlBorder = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT;
break;
case GLFW_WINDOW_BOTTOMLEFT:
wlBorder = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
break;
case GLFW_WINDOW_BOTTOMRIGHT:
wlBorder = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
break;
default:
assert(GLFW_FALSE);
}
xdg_toplevel_resize(window->wl.xdg.toplevel,
_glfw.wl.seat,
_glfw.wl.serial,
wlBorder);
}
void _glfwSetWindowMonitorWayland(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,

View File

@ -1223,6 +1223,8 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
_glfwHideWindowX11,
_glfwRequestWindowAttentionX11,
_glfwFocusWindowX11,
_glfwDragWindowX11,
_glfwResizeWindowX11,
_glfwSetWindowMonitorX11,
_glfwWindowFocusedX11,
_glfwWindowIconifiedX11,

View File

@ -921,6 +921,8 @@ void _glfwShowWindowX11(_GLFWwindow* window);
void _glfwHideWindowX11(_GLFWwindow* window);
void _glfwRequestWindowAttentionX11(_GLFWwindow* window);
void _glfwFocusWindowX11(_GLFWwindow* window);
void _glfwDragWindowX11(_GLFWwindow* window);
void _glfwResizeWindowX11(_GLFWwindow* window, int border);
void _glfwSetWindowMonitorX11(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedX11(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedX11(_GLFWwindow* window);

View File

@ -45,6 +45,15 @@
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
#define _NET_WM_MOVERESIZE_MOVE 8
// Additional mouse button names for XButtonEvent
#define Button6 6
@ -2464,6 +2473,78 @@ void _glfwFocusWindowX11(_GLFWwindow* window)
XFlush(_glfw.x11.display);
}
void _glfwDragWindowX11(_GLFWwindow* window)
{
int winXpos, winYpos;
double curXpos, curYpos;
XClientMessageEvent xclient;
memset(&xclient, 0, sizeof(XClientMessageEvent));
XUngrabPointer(_glfw.x11.display, 0);
XFlush(_glfw.x11.display);
_glfwGetCursorPosX11(window, &curXpos, &curYpos);
_glfwGetWindowPosX11(window, &winXpos, &winYpos);
xclient.type = ClientMessage;
xclient.window = window->x11.handle;
xclient.message_type = XInternAtom(_glfw.x11.display, "_NET_WM_MOVERESIZE", False);
xclient.format = 32;
xclient.data.l[0] = winXpos + curXpos;
xclient.data.l[1] = winYpos + curYpos;
xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent(_glfw.x11.display, _glfw.x11.root, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
}
void _glfwResizeWindowX11(_GLFWwindow* window, int border)
{
int winXpos, winYpos;
double curXpos, curYpos;
XClientMessageEvent xclient;
memset(&xclient, 0, sizeof(XClientMessageEvent));
XUngrabPointer(_glfw.x11.display, 0);
XFlush(_glfw.x11.display);
_glfwGetCursorPosX11(window, &curXpos, &curYpos);
_glfwGetWindowPosX11(window, &winXpos, &winYpos);
xclient.type = ClientMessage;
xclient.window = window->x11.handle;
xclient.message_type = XInternAtom(_glfw.x11.display, "_NET_WM_MOVERESIZE", False);
xclient.format = 32;
xclient.data.l[0] = winXpos + curXpos;
xclient.data.l[1] = winYpos + curYpos;
switch (border)
{
case GLFW_WINDOW_LEFT:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_LEFT;
break;
case GLFW_WINDOW_TOP:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_TOP;
break;
case GLFW_WINDOW_RIGHT:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_RIGHT;
break;
case GLFW_WINDOW_BOTTOM:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
break;
case GLFW_WINDOW_TOPLEFT:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
break;
case GLFW_WINDOW_TOPRIGHT:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
break;
case GLFW_WINDOW_BOTTOMLEFT:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
break;
case GLFW_WINDOW_BOTTOMRIGHT:
xclient.data.l[2] = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
break;
default:
assert(GLFW_FALSE);
}
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent(_glfw.x11.display, _glfw.x11.root, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
}
void _glfwSetWindowMonitorX11(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,