fixed the cursor staying visible in raw input mode when focusing the window while a mouse button is pressed

got rid of redundent mouse API calls when handling focus changes
simplified the mouse input code
This commit is contained in:
myT 2017-08-18 19:05:19 +02:00
parent 37ef941ac2
commit 9dd81a895b
4 changed files with 42 additions and 37 deletions

View file

@ -103,6 +103,9 @@ chg: updated mouse input for better grab (de-)activation and fixed window draggi
chg: reduced raw mouse input latency and added cl_drawMouseLag chg: reduced raw mouse input latency and added cl_drawMouseLag
fix: in raw mouse input mode, keeping any button pressed while focusing the window would keep
the cursor visible even after releasing all buttons
Linux: Linux:

View file

@ -25,31 +25,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
struct Mouse { struct Mouse {
virtual qbool Init() { return qtrue; }
virtual qbool Activate( qbool active );
virtual void Shutdown() {}
virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ) { return qfalse; } // returns true if the event was handled
Mouse() : active(qfalse), wheel(0) {} Mouse() : active(qfalse), wheel(0) {}
void UpdateWheel( int delta );
private: qbool IsActive() const { return active; }
virtual qbool Init() { return qfalse; } // qtrue if successful
virtual qbool Activate( qbool active ) { return qfalse; } // qtrue if successful
virtual void Shutdown() {}
virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ) { return qfalse; } // qtrue if the event was handled
protected:
void UpdateWheel( int delta ); // queues mouse wheel events if needed
qbool active; qbool active;
int wheel; int wheel;
}; };
static Mouse* mouse; static Mouse* mouse;
static qbool mouseSettingsSet = qfalse;
qbool Mouse::Activate( qbool _active )
{
if (active == _active)
return qfalse;
active = _active;
wheel = 0;
return qtrue;
}
void Mouse::UpdateWheel( int delta ) void Mouse::UpdateWheel( int delta )
@ -88,16 +81,30 @@ qbool rawmouse_t::Init()
} }
qbool rawmouse_t::Activate( qbool active ) qbool rawmouse_t::Activate( qbool _active )
{ {
// if raw input isn't initialized with the RIDEV_INPUTSINK flag,
// pressing *any* mouse button while bringing the window back
// into focus will keep the cursor visible indefinitely...
// this was tested to be true on Windows 7 and 8.1
wheel = 0;
// RIDEV_NOLEGACY means we only get WM_INPUT and not WM_LBUTTONDOWN etc // RIDEV_NOLEGACY means we only get WM_INPUT and not WM_LBUTTONDOWN etc
// RIDEV_INPUTSINK means we get input even when not in the foreground
RAWINPUTDEVICE rid; RAWINPUTDEVICE rid;
rid.usUsagePage = 1; rid.usUsagePage = 1;
rid.usUsage = 2; rid.usUsage = 2;
rid.dwFlags = active ? RIDEV_NOLEGACY : RIDEV_REMOVE; rid.dwFlags = _active ? (RIDEV_NOLEGACY | RIDEV_INPUTSINK) : RIDEV_REMOVE;
rid.hwndTarget = NULL; rid.hwndTarget = NULL;
return !!RegisterRawInputDevices( &rid, 1, sizeof(rid) ); if (!RegisterRawInputDevices( &rid, 1, sizeof(rid) )) {
active = !_active;
return qfalse;
}
active = _active;
return qtrue;
} }
@ -110,7 +117,6 @@ qbool rawmouse_t::ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam )
return qfalse; return qfalse;
HRAWINPUT h = (HRAWINPUT)lParam; HRAWINPUT h = (HRAWINPUT)lParam;
UINT size; UINT size;
if (GetRawInputData( h, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER) ) == -1) if (GetRawInputData( h, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER) ) == -1)
return qfalse; return qfalse;
@ -160,10 +166,10 @@ struct winmouse_t : public Mouse {
virtual qbool Activate( qbool active ); virtual qbool Activate( qbool active );
virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ); virtual qbool ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam );
private:
void UpdateWindowCenter(); void UpdateWindowCenter();
int window_center_x, window_center_y; int window_center_x, window_center_y;
qbool active;
}; };
static winmouse_t winmouse; static winmouse_t winmouse;
@ -179,6 +185,7 @@ void winmouse_t::UpdateWindowCenter()
qbool winmouse_t::Activate( qbool _active ) qbool winmouse_t::Activate( qbool _active )
{ {
wheel = 0;
active = _active; active = _active;
if (!_active) if (!_active)
@ -251,6 +258,7 @@ static void IN_StartupMouse()
{ {
assert( !mouse ); assert( !mouse );
mouse = 0; mouse = 0;
mouseSettingsSet = qfalse;
cvar_t* in_mouse = Cvar_Get( "in_mouse", "1", CVAR_ARCHIVE|CVAR_LATCH ); cvar_t* in_mouse = Cvar_Get( "in_mouse", "1", CVAR_ARCHIVE|CVAR_LATCH );
in_mouse->modified = qfalse; in_mouse->modified = qfalse;
@ -338,14 +346,14 @@ void IN_Shutdown()
} }
void IN_SetCursorSettings( qbool active ) static void IN_SetCursorSettings( qbool active )
{ {
if (active) { if (active) {
while (ShowCursor(FALSE) >= 0) while (ShowCursor(FALSE) >= 0)
; ;
RECT rc; RECT rc;
GetWindowRect( g_wv.hWnd, &rc );
SetCapture( g_wv.hWnd ); SetCapture( g_wv.hWnd );
GetWindowRect( g_wv.hWnd, &rc );
ClipCursor( &rc ); ClipCursor( &rc );
} else { } else {
while (ShowCursor(TRUE) < 0) while (ShowCursor(TRUE) < 0)
@ -361,16 +369,17 @@ void IN_SetCursorSettings( qbool active )
void IN_Activate( qbool active ) void IN_Activate( qbool active )
{ {
if ( !mouse || !mouse->Mouse::Activate( active ) ) if ( !mouse || (mouseSettingsSet && mouse->IsActive() == active) )
return; return;
IN_SetCursorSettings( active ); if ( mouse->Activate( active ) )
IN_SetCursorSettings( active );
mouse->Activate( active ); mouseSettingsSet = qtrue;
} }
qbool IN_ShouldBeActive() static qbool IN_ShouldBeActive()
{ {
return g_wv.activeApp && (!(cls.keyCatchers & KEYCATCH_CONSOLE) || Cvar_VariableIntegerValue("r_fullscreen")); return g_wv.activeApp && (!(cls.keyCatchers & KEYCATCH_CONSOLE) || Cvar_VariableIntegerValue("r_fullscreen"));
} }

View file

@ -33,9 +33,7 @@ void Conbuf_AppendText( const char *msg );
void IN_Init(); void IN_Init();
void IN_SetCursorSettings( qbool active );
void IN_Activate( qbool active ); void IN_Activate( qbool active );
qbool IN_ShouldBeActive();
qbool IN_ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ); // returns true if the event was handled qbool IN_ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ); // returns true if the event was handled
void IN_Frame(); void IN_Frame();
void IN_Shutdown(); void IN_Shutdown();

View file

@ -86,8 +86,6 @@ static void WIN_AppActivate( BOOL fActive, BOOL fMinimized )
// we don't want to act like we're active if we're minimized // we don't want to act like we're active if we're minimized
g_wv.activeApp = active; g_wv.activeApp = active;
IN_Activate( IN_ShouldBeActive() );
} }
@ -362,13 +360,10 @@ LRESULT CALLBACK MainWndProc (
} }
} }
g_wv.activeApp = (qbool)!IsIconic( hWnd ); g_wv.activeApp = (qbool)!IsIconic( hWnd );
IN_SetCursorSettings( IN_ShouldBeActive() );
break; break;
case WM_KILLFOCUS: case WM_KILLFOCUS:
g_wv.activeApp = qfalse; g_wv.activeApp = qfalse;
IN_SetCursorSettings( qfalse );
if ( glw_state.cdsDevModeValid ) if ( glw_state.cdsDevModeValid )
WIN_SetDesktopDisplaySettings(); WIN_SetDesktopDisplaySettings();
break; break;