mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-13 21:02:28 +00:00
Fix large mouse input delay on GFE 3.14.0 and earlier. Fixes #68
This commit is contained in:
parent
7ca2ca8045
commit
25d97e187a
4 changed files with 33 additions and 8 deletions
|
@ -29,9 +29,15 @@ NvHTTP::NvHTTP(QString address) :
|
|||
QVector<int>
|
||||
NvHTTP::parseQuad(QString quad)
|
||||
{
|
||||
QStringList parts = quad.split(".");
|
||||
QVector<int> ret;
|
||||
|
||||
// Return an empty vector for old GFE versions
|
||||
// that were missing GfeVersion.
|
||||
if (quad.isEmpty()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList parts = quad.split(".");
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ret.append(parts.at(i).toInt());
|
||||
|
|
|
@ -24,9 +24,10 @@ const int SdlInputHandler::k_ButtonMap[] = {
|
|||
UP_FLAG, DOWN_FLAG, LEFT_FLAG, RIGHT_FLAG
|
||||
};
|
||||
|
||||
SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs)
|
||||
SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer* computer)
|
||||
: m_LastMouseMotionTime(0),
|
||||
m_MultiController(prefs.multiController)
|
||||
m_MultiController(prefs.multiController),
|
||||
m_NeedsInputDelay(false)
|
||||
{
|
||||
// Allow gamepad input when the app doesn't have focus
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
|
@ -81,6 +82,19 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs)
|
|||
m_GamepadMask = 0;
|
||||
}
|
||||
|
||||
// Prior to GFE 3.14.1, sending too many mouse motion events can cause
|
||||
// GFE to choke and input latency to increase significantly. We will
|
||||
// artificially throttle them to avoid this situation.
|
||||
QVector<int> gfeVersion = NvHTTP::parseQuad(computer->gfeVersion);
|
||||
if (gfeVersion.isEmpty() || // Very old versions don't have GfeVersion at all
|
||||
gfeVersion[0] < 3 ||
|
||||
(gfeVersion[0] == 3 && gfeVersion[1] < 14) ||
|
||||
(gfeVersion[0] == 3 && gfeVersion[1] == 14 && gfeVersion[2] < 1)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"This older version of GFE requires input delay hack");
|
||||
m_NeedsInputDelay = true;
|
||||
}
|
||||
|
||||
SDL_zero(m_GamepadState);
|
||||
}
|
||||
|
||||
|
@ -430,9 +444,11 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event)
|
|||
short ydelta = (short)event->yrel;
|
||||
|
||||
// If we're sending more than one motion event per millisecond,
|
||||
// delay for 1 ms to allow batching of mouse move events.
|
||||
// delay for 1 ms to allow batching of mouse move events. On older
|
||||
// versions of GFE, we will unconditionally wait this 1 ms to
|
||||
// work around an input processing issue that causes massive mouse latency.
|
||||
Uint32 currentTime = SDL_GetTicks();
|
||||
if (!SDL_TICKS_PASSED(currentTime, m_LastMouseMotionTime + 1)) {
|
||||
if (m_NeedsInputDelay || !SDL_TICKS_PASSED(currentTime, m_LastMouseMotionTime + 1)) {
|
||||
SDL_Delay(1);
|
||||
currentTime = SDL_GetTicks();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "settings/streamingpreferences.h"
|
||||
#include "backend/computermanager.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
|
@ -20,7 +21,7 @@ struct GamepadState {
|
|||
class SdlInputHandler
|
||||
{
|
||||
public:
|
||||
explicit SdlInputHandler(StreamingPreferences& prefs);
|
||||
explicit SdlInputHandler(StreamingPreferences& prefs, NvComputer* computer);
|
||||
|
||||
~SdlInputHandler();
|
||||
|
||||
|
@ -48,6 +49,7 @@ private:
|
|||
|
||||
Uint32 m_LastMouseMotionTime;
|
||||
bool m_MultiController;
|
||||
bool m_NeedsInputDelay;
|
||||
int m_GamepadMask;
|
||||
GamepadState m_GamepadState[MAX_GAMEPADS];
|
||||
|
||||
|
|
|
@ -287,7 +287,8 @@ Session::Session(NvComputer* computer, NvApp& app)
|
|||
|
||||
void Session::initialize()
|
||||
{
|
||||
qDebug() << "Server GPU:" << m_Computer->gpuModel;
|
||||
qInfo() << "Server GPU:" << m_Computer->gpuModel;
|
||||
qInfo() << "Server GFE version:" << m_Computer->gfeVersion;
|
||||
|
||||
LiInitializeVideoCallbacks(&m_VideoCallbacks);
|
||||
m_VideoCallbacks.setup = drSetup;
|
||||
|
@ -731,7 +732,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||
|
||||
// Initialize the gamepad code with our preferences
|
||||
StreamingPreferences prefs;
|
||||
SdlInputHandler inputHandler(prefs);
|
||||
SdlInputHandler inputHandler(prefs, m_Computer);
|
||||
|
||||
// The UI should have ensured the old game was already quit
|
||||
// if we decide to stream a different game.
|
||||
|
|
Loading…
Reference in a new issue