diff --git a/README.md b/README.md index e11f176c..9c632f65 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ GLFW bundles a number of dependencies in the `deps/` directory. `GLFW_RELEASE_BEHAVIOR_NONE` for `GL_KHR_context_flush_control` support - Added `GLFW_INCLUDE_ES31` for including the OpenGL ES 3.1 header - Added `GLFW_FLOATING` for creating always-on-top windowed mode windows + - Added `GLFW_FOCUSED` window hint for controlling initial input focus - Added *partial and experimental* support for Wayland - Bugfix: The debug context attribute was set from `GL_ARB_debug_output` even when a debug context had not been requested diff --git a/docs/news.dox b/docs/news.dox index 91575dd4..04a6b4f3 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -47,6 +47,12 @@ GLFW now supports floating windows, also called topmost or always on top, for easier debugging, with the `GLFW_FLOATING` window hint. +@subsection news_31_focused Initially unfocused windows + +GLFW now supports preventing a windowed mode window from gaining input focus on +creation, with the `GLFW_FOCUSED` window hint. + + @subsection news_31_charmods Character with modifiers callback GLFW now provides a callback for character events with modifier key bits. diff --git a/docs/window.dox b/docs/window.dox index 098f0170..cf337916 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -121,6 +121,10 @@ window decorations such as a border, a close widget, etc. This hint is ignored for full screen windows. Note that even though a window may lack a close widget, it is usually still possible for the user to generate close events. +The `GLFW_FOCUSED` hint specifies whether the (windowed mode) window will be +given input focus when created. This hint is ignored for full screen and +initially hidden windows. + The `GLFW_AUTO_ICONIFY` hint specifies whether the (full screen) window will automatically iconify and restore the previous video mode on focus loss. This hint is ignored for windowed mode windows. @@ -243,6 +247,7 @@ extension. | `GLFW_RESIZABLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_VISIBLE` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_DECORATED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | +| `GLFW_FOCUSED` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_AUTO_ICONIFY` | `GL_TRUE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_FLOATING` | `GL_FALSE` | `GL_TRUE` or `GL_FALSE` | | `GLFW_RED_BITS` | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` | diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 03ac4b9e..ae82d8ca 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1155,6 +1155,12 @@ void _glfwPlatformShowWindow(_GLFWwindow* window) _glfwInputWindowVisibility(window, GL_TRUE); } +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + [window->ns.object orderFront:nil]; + _glfwInputWindowVisibility(window, GL_TRUE); +} + void _glfwPlatformHideWindow(_GLFWwindow* window) { [window->ns.object orderOut:nil]; diff --git a/src/internal.h b/src/internal.h index c963ada2..62504e4f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -152,6 +152,7 @@ struct _GLFWwndconfig GLboolean resizable; GLboolean visible; GLboolean decorated; + GLboolean focused; GLboolean autoIconify; GLboolean floating; _GLFWmonitor* monitor; @@ -326,6 +327,7 @@ struct _GLFWlibrary int resizable; int visible; int decorated; + int focused; int autoIconify; int floating; int samples; @@ -562,6 +564,10 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window); */ void _glfwPlatformShowWindow(_GLFWwindow* window); +/*! @ingroup platform + */ +void _glfwPlatformUnhideWindow(_GLFWwindow* window); + /*! @copydoc glfwHideWindow * @ingroup platform */ diff --git a/src/win32_window.c b/src/win32_window.c index 7aa7d8ae..016edbea 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1183,6 +1183,11 @@ void _glfwPlatformShowWindow(_GLFWwindow* window) SetFocus(window->win32.handle); } +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + ShowWindow(window->win32.handle, SW_SHOW); +} + void _glfwPlatformHideWindow(_GLFWwindow* window) { ShowWindow(window->win32.handle, SW_HIDE); diff --git a/src/window.c b/src/window.c index 15b75270..7d10f38b 100644 --- a/src/window.c +++ b/src/window.c @@ -163,6 +163,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, wndconfig.resizable = _glfw.hints.resizable ? GL_TRUE : GL_FALSE; wndconfig.visible = _glfw.hints.visible ? GL_TRUE : GL_FALSE; wndconfig.decorated = _glfw.hints.decorated ? GL_TRUE : GL_FALSE; + wndconfig.focused = _glfw.hints.focused ? GL_TRUE : GL_FALSE; wndconfig.autoIconify = _glfw.hints.autoIconify ? GL_TRUE : GL_FALSE; wndconfig.floating = _glfw.hints.floating ? GL_TRUE : GL_FALSE; wndconfig.monitor = (_GLFWmonitor*) monitor; @@ -190,6 +191,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, { wndconfig.resizable = GL_TRUE; wndconfig.visible = GL_TRUE; + wndconfig.focused = GL_TRUE; // Set up desired video mode window->videoMode.width = width; @@ -200,6 +202,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->videoMode.refreshRate = _glfw.hints.refreshRate; } + // Transfer window hints that are persistent settings and not + // just initial states window->monitor = wndconfig.monitor; window->resizable = wndconfig.resizable; window->decorated = wndconfig.decorated; @@ -257,7 +261,12 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, else { if (wndconfig.visible) - _glfwPlatformShowWindow(window); + { + if (wndconfig.focused) + _glfwPlatformShowWindow(window); + else + _glfwPlatformUnhideWindow(window); + } } return (GLFWwindow*) window; @@ -274,10 +283,11 @@ void glfwDefaultWindowHints(void) _glfw.hints.major = 1; _glfw.hints.minor = 0; - // The default is a visible, resizable window with decorations + // The default is a focused, visible, resizable window with decorations _glfw.hints.resizable = GL_TRUE; _glfw.hints.visible = GL_TRUE; _glfw.hints.decorated = GL_TRUE; + _glfw.hints.focused = GL_TRUE; _glfw.hints.autoIconify = GL_TRUE; // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, @@ -345,6 +355,9 @@ GLFWAPI void glfwWindowHint(int target, int hint) case GLFW_DECORATED: _glfw.hints.decorated = hint; break; + case GLFW_FOCUSED: + _glfw.hints.focused = hint; + break; case GLFW_AUTO_ICONIFY: _glfw.hints.autoIconify = hint; break; diff --git a/src/wl_window.c b/src/wl_window.c index 255c194d..0fa16aa3 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -325,6 +325,12 @@ void _glfwPlatformShowWindow(_GLFWwindow* window) 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) { wl_surface_attach(window->wl.surface, NULL, 0, 0); diff --git a/src/x11_window.c b/src/x11_window.c index 4e18cd22..41f05ce6 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1577,6 +1577,12 @@ void _glfwPlatformShowWindow(_GLFWwindow* window) XFlush(_glfw.x11.display); } +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ + XMapWindow(_glfw.x11.display, window->x11.handle); + XFlush(_glfw.x11.display); +} + void _glfwPlatformHideWindow(_GLFWwindow* window) { XUnmapWindow(_glfw.x11.display, window->x11.handle);