I bet you've already noticed the focusing issue with
nxclient if you tried to use it in rootless mode, just by running with
xinit
. The problem occurs when you disconnect from the NX server and start nxclient again: the client does not get the keyboard focus no matter what.
This caused me quite some headache and several hours of debugging. I noticed by accident that if I start rdesktop in full-screen mode after I disconnected from an NX session, it "repaired" the focus issue with nxclient. One does not have to actually log in to any server with rdesktop, you just have to make it switch to full-screen mode and you're all done (can exit the RDP session). This was my first clue.
Parallely I started looking for traces of the issue on the net. I've found
a thread at the ltsp-discuss mailing list where Gideon Romm mentioned the issue. He's the developer and maintainer of the
NX_LTSP package which provides a pre-packaged nxclient for an LTSP environment. He solved the problem by adding a window manager (twm) to the xinit startup script. This is something that I did not want to choose since I had no use for a window manager except for this fix. I knew there had to be another way.
I've found
a post in Nomachine's knowledge base where they describe the very same issue, but in a bit different context. This was the first time I read about the use of the XSetInputFocus() function call as a possible fix.
The next step was to analyze rdesktop (a thousand hurrahs to open source
) and see what exactly it is doing that fixes the issue with nxclient. I've spent several hours with taking apart rdesktop's code (commenting out some parts, compiling, testing whether it still fixes the issue with nxclient, then start over again) and finally came to the conclusion that a call to XSetInputFocus() (what a surprise
) makes the difference (it's the call in the function
xwin_process_events()
in the handler of the
EnterNotify
event).
The final step was not much easier, than the previous one: I had to use this function call in a separate program that I could run before (or after) nxclient to fix the focusing problem. Rdesktop used this call:
XSetInputFocus(g_display, g_wnd, RevertToPointerRoot, CurrentTime);
Here
g_display
specifies the connection to the X server,
g_wnd
stands for the full-screen window of rdesktop, RevertToPointerRoot is a focus-reverting policy and CurrentTime is the actual time of the X server). You can read more about
XSetInputFocus and its parameters in the
Xlib Programming Manual.
Of course this did not work for me.
I tried setting the focus to the root window (
XSetInputFocus(display, DefaultRootWindow(display), RevertToPointerRoot, CurrentTime);
), setting the focus to nxclient's window (which can be found by going through the result of
XQueryTree
executed on the root window and looking for a window with a class "nxclient") and a number of combinations.
The problem was with the revert policy: I changed RevertToPointerRoot to RevertToParent and it started to work all of a sudden.
So the proper code is:
XSetInputFocus(display, PointerRoot, RevertToParent, CurrentTime);
You can find the full source packaged into a ZIP and attached to this post.
Use of the utility is pretty obvious: start it prior to starting nxclient.
Btw. this was my first encounter with X programming and I've quickly learnt that I do not want to get more familiar with it in near future ...
Comments
Thanks.
It just saved me a minor headache setting up an NX connection.
Ta.