Fix lag on events

Found on sanctum2, returning 0 in XPending & XEventsQueued make the SDL do something else than polling events and makes lag the event loop.
Now the event loop returns 0 when there are no more events.
This commit is contained in:
Nemirtingas 2019-09-03 17:24:34 +02:00
parent 9fa4053551
commit 1016e7f47f
4 changed files with 78 additions and 69 deletions

View file

@ -23,6 +23,7 @@
// X11 Data // X11 Data
static Display* g_Display = nullptr; static Display* g_Display = nullptr;
static Window g_Window = 0;
static uint64_t g_Time = 0; static uint64_t g_Time = 0;
static uint64_t g_TicksPerSecond = 0; static uint64_t g_TicksPerSecond = 0;
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT;
@ -56,7 +57,7 @@ bool IsKeySys(int key)
} }
// Functions // Functions
bool ImGui_ImplX11_Init(void *display) bool ImGui_ImplX11_Init(void *display, void *window)
{ {
timespec ts, tsres; timespec ts, tsres;
clock_getres(CLOCK_MONOTONIC_RAW, &tsres); clock_getres(CLOCK_MONOTONIC_RAW, &tsres);
@ -72,6 +73,7 @@ bool ImGui_ImplX11_Init(void *display)
// Setup back-end capabilities flags // Setup back-end capabilities flags
g_Display = reinterpret_cast<Display*>(display); g_Display = reinterpret_cast<Display*>(display);
g_Window = reinterpret_cast<Window>(window);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
@ -107,6 +109,7 @@ bool ImGui_ImplX11_Init(void *display)
void ImGui_ImplX11_Shutdown() void ImGui_ImplX11_Shutdown()
{ {
g_Display = nullptr; g_Display = nullptr;
g_Window = 0;
} }
static bool ImGui_ImplX11_UpdateMouseCursor() static bool ImGui_ImplX11_UpdateMouseCursor()
@ -143,7 +146,7 @@ static bool ImGui_ImplX11_UpdateMouseCursor()
return true; return true;
} }
static void ImGui_ImplX11_UpdateMousePos(Window window) static void ImGui_ImplX11_UpdateMousePos()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -160,7 +163,7 @@ static void ImGui_ImplX11_UpdateMousePos(Window window)
int rx, ry, x, y; int rx, ry, x, y;
unsigned int mask; unsigned int mask;
XQueryPointer(g_Display, window, &unused_window, &unused_window, &rx, &ry, &x, &y, &mask); XQueryPointer(g_Display, g_Window, &unused_window, &unused_window, &rx, &ry, &x, &y, &mask);
io.MousePos.x = x; io.MousePos.x = x;
io.MousePos.y = y; io.MousePos.y = y;
@ -215,7 +218,7 @@ static void ImGui_ImplX11_UpdateGamepads()
*/ */
} }
void ImGui_ImplX11_NewFrame(void* window) void ImGui_ImplX11_NewFrame()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
@ -225,7 +228,7 @@ void ImGui_ImplX11_NewFrame(void* window)
int unused_int; int unused_int;
unsigned int unused_unsigned_int; unsigned int unused_unsigned_int;
XGetGeometry(g_Display, (Window)window, &unused_window, &unused_int, &unused_int, &width, &height, &unused_unsigned_int, &unused_unsigned_int); XGetGeometry(g_Display, (Window)g_Window, &unused_window, &unused_int, &unused_int, &width, &height, &unused_unsigned_int, &unused_unsigned_int);
io.DisplaySize.x = width; io.DisplaySize.x = width;
io.DisplaySize.y = height; io.DisplaySize.y = height;
@ -249,7 +252,7 @@ void ImGui_ImplX11_NewFrame(void* window)
// io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below.
// Update OS mouse position // Update OS mouse position
ImGui_ImplX11_UpdateMousePos((Window)window); ImGui_ImplX11_UpdateMousePos();
/* /*
// Update OS mouse cursor with the cursor requested by imgui // Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();

View file

@ -9,9 +9,9 @@
#pragma once #pragma once
IMGUI_IMPL_API bool ImGui_ImplX11_Init(void* display); IMGUI_IMPL_API bool ImGui_ImplX11_Init(void* display, void* window);
IMGUI_IMPL_API void ImGui_ImplX11_Shutdown(); IMGUI_IMPL_API void ImGui_ImplX11_Shutdown();
IMGUI_IMPL_API void ImGui_ImplX11_NewFrame(void* window); IMGUI_IMPL_API void ImGui_ImplX11_NewFrame();
// Handler for Win32 messages, update mouse/keyboard data. // Handler for Win32 messages, update mouse/keyboard data.
// You may or not need this for your implementation, but it can serve as reference for handling inputs. // You may or not need this for your implementation, but it can serve as reference for handling inputs.

View file

@ -41,14 +41,14 @@ void X11_Hook::prepareForOverlay(Display *display, Window wnd)
{ {
if (!initialized) if (!initialized)
{ {
ImGui_ImplX11_Init(display); ImGui_ImplX11_Init(display, (void*)wnd);
game_wnd = wnd; game_wnd = wnd;
initialized = true; initialized = true;
} }
ImGui_ImplX11_NewFrame((void*)wnd); ImGui_ImplX11_NewFrame();
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -68,19 +68,19 @@ bool IgnoreEvent(XEvent &event)
return false; return false;
} }
int X11_Hook::MyXEventsQueued(Display *display, int mode) int X11_Hook::check_for_overlay(Display *d, int num_events)
{
X11_Hook* inst = X11_Hook::Inst();
int res = inst->_XEventsQueued(display, mode);
if( res )
{ {
static Time prev_time = {}; static Time prev_time = {};
X11_Hook* inst = Inst();
if( inst->initialized )
{
XEvent event; XEvent event;
//inst->_XPeekEvent(display, &event); while(num_events)
XPeekEvent(display, &event); {
//inst->_XPeekEvent(d, &event);
XPeekEvent(d, &event);
Steam_Overlay* overlay = get_steam_client()->steam_overlay; Steam_Overlay* overlay = get_steam_client()->steam_overlay;
bool show = overlay->ShowOverlay(); bool show = overlay->ShowOverlay();
@ -88,8 +88,8 @@ int X11_Hook::MyXEventsQueued(Display *display, int mode)
if (event.type == KeyPress) if (event.type == KeyPress)
{ {
// Tab is pressed and was not pressed before // Tab is pressed and was not pressed before
//if (event.xkey.keycode == inst->_XKeysymToKeycode(display, XK_Tab) && event.xkey.state & ShiftMask) //if (event.xkey.keycode == inst->_XKeysymToKeycode(d, XK_Tab) && event.xkey.state & ShiftMask)
if (event.xkey.keycode == XKeysymToKeycode(display, XK_Tab) && event.xkey.state & ShiftMask) if (event.xkey.keycode == XKeysymToKeycode(d, XK_Tab) && event.xkey.state & ShiftMask)
{ {
// if key TAB is held, don't make the overlay flicker :p // if key TAB is held, don't make the overlay flicker :p
if( event.xkey.time != prev_time) if( event.xkey.time != prev_time)
@ -101,8 +101,8 @@ int X11_Hook::MyXEventsQueued(Display *display, int mode)
} }
} }
} }
//else if(event.type == KeyRelease && event.xkey.keycode == inst->_XKeysymToKeycode(display, XK_Tab)) //else if(event.type == KeyRelease && event.xkey.keycode == inst->_XKeysymToKeycode(d, XK_Tab))
else if(event.type == KeyRelease && event.xkey.keycode == XKeysymToKeycode(display, XK_Tab)) else if(event.type == KeyRelease && event.xkey.keycode == XKeysymToKeycode(d, XK_Tab))
{ {
prev_time = event.xkey.time; prev_time = event.xkey.time;
} }
@ -113,16 +113,31 @@ int X11_Hook::MyXEventsQueued(Display *display, int mode)
if (IgnoreEvent(event)) if (IgnoreEvent(event))
{ {
//inst->_XNextEvent(display, &event); //inst->_XNextEvent(d, &event);
XNextEvent(display, &event); XNextEvent(d, &event);
return 0; --num_events;
}
else
break;
}
else
break;
} }
} }
return num_events;
}
int X11_Hook::MyXEventsQueued(Display *display, int mode)
{
X11_Hook* inst = X11_Hook::Inst();
int res = inst->_XEventsQueued(display, mode);
if( res )
{
res = inst->check_for_overlay(display, res);
} }
// XEventsQueued returns the num of events available.
// Usually, games tend to read all events queued before calling again XEventsQueued
// making us unavailable to intercept undesired events
return res; return res;
} }
@ -140,19 +155,9 @@ int X11_Hook::MyXPending(Display* display)
{ {
int res = Inst()->_XPending(display); int res = Inst()->_XPending(display);
if( res && get_steam_client()->steam_overlay->ShowOverlay() ) if( res )
{ {
XEvent event; res = Inst()->check_for_overlay(display, res);
//Inst()->_XPeekEvent(display, &event);
XPeekEvent(display, &event);
if( IgnoreEvent(event) )
{
ImGui_ImplX11_EventHandler(event);
//Inst()->_XNextEvent(display, &event);
XNextEvent(display, &event);
res = 0;
}
} }
return res; return res;

View file

@ -24,6 +24,7 @@ private:
// Functions // Functions
X11_Hook(); X11_Hook();
int check_for_overlay(Display *d, int num_events);
// Hook to X11 window messages // Hook to X11 window messages