Commit 641761dd authored by Camilla Berglund's avatar Camilla Berglund
Browse files

Changed state attribs to direct access.

Changed the window states (focused, iconified and visible) to query the
system directly.

THIS IS A BREAKING CHANGE, although a fairly obscure one.  It affects
applications that both care about telling actual key events from
synthetic ones, and are implemented in a non-self-synchronizing way, and
that poll the GLFW_FOCUSED window attribute instead of using the window
focus callback.

If you maintain one of these, please feel free to drop me an email and
I'll help any way I can to transition your application to 3.1.

Fixes #189.
Fixes #204.
parent f9c1f85f
......@@ -86,6 +86,8 @@ GLFW bundles a number of dependencies in the `deps/` directory.
- Added `GLFW_FOCUSED` window hint for controlling initial input focus
- Added *partial and experimental* support for Wayland
- Added *partial and experimental* support for Mir
- Changed the window states (focused, iconified and visible) to query the
system directly
- Changed the default of `GLFW_REFRESH_RATE` to `GLFW_DONT_CARE` to maintain
the default behavior
- Changed static library to build as position independent code for easier use
......
......@@ -226,25 +226,6 @@ static NSRect convertRectToBacking(_GLFWwindow* window, NSRect contentRect)
return NSTerminateCancel;
}
- (void)applicationDidHide:(NSNotification *)notification
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
_glfwInputWindowVisibility(window, GL_FALSE);
}
- (void)applicationDidUnhide:(NSNotification *)notification
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if ([window->ns.object isVisible])
_glfwInputWindowVisibility(window, GL_TRUE);
}
}
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{
_glfwInputMonitorChange();
......@@ -1047,13 +1028,26 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
[window->ns.object orderFront:nil];
_glfwInputWindowVisibility(window, GL_TRUE);
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
[window->ns.object orderOut:nil];
_glfwInputWindowVisibility(window, GL_FALSE);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return [window->ns.object isKeyWindow];
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return [window->ns.object isMiniaturized];
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
return [window->ns.object isVisible];
}
void _glfwPlatformPollEvents(void)
......
......@@ -219,12 +219,10 @@ struct _GLFWwindow
struct _GLFWwindow* next;
// Window settings and state
GLboolean iconified;
GLboolean resizable;
GLboolean decorated;
GLboolean autoIconify;
GLboolean floating;
GLboolean visible;
GLboolean closed;
void* userPointer;
GLFWvidmode videoMode;
......@@ -575,6 +573,21 @@ void _glfwPlatformUnhideWindow(_GLFWwindow* window);
*/
void _glfwPlatformHideWindow(_GLFWwindow* window);
/*! @brief Returns whether the window is focused.
* @ingroup platform
*/
int _glfwPlatformWindowFocused(_GLFWwindow* window);
/*! @brief Returns whether the window is iconified.
* @ingroup platform
*/
int _glfwPlatformWindowIconified(_GLFWwindow* window);
/*! @brief Returns whether the window is visible.
* @ingroup platform
*/
int _glfwPlatformWindowVisible(_GLFWwindow* window);
/*! @copydoc glfwPollEvents
* @ingroup platform
*/
......@@ -685,14 +698,6 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
*/
void _glfwInputWindowIconify(_GLFWwindow* window, int iconified);
/*! @brief Notifies shared code of a window show/hide event.
* @param[in] window The window that received the event.
* @param[in] visible `GL_TRUE` if the window was shown, or `GL_FALSE` if it
* was hidden.
* @ingroup event
*/
void _glfwInputWindowVisibility(_GLFWwindow* window, int visible);
/*! @brief Notifies shared code of a window damage event.
* @param[in] window The window that received the event.
*/
......
......@@ -565,6 +565,27 @@ void _glfwPlatformUnhideWindow(_GLFWwindow* window)
"Mir: Unsupported Function %s!", __PRETTY_FUNCTION__);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported Function %s!", __PRETTY_FUNCTION__);
return GL_FALSE;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported Function %s!", __PRETTY_FUNCTION__);
return GL_FALSE;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported Function %s!", __PRETTY_FUNCTION__);
return GL_FALSE;
}
void _glfwPlatformPollEvents(void)
{
EventNode* node = NULL;
......
......@@ -257,86 +257,33 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
break;
}
case WM_ACTIVATE:
case WM_SETFOCUS:
{
// Window was (de)focused and/or (de)iconified
if (window->cursorMode != GLFW_CURSOR_NORMAL)
_glfwPlatformApplyCursorMode(window);
BOOL focused = LOWORD(wParam) != WA_INACTIVE;
BOOL iconified = HIWORD(wParam) ? TRUE : FALSE;
if (window->monitor && window->autoIconify)
enterFullscreenMode(window);
if (focused && iconified)
{
if (window->iconified && _glfw.focusedWindow != window)
{
// This is a workaround for window restoration using the
// Win+D hot key leading to windows being told they're
// focused and iconified and then never told they're
// restored
iconified = FALSE;
}
else
{
// This is a workaround for window iconification using the
// taskbar leading to windows being told they're focused and
// iconified and then never told they're defocused
focused = FALSE;
}
}
if (!focused && _glfw.focusedWindow == window)
{
// The window was defocused (or iconified, see above)
if (window->cursorMode != GLFW_CURSOR_NORMAL)
restoreCursor(window);
if (window->monitor && window->autoIconify)
{
if (!iconified)
{
// Iconify the (on top, borderless, oddly positioned)
// window or the user will be annoyed
_glfwPlatformIconifyWindow(window);
}
leaveFullscreenMode(window);
}
}
else if (focused && _glfw.focusedWindow != window)
{
// The window was focused
if (window->cursorMode != GLFW_CURSOR_NORMAL)
_glfwPlatformApplyCursorMode(window);
if (window->monitor && window->autoIconify)
enterFullscreenMode(window);
}
_glfwInputWindowFocus(window, focused);
_glfwInputWindowIconify(window, iconified);
_glfwInputWindowFocus(window, GL_TRUE);
return 0;
}
case WM_ACTIVATEAPP:
case WM_KILLFOCUS:
{
if (!wParam && IsIconic(hWnd))
if (window->cursorMode != GLFW_CURSOR_NORMAL)
restoreCursor(window);
if (window->monitor && window->autoIconify)
{
// This is a workaround for full screen windows losing focus
// through Alt+Tab leading to windows being told they're
// unfocused and restored and then never told they're iconified
_glfwInputWindowIconify(window, GL_TRUE);
_glfwPlatformIconifyWindow(window);
leaveFullscreenMode(window);
}
_glfwInputWindowFocus(window, GL_FALSE);
return 0;
}
case WM_SHOWWINDOW:
{
_glfwInputWindowVisibility(window, wParam ? GL_TRUE : GL_FALSE);
break;
}
case WM_SYSCOMMAND:
{
switch (wParam & 0xfff0)
......@@ -560,6 +507,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_SIZE:
{
if (wParam == SIZE_MINIMIZED)
_glfwInputWindowIconify(window, GL_TRUE);
else if (wParam == SIZE_RESTORED)
_glfwInputWindowIconify(window, GL_FALSE);
if (_glfw.focusedWindow == window)
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
......@@ -1041,6 +993,21 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
ShowWindow(window->win32.handle, SW_HIDE);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
return window->win32.handle == GetActiveWindow();
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return IsIconic(window->win32.handle);
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
return IsWindowVisible(window->win32.handle);
}
void _glfwPlatformPollEvents(void)
{
MSG msg;
......@@ -1238,7 +1205,8 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
// the following condition is not met. That way it should be safe to destroy the
// cursor after calling glfwSetCursor(window, NULL) on all windows using the cursor.
if (window->cursorMode == GLFW_CURSOR_NORMAL && _glfw.focusedWindow == window &&
if (_glfw.focusedWindow == window &&
window->cursorMode == GLFW_CURSOR_NORMAL &&
window->win32.cursorInside)
{
if (cursor)
......
......@@ -84,8 +84,6 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
void _glfwInputWindowIconify(_GLFWwindow* window, int iconified)
{
window->iconified = iconified;
if (window->callbacks.iconify)
window->callbacks.iconify((GLFWwindow*) window, iconified);
}
......@@ -96,11 +94,6 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
window->callbacks.fbsize((GLFWwindow*) window, width, height);
}
void _glfwInputWindowVisibility(_GLFWwindow* window, int visible)
{
window->visible = visible;
}
void _glfwInputWindowDamage(_GLFWwindow* window)
{
if (window->callbacks.refresh)
......@@ -600,17 +593,17 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
switch (attrib)
{
case GLFW_FOCUSED:
return window == _glfw.focusedWindow;
return _glfwPlatformWindowFocused(window);
case GLFW_ICONIFIED:
return window->iconified;
return _glfwPlatformWindowIconified(window);
case GLFW_VISIBLE:
return _glfwPlatformWindowVisible(window);
case GLFW_RESIZABLE:
return window->resizable;
case GLFW_DECORATED:
return window->decorated;
case GLFW_FLOATING:
return window->floating;
case GLFW_VISIBLE:
return window->visible;
case GLFW_CLIENT_API:
return window->context.api;
case GLFW_CONTEXT_VERSION_MAJOR:
......
......@@ -307,6 +307,24 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
wl_surface_commit(window->wl.surface);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
// TODO
return GL_FALSE;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
// TODO
return GL_FALSE;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
// TODO
return GL_FALSE;
}
void _glfwPlatformPollEvents(void)
{
struct wl_display* display = _glfw.wl.display;
......
......@@ -57,6 +57,28 @@ typedef struct
#define MWM_HINTS_DECORATIONS (1L << 1)
// Returns whether the window is iconified
//
static int getWindowState(_GLFWwindow* window)
{
int result = WithdrawnState;
struct {
CARD32 state;
Window icon;
} *state = NULL;
if (_glfwGetWindowProperty(window->x11.handle,
_glfw.x11.WM_STATE,
_glfw.x11.WM_STATE,
(unsigned char**) &state) >= 2)
{
result = state->state;
}
XFree(state);
return result;
}
// Returns whether the event is a selection event
//
static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
......@@ -1229,18 +1251,6 @@ static void processEvent(XEvent *event)
break;
}
case MapNotify:
{
_glfwInputWindowVisibility(window, GL_TRUE);
break;
}
case UnmapNotify:
{
_glfwInputWindowVisibility(window, GL_FALSE);
break;
}
case FocusIn:
{
if (event->xfocus.mode == NotifyNormal)
......@@ -1278,23 +1288,11 @@ static void processEvent(XEvent *event)
if (event->xproperty.atom == _glfw.x11.WM_STATE &&
event->xproperty.state == PropertyNewValue)
{
struct {
CARD32 state;
Window icon;
} *state = NULL;
if (_glfwGetWindowProperty(window->x11.handle,
_glfw.x11.WM_STATE,
_glfw.x11.WM_STATE,
(unsigned char**) &state) >= 2)
{
if (state->state == IconicState)
_glfwInputWindowIconify(window, GL_TRUE);
else if (state->state == NormalState)
_glfwInputWindowIconify(window, GL_FALSE);
}
XFree(state);
const int state = getWindowState(window);
if (state == IconicState)
_glfwInputWindowIconify(window, GL_TRUE);
else if (state == NormalState)
_glfwInputWindowIconify(window, GL_FALSE);
}
break;
......@@ -1671,6 +1669,27 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
XFlush(_glfw.x11.display);
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
Window focused;
int state;
XGetInputFocus(_glfw.x11.display, &focused, &state);
return window->x11.handle == focused;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
return getWindowState(window) == IconicState;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
XWindowAttributes wa;
XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa);
return wa.map_state == IsViewable;
}
void _glfwPlatformPollEvents(void)
{
int count = XPending(_glfw.x11.display);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment