Implementation of glfwDragWindow for X11

This is the initial implementation of glfwDragWindow, with support for
X11. The function glfwDragWindow requires only the target window to be
dragged. To make the function easier and more portable, the position of
the window and of the cursor are grabbed internally, so the end-user do
not need to pass them manually.

The example 'simple.c' was updated to include this functionality when
clicking on the client area of the window.
This commit is contained in:
Felipe Ferreira da Silva 2017-04-05 22:14:09 -03:00
parent 66b16f1fc1
commit b9d2ea9fa6
5 changed files with 56 additions and 0 deletions

View File

@ -68,6 +68,12 @@ static void error_callback(int error, const char* description)
fprintf(stderr, "Error: %s\n", description);
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
glfwDragWindow(window);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
@ -96,6 +102,7 @@ int main(void)
}
glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);

View File

@ -2751,6 +2751,25 @@ 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.
*
* @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_drag
*
* @since Added in version 3.2.
*
* @ingroup window
*/
GLFWAPI void glfwDragWindow(GLFWwindow* handle);
/*! @brief Returns the monitor that the window uses for full screen mode.
*
* This function returns the handle of the monitor that the specified window is

View File

@ -631,6 +631,7 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
void _glfwPlatformShowWindow(_GLFWwindow* window);
void _glfwPlatformHideWindow(_GLFWwindow* window);
void _glfwPlatformFocusWindow(_GLFWwindow* window);
void _glfwPlatformDragWindow(_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);

View File

@ -698,6 +698,16 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
_glfwPlatformFocusWindow(window);
}
GLFWAPI void glfwDragWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfwPlatformDragWindow(window);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{
_GLFWwindow* window = (_GLFWwindow*) handle;

View File

@ -43,6 +43,7 @@
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2
#define _NET_WM_MOVERESIZE_MOVE 8
// Additional mouse button names for XButtonEvent
#define Button6 6
@ -2091,6 +2092,24 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
XFlush(_glfw.x11.display);
}
void _glfwPlatformDragWindow(_GLFWwindow* window)
{
XClientMessageEvent xclient;
memset(&xclient, 0, sizeof(XClientMessageEvent));
XUngrabPointer(_glfw.x11.display, 0);
XFlush(_glfw.x11.display);
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] = window->x11.xpos + window->x11.lastCursorPosX;
xclient.data.l[1] = window->x11.ypos + window->x11.lastCursorPosY;
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 _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,