mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-01 23:35:55 +00:00
Use a barrier to ensure we don't flush important window events
This commit is contained in:
parent
e6f59062fa
commit
2d62d090df
@ -22,6 +22,8 @@
|
||||
#define ICON_SIZE 64
|
||||
#endif
|
||||
|
||||
#define SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER 100
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <QtEndian>
|
||||
@ -378,6 +380,7 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere
|
||||
m_InputHandler(nullptr),
|
||||
m_InputHandlerLock(0),
|
||||
m_MouseEmulationRefCount(0),
|
||||
m_FlushingWindowEvents(false),
|
||||
m_AsyncConnectionSuccess(false),
|
||||
m_PortTestResults(0),
|
||||
m_OpusDecoder(nullptr),
|
||||
@ -1093,6 +1096,23 @@ bool Session::startConnectionAsync()
|
||||
return true;
|
||||
}
|
||||
|
||||
void Session::flushWindowEvents()
|
||||
{
|
||||
// Pump events to ensure all pending OS events are posted
|
||||
SDL_PumpEvents();
|
||||
|
||||
// Insert a barrier to discard any additional window events.
|
||||
// We don't use SDL_FlushEvent() here because it could cause
|
||||
// important events to be lost.
|
||||
m_FlushingWindowEvents = true;
|
||||
|
||||
// This event will cause us to set m_FlushingWindowEvents back to false.
|
||||
SDL_Event flushEvent = {};
|
||||
flushEvent.type = SDL_USEREVENT;
|
||||
flushEvent.user.code = SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER;
|
||||
SDL_PushEvent(&flushEvent);
|
||||
}
|
||||
|
||||
void Session::exec(int displayOriginX, int displayOriginY)
|
||||
{
|
||||
m_DisplayOriginX = displayOriginX;
|
||||
@ -1313,6 +1333,9 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
||||
case SDL_CODE_SHOW_CURSOR:
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
break;
|
||||
case SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER:
|
||||
m_FlushingWindowEvents = false;
|
||||
break;
|
||||
default:
|
||||
SDL_assert(false);
|
||||
}
|
||||
@ -1372,6 +1395,11 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
||||
SDL_SetWindowPosition(m_Window, x, y);
|
||||
}
|
||||
|
||||
if (m_FlushingWindowEvents) {
|
||||
// Ignore window events for renderer reset if flushing
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Recreating renderer for window event: %d (%d %d)",
|
||||
event.window.event,
|
||||
@ -1387,10 +1415,11 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
||||
// Destroy the old decoder
|
||||
delete m_VideoDecoder;
|
||||
|
||||
// Flush any other pending window events that could
|
||||
// send us back here immediately
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_WINDOWEVENT);
|
||||
// Insert a barrier to discard any additional window events
|
||||
// that could cause the renderer to be and recreated again.
|
||||
// We don't use SDL_FlushEvent() here because it could cause
|
||||
// important events to be lost.
|
||||
flushWindowEvents();
|
||||
|
||||
// Update the window display mode based on our current monitor
|
||||
currentDisplayIndex = SDL_GetWindowDisplayIndex(m_Window);
|
||||
|
@ -39,6 +39,8 @@ public:
|
||||
return m_OverlayManager;
|
||||
}
|
||||
|
||||
void flushWindowEvents();
|
||||
|
||||
signals:
|
||||
void stageStarting(QString stage);
|
||||
|
||||
@ -150,6 +152,7 @@ private:
|
||||
SdlInputHandler* m_InputHandler;
|
||||
SDL_SpinLock m_InputHandlerLock;
|
||||
int m_MouseEmulationRefCount;
|
||||
bool m_FlushingWindowEvents;
|
||||
|
||||
bool m_AsyncConnectionSuccess;
|
||||
int m_PortTestResults;
|
||||
|
@ -112,8 +112,17 @@ bool SdlRenderer::initialize(PDECODER_PARAMETERS params)
|
||||
// can get spurious SDL_WINDOWEVENT events that will cause us to (again) recreate our
|
||||
// renderer. This can lead to an infinite to renderer recreation, so discard all
|
||||
// SDL_WINDOWEVENT events after SDL_CreateRenderer().
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_WINDOWEVENT);
|
||||
Session* session = Session::get();
|
||||
if (session != nullptr) {
|
||||
// If we get here during a session, we need to synchronize with the event loop
|
||||
// to ensure we don't drop any important events.
|
||||
session->flushWindowEvents();
|
||||
}
|
||||
else {
|
||||
// If we get here prior to the start of a session, just pump and flush ourselves.
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_WINDOWEVENT);
|
||||
}
|
||||
|
||||
// Calculate the video region size, scaling to fill the output size while
|
||||
// preserving the aspect ratio of the video stream.
|
||||
|
Loading…
x
Reference in New Issue
Block a user