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 - Added `glfwGetKeyScancode` function that allows retrieving platform dependent
scancodes for keys (#830) 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: Calling `glfwMaximizeWindow` on a full screen window was not ignored
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding - Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
OpenGL and OpenGL ES header macros OpenGL and OpenGL ES header macros

View File

@ -4,6 +4,11 @@
@section news_33 New features in 3.3 @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 @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 When a full screen window is iconified, the original video mode of its monitor
is restored until the user or application restores the window. 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 @code
glfwRestoreWindow(window); glfwRestoreWindow(window);
@ -769,6 +770,54 @@ int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
@endcode @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 @subsection window_hide Window visibility
Windowed mode windows can be hidden with @ref glfwHideWindow. 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); 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. /*! @brief The function signature for framebuffer resize callbacks.
* *
* This is the function signature for framebuffer resize callback * 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); 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. /*! @brief Sets the framebuffer resize callback for the specified window.
* *
* This function sets the framebuffer resize callback of 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 delegate;
id view; id view;
GLFWbool maximized;
// The total sum of the distances the cursor has been warped // The total sum of the distances the cursor has been warped
// since the last cursor motion event was processed // since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally // 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) if (_glfw.ns.disabledCursorWindow == window)
centerCursor(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 contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect]; const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];

View File

@ -378,6 +378,7 @@ struct _GLFWwindow
GLFWwindowrefreshfun refresh; GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus; GLFWwindowfocusfun focus;
GLFWwindowiconifyfun iconify; GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize; GLFWframebuffersizefun fbsize;
GLFWmousebuttonfun mouseButton; GLFWmousebuttonfun mouseButton;
GLFWcursorposfun cursorPos; GLFWcursorposfun cursorPos;
@ -856,6 +857,14 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
*/ */
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified); 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. /*! @brief Notifies shared code of a window damage event.
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
*/ */

View File

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

View File

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

View File

@ -86,6 +86,12 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
window->callbacks.iconify((GLFWwindow*) window, 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) void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
{ {
if (window->callbacks.fbsize) if (window->callbacks.fbsize)
@ -856,6 +862,17 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
return cbfun; 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, GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle,
GLFWframebuffersizefun cbfun) GLFWframebuffersizefun cbfun)
{ {

View File

@ -112,6 +112,8 @@ typedef struct _GLFWwindowX11
XIC ic; XIC ic;
GLFWbool overrideRedirect; GLFWbool overrideRedirect;
GLFWbool iconified;
GLFWbool maximized;
// Cached position and size used to filter out duplicate events // Cached position and size used to filter out duplicate events
int width, height; 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_VERT;
states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ; 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: case PropertyNotify:
{ {
if (event->xproperty.atom == _glfw.x11.WM_STATE && if (event->xproperty.state != PropertyNewValue)
event->xproperty.state == PropertyNewValue) return;
if (event->xproperty.atom == _glfw.x11.WM_STATE)
{ {
const int state = getWindowState(window); 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) 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) window->x11.maximized = maximized;
acquireMonitor(window); _glfwInputWindowMaximize(window, maximized);
_glfwInputWindowIconify(window, GLFW_FALSE);
} }
} }

View File

@ -322,7 +322,15 @@ static void window_iconify_callback(GLFWwindow* window, int iconified)
Slot* slot = glfwGetWindowUserPointer(window); Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Window was %s\n", printf("%08x to %i at %0.3f: Window was %s\n",
counter++, slot->number, glfwGetTime(), 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) 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); glfwSetWindowRefreshCallback(slots[i].window, window_refresh_callback);
glfwSetWindowFocusCallback(slots[i].window, window_focus_callback); glfwSetWindowFocusCallback(slots[i].window, window_focus_callback);
glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback); glfwSetWindowIconifyCallback(slots[i].window, window_iconify_callback);
glfwSetWindowMaximizeCallback(slots[i].window, window_maximize_callback);
glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback); glfwSetMouseButtonCallback(slots[i].window, mouse_button_callback);
glfwSetCursorPosCallback(slots[i].window, cursor_position_callback); glfwSetCursorPosCallback(slots[i].window, cursor_position_callback);
glfwSetCursorEnterCallback(slots[i].window, cursor_enter_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", printf("%0.2f Window %s\n",
glfwGetTime(), 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) static void window_refresh_callback(GLFWwindow* window)
@ -266,6 +273,7 @@ int main(int argc, char** argv)
glfwSetWindowSizeCallback(windows[i], window_size_callback); glfwSetWindowSizeCallback(windows[i], window_size_callback);
glfwSetWindowFocusCallback(windows[i], window_focus_callback); glfwSetWindowFocusCallback(windows[i], window_focus_callback);
glfwSetWindowIconifyCallback(windows[i], window_iconify_callback); glfwSetWindowIconifyCallback(windows[i], window_iconify_callback);
glfwSetWindowMaximizeCallback(windows[i], window_maximize_callback);
glfwSetWindowRefreshCallback(windows[i], window_refresh_callback); glfwSetWindowRefreshCallback(windows[i], window_refresh_callback);
window_refresh_callback(windows[i]); window_refresh_callback(windows[i]);