Add glfwGetMonitorWorkarea This function retrieves the work area rectangle of the specified monitor. Related to #920. Closes #989.
diff --git a/README.md b/README.md index 382b5b5..af7a3b1 100644 --- a/README.md +++ b/README.md
@@ -141,6 +141,7 @@ (#235,#439,#677,#845,#898) - Added `glfwRequestWindowAttention` function for requesting attention from the user (#732,#988) +- Added `glfwGetMonitorWorkarea` function for querying the monitor work area - Added `glfwGetKeyScancode` function that allows retrieving platform dependent scancodes for keys (#830) - Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
diff --git a/examples/simple.c b/examples/simple.c index 7752a36..ce9c22d 100644 --- a/examples/simple.c +++ b/examples/simple.c
@@ -79,6 +79,7 @@ GLFWwindow* window; GLuint vertex_buffer, vertex_shader, fragment_shader, program; GLint mvp_location, vpos_location, vcol_location; + int workarea_x, workarea_y, workarea_width, workarea_height; glfwSetErrorCallback(error_callback); @@ -131,6 +132,8 @@ glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), (void*) (sizeof(float) * 2)); + glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &workarea_x, &workarea_y, &workarea_width, &workarea_height); + printf("Monitor work area: %d, %d, %d, %d\n", workarea_x, workarea_y, workarea_width, workarea_height); while (!glfwWindowShouldClose(window)) { float ratio;
diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 57d5c9c..3019b95 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h
@@ -1931,6 +1931,31 @@ */ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); +/*! @brief Returns the work area of the monitor. + * + * This function returns the position, in screen coordinates, of the upper-left + * corner of the specified monitor. + * + * Any or all of the position arguments may be `NULL`. If an error occurs, all + * non-`NULL` position arguments will be set to zero. + * + * @param[in] monitor The monitor to query. + * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. + * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. + * + * @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 monitor_properties + * + * @since Added in version 3.0. + * + * @ingroup monitor + */ +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height); + /*! @brief Returns the physical size of the monitor. * * This function returns the size, in millimetres, of the display area of the
diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 5767d24..736a905 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m
@@ -408,6 +408,24 @@ *yscale = (float) (pixels.size.height / points.size.height); } +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height) +{ + NSScreen *resultScreen; + for (NSScreen *screen in [NSScreen screens]) { + if ([[[screen deviceDescription] valueForKey:@"NSScreenNumber"] intValue] == monitor->ns.displayID) { + resultScreen = screen; + break; + } + } + + NSRect frameRect = [[NSScreen resultScreen] visibleFrame]; + + *xpos = NSMinX(frameRect); + *ypos = NSMinY(frameRect); + *width = NSMaxX(frameRect); + *height = NSMaxY(frameRect); +} + GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) { CFArrayRef modes;
diff --git a/src/internal.h b/src/internal.h index abba5ba..3d5e22f 100644 --- a/src/internal.h +++ b/src/internal.h
@@ -612,6 +612,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos); void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, float* xscale, float* yscale); +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height); GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count); void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode); GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
diff --git a/src/monitor.c b/src/monitor.c index 0ab865e..869fdfb 100644 --- a/src/monitor.c +++ b/src/monitor.c
@@ -330,6 +330,25 @@ _glfwPlatformGetMonitorPos(monitor, xpos, ypos); } +GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, int* xpos, int* ypos, int* width, int* height) +{ + _GLFWmonitor* monitor = (_GLFWmonitor*) handle; + assert(monitor != NULL); + + if (xpos) + *xpos = 0; + if (ypos) + *ypos = 0; + if (width) + *width = 0; + if (width) + *width = 0; + + _GLFW_REQUIRE_INIT(); + + _glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height); +} + GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) { _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
diff --git a/src/null_monitor.c b/src/null_monitor.c index 45c4a10..9979737 100644 --- a/src/null_monitor.c +++ b/src/null_monitor.c
@@ -49,6 +49,10 @@ *yscale = 1.f; } +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height) +{ +} + GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { return NULL;
diff --git a/src/win32_monitor.c b/src/win32_monitor.c index 07b3614..a8fb4fc 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c
@@ -361,6 +361,37 @@ _glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale); } +static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +{ + RECT *workarea = (RECT *)dwData; + MONITORINFO monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + workarea->left = monitorInfo.rcWork.left; + workarea->top = monitorInfo.rcWork.top; + workarea->right = monitorInfo.rcWork.right; + workarea->bottom = monitorInfo.rcWork.bottom; + return TRUE; +} + +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height) +{ + HDC dc; + RECT workarea; + + dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL); + + if (!EnumDisplayMonitors(dc, NULL, MonitorEnumProc, (LPARAM)&workarea)) + return; + + DeleteDC(dc); + + *xpos = workarea.left; + *ypos = workarea.top; + *width = workarea.right; + *height = workarea.bottom; +} + GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) { int modeIndex = 0, size = 0;
diff --git a/src/x11_init.c b/src/x11_init.c index e3e3ad5..f1e7261 100644 --- a/src/x11_init.c +++ b/src/x11_init.c
@@ -446,6 +446,8 @@ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE"); _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL"); + _glfw.x11.NET_WORKAREA = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA"); _glfw.x11.NET_ACTIVE_WINDOW = getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW"); _glfw.x11.NET_FRAME_EXTENTS =
diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 240e9fb..d0aa9f9 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c
@@ -342,6 +342,22 @@ *yscale = _glfw.x11.contentScaleY; } +void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height) +{ + if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) + { + Atom* extents = NULL; + + _glfwGetWindowPropertyX11(_glfw.x11.root, _glfw.x11.NET_WORKAREA, XA_CARDINAL, (unsigned char**) &extents); + + *xpos = extents[0]; + *ypos = extents[1]; + *width = extents[2]; + *height = extents[3]; + XFree(extents); + } +} + GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) { GLFWvidmode* result;
diff --git a/src/x11_platform.h b/src/x11_platform.h index c37c740..153daee 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h
@@ -259,6 +259,7 @@ Atom NET_WM_FULLSCREEN_MONITORS; Atom NET_WM_WINDOW_OPACITY; Atom NET_WM_CM_Sx; + Atom NET_WORKAREA; Atom NET_ACTIVE_WINDOW; Atom NET_FRAME_EXTENTS; Atom NET_REQUEST_FRAME_EXTENTS;