I've been reading a few articles about input latency lately:
https://danluu.com/term-latency/
https://pavelfatin.com/typing-with-pleasure/
And I've been trying to improve the user experience of my small text editor. I was using SDL to pool input and create the window, but decided to remove it and do my own X implementation. Application startup has improved, but input latency not so much. Is there any specific technique that can be done to improve how my application picks up mouse and keyboard data from X? Or should I just give up and force Wayland?
I've considered running my XNextEvent() loop on a separate thread, but is that really the only solution for this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include <GL/glu.h>
Display *dpy;
Window root, win;
GLint att[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
XVisualInfo *vi;
Colormap cmap;
XSetWindowAttributes swa;
XWindowAttributes wa;
XEvent xev;
Mask mask;
float TimeCounter, LastFrameTimeCounter, DT, prevTime = 0.0, FPS;
struct timeval tv, tv0;
int Frame = 1, FramesPerFPS;
void CreateWindow() {
if ((dpy = XOpenDisplay(NULL)) == NULL) {
printf("\n\tcannot connect to x server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
if ((vi = glXChooseVisual(dpy, 0, att)) == NULL) {
printf("\n\tno matching visual\n\n");
exit(0);
}
if ((cmap = XCreateColormap(dpy, root, vi->visual, AllocNone)) == 0) {
printf("\n\tcannot create colormap\n\n");
exit(0);
}
swa.event_mask = KeyPressMask;
swa.colormap = cmap;
win = XCreateWindow(dpy, root, 0, 0, 1024, 768, 0, vi->depth, InputOutput,
vi->visual, CWColormap | CWEventMask, &swa);
XStoreName(dpy, win, "ed");
XMapWindow(dpy, win);
}
void Close() {
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
exit(0);
}
int main(int argc, char *argv[]) {
CreateWindow();
while (true) {
mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
while (XCheckWindowEvent(dpy, win, mask, &xev) ||
XCheckTypedWindowEvent(dpy, win, ClientMessage, &xev)) {
char *key_string =
XKeysymToString(XkbKeycodeToKeysym(dpy, xev.xkey.keycode, 0, 0));
if (strncmp(key_string, "Escape", 5) == 0) {
Close();
}
}
}
}