Question

Imagine a cross-platform library that has to create its own windows without relying on WinForms/GTK#/WPF/MonoMac/etc (this is OpenTK in case anyone is interested).

Here is the deal: Windows and X11-capable Unices support (or can work with) multiple event loops, one on each thread. This means (a) you can create one window per thread and have them work independently and (b) you can run a WinForms (or GTK#, WPF, ...) window on one thread and open an OpenTK window on a different, without interference.

Now, to the best of my - admittedly limited - knowledge, Carbon does not support this. OS events are only delivered to the "main" event loop and all secondary threads run on fumes (that is, ReceiveNextEvent always returns eventLoopTimedOutErr and doesn't find any events). OpenTK itself can work with this limitation, no problem, but this poses an interesting problem to applications that try to mix OpenTK with a different toolkit (e.g. MonoMac) to present a configuration window.

Two options:

  • abandon the idea as crazy and disallow mixing OpenTK with different toolkits (bad).
  • pick a battle-axe and hack Carbon into submission (good).

Here is were you come in: can you think of any way to make this work? Imagine the following scenario:

  1. Thread #1 (main) runs some initialization code of our own choosing and spawns a second thread (we can modify this freely).
  2. Thread #1 (main) opens a native window and runs a RAEL loop (RunApplicationEventLoop). It goes out of our direct control, although we can still install timers to run our code, if necessary.
  3. Thread #2 (secondary) opens an OpenTK window that promptly hangs (events are only delivered to thread #1 and ReceiveNextEvent gets nothing).

Is it possible to filter events from thread #1 and deliver them to thread #2 as necessary? Could CF somehow help here? Gurus of Mac OS X, please help!

(Programming language doesn't matter, use anything you are familiar with. I'd prefer a Carbon-based solution but Cocoa would work just fine.)

Was it helpful?

Solution

Passing the events from one thread to another should work as far as just plain getting the events delivered. The sticky part is that a lot of the UI-related APIs are not thread safe, even though the core Carbon Event handling is. Anything that involves updating controls and drawing should probably be handled back on the main thread. That would require a lot of back-and-forth, and it may not be worthwhile to try to make it work.

OTHER TIPS

Take a look at Application.AddMessageFilter and the IMessageFilter interface. You might be able to intercept and forward messages using custom logic. I have used this technique in the past (very distant past), but it has been so long ago that I do not remember all of the caveats that go along with it. I am not even certain that the message filter will receive all of the messages. .NET might not be filtering them out behind the scenes before sending them to the IMessageFilter, but it is worth a shot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top