Simplify cursor window logic

This commit is contained in:
Camilla Berglund 2016-05-30 21:21:09 +02:00
parent 03db3ed6e9
commit 2d2756cbad
9 changed files with 104 additions and 104 deletions

View File

@ -101,6 +101,8 @@ typedef struct _GLFWlibraryNS
char* clipboardString;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
struct {
CFBundleRef bundle;

View File

@ -85,11 +85,19 @@ static void centerCursor(_GLFWwindow *window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Updates the cursor image according to the specified cursor mode
// Returns whether the cursor is in the client area of the specified window
//
static void updateCursorImage(_GLFWwindow* window, int mode)
static GLFWbool cursorInClientArea(_GLFWwindow* window)
{
if (mode == GLFW_CURSOR_NORMAL)
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
@ -227,11 +235,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
if (_glfw.cursorWindow == window &&
window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window);
}
const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
@ -245,11 +250,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
if (_glfw.cursorWindow == window &&
window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window);
}
int x, y;
_glfwPlatformGetWindowPos(window, &x, &y);
@ -274,11 +276,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidBecomeKey:(NSNotification *)notification
{
if (_glfw.cursorWindow == window &&
window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.ns.disabledCursorWindow == window)
centerCursor(window);
}
_glfwInputWindowFocus(window, GLFW_TRUE);
_glfwPlatformSetCursorMode(window, window->cursorMode);
@ -409,7 +408,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)cursorUpdate:(NSEvent *)event
{
updateCursorImage(window, window->cursorMode);
updateCursorImage(window);
}
- (void)mouseDown:(NSEvent *)event
@ -1060,6 +1059,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (_glfw.ns.disabledCursorWindow == window)
_glfw.ns.disabledCursorWindow = NULL;
[window->ns.object orderOut:nil];
if (window->monitor)
@ -1417,7 +1419,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
updateCursorImage(window, window->cursorMode);
updateCursorImage(window);
const NSRect contentRect = [window->ns.view frame];
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
@ -1445,21 +1447,24 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_DISABLED)
{
_glfw.ns.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window,
&_glfw.ns.restoreCursorPosX,
&_glfw.ns.restoreCursorPosY);
centerCursor(window);
CGAssociateMouseAndMouseCursorPosition(false);
}
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
else if (_glfw.ns.disabledCursorWindow == window)
{
_glfw.ns.disabledCursorWindow = NULL;
CGAssociateMouseAndMouseCursorPosition(true);
_glfwPlatformSetCursorPos(window,
_glfw.ns.restoreCursorPosX,
_glfw.ns.restoreCursorPosY);
}
updateCursorImage(window, mode);
if (cursorInClientArea(window))
updateCursorImage(window);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -1572,16 +1577,8 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
if (window->cursorMode == GLFW_CURSOR_NORMAL &&
[window->ns.view mouse:pos inRect:[window->ns.view frame]])
{
if (cursor)
[(NSCursor*) cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
if (cursorInClientArea(window))
updateCursorImage(window);
}
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)

View File

@ -192,14 +192,15 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfw.cursorWindow == window)
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, value);
window->cursorMode = value;
return;
}
@ -340,7 +341,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
return;
}
if (_glfw.cursorWindow != window)
if (!_glfwPlatformWindowFocused(window))
return;
if (window->cursorMode == GLFW_CURSOR_DISABLED)

View File

@ -440,7 +440,6 @@ struct _GLFWlibrary
_GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead;
_GLFWwindow* cursorWindow;
_GLFWmonitor** monitors;
int monitorCount;

View File

@ -254,6 +254,8 @@ typedef struct _GLFWlibraryWin32
short int nativeKeys[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
struct {
HINSTANCE instance;

View File

@ -227,7 +227,7 @@ static void centerCursor(_GLFWwindow* window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
//
// Returns whether the cursor is in the client area of the specified window
//
static GLFWbool cursorInClientArea(_GLFWwindow* window)
{
@ -247,11 +247,11 @@ static GLFWbool cursorInClientArea(_GLFWwindow* window)
return PtInRect(&area, pos);
}
// Updates the cursor image according to the specified cursor mode
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window, int mode)
static void updateCursorImage(_GLFWwindow* window)
{
if (mode == GLFW_CURSOR_NORMAL)
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
SetCursor(window->cursor->win32.handle);
@ -259,12 +259,7 @@ static void updateCursorImage(_GLFWwindow* window, int mode)
SetCursor(LoadCursorW(NULL, IDC_ARROW));
}
else
{
if (mode == GLFW_CURSOR_DISABLED && _glfw.cursorWindow != window)
SetCursor(LoadCursorW(NULL, IDC_ARROW));
else
SetCursor(NULL);
}
SetCursor(NULL);
}
// Updates the cursor clip rect
@ -430,7 +425,7 @@ static void releaseMonitor(_GLFWwindow* window)
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
_GLFWwindow* window = (_GLFWwindow*) GetPropW(hWnd, L"GLFW");
_GLFWwindow* window = GetPropW(hWnd, L"GLFW");
if (!window)
{
// This is the message handling for the hidden helper window
@ -623,7 +618,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.cursorWindow != window)
if (_glfw.win32.disabledCursorWindow != window)
break;
const int dx = x - window->win32.lastCursorPosX;
@ -684,11 +679,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
window->win32.iconified &&
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED);
if (_glfw.cursorWindow == window)
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
updateClipRect(window);
}
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
if (iconified)
_glfwInputWindowIconify(window, GLFW_TRUE);
@ -716,11 +708,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOVE:
{
if (_glfw.cursorWindow == window)
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
updateClipRect(window);
}
if (_glfw.win32.disabledCursorWindow == window)
updateClipRect(window);
// NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
// those macros do not handle negative window positions correctly
@ -785,7 +774,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{
if (LOWORD(lParam) == HTCLIENT)
{
updateCursorImage(window, window->cursorMode);
updateCursorImage(window);
return TRUE;
}
@ -925,6 +914,9 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig)
//
static void destroyWindow(_GLFWwindow* window)
{
if (_glfw.win32.disabledCursorWindow == window)
_glfw.win32.disabledCursorWindow = NULL;
if (window->win32.handle)
{
RemovePropW(window->win32.handle, L"GLFW");
@ -1384,6 +1376,8 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
void _glfwPlatformPollEvents(void)
{
MSG msg;
HWND handle;
_GLFWwindow* window;
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
@ -1393,7 +1387,7 @@ void _glfwPlatformPollEvents(void)
// While GLFW does not itself post WM_QUIT, other processes may post
// it to this one, for example Task Manager
_GLFWwindow* window = _glfw.windowListHead;
window = _glfw.windowListHead;
while (window)
{
_glfwInputWindowCloseRequest(window);
@ -1407,13 +1401,14 @@ void _glfwPlatformPollEvents(void)
}
}
if (_glfw.cursorWindow)
handle = GetActiveWindow();
if (handle)
{
_GLFWwindow* window = _glfw.cursorWindow;
// LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
// This is the only async event handling in GLFW, but it solves some
// nasty problems
window = GetPropW(handle, L"GLFW");
if (window)
{
const int mods = getAsyncKeyMods();
@ -1429,19 +1424,20 @@ void _glfwPlatformPollEvents(void)
if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1)
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods);
}
}
if (window->cursorMode == GLFW_CURSOR_DISABLED)
window = _glfw.win32.disabledCursorWindow;
if (window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
// NOTE: Re-center the cursor only if it has moved since the last call,
// to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
if (window->win32.lastCursorPosX != width / 2 ||
window->win32.lastCursorPosY != height / 2)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
// NOTE: Re-center the cursor only if it has moved since the last
// call, to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
if (window->win32.lastCursorPosX != width / 2 ||
window->win32.lastCursorPosY != height / 2)
{
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
}
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
}
}
}
@ -1497,14 +1493,16 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_DISABLED)
{
_glfw.win32.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window,
&_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY);
centerCursor(window);
updateClipRect(window);
}
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
else if (_glfw.win32.disabledCursorWindow == window)
{
_glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL);
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
@ -1512,7 +1510,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
}
if (cursorInClientArea(window))
updateCursorImage(window, mode);
updateCursorImage(window);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -1573,7 +1571,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
if (cursorInClientArea(window))
updateCursorImage(window, window->cursorMode);
updateCursorImage(window);
}
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)

View File

@ -42,8 +42,6 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{
if (focused)
{
_glfw.cursorWindow = window;
if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused);
}
@ -51,8 +49,6 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{
int i;
_glfw.cursorWindow = NULL;
if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused);
@ -394,10 +390,6 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
if (window == _glfwPlatformGetCurrentContext())
glfwMakeContextCurrent(NULL);
// Clear the focused window pointer if this is the focused window
if (_glfw.cursorWindow == window)
_glfw.cursorWindow = NULL;
_glfwPlatformDestroyWindow(window);
// Unlink window from global linked list

View File

@ -157,6 +157,8 @@ typedef struct _GLFWlibraryX11
short int nativeKeys[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// Window manager atoms
Atom WM_PROTOCOLS;

View File

@ -396,6 +396,24 @@ static void centerCursor(_GLFWwindow* window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
{
XDefineCursor(_glfw.x11.display, window->x11.handle,
window->cursor->x11.handle);
}
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
}
else
XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor);
}
// Create the X11 window (and its colormap)
//
static GLFWbool createWindow(_GLFWwindow* window,
@ -1164,7 +1182,7 @@ static void processEvent(XEvent *event)
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.cursorWindow != window)
if (_glfw.x11.disabledCursorWindow != window)
return;
const int dx = x - window->x11.lastCursorPosX;
@ -1538,6 +1556,9 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (_glfw.x11.disabledCursorWindow == window)
_glfw.x11.disabledCursorWindow = NULL;
if (window->monitor)
releaseMonitor(window);
@ -2011,9 +2032,8 @@ void _glfwPlatformPollEvents(void)
processEvent(&event);
}
_GLFWwindow* window = _glfw.cursorWindow;
if (window && window->cursorMode == GLFW_CURSOR_DISABLED)
centerCursor(window);
if (_glfw.x11.disabledCursorWindow)
centerCursor(_glfw.x11.disabledCursorWindow);
}
void _glfwPlatformWaitEvents(void)
@ -2092,6 +2112,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
if (mode == GLFW_CURSOR_DISABLED)
{
_glfw.x11.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window,
&_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
@ -2101,26 +2122,16 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
GrabModeAsync, GrabModeAsync,
window->x11.handle, _glfw.x11.cursor, CurrentTime);
}
else if (window->cursorMode == GLFW_CURSOR_DISABLED)
else if (_glfw.x11.disabledCursorWindow == window)
{
_glfw.x11.disabledCursorWindow = NULL;
XUngrabPointer(_glfw.x11.display, CurrentTime);
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
}
if (mode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
{
XDefineCursor(_glfw.x11.display, window->x11.handle,
window->cursor->x11.handle);
}
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
}
else
XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor);
updateCursorImage(window);
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -2186,11 +2197,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (cursor)
XDefineCursor(_glfw.x11.display, window->x11.handle, cursor->x11.handle);
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
updateCursorImage(window);
XFlush(_glfw.x11.display);
}
}