Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

X11 - How to raise another application's window using Python

Tags:

python

x11

I'd like to be able to raise another application's Window using Python.

I did see this, which I suppose I could try:

X11: raise an existing window via command line?

However, I'd prefer to do it in Python if at all possible.

like image 758
Dave Avatar asked Apr 20 '10 15:04

Dave


1 Answers

To activate another window, the right thing to do on the Xlib protocol layer is to send a _NET_ACTIVE_WINDOW message as described in the EWMH spec http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html

This could be done with python-xlib (presumably) or with gdk_window_focus() on a foreign GdkWindow using GDK through pygtk

_NET_ACTIVE_WINDOW is superior to XRaiseWindow() and has been in all the important WMs for many many years.

You should avoid XSetInputFocus() which will cause problems (especially if you get the timestamp wrong). The issue is that the WM can't intercept the SetInputFocus() so it causes weird race conditions and UI inconsistencies.

Really only _NET_ACTIVE_WINDOW works properly, which is why it was invented, because the previous hacks were bad.

There is a library called libwnck that will let you activate windows (among other things) but unfortunately it adds quite a lot of overhead because it always tracks all open windows from any app, even if you don't need to do that. However if you want to track windows from other apps anyway, then libwnck has a function to activate those windows that does the right thing and would be a good choice.

The strictly correct approach is to check for EWMH _NET_ACTIVE_WINDOW support (EWMH documents how to do this) and fall back to XRaiseWindow if the WM doesn't have _NET_ACTIVE_WINDOW. However, since any WM that's been actively worked on in the last many years has EWMH, lots of people are lazy about the fallback for legacy WMs.

like image 64
Havoc P Avatar answered Oct 21 '22 12:10

Havoc P