This commit is contained in:
Carsten Tewes 2024-02-02 20:07:07 +00:00 committed by GitHub
commit 59d0b4c79e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 126 additions and 0 deletions

View File

@ -122,6 +122,8 @@ information on what to include when reporting a bug.
## Changelog since 3.3.9
- Added `glfwGetMonitorFromWindow` function to query the monitor where the
largest part of a window is currently located (#1699)
- Added `GLFW_PLATFORM` init hint for runtime platform selection (#1958)
- Added `GLFW_ANY_PLATFORM`, `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
`GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` and `GLFW_PLATFORM_NULL` symbols to

View File

@ -907,6 +907,19 @@ glfwSetWindowIcon(window, 0, NULL);
@endcode
@subsection window_monitor_from Window monitor
Windows are always located on one or more monitors. You can get the
handle for the monitor were the biggest part of a specified window is
currently located with @ref glfwGetMonitorFromWindow
@code
GLFWmonitor* monitor = glfwGetMonitorFromWindow(window);
@endcode
This monitor handle is one of those returned by @ref glfwGetMonitors.
@subsection window_monitor Window monitor
Full screen windows are associated with a specific monitor. You can get the

View File

@ -3900,6 +3900,28 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
*/
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window);
/*! @brief Returns the monitor with the largest intersection area of the window
*
* This function returns the handle of the monitor which has the largest area of
* intersection with the area of the specified window
*
* @param[in] window The window to query.
* @return The monitor, or `NULL`
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_monitor
* @sa @ref glfwGetWindowMonitor
*
* @since Added in version 3.4.
*
* @ingroup window
*/
GLFWAPI GLFWmonitor* glfwGetMonitorFromWindow(GLFWwindow* window);
/*! @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

@ -952,6 +952,95 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
}
typedef struct _rect { int x, y; int w, h; } _rect;
#define RECT_INTERSECTS(ra, rb) \
((ra)->x <= ((rb)->x + (rb)->w) && ((ra)->x + (ra)->w) >= (rb)->x && \
(ra)->y <= ((rb)->y + (rb)->h) && ((ra)->y + (ra)->h) >= (rb)->y)
static _rect _get_intersection(_rect* ra, _rect* rb)
{
_rect result = { 0, 0, 0, 0 };
if (RECT_INTERSECTS(ra, rb))
{
result.x = _glfw_max(ra->x, rb->x);
result.w = _glfw_min((ra->x + ra->w), (rb->x + rb->w)) - result.x;
result.y = _glfw_max(ra->y, rb->y);
result.h = _glfw_min((ra->y + ra->h), (rb->y + rb->h)) - result.y;
}
return result;
}
GLFWAPI GLFWmonitor* glfwGetMonitorFromWindow(GLFWwindow* window)
{
GLFWmonitor* result = NULL;
int monitorCount;
GLFWmonitor** monitors;
const GLFWvidmode* vidmode;
unsigned int currentDim, overlapDim;
int overlapMonitor, i;
_rect windowRect;
_rect monitorRect;
_rect scratchRect = { 0, 0, 0, 0 };
_rect overlapRect = { 0, 0, 0, 0 };
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
monitors = glfwGetMonitors(&monitorCount);
if (monitorCount == 1)
{
result = monitors[0];
}
else if (monitorCount > 1)
{
glfwGetWindowPos(window, &windowRect.x, &windowRect.y);
glfwGetWindowSize(window, &windowRect.w, &windowRect.h);
glfwGetWindowFrameSize(window, &scratchRect.x, &scratchRect.y,
&scratchRect.w, &scratchRect.h);
windowRect.x -= scratchRect.x;
windowRect.y -= scratchRect.y;
windowRect.w += scratchRect.x + scratchRect.w;
windowRect.h += scratchRect.y + scratchRect.h;
overlapMonitor = -1;
for (i = 0; i < monitorCount; i++)
{
glfwGetMonitorPos(monitors[i], &monitorRect.x, &monitorRect.y);
vidmode = glfwGetVideoMode(monitors[i]);
monitorRect.w = vidmode->width;
monitorRect.h = vidmode->height;
scratchRect = _get_intersection(&windowRect, &monitorRect);
currentDim = scratchRect.w * scratchRect.h;
overlapDim = overlapRect.w * overlapRect.h;
if (currentDim > 0 && currentDim > overlapDim)
{
overlapRect = scratchRect;
overlapMonitor = i;
}
}
if (overlapMonitor >= 0)
{
result = monitors[overlapMonitor];
}
}
return result;
}
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;