Window events non-main thread


#1

So simple question I haven’t found a definite (recent) answer to.
I’m injecting a dll into another process and I want to create a window and monitor mouse and keyboard events. I do not need to do any rendering (other than making the window transparent using SDL_SetWindowOpacity)

All SDL methods are called and handled from the SAME thread, it just won’t be the main one (as its injected it can’t access that without blocking).
Would this work on Windows and osx? And if so is there a specific approach or method required?


#2

Would this work on Windows and osx? And if so is there a specific approach or method required?

I don’t know the answer in practice (beyond “we don’t promise this will work”), but my reading of the Windows-specific source code is that this should work as long as your stuff is all in the same thread.

If you need to catch events from a window not made with SDL_CreateWindow, you can use SDL_CreateWindowFrom and SDL should hook in appropriately, even if hooking into a different thread, but probably won’t get events until the other thread pumps its own event queue.

It might be interesting to hook into the main window with SDL_CreateWindowFrom so you can get a callback on the main thread when it pumps its event queue, and hook up all the things you need from there. Again, totally untried here.

I don’t know if this will work on macOS. I haven’t researched it. Please report back if you try it, though!


#3

Cocoa/macOS requires UI function calls and event processing to be on the main thread, it will crash or have other unexpected behaviour otherwise I believe.

SDL_PollEvent calls SDL_PumpEvents internally, which calls Cocoa UI functions and does the OS event processing. Many SDL_Window APIs call Cocoa UI functions as well.


#4

Would this work on Windows and osx?

Sorry to be the bearer of bad news, but this is not guaranteed to work
on OSX, and probably won’t work. And if it does work for you, it is
not guaranteed to work in past or future versions of OS X.

The general rule of thumb on Mac is that AppKit stuff must be on the
main thread. There are exceptions, but since SDL’s implementation
touches on a lot of components including NSWindow and NSView, the
situation is complex enough that it probably won’t fall within those
allowed exceptions.

And Mac isn’t the only platform where UI things must be on the UI
thread. (Android comes to mind.) There have been many frustrated users
on this list over the years who have tried similar things and gotten
away with it on Windows, only to find out later that it doesn’t work
on Mac or sometimes other platforms.

-Eric


#5

Thanks for all replies, looks like I’ll have to rethink my approach.

As I’m injecting from my own app I believe the best option is creating a window on the main thread there and then use some shared memory to send over input events to the injected dll. Hopefully the latency isn’t too bad.