mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
Add GLFW_SCALE_TO_MONITOR
This adds the GLFW_SCALE_TO_MONITOR window hint for automatically resizing the content area of a window to the requested size times the monitor content scale each time it is placed on a new monitor. This only applies to windowed mode windows and includes the initial placement at window creation. This hint only has an effect on platforms where screen coordinates and pixels always map 1:1 such as Windows and X11. Platforms like macOS instead change the resolution of the framebuffer independently of the window size. Related to #676. Related to #1115.
This commit is contained in:
parent
5294439595
commit
089ea9af22
@ -73,6 +73,10 @@ glfwGetWindowContentScale and @ref glfwGetMonitorContentScale.
|
|||||||
Changes of the content scale of a window can be received with the window content
|
Changes of the content scale of a window can be received with the window content
|
||||||
scale callback, set with @ref glfwSetWindowContentScaleCallback.
|
scale callback, set with @ref glfwSetWindowContentScaleCallback.
|
||||||
|
|
||||||
|
The @ref GLFW_SCALE_TO_MONITOR window hint enables automatic resizing of a
|
||||||
|
window by the content scale of the monitor it is placed, on platforms like
|
||||||
|
Windows and X11 where this is necessary.
|
||||||
|
|
||||||
@see @ref window_scale
|
@see @ref window_scale
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,6 +238,17 @@ does not affect window decorations. Possible values are `GLFW_TRUE` and
|
|||||||
__GLFW_FOCUS_ON_SHOW__ specifies whether the window will be given input
|
__GLFW_FOCUS_ON_SHOW__ specifies whether the window will be given input
|
||||||
focus when @ref glfwShowWindow is called. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
focus when @ref glfwShowWindow is called. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
|
|
||||||
|
@anchor GLFW_SCALE_TO_MONITOR
|
||||||
|
__GLFW_SCALE_TO_MONITOR__ specified whether the window content area should be
|
||||||
|
resized based on the [monitor content scale](@ref monitor_scale) of any monitor
|
||||||
|
it is placed on. This includes the initial placement when the window is
|
||||||
|
created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
||||||
|
|
||||||
|
This hint only has an effect on platforms where screen coordinates and pixels
|
||||||
|
always map 1:1 such as Windows and X11. On platforms like macOS the resolution
|
||||||
|
of the framebuffer is changed independently of the window size.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_fb Framebuffer related hints
|
@subsubsection window_hints_fb Framebuffer related hints
|
||||||
|
|
||||||
@anchor GLFW_RED_BITS
|
@anchor GLFW_RED_BITS
|
||||||
@ -493,6 +504,7 @@ GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GL
|
|||||||
GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
|
GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
@ -716,6 +728,12 @@ void window_content_scale_callback(GLFWwindow* window, float xscale, float yscal
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
On platforms where pixels and screen coordinates always map 1:1, the window
|
||||||
|
will need to be resized to appear the same size when it is moved to a monitor
|
||||||
|
with a different content scale. To have this done automatically both when the
|
||||||
|
window is created and when its content scale later changes, set the @ref
|
||||||
|
GLFW_SCALE_TO_MONITOR window hint.
|
||||||
|
|
||||||
|
|
||||||
@subsection window_sizelimits Window size limits
|
@subsection window_sizelimits Window size limits
|
||||||
|
|
||||||
|
@ -973,6 +973,10 @@ extern "C" {
|
|||||||
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
* [attribute](@ref GLFW_CLIENT_API_attrib).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||||
|
/*! @brief Window content area scaling window
|
||||||
|
* [window hint](@ref GLFW_SCALE_TO_MONITOR).
|
||||||
|
*/
|
||||||
|
#define GLFW_SCALE_TO_MONITOR 0x0002200C
|
||||||
|
|
||||||
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001
|
||||||
#define GLFW_COCOA_FRAME_NAME 0x00023002
|
#define GLFW_COCOA_FRAME_NAME 0x00023002
|
||||||
|
@ -268,6 +268,7 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
GLFWbool centerCursor;
|
GLFWbool centerCursor;
|
||||||
GLFWbool focusOnShow;
|
GLFWbool focusOnShow;
|
||||||
|
GLFWbool scaleToMonitor;
|
||||||
struct {
|
struct {
|
||||||
GLFWbool retina;
|
GLFWbool retina;
|
||||||
char frameName[256];
|
char frameName[256];
|
||||||
|
@ -306,6 +306,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
// Whether to enable framebuffer transparency on DWM
|
// Whether to enable framebuffer transparency on DWM
|
||||||
GLFWbool transparent;
|
GLFWbool transparent;
|
||||||
|
GLFWbool scaleToMonitor;
|
||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
@ -1063,6 +1063,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
case WM_GETDPISCALEDSIZE:
|
case WM_GETDPISCALEDSIZE:
|
||||||
{
|
{
|
||||||
|
if (window->win32.scaleToMonitor)
|
||||||
|
break;
|
||||||
|
|
||||||
// Adjust the window size to keep the client area size constant
|
// Adjust the window size to keep the client area size constant
|
||||||
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
||||||
{
|
{
|
||||||
@ -1230,15 +1233,34 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust window size to account for the DPI scaled window frame
|
window->win32.scaleToMonitor = wndconfig->scaleToMonitor;
|
||||||
|
|
||||||
|
// Adjust window size to account for DPI scaling of the window frame and
|
||||||
|
// optionally DPI scaling of the client area
|
||||||
// This cannot be done until we know what monitor it was placed on
|
// This cannot be done until we know what monitor it was placed on
|
||||||
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32() && !window->monitor)
|
if (!window->monitor)
|
||||||
{
|
{
|
||||||
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
|
||||||
|
|
||||||
|
if (wndconfig->scaleToMonitor)
|
||||||
|
{
|
||||||
|
float xscale, yscale;
|
||||||
|
_glfwPlatformGetWindowContentScale(window, &xscale, &yscale);
|
||||||
|
rect.right = (int) (rect.right * xscale);
|
||||||
|
rect.bottom = (int) (rect.bottom * yscale);
|
||||||
|
}
|
||||||
|
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
||||||
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
||||||
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
|
|
||||||
GetDpiForWindow(window->win32.handle));
|
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
|
||||||
|
{
|
||||||
|
AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
|
||||||
|
GetDpiForWindow(window->win32.handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
|
||||||
|
|
||||||
SetWindowPos(window->win32.handle, NULL,
|
SetWindowPos(window->win32.handle, NULL,
|
||||||
rect.left, rect.top,
|
rect.left, rect.top,
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
|
@ -369,6 +369,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
case GLFW_SCALE_TO_MONITOR:
|
||||||
|
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
return;
|
||||||
case GLFW_CENTER_CURSOR:
|
case GLFW_CENTER_CURSOR:
|
||||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
|
@ -592,6 +592,15 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
const _GLFWwndconfig* wndconfig,
|
const _GLFWwndconfig* wndconfig,
|
||||||
Visual* visual, int depth)
|
Visual* visual, int depth)
|
||||||
{
|
{
|
||||||
|
int width = wndconfig->width;
|
||||||
|
int height = wndconfig->height;
|
||||||
|
|
||||||
|
if (wndconfig->scaleToMonitor)
|
||||||
|
{
|
||||||
|
width *= _glfw.x11.contentScaleX;
|
||||||
|
height *= _glfw.x11.contentScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a colormap based on the visual used by the current context
|
// Create a colormap based on the visual used by the current context
|
||||||
window->x11.colormap = XCreateColormap(_glfw.x11.display,
|
window->x11.colormap = XCreateColormap(_glfw.x11.display,
|
||||||
_glfw.x11.root,
|
_glfw.x11.root,
|
||||||
@ -617,7 +626,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
window->x11.handle = XCreateWindow(_glfw.x11.display,
|
||||||
_glfw.x11.root,
|
_glfw.x11.root,
|
||||||
0, 0,
|
0, 0,
|
||||||
wndconfig->width, wndconfig->height,
|
width, height,
|
||||||
0, // Border width
|
0, // Border width
|
||||||
depth, // Color depth
|
depth, // Color depth
|
||||||
InputOutput,
|
InputOutput,
|
||||||
@ -720,7 +729,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
XFree(hints);
|
XFree(hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNormalHints(window, wndconfig->width, wndconfig->height);
|
updateNormalHints(window, width, height);
|
||||||
|
|
||||||
// Set ICCCM WM_CLASS property
|
// Set ICCCM WM_CLASS property
|
||||||
{
|
{
|
||||||
|
@ -99,6 +99,8 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
monitor = glfwGetPrimaryMonitor();
|
monitor = glfwGetPrimaryMonitor();
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(800, 400, "Gamma Test", NULL, NULL);
|
window = glfwCreateWindow(800, 400, "Gamma Test", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
@ -200,6 +200,8 @@ int main(int argc, char** argv)
|
|||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL);
|
window = glfwCreateWindow(width, height, "Input lag test", monitor, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
@ -180,6 +180,8 @@ int main(void)
|
|||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(800, 600, "Joystick Test", NULL, NULL);
|
window = glfwCreateWindow(800, 600, "Joystick Test", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
@ -57,6 +57,8 @@ int main(int argc, char** argv)
|
|||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow(400, 400, "Opacity", NULL, NULL);
|
window = glfwCreateWindow(400, 400, "Opacity", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user