Support for resize operation on X11

This adds the function ```glfwResizeWindow```, that allows to resize
windows without borders.
This commit is contained in:
Felipe Ferreira da Silva 2017-04-07 21:35:58 -03:00
parent 66b16f1fc1
commit cd02f4ac30
4 changed files with 109 additions and 0 deletions

View File

@ -900,6 +900,15 @@ 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
/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.
*
@ -2751,6 +2760,36 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
*/
GLFWAPI void glfwFocusWindow(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.
*
* 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 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 _glfwPlatformResizeWindow(_GLFWwindow* window, int border);
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,19 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
_glfwPlatformFocusWindow(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;
_glfwPlatformResizeWindow(window, border);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{
_GLFWwindow* window = (_GLFWwindow*) handle;

View File

@ -43,6 +43,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
// Additional mouse button names for XButtonEvent
#define Button6 6
@ -2091,6 +2100,53 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
XFlush(_glfw.x11.display);
}
void _glfwPlatformResizeWindow(_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);
_glfwPlatformGetCursorPos(window, &curXpos, &curYpos);
_glfwPlatformGetWindowPos(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;
}
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,