Add glfwFocusWindow

This removes the (undocumented) behavior where glfwShowWindow would
bring the window to front and set input focus.  That function now
does what it says.
This commit is contained in:
Camilla Berglund 2016-02-21 15:42:49 +01:00
parent de3e413aab
commit baf574494d
11 changed files with 103 additions and 51 deletions

View File

@ -78,6 +78,7 @@ does not find Doxygen, the documentation will not be generated.
`glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and `glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and
`glfwCreateWindowSurface` for platform independent Vulkan support `glfwCreateWindowSurface` for platform independent Vulkan support
- Added `glfwMaximizeWindow` and `GLFW_MAXIMIZED` for window maximization - Added `glfwMaximizeWindow` and `GLFW_MAXIMIZED` for window maximization
- Added `glfwFocusWindow` for giving windows input focus
- Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting - Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting
absolute and relative window size limits absolute and relative window size limits
- Added `glfwGetKeyName` for querying the layout-specific name of printable - Added `glfwGetKeyName` for querying the layout-specific name of printable

View File

@ -32,6 +32,11 @@ GLFW now supports window maximization with @ref glfwMaximizeWindow and the
[GLFW_MAXIMIZED](@ref window_attribs_wnd) window hint and attribute. [GLFW_MAXIMIZED](@ref window_attribs_wnd) window hint and attribute.
@subsection news_32_focus Window input focus control
GLFW now supports giving windows input focus with @ref glfwFocusWindow.
@section news_31 New features in 3.1 @section news_31 New features in 3.1
These are the release highlights. For a full list of changes see the These are the release highlights. For a full list of changes see the

View File

@ -715,6 +715,13 @@ int visible = glfwGetWindowAttrib(window, GLFW_VISIBLE);
@subsection window_focus Window input focus @subsection window_focus Window input focus
Windows can be given input focus and brought to the front with @ref
glfwFocusWindow.
@code
glfwFocusWindow(window);
@endcode
If you wish to be notified when a window gains or loses input focus, whether by If you wish to be notified when a window gains or loses input focus, whether by
the user, system or your own code, set a focus callback. the user, system or your own code, set a focus callback.

View File

@ -2283,6 +2283,34 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window);
*/ */
GLFWAPI void glfwHideWindow(GLFWwindow* window); GLFWAPI void glfwHideWindow(GLFWwindow* window);
/*! @brief Brings the specified window to front and sets input focus.
*
* This function brings the specified window to front and sets input focus.
* The window should already be visible and not iconified.
*
* By default, both windowed and full screen mode windows are focused when
* initially created. Set the [GLFW_FOCUSED](@ref window_hints_wnd) to disable
* this behavior.
*
* __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
* extremely disruptive.
*
* @param[in] window The window to give input focus.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_focus
*
* @since Added in version 3.2.
*
* @ingroup window
*/
GLFWAPI void glfwFocusWindow(GLFWwindow* window);
/*! @brief Returns the monitor that the window uses for full screen mode. /*! @brief Returns the monitor that the window uses for full screen mode.
* *
* This function returns the handle of the monitor that the specified window is * This function returns the handle of the monitor that the specified window is

View File

@ -84,6 +84,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
bounds.size.height); bounds.size.height);
[window->ns.object setFrame:frame display:YES]; [window->ns.object setFrame:frame display:YES];
_glfwPlatformFocusWindow(window);
return status; return status;
} }
@ -1039,6 +1040,16 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
} }
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{
[window->ns.object orderFront:nil];
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
[window->ns.object orderOut:nil];
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{ {
// Make us the active application // Make us the active application
// HACK: This has been moved here from initializeAppKit to prevent // HACK: This has been moved here from initializeAppKit to prevent
@ -1049,16 +1060,6 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
[window->ns.object makeKeyAndOrderFront:nil]; [window->ns.object makeKeyAndOrderFront:nil];
} }
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
[window->ns.object orderFront:nil];
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
[window->ns.object orderOut:nil];
}
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
return [window->ns.object isKeyWindow]; return [window->ns.object isKeyWindow];

View File

@ -684,15 +684,16 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
*/ */
void _glfwPlatformShowWindow(_GLFWwindow* window); void _glfwPlatformShowWindow(_GLFWwindow* window);
/*! @ingroup platform
*/
void _glfwPlatformUnhideWindow(_GLFWwindow* window);
/*! @copydoc glfwHideWindow /*! @copydoc glfwHideWindow
* @ingroup platform * @ingroup platform
*/ */
void _glfwPlatformHideWindow(_GLFWwindow* window); void _glfwPlatformHideWindow(_GLFWwindow* window);
/*! @copydoc glfwFocusWindow
* @ingroup platform
*/
void _glfwPlatformFocusWindow(_GLFWwindow* window);
/*! @brief Returns whether the window is focused. /*! @brief Returns whether the window is focused.
* @ingroup platform * @ingroup platform
*/ */

View File

@ -495,7 +495,7 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
mir_surface_spec_release(spec); mir_surface_spec_release(spec);
} }
void _glfwPlatformUnhideWindow(_GLFWwindow* window) void _glfwPlatformFocusWindow(_GLFWwindow* window)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__); "Mir: Unsupported function %s", __PRETTY_FUNCTION__);

View File

@ -1034,14 +1034,6 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
} }
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{
ShowWindow(window->win32.handle, SW_SHOW);
BringWindowToTop(window->win32.handle);
SetForegroundWindow(window->win32.handle);
SetFocus(window->win32.handle);
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{ {
ShowWindow(window->win32.handle, SW_SHOW); ShowWindow(window->win32.handle, SW_SHOW);
} }
@ -1051,6 +1043,13 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
ShowWindow(window->win32.handle, SW_HIDE); ShowWindow(window->win32.handle, SW_HIDE);
} }
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
BringWindowToTop(window->win32.handle);
SetForegroundWindow(window->win32.handle);
SetFocus(window->win32.handle);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
return window->win32.handle == GetActiveWindow(); return window->win32.handle == GetActiveWindow();

View File

@ -231,10 +231,9 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
{ {
if (wndconfig.visible) if (wndconfig.visible)
{ {
if (wndconfig.focused)
_glfwPlatformShowWindow(window); _glfwPlatformShowWindow(window);
else if (wndconfig.focused)
_glfwPlatformUnhideWindow(window); _glfwPlatformFocusWindow(window);
} }
} }
@ -629,6 +628,16 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
_glfwPlatformHideWindow(window); _glfwPlatformHideWindow(window);
} }
GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window);
_GLFW_REQUIRE_INIT();
_glfwPlatformFocusWindow(window);
}
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;

View File

@ -470,18 +470,18 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
wl_shell_surface_set_toplevel(window->wl.shell_surface); wl_shell_surface_set_toplevel(window->wl.shell_surface);
} }
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
// TODO
fprintf(stderr, "_glfwPlatformUnhideWindow not implemented yet\n");
}
void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwPlatformHideWindow(_GLFWwindow* window)
{ {
wl_surface_attach(window->wl.surface, NULL, 0, 0); wl_surface_attach(window->wl.surface, NULL, 0, 0);
wl_surface_commit(window->wl.surface); wl_surface_commit(window->wl.surface);
} }
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
// TODO
fprintf(stderr, "_glfwPlatformFocusWindow not implemented yet\n");
}
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
// TODO // TODO

View File

@ -763,19 +763,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
0); 0);
} }
if (_glfw.x11.NET_ACTIVE_WINDOW) _glfwPlatformFocusWindow(window);
{
// Ask the window manager to raise and focus the GLFW window
// Only focused windows with the _NET_WM_STATE_FULLSCREEN state end up
// on top of all other windows ("Stacking order" in EWMH spec)
sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
}
else
{
XRaiseWindow(_glfw.x11.display, window->x11.handle);
XSetInputFocus(_glfw.x11.display, window->x11.handle,
RevertToParent, CurrentTime);
}
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
{ {
@ -1810,12 +1798,6 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
} }
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{
XMapRaised(_glfw.x11.display, window->x11.handle);
XFlush(_glfw.x11.display);
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{ {
XMapWindow(_glfw.x11.display, window->x11.handle); XMapWindow(_glfw.x11.display, window->x11.handle);
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
@ -1827,6 +1809,25 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
} }
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
if (_glfw.x11.NET_ACTIVE_WINDOW)
{
// Ask the window manager to raise and focus the GLFW window
// Only focused windows with the _NET_WM_STATE_FULLSCREEN state end up
// on top of all other windows ("Stacking order" in EWMH spec)
sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
}
else
{
XRaiseWindow(_glfw.x11.display, window->x11.handle);
XSetInputFocus(_glfw.x11.display, window->x11.handle,
RevertToParent, CurrentTime);
}
XFlush(_glfw.x11.display);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
Window focused; Window focused;