diff --git a/glfw/cocoa_monitor.m b/glfw/cocoa_monitor.m index 6a8ff0d67..9742faccd 100644 --- a/glfw/cocoa_monitor.m +++ b/glfw/cocoa_monitor.m @@ -468,6 +468,24 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, *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/glfw/glfw3.h b/glfw/glfw3.h index d531d2243..59835edeb 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1937,6 +1937,31 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); */ 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/glfw/internal.h b/glfw/internal.h index dce8d7ae1..11d8a3f5c 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -619,6 +619,7 @@ void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor); 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/glfw/monitor.c b/glfw/monitor.c index 6ab31b277..32a955126 100644 --- a/glfw/monitor.c +++ b/glfw/monitor.c @@ -330,6 +330,25 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) _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/glfw/null_monitor.c b/glfw/null_monitor.c index 77431ad8f..136731835 100644 --- a/glfw/null_monitor.c +++ b/glfw/null_monitor.c @@ -49,6 +49,10 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, *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/glfw/x11_init.c b/glfw/x11_init.c index 87ba62787..3f6cd9c4f 100644 --- a/glfw/x11_init.c +++ b/glfw/x11_init.c @@ -137,6 +137,8 @@ static void detectEWMH(void) 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/glfw/x11_monitor.c b/glfw/x11_monitor.c index 17b3812cc..61100d58a 100644 --- a/glfw/x11_monitor.c +++ b/glfw/x11_monitor.c @@ -349,6 +349,22 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, *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/glfw/x11_platform.h b/glfw/x11_platform.h index 01597ab72..070ce84f1 100644 --- a/glfw/x11_platform.h +++ b/glfw/x11_platform.h @@ -248,6 +248,7 @@ typedef struct _GLFWlibraryX11 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;