diff --git a/README.md b/README.md index e0a7fd58..0580d62d 100644 --- a/README.md +++ b/README.md @@ -123,8 +123,8 @@ information on what to include when reporting a bug. ## Changelog - Added `glfwGetError` function for querying the last error code (#970) -- Added `glfwRequestWindowAttention` function that request attention to the - non-focused or minimized window +- Added `glfwRequestWindowAttention` function for requesting attention from the + user (#732,#988) - Added `glfwGetKeyScancode` function that allows retrieving platform dependent scancodes for keys (#830) - Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for @@ -251,6 +251,7 @@ skills. - Jonathan Dummer - Ralph Eastwood - Siavash Eliasi + - Felipe Ferreira - Michael Fogleman - Gerald Franz - Mário Freitas diff --git a/docs/news.dox b/docs/news.dox index ad5de5aa..b2c8571f 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -13,6 +13,12 @@ glfwGetError. @see @ref error_handling +@subsection news_33_attention User attention request + +GLFW now supports requesting user attention with @ref +glfwRequestWindowAttention. + + @subsection news_33_maximize Window maximization callback GLFW now supports window maximization notifications with @ref diff --git a/docs/window.dox b/docs/window.dox index 653f2fd6..c8d4a18e 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -984,6 +984,10 @@ glfwFocusWindow. glfwFocusWindow(window); @endcode +Keep in mind that it can be very disruptive to the user when a window is forced +to the top. For a less disruptive way of getting the user's attention, see +[attention requests](@ref window_attention). + 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. @@ -1022,6 +1026,20 @@ glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE); @endcode +@subsection window_attention Window attention request + +If you wish to notify the user of an event without interrupting, you can request +attention with @ref glfwRequestWindowAttention. + +@code +glfwRequestWindowAttention(window); +@endcode + +The system will highlight the specified window, or on platforms where this is +not supported, the application as a whole. Once the user has given it +attention, the system will automatically end the request. + + @subsection window_refresh Window damage and refresh If you wish to be notified when the contents of a window is damaged and needs diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index fb202209..706fb958 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -2766,6 +2766,9 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * you are certain that is what the user wants. Focus stealing can be * extremely disruptive. * + * For a less disruptive way of getting the user's attention, see + * [attention requests](@ref window_attention). + * * @param[in] window The window to give input focus. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref @@ -2777,6 +2780,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * @thread_safety This function must only be called from the main thread. * * @sa @ref window_focus + * @sa @ref window_attention * * @since Added in version 3.2. * @@ -2784,20 +2788,27 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); */ GLFWAPI void glfwFocusWindow(GLFWwindow* window); -/*! @brief Request attention to the specified window. +/*! @brief Requests user attention to the specified window. * - * This function makes the specified window to request attention. + * This function requests user attention to the specified window. On + * platforms where this is not supported, attention is requested to the + * application as a whole. * - * @param[in] window The window to request attention. + * Once the user has given attention, usually by focusing the window or + * application, the system will end the request automatically. + * + * @param[in] window The window to request attention to. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @macos The attention request will be made for the application and - * not the window passed in the argument. + * @remark @macos Attention is requested to the application as a whole, not the + * specific window. * * @thread_safety This function must only be called from the main thread. * + * @sa @ref window_attention + * * @since Added in version 3.3. * * @ingroup window diff --git a/src/internal.h b/src/internal.h index 0772d8ee..c2b35813 100644 --- a/src/internal.h +++ b/src/internal.h @@ -630,8 +630,8 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window); void _glfwPlatformRestoreWindow(_GLFWwindow* window); void _glfwPlatformMaximizeWindow(_GLFWwindow* window); void _glfwPlatformShowWindow(_GLFWwindow* window); -void _glfwPlatformRequestWindowAttention(_GLFWwindow* window); void _glfwPlatformHideWindow(_GLFWwindow* window); +void _glfwPlatformRequestWindowAttention(_GLFWwindow* window); void _glfwPlatformFocusWindow(_GLFWwindow* window); void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); int _glfwPlatformWindowFocused(_GLFWwindow* window); diff --git a/src/mir_window.c b/src/mir_window.c index aefb8933..566f571c 100644 --- a/src/mir_window.c +++ b/src/mir_window.c @@ -572,6 +572,8 @@ void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Mir: Unsupported function %s", __PRETTY_FUNCTION__); } void _glfwPlatformFocusWindow(_GLFWwindow* window) diff --git a/src/wl_window.c b/src/wl_window.c index 9dace92a..e9c817d5 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -601,6 +601,9 @@ void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) { + // TODO + _glfwInputError(GLFW_PLATFORM_ERROR, + "Wayland: Window attention request not implemented yet"); } void _glfwPlatformFocusWindow(_GLFWwindow* window) diff --git a/src/x11_window.c b/src/x11_window.c index fca3270e..a683a821 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2079,17 +2079,11 @@ void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) { - XEvent xev; - - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = window->x11.handle; - xev.xclient.message_type = _glfw.x11.NET_WM_STATE; - xev.xclient.format = 32; - xev.xclient.data.l[0] = _NET_WM_STATE_ADD; - xev.xclient.data.l[1] = _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION; - - XSendEvent(_glfw.x11.display, DefaultRootWindow(_glfw.x11.display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + sendEventToWM(window, + _glfw.x11.NET_WM_STATE, + _NET_WM_STATE_ADD, + _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION, + 0, 1, 0); } void _glfwPlatformFocusWindow(_GLFWwindow* window)