mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 14:11:33 +00:00
Fix large mouse input delay on GFE 3.14.0 and earlier. Fixes #68
This commit is contained in:
@@ -29,9 +29,15 @@ NvHTTP::NvHTTP(QString address) :
|
|||||||
QVector<int>
|
QVector<int>
|
||||||
NvHTTP::parseQuad(QString quad)
|
NvHTTP::parseQuad(QString quad)
|
||||||
{
|
{
|
||||||
QStringList parts = quad.split(".");
|
|
||||||
QVector<int> ret;
|
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++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
ret.append(parts.at(i).toInt());
|
ret.append(parts.at(i).toInt());
|
||||||
|
|||||||
+20
-4
@@ -24,9 +24,10 @@ const int SdlInputHandler::k_ButtonMap[] = {
|
|||||||
UP_FLAG, DOWN_FLAG, LEFT_FLAG, RIGHT_FLAG
|
UP_FLAG, DOWN_FLAG, LEFT_FLAG, RIGHT_FLAG
|
||||||
};
|
};
|
||||||
|
|
||||||
SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs)
|
SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer* computer)
|
||||||
: m_LastMouseMotionTime(0),
|
: m_LastMouseMotionTime(0),
|
||||||
m_MultiController(prefs.multiController)
|
m_MultiController(prefs.multiController),
|
||||||
|
m_NeedsInputDelay(false)
|
||||||
{
|
{
|
||||||
// Allow gamepad input when the app doesn't have focus
|
// Allow gamepad input when the app doesn't have focus
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||||
@@ -81,6 +82,19 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs)
|
|||||||
m_GamepadMask = 0;
|
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);
|
SDL_zero(m_GamepadState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,9 +444,11 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event)
|
|||||||
short ydelta = (short)event->yrel;
|
short ydelta = (short)event->yrel;
|
||||||
|
|
||||||
// If we're sending more than one motion event per millisecond,
|
// 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();
|
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);
|
SDL_Delay(1);
|
||||||
currentTime = SDL_GetTicks();
|
currentTime = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "settings/streamingpreferences.h"
|
#include "settings/streamingpreferences.h"
|
||||||
|
#include "backend/computermanager.h"
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ struct GamepadState {
|
|||||||
class SdlInputHandler
|
class SdlInputHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SdlInputHandler(StreamingPreferences& prefs);
|
explicit SdlInputHandler(StreamingPreferences& prefs, NvComputer* computer);
|
||||||
|
|
||||||
~SdlInputHandler();
|
~SdlInputHandler();
|
||||||
|
|
||||||
@@ -48,6 +49,7 @@ private:
|
|||||||
|
|
||||||
Uint32 m_LastMouseMotionTime;
|
Uint32 m_LastMouseMotionTime;
|
||||||
bool m_MultiController;
|
bool m_MultiController;
|
||||||
|
bool m_NeedsInputDelay;
|
||||||
int m_GamepadMask;
|
int m_GamepadMask;
|
||||||
GamepadState m_GamepadState[MAX_GAMEPADS];
|
GamepadState m_GamepadState[MAX_GAMEPADS];
|
||||||
|
|
||||||
|
|||||||
@@ -287,7 +287,8 @@ Session::Session(NvComputer* computer, NvApp& app)
|
|||||||
|
|
||||||
void Session::initialize()
|
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);
|
LiInitializeVideoCallbacks(&m_VideoCallbacks);
|
||||||
m_VideoCallbacks.setup = drSetup;
|
m_VideoCallbacks.setup = drSetup;
|
||||||
@@ -731,7 +732,7 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
|
|
||||||
// Initialize the gamepad code with our preferences
|
// Initialize the gamepad code with our preferences
|
||||||
StreamingPreferences prefs;
|
StreamingPreferences prefs;
|
||||||
SdlInputHandler inputHandler(prefs);
|
SdlInputHandler inputHandler(prefs, m_Computer);
|
||||||
|
|
||||||
// The UI should have ensured the old game was already quit
|
// The UI should have ensured the old game was already quit
|
||||||
// if we decide to stream a different game.
|
// if we decide to stream a different game.
|
||||||
|
|||||||
Reference in New Issue
Block a user