Add glfwSetWindowMaximizeCallback

Fixes #778.
This commit is contained in:
Camilla Berglund 2016-06-16 13:09:28 +02:00
parent 3752d68e7d
commit c156b50e4c
14 changed files with 194 additions and 30 deletions

View File

@ -102,6 +102,8 @@ information on what to include when reporting a bug.
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
scancodes for keys (#830)
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
receiving window maximization events (#778)
- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
OpenGL and OpenGL ES header macros

View File

@ -4,6 +4,11 @@
@section news_33 New features in 3.3
@subsection news_33_maximize Window maximization callback
GLFW now supports window maximization notifications with @ref
glfwSetWindowMaximizeCallback.
@subsection news_33_keyscancode Platform-specific key scancode query

View File

@ -730,7 +730,8 @@ glfwIconifyWindow(window);
When a full screen window is iconified, the original video mode of its monitor
is restored until the user or application restores the window.
Iconified windows can be restored with @ref glfwRestoreWindow.
Iconified windows can be restored with @ref glfwRestoreWindow. This function
also restores windows from maximization.
@code
glfwRestoreWindow(window);
@ -769,6 +770,54 @@ int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
@endcode
@subsection window_maximize Window maximization
Windows can be maximized (i.e. zoomed) with @ref glfwMaximizeWindow.
@code
glfwMaximizeWindow(window);
@endcode
Full screen windows cannot be maximized and passing a full screen window to this
function does nothing.
Maximized windows can be restored with @ref glfwRestoreWindow. This function
also restores windows from iconification.
@code
glfwRestoreWindow(window);
@endcode
If you wish to be notified when a window is maximized or restored, whether by
the user, system or your own code, set a maximize callback.
@code
glfwSetWindowMaximizeCallback(window, window_maximize_callback);
@endcode
The callback function receives changes in the maximization state of the window.
@code
void window_maximize_callback(GLFWwindow* window, int maximized)
{
if (maximized)
{
// The window was maximized
}
else
{
// The window was restored
}
}
@endcode
You can also get the current maximization state with @ref glfwGetWindowAttrib.
@code
int maximized = glfwGetWindowAttrib(window, GLFW_MAXIMIZED);
@endcode
@subsection window_hide Window visibility
Windowed mode windows can be hidden with @ref glfwHideWindow.

View File

@ -921,6 +921,24 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
*/
typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
/*! @brief The function signature for window maximize/restore callbacks.
*
* This is the function signature for window maximize/restore callback
* functions.
*
* @param[in] window The window that was maximized or restored.
* @param[in] iconified `GLFW_TRUE` if the window was maximized, or
* `GLFW_FALSE` if it was restored.
*
* @sa @ref window_maximize
* @sa glfwSetWindowMaximizeCallback
*
* @since Added in version 3.3.
*
* @ingroup window
*/
typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int);
/*! @brief The function signature for framebuffer resize callbacks.
*
* This is the function signature for framebuffer resize callback
@ -2705,6 +2723,29 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*/
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun cbfun);
/*! @brief Sets the maximize callback for the specified window.
*
* This function sets the maximization callback of the specified window, which
* is called when the window is maximized or restored.
*
* @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_maximize
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun cbfun);
/*! @brief Sets the framebuffer resize callback for the specified window.
*
* This function sets the framebuffer resize callback of the specified window,

View File

@ -75,6 +75,8 @@ typedef struct _GLFWwindowNS
id delegate;
id view;
GLFWbool maximized;
// The total sum of the distances the cursor has been warped
// since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally

View File

@ -238,6 +238,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window);
const int maximized = [window->ns.object isZoomed];
if (window->ns.maximized != maximized)
{
window->ns.maximized = maximized;
_glfwInputWindowMaximize(window, maximized);
}
const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];

View File

@ -378,6 +378,7 @@ struct _GLFWwindow
GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus;
GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize;
GLFWmousebuttonfun mouseButton;
GLFWcursorposfun cursorPos;
@ -856,6 +857,14 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
*/
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
/*! @brief Notifies shared code of a window maximization event.
* @param[in] window The window that received the event.
* @param[in] maximized `GLFW_TRUE` if the window was maximized, or
* `GLFW_FALSE` if it was restored.
* @ingroup event
*/
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
/*! @brief Notifies shared code of a window damage event.
* @param[in] window The window that received the event.
*/

View File

@ -235,6 +235,7 @@ typedef struct _GLFWwindowWin32
GLFWbool cursorTracked;
GLFWbool iconified;
GLFWbool maximized;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;

View File

@ -693,36 +693,33 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_SIZE:
{
const GLFWbool iconified =
!window->win32.iconified && wParam == SIZE_MINIMIZED;
const GLFWbool restored =
window->win32.iconified &&
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED);
const GLFWbool iconified = wParam == SIZE_MINIMIZED;
const GLFWbool maximized = wParam == SIZE_MAXIMIZED ||
(window->win32.maximized &&
wParam != SIZE_RESTORED);
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
if (iconified)
_glfwInputWindowIconify(window, GLFW_TRUE);
else if (restored)
_glfwInputWindowIconify(window, GLFW_FALSE);
if (window->win32.iconified != iconified)
_glfwInputWindowIconify(window, iconified);
if (window->win32.maximized != maximized)
_glfwInputWindowMaximize(window, maximized);
_glfwInputFramebufferSize(window, LOWORD(lParam), HIWORD(lParam));
_glfwInputWindowSize(window, LOWORD(lParam), HIWORD(lParam));
if (iconified)
if (window->monitor && window->win32.iconified != iconified)
{
window->win32.iconified = GLFW_TRUE;
if (window->monitor)
if (iconified)
releaseMonitor(window);
}
else if (restored)
{
window->win32.iconified = GLFW_FALSE;
if (window->monitor)
else
acquireMonitor(window);
}
window->win32.iconified = iconified;
window->win32.maximized = maximized;
return 0;
}

View File

@ -86,6 +86,12 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
window->callbacks.iconify((GLFWwindow*) window, iconified);
}
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
{
if (window->callbacks.maximize)
window->callbacks.maximize((GLFWwindow*) window, maximized);
}
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
{
if (window->callbacks.fbsize)
@ -856,6 +862,17 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
return cbfun;
}
GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
GLFWwindowmaximizefun cbfun)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun);
return cbfun;
}
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle,
GLFWframebuffersizefun cbfun)
{

View File

@ -112,6 +112,8 @@ typedef struct _GLFWwindowX11
XIC ic;
GLFWbool overrideRedirect;
GLFWbool iconified;
GLFWbool maximized;
// Cached position and size used to filter out duplicate events
int width, height;

View File

@ -559,6 +559,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
window->x11.maximized = GLFW_TRUE;
}
}
@ -1415,23 +1416,37 @@ static void processEvent(XEvent *event)
case PropertyNotify:
{
if (event->xproperty.atom == _glfw.x11.WM_STATE &&
event->xproperty.state == PropertyNewValue)
if (event->xproperty.state != PropertyNewValue)
return;
if (event->xproperty.atom == _glfw.x11.WM_STATE)
{
const int state = getWindowState(window);
if (state == IconicState)
if (state != IconicState && state != NormalState)
return;
const GLFWbool iconified = (state == IconicState);
if (window->x11.iconified != iconified)
{
if (window->monitor)
releaseMonitor(window);
{
if (iconified)
releaseMonitor(window);
else
acquireMonitor(window);
}
_glfwInputWindowIconify(window, GLFW_TRUE);
window->x11.iconified = iconified;
_glfwInputWindowIconify(window, iconified);
}
else if (state == NormalState)
}
else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE)
{
const GLFWbool maximized = _glfwPlatformWindowMaximized(window);
if (window->x11.maximized != maximized)
{
if (window->monitor)
acquireMonitor(window);
_glfwInputWindowIconify(window, GLFW_FALSE);
window->x11.maximized = maximized;
_glfwInputWindowMaximize(window, maximized);
}
}

View File

@ -322,7 +322,15 @@ static void window_iconify_callback(GLFWwindow* window, int iconified)
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Window was %s\n",
counter++, slot->number, glfwGetTime(),
iconified ? "iconified" : "restored");
iconified ? "iconified" : "uniconified");
}
static void window_maximize_callback(GLFWwindow* window, int maximized)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Window was %s\n",
counter++, slot->number, glfwGetTime(),
maximized ? "maximized" : "unmaximized");
}
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
@ -580,6 +588,7 @@ int main(int argc, char** argv)
glfwSetWindowRefreshCallback(slots[i].window, window_refresh_callback);
glfwSetWindowFocusCallback(slots[i].window, window_focus_callback);
glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback);
glfwSetWindowMaximizeCallback(slots[i].window, window_maximize_callback);
glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback);
glfwSetCursorPosCallback(slots[i].window, cursor_position_callback);
glfwSetCursorEnterCallback(slots[i].window, cursor_enter_callback);

View File

@ -131,7 +131,14 @@ static void window_iconify_callback(GLFWwindow* window, int iconified)
{
printf("%0.2f Window %s\n",
glfwGetTime(),
iconified ? "iconified" : "restored");
iconified ? "iconified" : "uniconified");
}
static void window_maximize_callback(GLFWwindow* window, int maximized)
{
printf("%0.2f Window %s\n",
glfwGetTime(),
maximized ? "maximized" : "unmaximized");
}
static void window_refresh_callback(GLFWwindow* window)
@ -266,6 +273,7 @@ int main(int argc, char** argv)
glfwSetWindowSizeCallback(windows[i], window_size_callback);
glfwSetWindowFocusCallback(windows[i], window_focus_callback);
glfwSetWindowIconifyCallback(windows[i], window_iconify_callback);
glfwSetWindowMaximizeCallback(windows[i], window_maximize_callback);
glfwSetWindowRefreshCallback(windows[i], window_refresh_callback);
window_refresh_callback(windows[i]);