Add GLFW_FOCUS_ON_SHOW window hint and attribute

This adds a window hint and attribute for controlling whether
glfwShowWindow gives the specified window input focus in addition to
making it visible.

Fixes #1189.
Closes #1275.
This commit is contained in:
Doug Binks 2018-05-29 14:51:36 +01:00 committed by Camilla Löwy
parent bf6551a3ca
commit 0be4f3f75a
7 changed files with 65 additions and 7 deletions

View File

@ -165,6 +165,8 @@ information on what to include when reporting a bug.
- Added `GLFW_HOVERED` window attribute for polling cursor hover state (#1166) - Added `GLFW_HOVERED` window attribute for polling cursor hover state (#1166)
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering - Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
(#749,#842) (#749,#842)
- Added `GLFW_FOCUS_ON_SHOW` window hint and attribute to control input focus
on calling show window (#1189)
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889) - Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
- Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946) - Added `GLFW_LOCK_KEY_MODS` input mode and `GLFW_MOD_*_LOCK` mod bits (#946)
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint - Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint

View File

@ -4,6 +4,12 @@
@section news_33 Release notes for 3.3 @section news_33 Release notes for 3.3
@subsection news_33_focusonshow GLFW_FOCUS_ON_SHOW window hint and attribute
GLFW now supports the [GLFW_FOCUS_ON_SHOW](@ref GLFW_DECORATED_hint) window hint
and attribute for controlling input focus when calling @ref glfwShowWindow
@see @ref window_hide
@subsection news_33_geterror Error query @subsection news_33_geterror Error query

View File

@ -234,6 +234,9 @@ alpha channel will be used to combine the framebuffer with the background. This
does not affect window decorations. Possible values are `GLFW_TRUE` and does not affect window decorations. Possible values are `GLFW_TRUE` and
`GLFW_FALSE`. `GLFW_FALSE`.
@anchor GLFW_FOCUS_ON_SHOW_hint
__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`.
@subsubsection window_hints_fb Framebuffer related hints @subsubsection window_hints_fb Framebuffer related hints
@ -489,6 +492,7 @@ GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GL
GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
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_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`
@ -1009,6 +1013,10 @@ Hidden windows can be shown with @ref glfwShowWindow.
glfwShowWindow(window); glfwShowWindow(window);
@endcode @endcode
By default, this function will also set the input focus to that window. Set
the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint to change
this behavior for all newly created windows, or change the behavior for an
existing window with @ref glfwSetWindowAttrib.
You can also get the current visibility state with @ref glfwGetWindowAttrib. You can also get the current visibility state with @ref glfwGetWindowAttrib.
@ -1196,8 +1204,9 @@ if (glfwGetWindowAttrib(window, GLFW_FOCUSED))
The [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), The [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
[GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib), [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib),
[GLFW_FLOATING](@ref GLFW_FLOATING_attrib) and [GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) window attributes can be [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
[GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib) window attributes can be
changed with @ref glfwSetWindowAttrib. changed with @ref glfwSetWindowAttrib.
@code @code
@ -1259,6 +1268,11 @@ a transparent framebuffer, i.e. the window contents is composited with the
background using the window framebuffer alpha channel. See @ref background using the window framebuffer alpha channel. See @ref
window_transparency for details. window_transparency for details.
@anchor GLFW_FOCUS_ON_SHOW_attrib
__GLFW_FOCUS_ON_SHOW__ specifies whether the window will be given input
focus when @ref glfwShowWindow is called. This can be set before creation
with the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint or
after with @ref glfwSetWindowAttrib.
@subsubsection window_attribs_ctx Context related attributes @subsubsection window_attribs_ctx Context related attributes

View File

@ -819,6 +819,12 @@ extern "C" {
* Mouse cursor hover [window attribute](@ref GLFW_HOVERED_attrib). * Mouse cursor hover [window attribute](@ref GLFW_HOVERED_attrib).
*/ */
#define GLFW_HOVERED 0x0002000B #define GLFW_HOVERED 0x0002000B
/*! @brief Input focus on calling show window hint and attribute
*
* Input focus [window hint](@ref GLFW_FOCUS_ON_SHOW_hint) or
* [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib).
*/
#define GLFW_FOCUS_ON_SHOW 0x0002000C
/*! @brief Framebuffer bit depth hint. /*! @brief Framebuffer bit depth hint.
* *
@ -3085,6 +3091,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
* hidden. If the window is already visible or is in full screen mode, this * hidden. If the window is already visible or is in full screen mode, this
* function does nothing. * function does nothing.
* *
* By default, windowed mode windows are focused when shown
* Set the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint
* to change this behavior for all newly created windows, or change the
* behavior for an existing window with @ref glfwSetWindowAttrib.
*
* @param[in] window The window to make visible. * @param[in] window The window to make visible.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
@ -3132,6 +3143,10 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to * initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to
* disable this behavior. * disable this behavior.
* *
* Also by default, windowed mode windows are focused when shown
* with @ref glfwShowWindow. Set the
* [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) to disable this behavior.
*
* __Do not use this function__ to steal focus from other applications unless * __Do not use this function__ to steal focus from other applications unless
* you are certain that is what the user wants. Focus stealing can be * you are certain that is what the user wants. Focus stealing can be
* extremely disruptive. * extremely disruptive.
@ -3306,8 +3321,9 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
* *
* The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), * The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
* [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib), * [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib),
* [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) and * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib),
* [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib). * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and
* [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib).
* *
* Some of these attributes are ignored for full screen windows. The new * Some of these attributes are ignored for full screen windows. The new
* value will take effect if the window is later made windowed. * value will take effect if the window is later made windowed.

View File

@ -267,6 +267,7 @@ struct _GLFWwndconfig
GLFWbool floating; GLFWbool floating;
GLFWbool maximized; GLFWbool maximized;
GLFWbool centerCursor; GLFWbool centerCursor;
GLFWbool focusOnShow;
struct { struct {
GLFWbool retina; GLFWbool retina;
char frameName[256]; char frameName[256];
@ -372,6 +373,7 @@ struct _GLFWwindow
GLFWbool decorated; GLFWbool decorated;
GLFWbool autoIconify; GLFWbool autoIconify;
GLFWbool floating; GLFWbool floating;
GLFWbool focusOnShow;
GLFWbool shouldClose; GLFWbool shouldClose;
void* userPointer; void* userPointer;
GLFWvidmode videoMode; GLFWvidmode videoMode;

View File

@ -201,6 +201,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->decorated = wndconfig.decorated; window->decorated = wndconfig.decorated;
window->autoIconify = wndconfig.autoIconify; window->autoIconify = wndconfig.autoIconify;
window->floating = wndconfig.floating; window->floating = wndconfig.floating;
window->focusOnShow = wndconfig.focusOnShow;
window->cursorMode = GLFW_CURSOR_NORMAL; window->cursorMode = GLFW_CURSOR_NORMAL;
window->minwidth = GLFW_DONT_CARE; window->minwidth = GLFW_DONT_CARE;
@ -267,6 +268,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.window.focused = GLFW_TRUE; _glfw.hints.window.focused = GLFW_TRUE;
_glfw.hints.window.autoIconify = GLFW_TRUE; _glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = GLFW_TRUE; _glfw.hints.window.centerCursor = GLFW_TRUE;
_glfw.hints.window.focusOnShow = GLFW_TRUE;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered // double buffered
@ -370,6 +372,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
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;
case GLFW_FOCUS_ON_SHOW:
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
return;
case GLFW_CLIENT_API: case GLFW_CLIENT_API:
_glfw.hints.context.client = value; _glfw.hints.context.client = value;
return; return;
@ -755,6 +760,8 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
return; return;
_glfwPlatformShowWindow(window); _glfwPlatformShowWindow(window);
if (window->focusOnShow)
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
} }
@ -810,6 +817,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return _glfwPlatformWindowMaximized(window); return _glfwPlatformWindowMaximized(window);
case GLFW_HOVERED: case GLFW_HOVERED:
return _glfwPlatformWindowHovered(window); return _glfwPlatformWindowHovered(window);
case GLFW_FOCUS_ON_SHOW:
return window->focusOnShow;
case GLFW_TRANSPARENT_FRAMEBUFFER: case GLFW_TRANSPARENT_FRAMEBUFFER:
return _glfwPlatformFramebufferTransparent(window); return _glfwPlatformFramebufferTransparent(window);
case GLFW_RESIZABLE: case GLFW_RESIZABLE:
@ -886,6 +895,8 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
if (!window->monitor) if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value); _glfwPlatformSetWindowFloating(window, value);
} }
else if (attrib == GLFW_FOCUS_ON_SHOW)
window->focusOnShow = value;
else else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
} }

View File

@ -56,9 +56,10 @@ static const struct
static void usage(void) static void usage(void)
{ {
printf("Usage: windows [-h] [-b]\n"); printf("Usage: windows [-h] [-b] [-f] \n");
printf("Options:\n"); printf("Options:\n");
printf(" -b create decorated windows\n"); printf(" -b create decorated windows\n");
printf(" -f set focus on show off for all but first window\n");
printf(" -h show this help\n"); printf(" -h show this help\n");
} }
@ -92,16 +93,20 @@ int main(int argc, char** argv)
{ {
int i, ch; int i, ch;
int decorated = GLFW_FALSE; int decorated = GLFW_FALSE;
int focusOnShow = GLFW_TRUE;
int running = GLFW_TRUE; int running = GLFW_TRUE;
GLFWwindow* windows[4]; GLFWwindow* windows[4];
while ((ch = getopt(argc, argv, "bh")) != -1) while ((ch = getopt(argc, argv, "bfh")) != -1)
{ {
switch (ch) switch (ch)
{ {
case 'b': case 'b':
decorated = GLFW_TRUE; decorated = GLFW_TRUE;
break; break;
case 'f':
focusOnShow = GLFW_FALSE;
break;
case 'h': case 'h':
usage(); usage();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -122,6 +127,8 @@ int main(int argc, char** argv)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
int left, top, right, bottom; int left, top, right, bottom;
if (i)
glfwWindowHint(GLFW_FOCUS_ON_SHOW, focusOnShow);
windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL); windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL);
if (!windows[i]) if (!windows[i])