[Mono-dev] AppActivate and System.Windows.Forms.SendKeys on Ubuntu 10.10

Jonathan Pryor jonpryor at vt.edu
Wed Mar 16 22:19:52 EDT 2011


On Mar 16, 2011, at 4:07 PM, Quandary wrote:
> What, only SendKeys to WinForms, are you serious ?
> That doesn't make much sense.

It makes perfect sense.

> It sends KeyEvents to the Windowing system, which happens to be the
> WinAPI on Windows, or X11 on Linux for all intents and purposes.
> GTK has nothing to do with it.
> 
> You send the keyboard keys as simulated input to X11, and before that,
> you set the focus window.

The problem is that there is no such mechanism in X11, at least not in a way that can be used in a straightforward fashion.

For example, Microsoft's SendKeys.Send() method is _probably_ implemented in terms of the SendInput() WinAPI function:

	http://msdn.microsoft.com/en-us/library/ms646310(VS.85).aspx

So SendKeys.Send() presumably maps the input string into a set of INPUT structures, then sends the structures to SendInput() so that the operating system will interpret them. Note that this is _very_ low level, working at the keyboard level, not the thread event loop level.

One of the things that this allows is that SendKeys.Send("%{TAB}") (aka Alt+Tab) will change the active window.

Now, what does X11 provide? A cursory glance shows XSendEvent:

	http://tronche.com/gui/x/xlib/event-handling/XSendEvent.html

This allows passing an XEvent, such as an XKeyEvent, to a given window.

Problem: In Windows, it's the operating system which handles the input, which thus allows OS "capturing" of Alt+Tab so that the active application is switched. In X11, XSendEvent() requires that you explicitly specify both the Display and Window that the event is being passed to. Consequently, there is NO MECHANISM to have Alt+Tab "captured" by the OS and thus change windows (even if Alt+Tab _will_ change windows when typed via the keyboard). This is because the WIndow Manager is grabbing Alt+Tab, but the Window Manager is a completely separate process, and there's not necessarily an easy way to grab the Display+Window for the Window Manager (which might not have a Window to begin with).

In short, you can't get there from here, as the entire X11 architecture is ~completely different.

> At least on Windows.

Exactly. On Windows, everything uses the same WinAPI message looping mechanism. On X11, very little is consistent across toolkits, and X11 doesn't specify much (leaving it up to the Window Manager + applications + ... to work out the details).

Then there's OSX, which uses yet another completely different mechanism. SendKeys.Send() is inherently Windows specific; you should be glad it works for System.Windows.Forms apps at all.

 - Jon



More information about the Mono-devel-list mailing list