Add window hints for initial position

This adds window hints for the initial position, in screen coordinates,
of a window.  The special value GLFW_ANY_POSITION means the window
manager will be allowed to position the window.

It is not possible to set window positions on Wayland and GLFW will
always behave as if these hints are set to GLFW_ANY_POSITION.

Fixes #1603
Fixes #1747
This commit is contained in:
Camilla Löwy
2021-10-26 14:25:03 +02:00
parent 7d73629e50
commit 0f9a9578f3
12 changed files with 138 additions and 31 deletions
+21 -5
View File
@@ -791,7 +791,19 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height);
}
else
contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height);
{
if (wndconfig->xpos == GLFW_ANY_POSITION ||
wndconfig->ypos == GLFW_ANY_POSITION)
{
contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height);
}
else
{
const int xpos = wndconfig->xpos;
const int ypos = _glfwTransformYCocoa(wndconfig->ypos + wndconfig->height - 1);
contentRect = NSMakeRect(xpos, ypos, wndconfig->width, wndconfig->height);
}
}
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
@@ -821,10 +833,14 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
else
{
[(NSWindow*) window->ns.object center];
_glfw.ns.cascadePoint =
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
if (wndconfig->xpos == GLFW_ANY_POSITION ||
wndconfig->ypos == GLFW_ANY_POSITION)
{
[(NSWindow*) window->ns.object center];
_glfw.ns.cascadePoint =
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
}
if (wndconfig->resizable)
{
+2
View File
@@ -396,6 +396,8 @@ struct _GLFWinitconfig
//
struct _GLFWwndconfig
{
int xpos;
int ypos;
int width;
int height;
const char* title;
+11 -2
View File
@@ -82,8 +82,17 @@ static int createNativeWindow(_GLFWwindow* window,
fitToMonitor(window);
else
{
window->null.xpos = 17;
window->null.ypos = 17;
if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION)
{
window->null.xpos = 17;
window->null.ypos = 17;
}
else
{
window->null.xpos = wndconfig->xpos;
window->null.ypos = wndconfig->ypos;
}
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
}
+16 -6
View File
@@ -1316,17 +1316,27 @@ static int createNativeWindow(_GLFWwindow* window,
}
else
{
xpos = CW_USEDEFAULT;
ypos = CW_USEDEFAULT;
RECT rect = { 0, 0, wndconfig->width, wndconfig->height };
window->win32.maximized = wndconfig->maximized;
if (wndconfig->maximized)
style |= WS_MAXIMIZE;
getFullWindowSize(style, exStyle,
wndconfig->width, wndconfig->height,
&fullWidth, &fullHeight,
USER_DEFAULT_SCREEN_DPI);
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION)
{
xpos = CW_USEDEFAULT;
ypos = CW_USEDEFAULT;
}
else
{
xpos = wndconfig->xpos + rect.left;
ypos = wndconfig->ypos + rect.top;
}
fullWidth = rect.right - rect.left;
fullHeight = rect.bottom - rect.top;
}
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
+8
View File
@@ -274,6 +274,8 @@ void glfwDefaultWindowHints(void)
_glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = GLFW_TRUE;
_glfw.hints.window.focusOnShow = GLFW_TRUE;
_glfw.hints.window.xpos = GLFW_ANY_POSITION;
_glfw.hints.window.ypos = GLFW_ANY_POSITION;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered
@@ -368,6 +370,12 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
return;
case GLFW_POSITION_X:
_glfw.hints.window.xpos = value;
return;
case GLFW_POSITION_Y:
_glfw.hints.window.ypos = value;
return;
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
return;
+18 -1
View File
@@ -575,6 +575,14 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
height *= _glfw.x11.contentScaleY;
}
int xpos = 0, ypos = 0;
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
{
xpos = wndconfig->xpos;
ypos = wndconfig->ypos;
}
// Create a colormap based on the visual used by the current context
window->x11.colormap = XCreateColormap(_glfw.x11.display,
_glfw.x11.root,
@@ -595,7 +603,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
window->x11.parent = _glfw.x11.root;
window->x11.handle = XCreateWindow(_glfw.x11.display,
_glfw.x11.root,
0, 0, // Position
xpos, ypos,
width, height,
0, // Border width
depth, // Color depth
@@ -714,6 +722,15 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
hints->min_height = hints->max_height = height;
}
// HACK: Explicitly setting PPosition to any value causes some WMs, notably
// Compiz and Metacity, to honor the position of unmapped windows
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
{
hints->flags |= PPosition;
hints->x = 0;
hints->y = 0;
}
hints->flags |= PWinGravity;
hints->win_gravity = StaticGravity;