瀏覽代碼

Added glfwGetWindowFrameSize.

Camilla Berglund 11 年之前
父節點
當前提交
eb3f75e03e
共有 10 個文件被更改,包括 130 次插入0 次删除
  1. 2 0
      README.md
  2. 6 0
      docs/news.dox
  3. 27 0
      include/GLFW/glfw3.h
  4. 19 0
      src/cocoa_window.m
  5. 5 0
      src/internal.h
  6. 22 0
      src/win32_window.c
  7. 9 0
      src/window.c
  8. 2 0
      src/x11_init.c
  9. 1 0
      src/x11_platform.h
  10. 37 0
      src/x11_window.c

+ 2 - 0
README.md

@@ -54,6 +54,8 @@ The following dependencies are needed by the examples and test programs:
  - Added `glfwPostEmptyEvent` for allowing secondary threads to cause
    `glfwWaitEvents` to return
  - Added `empty` test program for verifying posting of empty events
+ - Added `glfwGetWindowFrameSize` for retrieving the size of the frame around
+   the client area of a window
  - Added `GLFW_INCLUDE_ES31` for including the OpenGL ES 3.1 header
  - Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even
            when a debug context had not been requested

+ 6 - 0
docs/news.dox

@@ -27,6 +27,12 @@ event from a secondary thread to the main thread event queue, causing @ref
 glfwWaitEvents to return.
 
 
+@subsection news_31_framesize Window frame size query
+
+GLFW now supports querying the size, on each side, of the frame around the
+client area of a window, with @ref glfwGetWindowFrameSize.
+
+
 @section news_30 New features in version 3.0
 
 @subsection news_30_cmake CMake build system

+ 27 - 0
include/GLFW/glfw3.h

@@ -1498,6 +1498,33 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
  */
 GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height);
 
+/*! @brief Retrieves the size of the frame of the window.
+ *
+ *  This function retrieves the size, in screen coordinates, of each edge of the
+ *  frame of the specified window.  This size includes the title bar, if the
+ *  window has one.  The size of the frame may vary depending on the
+ *  [window-related hints](@ref window_hints_wnd) used to create it.
+ *
+ *  @param[in] window The window whose frame size to query.
+ *  @param[out] left Where to store the size, in screen coordinates, of the left
+ *  edge of the window frame.
+ *  @param[out] top Where to store the offset, in screen coordinates, of the top
+ *  edge of the window frame.
+ *  @param[out] right Where to store the offset, in screen coordinates, of the
+ *  right edge of the window frame.
+ *  @param[out] bottom Where to store the offset, in screen coordinates, of the
+ *  bottom edge of the window frame.
+ *
+ *  @remarks This function returns the size of each window frame edge, not its
+ *  offset from the client area edge, so the returned values will always be zero
+ *  or positive.
+ *
+ *  @note This function may only be called from the main thread.
+ *
+ *  @ingroup window
+ */
+GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom);
+
 /*! @brief Iconifies the specified window.
  *
  *  This function iconifies/minimizes the specified window, if it was previously

+ 19 - 0
src/cocoa_window.m

@@ -1091,6 +1091,25 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
         *height = (int) fbRect.size.height;
 }
 
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+                                     int* left, int* top,
+                                     int* right, int* bottom)
+{
+    const NSRect contentRect = [window->ns.view frame];
+    const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect];
+
+    if (left)
+        *left = contentRect.origin.x - frameRect.origin.x;
+    if (top)
+        *top = frameRect.origin.y + frameRect.size.height -
+               contentRect.origin.y - contentRect.size.height;
+    if (right)
+        *right = frameRect.origin.x + frameRect.size.width -
+                 contentRect.origin.x - contentRect.size.width;
+    if (bottom)
+        *bottom = contentRect.origin.y - frameRect.origin.y;
+}
+
 void _glfwPlatformIconifyWindow(_GLFWwindow* window)
 {
     if (window->monitor)

+ 5 - 0
src/internal.h

@@ -524,6 +524,11 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
  */
 void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
 
+/*! @copydoc glfwGetWindowFrameSize
+ *  @ingroup platform
+ */
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
+
 /*! @copydoc glfwIconifyWindow
  *  @ingroup platform
  */

+ 22 - 0
src/win32_window.c

@@ -1120,6 +1120,28 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
     _glfwPlatformGetWindowSize(window, width, height);
 }
 
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+                                     int* left, int* top,
+                                     int* right, int* bottom)
+{
+    RECT rect;
+    int width, height;
+
+    _glfwPlatformGetWindowSize(window, &width, &height);
+    SetRect(&rect, 0, 0, width, height);
+    AdjustWindowRectEx(&rect, window->win32.dwStyle,
+                       FALSE, window->win32.dwExStyle);
+
+    if (left)
+        *left = -rect.left;
+    if (top)
+        *top = -rect.top;
+    if (right)
+        *right = rect.right - width;
+    if (bottom)
+        *bottom = rect.bottom - height;
+}
+
 void _glfwPlatformIconifyWindow(_GLFWwindow* window)
 {
     ShowWindow(window->win32.handle, SW_MINIMIZE);

+ 9 - 0
src/window.c

@@ -488,6 +488,15 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
     _glfwPlatformGetFramebufferSize(window, width, height);
 }
 
+GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
+                                    int* left, int* top,
+                                    int* right, int* bottom)
+{
+    _GLFWwindow* window = (_GLFWwindow*) handle;
+    _GLFW_REQUIRE_INIT();
+    _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom);
+}
+
 GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
 {
     _GLFWwindow* window = (_GLFWwindow*) handle;

+ 2 - 0
src/x11_init.c

@@ -415,6 +415,8 @@ static void detectEWMH(void)
         getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");
     _glfw.x11.NET_ACTIVE_WINDOW =
         getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
+    _glfw.x11.NET_FRAME_EXTENTS =
+        getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
     _glfw.x11.NET_WM_BYPASS_COMPOSITOR =
         getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_BYPASS_COMPOSITOR");
 

+ 1 - 0
src/x11_platform.h

@@ -120,6 +120,7 @@ typedef struct _GLFWlibraryX11
     Atom            NET_WM_STATE_FULLSCREEN;
     Atom            NET_WM_BYPASS_COMPOSITOR;
     Atom            NET_ACTIVE_WINDOW;
+    Atom            NET_FRAME_EXTENTS;
     Atom            MOTIF_WM_HINTS;
 
     // Xdnd (drag and drop) atoms

+ 37 - 0
src/x11_window.c

@@ -1234,6 +1234,43 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
     _glfwPlatformGetWindowSize(window, width, height);
 }
 
+void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
+                                     int* left, int* top,
+                                     int* right, int* bottom)
+{
+    long* extents = NULL;
+
+    if (left)
+        *left = 0;
+    if (top)
+        *top = 0;
+    if (right)
+        *right = 0;
+    if (bottom)
+        *bottom = 0;
+
+    if (_glfw.x11.NET_FRAME_EXTENTS == None)
+        return;
+
+    if (_glfwGetWindowProperty(window->x11.handle,
+                               _glfw.x11.NET_FRAME_EXTENTS,
+                               XA_CARDINAL,
+                               (unsigned char**) &extents) == 4)
+    {
+        if (left)
+            *left = extents[0];
+        if (top)
+            *top = extents[2];
+        if (right)
+            *right = extents[1];
+        if (bottom)
+            *bottom = extents[3];
+    }
+
+    if (extents)
+        XFree(extents);
+}
+
 void _glfwPlatformIconifyWindow(_GLFWwindow* window)
 {
     if (window->x11.overrideRedirect)