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:
parent
7d73629e50
commit
0f9a9578f3
@ -141,6 +141,9 @@ information on what to include when reporting a bug.
|
||||
through the window (#1236,#1568)
|
||||
- Added `GLFW_CURSOR_CAPTURED` cursor mode to confine the cursor to the window
|
||||
content area (#58)
|
||||
- Added `GLFW_POSITION_X` and `GLFW_POSITION_Y` window hints for initial position
|
||||
(#1603,#1747)
|
||||
- Added `GLFW_ANY_POSITION` hint value for letting the window manager choose (#1603,#1747)
|
||||
- Added `GLFW_PLATFORM_UNAVAILABLE` error for platform detection failures (#1958)
|
||||
- Added `GLFW_FEATURE_UNAVAILABLE` error for platform limitations (#1692)
|
||||
- Added `GLFW_FEATURE_UNIMPLEMENTED` error for incomplete backends (#1692)
|
||||
|
@ -76,6 +76,14 @@ function pointers corresponding to the standard library functions `malloc`,
|
||||
For more information see @ref init_allocator.
|
||||
|
||||
|
||||
@subsubsection features_34_position_hint Window hints for initial position
|
||||
|
||||
GLFW now provides the @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints for
|
||||
specifying the initial position of the window. This removes the need to create a hidden
|
||||
window, move it and then show it. The default value of these hints is
|
||||
`GLFW_ANY_POSITION`, which selects the previous behavior.
|
||||
|
||||
|
||||
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
|
||||
|
||||
GLFW now provides the
|
||||
@ -243,6 +251,9 @@ then GLFW will fail to initialize.
|
||||
- @ref GLFW_ANGLE_PLATFORM_TYPE_METAL
|
||||
- @ref GLFW_X11_XCB_VULKAN_SURFACE
|
||||
- @ref GLFW_CURSOR_CAPTURED
|
||||
- @ref GLFW_POSITION_X
|
||||
- @ref GLFW_POSITION_Y
|
||||
- @ref GLFW_ANY_POSITION
|
||||
|
||||
|
||||
@section news_archive Release notes for earlier versions
|
||||
|
@ -256,6 +256,14 @@ This is only supported for undecorated windows. Decorated windows with this
|
||||
enabled will behave differently between platforms. Possible values are
|
||||
`GLFW_TRUE` and `GLFW_FALSE`.
|
||||
|
||||
@anchor GLFW_POSITION_X
|
||||
@anchor GLFW_POSITION_Y
|
||||
__GLFW_POSITION_X__ and __GLFW_POSITION_Y__ specify the desired initial position
|
||||
of the window. The window manager may modify or ignore these coordinates. If
|
||||
either or both of these hints are set to `GLFW_ANY_POSITION` then the window
|
||||
manager will position the window where it thinks the user will prefer it.
|
||||
Possible values are any valid screen coordinates and `GLFW_ANY_POSITION`.
|
||||
|
||||
|
||||
@subsubsection window_hints_fb Framebuffer related hints
|
||||
|
||||
@ -516,6 +524,8 @@ GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GL
|
||||
GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
GLFW_MOUSE_PASSTHROUGH | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
GLFW_POSITION_X | `GLFW_ANY_POSITION` | Any valid screen x-coordinate or `GLFW_ANY_POSITION`
|
||||
GLFW_POSITION_Y | `GLFW_ANY_POSITION` | Any valid screen y-coordinate or `GLFW_ANY_POSITION`
|
||||
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_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||
@ -798,7 +808,20 @@ are undefined if they conflict.
|
||||
|
||||
@subsection window_pos Window position
|
||||
|
||||
The position of a windowed-mode window can be changed with @ref
|
||||
By default, the window manager chooses the position of new windowed mode
|
||||
windows, based on its size and which monitor the user appears to be working on.
|
||||
This is most often the right choice. If you need to create a window at
|
||||
a specific position, you can set the desired position with the @ref
|
||||
GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints.
|
||||
|
||||
@code
|
||||
glfwWindowHint(GLFW_POSITION_X, 70);
|
||||
glfwWindowHint(GLFW_POSITION_Y, 83);
|
||||
@endcode
|
||||
|
||||
To restore the previous behavior, set these hints to `GLFW_ANY_POSITION`.
|
||||
|
||||
The position of a windowed mode window can be changed with @ref
|
||||
glfwSetWindowPos. This moves the window so that the upper-left corner of its
|
||||
content area has the specified [screen coordinates](@ref coordinate_systems).
|
||||
The window system may put limitations on window placement.
|
||||
|
@ -44,7 +44,6 @@ int main(int argc, char** argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
|
||||
|
||||
glfwGetMonitorWorkarea(glfwGetPrimaryMonitor(), &xpos, &ypos, NULL, &height);
|
||||
@ -66,6 +65,9 @@ int main(int argc, char** argv)
|
||||
if (i > 0)
|
||||
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
||||
|
||||
glfwWindowHint(GLFW_POSITION_X, xpos + size * (1 + (i & 1)));
|
||||
glfwWindowHint(GLFW_POSITION_Y, ypos + size * (1 + (i >> 1)));
|
||||
|
||||
windows[i] = glfwCreateWindow(size, size, "Multi-Window Example", NULL, NULL);
|
||||
if (!windows[i])
|
||||
{
|
||||
@ -75,9 +77,6 @@ int main(int argc, char** argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSetWindowPos(windows[i],
|
||||
xpos + size * (1 + (i & 1)),
|
||||
ypos + size * (1 + (i >> 1)));
|
||||
glfwSetInputMode(windows[i], GLFW_STICKY_KEYS, GLFW_TRUE);
|
||||
|
||||
glfwMakeContextCurrent(windows[i]);
|
||||
@ -85,9 +84,6 @@ int main(int argc, char** argv)
|
||||
glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
glfwShowWindow(windows[i]);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
@ -927,6 +927,18 @@ extern "C" {
|
||||
*/
|
||||
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D
|
||||
|
||||
/*! @brief Initial position x-coordinate window hint.
|
||||
*
|
||||
* Initial position x-coordinate [window hint](@ref GLFW_POSITION_X).
|
||||
*/
|
||||
#define GLFW_POSITION_X 0x0002000E
|
||||
|
||||
/*! @brief Initial position y-coordinate window hint.
|
||||
*
|
||||
* Initial position y-coordinate [window hint](@ref GLFW_POSITION_Y).
|
||||
*/
|
||||
#define GLFW_POSITION_Y 0x0002000F
|
||||
|
||||
/*! @brief Framebuffer bit depth hint.
|
||||
*
|
||||
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
|
||||
@ -1152,6 +1164,8 @@ extern "C" {
|
||||
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
|
||||
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
|
||||
|
||||
#define GLFW_ANY_POSITION 0x80000000
|
||||
|
||||
/*! @defgroup shapes Standard cursor shapes
|
||||
* @brief Standard system cursor shapes.
|
||||
*
|
||||
@ -3036,10 +3050,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
|
||||
* OpenGL or OpenGL ES context.
|
||||
*
|
||||
* By default, newly created windows use the placement recommended by the
|
||||
* window system. To create the window at a specific position, make it
|
||||
* initially invisible using the [GLFW_VISIBLE](@ref GLFW_VISIBLE_hint) window
|
||||
* hint, set its [position](@ref window_pos) and then [show](@ref window_hide)
|
||||
* it.
|
||||
* window system. To create the window at a specific position, set the @ref
|
||||
* GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints before creation. To
|
||||
* restore the default behavior, set either or both hints back to
|
||||
* `GLFW_ANY_POSITION`.
|
||||
*
|
||||
* As long as at least one full screen window is not iconified, the screensaver
|
||||
* is prohibited from starting.
|
||||
|
@ -791,7 +791,19 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
@ -820,11 +832,15 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
if (window->monitor)
|
||||
[window->ns.object setLevel:NSMainMenuWindowLevel + 1];
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -396,6 +396,8 @@ struct _GLFWinitconfig
|
||||
//
|
||||
struct _GLFWwndconfig
|
||||
{
|
||||
int xpos;
|
||||
int ypos;
|
||||
int width;
|
||||
int height;
|
||||
const char* title;
|
||||
|
@ -81,9 +81,18 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
if (window->monitor)
|
||||
fitToMonitor(window);
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -96,10 +96,11 @@ int main(void)
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i);
|
||||
glfwWindowHint(GLFW_POSITION_Y, 200);
|
||||
|
||||
threads[i].window = glfwCreateWindow(200, 200,
|
||||
threads[i].title,
|
||||
NULL, NULL);
|
||||
@ -110,9 +111,6 @@ int main(void)
|
||||
}
|
||||
|
||||
glfwSetKeyCallback(threads[i].window, key_callback);
|
||||
|
||||
glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200);
|
||||
glfwShowWindow(threads[i].window);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(threads[0].window);
|
||||
|
Loading…
Reference in New Issue
Block a user