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:
Camilla Löwy
2018-08-31 13:33:48 +02:00
parent 5294439595
commit 089ea9af22
12 changed files with 76 additions and 6 deletions
+1
View File
@@ -268,6 +268,7 @@ struct _GLFWwndconfig
GLFWbool maximized;
GLFWbool centerCursor;
GLFWbool focusOnShow;
GLFWbool scaleToMonitor;
struct {
GLFWbool retina;
char frameName[256];
+1
View File
@@ -306,6 +306,7 @@ typedef struct _GLFWwindowWin32
GLFWbool maximized;
// Whether to enable framebuffer transparency on DWM
GLFWbool transparent;
GLFWbool scaleToMonitor;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;
+26 -4
View File
@@ -1063,6 +1063,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_GETDPISCALEDSIZE:
{
if (window->win32.scaleToMonitor)
break;
// Adjust the window size to keep the client area size constant
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
{
@@ -1230,15 +1233,34 @@ static int createNativeWindow(_GLFWwindow* window,
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
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32() && !window->monitor)
if (!window->monitor)
{
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.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,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
+3
View File
@@ -369,6 +369,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
return;
case GLFW_SCALE_TO_MONITOR:
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
return;
case GLFW_CENTER_CURSOR:
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
return;
+11 -2
View File
@@ -592,6 +592,15 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
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
window->x11.colormap = XCreateColormap(_glfw.x11.display,
_glfw.x11.root,
@@ -617,7 +626,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
window->x11.handle = XCreateWindow(_glfw.x11.display,
_glfw.x11.root,
0, 0,
wndconfig->width, wndconfig->height,
width, height,
0, // Border width
depth, // Color depth
InputOutput,
@@ -720,7 +729,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
XFree(hints);
}
updateNormalHints(window, wndconfig->width, wndconfig->height);
updateNormalHints(window, width, height);
// Set ICCCM WM_CLASS property
{