Add window occlusion callback

This commit is contained in:
Green Lightning 2017-11-09 16:59:40 +01:00
parent 5595fa3ae6
commit 9ebcfb4764
6 changed files with 110 additions and 0 deletions

View File

@ -1120,6 +1120,39 @@ not supported, the application as a whole. Once the user has given it
attention, the system will automatically end the request.
@subsection window_occlusion Window occlusion state
A window may not be visible to the user because it is occluded by other windows.
In contrast to a hidden window it will still be shown in the task bar, dock or
window list. The occluded state can change without any direct interaction with
the window, e.g. if the user moves an overlapping window out of the way.
If you wish to be notified when a window becomes occluded or when a part of it
becomes visible again, set an occlusion callback.
@code
glfwSetWindowOcclusionCallback(window, window_occlusion_callback);
@endcode
The callback function receives changes in the occlusion state of the window.
@code
void window_occlusion_callback(GLFWwindow* window, int occluded)
{
if (occluded)
{
// The window became fully occluded by other windows
}
else
{
// The window is no longer fully occluded
}
}
@endcode
@note This is currently implemented on macOS only.
@subsection window_refresh Window damage and refresh
If you wish to be notified when the contents of a window is damaged and needs

View File

@ -1239,6 +1239,23 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
*/
typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
/*! @brief The function signature for window occlusion callbacks.
*
* This is the function signature for window occlusion callback functions.
*
* @param[in] window The window whose occlusion state changed.
* @param[in] occluded `GLFW_TRUE` if the window was occluded, or `GLFW_FALSE`
* if the window is no longer occluded.
*
* @sa @ref window_occlusion
* @sa @ref glfwSetWindowOcclusionCallback
*
* @since Added in version 3.3.
*
* @ingroup window
*/
typedef void (* GLFWwindowocclusionfun)(GLFWwindow*,int);
/*! @brief The function signature for window iconify/restore callbacks.
*
* This is the function signature for window iconify/restore callback
@ -3543,6 +3560,31 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL
*/
GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun cbfun);
/*! @brief Sets the occlusion callback for the specified window.
*
* This function sets the occlusion callback of the specified window, which is
* called when the window becomes (fully) occluded by other windows or when (a
* part of) the window becomes visible again because an overlapping window is
* moved away.
*
* @param[in] window The window whose callback to set.
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
* callback.
* @return The previously set callback, or `NULL` if no callback was set or the
* library had not been [initialized](@ref intro_init).
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref window_occlusion
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI GLFWwindowocclusionfun glfwSetWindowOcclusionCallback(GLFWwindow* window, GLFWwindowocclusionfun cbfun);
/*! @brief Sets the iconify callback for the specified window.
*
* This function sets the iconification callback of the specified window, which

View File

@ -329,6 +329,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_glfwInputWindowPos(window, x, y);
}
- (void)windowDidChangeOcclusionState:(NSNotification *)notification
{
_glfwInputWindowOcclusion(window, !([window->ns.object occlusionState] & NSWindowOcclusionStateVisible));
}
- (void)windowDidMiniaturize:(NSNotification *)notification
{
if (window->monitor)

View File

@ -399,6 +399,7 @@ struct _GLFWwindow
GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus;
GLFWwindowocclusionfun occlusion;
GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize;
@ -697,6 +698,7 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
//////////////////////////////////////////////////////////////////////////
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
void _glfwInputWindowOcclusion(_GLFWwindow* window, GLFWbool occluded);
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);

View File

@ -66,6 +66,14 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
}
}
// Notifies shared code that a window's occlusion state has changed
//
void _glfwInputWindowOcclusion(_GLFWwindow* window, GLFWbool occluded)
{
if (window->callbacks.occlusion)
window->callbacks.occlusion((GLFWwindow*) window, occluded);
}
// Notifies shared code that a window has moved
// The position is specified in client-area relative screen coordinates
//
@ -1025,6 +1033,17 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
return cbfun;
}
GLFWAPI GLFWwindowocclusionfun glfwSetWindowOcclusionCallback(GLFWwindow* handle,
GLFWwindowocclusionfun cbfun)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.occlusion, cbfun);
return cbfun;
}
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
GLFWwindowiconifyfun cbfun)
{

View File

@ -326,6 +326,14 @@ static void window_focus_callback(GLFWwindow* window, int focused)
focused ? "focused" : "defocused");
}
static void window_occlusion_callback(GLFWwindow* window, int occluded)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Window %s\n",
counter++, slot->number, glfwGetTime(),
occluded ? "occluded" : "not occluded");
}
static void window_iconify_callback(GLFWwindow* window, int iconified)
{
Slot* slot = glfwGetWindowUserPointer(window);
@ -608,6 +616,7 @@ int main(int argc, char** argv)
glfwSetWindowCloseCallback(slots[i].window, window_close_callback);
glfwSetWindowRefreshCallback(slots[i].window, window_refresh_callback);
glfwSetWindowFocusCallback(slots[i].window, window_focus_callback);
glfwSetWindowOcclusionCallback(slots[i].window, window_occlusion_callback);
glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback);
glfwSetWindowMaximizeCallback(slots[i].window, window_maximize_callback);
glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback);