Added glfwDragWindow function to latest platform structure

Based on work by Felipe da Silva (felselva) #987 ported to v3.4

Add a function glfwDragWindow that starts a drag operation for the
specified window. The implementation is done for X11, Windows, and
requires tests on Wayland. Patch is related with the issue #923.
This commit is contained in:
Naveen K 2022-07-13 17:14:28 +05:30
parent aa80d24d01
commit cefef4a4cc
20 changed files with 90 additions and 0 deletions

View File

@ -121,6 +121,7 @@ information on what to include when reporting a bug.
## Changelog ## Changelog
- Added `glfwDragWindow` function for starting a drag operation on a window
- Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958) - Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958)
- Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, - Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
`GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to

View File

@ -31,6 +31,12 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods){
if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS){
glfwDragWindow(window);
}
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int xpos, ypos, height; int xpos, ypos, height;
@ -79,6 +85,7 @@ int main(int argc, char** argv)
xpos + size * (1 + (i & 1)), xpos + size * (1 + (i & 1)),
ypos + size * (1 + (i >> 1))); ypos + size * (1 + (i >> 1)));
glfwSetInputMode(windows[i], GLFW_STICKY_KEYS, GLFW_TRUE); glfwSetInputMode(windows[i], GLFW_STICKY_KEYS, GLFW_TRUE);
glfwSetMouseButtonCallback(windows[i], mouse_button_callback);
glfwMakeContextCurrent(windows[i]); glfwMakeContextCurrent(windows[i]);
gladLoadGL(glfwGetProcAddress); gladLoadGL(glfwGetProcAddress);

View File

@ -3842,6 +3842,23 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
*/ */
GLFWAPI void glfwFocusWindow(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.
*
* @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.
*
* @since Added in version 3.4.
*
* @ingroup window
*/
GLFWAPI void glfwDragWindow(GLFWwindow* handle);
/*! @brief Requests user attention to the specified window. /*! @brief Requests user attention to the specified window.
* *
* This function requests user attention to the specified window. On * This function requests user attention to the specified window. On

View File

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

View File

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

View File

@ -1218,6 +1218,11 @@ void _glfwFocusWindowCocoa(_GLFWwindow* window)
} // autoreleasepool } // autoreleasepool
} }
void _glfwDragWindowCocoa(_GLFWwindow* window)
{
// TODO
}
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,

View File

@ -724,6 +724,7 @@ struct _GLFWplatform
void (*hideWindow)(_GLFWwindow*); void (*hideWindow)(_GLFWwindow*);
void (*requestWindowAttention)(_GLFWwindow*); void (*requestWindowAttention)(_GLFWwindow*);
void (*focusWindow)(_GLFWwindow*); void (*focusWindow)(_GLFWwindow*);
void (*dragWindow)(_GLFWwindow*);
void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int); void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int);
GLFWbool (*windowFocused)(_GLFWwindow*); GLFWbool (*windowFocused)(_GLFWwindow*);
GLFWbool (*windowIconified)(_GLFWwindow*); GLFWbool (*windowIconified)(_GLFWwindow*);

View File

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

View File

@ -118,6 +118,7 @@ void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window); void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwHideWindowNull(_GLFWwindow* window); void _glfwHideWindowNull(_GLFWwindow* window);
void _glfwFocusWindowNull(_GLFWwindow* window); void _glfwFocusWindowNull(_GLFWwindow* window);
void _glfwDragWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window); GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window); GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window); GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window);

View File

@ -461,6 +461,11 @@ void _glfwFocusWindowNull(_GLFWwindow* window)
_glfwInputWindowFocus(window, GLFW_TRUE); _glfwInputWindowFocus(window, GLFW_TRUE);
} }
void _glfwDragWindowNull(_GLFWwindow* window)
{
// TODO
}
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window) GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window)
{ {
return _glfw.null.focusedWindow == window; return _glfw.null.focusedWindow == window;

View File

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

View File

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

View File

@ -1751,6 +1751,12 @@ void _glfwFocusWindowWin32(_GLFWwindow* window)
SetFocus(window->win32.handle); SetFocus(window->win32.handle);
} }
void _glfwDragWindowWin32(_GLFWwindow* window)
{
ReleaseCapture();
SendMessage(window->win32.handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
void _glfwSetWindowMonitorWin32(_GLFWwindow* window, void _glfwSetWindowMonitorWin32(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,

View File

@ -833,6 +833,16 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
_glfw.platform.focusWindow(window); _glfw.platform.focusWindow(window);
} }
GLFWAPI void glfwDragWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfw.platform.dragWindow(window);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;

View File

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

View File

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

View File

@ -2087,6 +2087,11 @@ void _glfwFocusWindowWayland(_GLFWwindow* window)
"Wayland: The platform does not support setting the input focus"); "Wayland: The platform does not support setting the input focus");
} }
void _glfwDragWindowWayland(_GLFWwindow* window)
{
wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, _glfw.wl.pointerSerial);
}
void _glfwSetWindowMonitorWayland(_GLFWwindow* window, void _glfwSetWindowMonitorWayland(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,

View File

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

View File

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

View File

@ -45,6 +45,7 @@
#define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1 #define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2 #define _NET_WM_STATE_TOGGLE 2
#define _NET_WM_MOVERESIZE_MOVE 8
// Additional mouse button names for XButtonEvent // Additional mouse button names for XButtonEvent
#define Button6 6 #define Button6 6
@ -2405,6 +2406,28 @@ void _glfwFocusWindowX11(_GLFWwindow* window)
XFlush(_glfw.x11.display); 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 _glfwSetWindowMonitorX11(_GLFWwindow* window, void _glfwSetWindowMonitorX11(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,