9
votes

I want to draw some primitives on top of all windows on the screen. I've found some code in C and tried to port it to use python's xlib:

from Xlib.display import Display
from Xlib import X
from Xlib import protocol

display = Display(':0')
root = display.screen().root
gc = root.create_gc()
root.fill_rectangle(gc, 100, 100, 500, 500)

But nothing appears on the screen (however, the root window is assigned: grabbing keyboard after it works). How to do this correctly?

1
Unless you are writing a window manager, writing the X root is a really poor idea. Stealing the input focus from everything else is an example of how "rude" an application that does this is. I'd look for a "modal dialog" in whatever GUI toolkit you are using.msw
@msw: I'm writing not a window manager, but another low-level application, so it's really necessary to draw on top of all the windows.aplavin

1 Answers

6
votes

You can draw on root window - your code probably works, but root window may be obscured by some kind of desktop window (nautilus, kde desktop etc). Try to start X session without any programs running and you'll see updates (you can use Xephyr or Xnest for this)

Another approach would be to create transparent window, make it topmost and draw on it's surface. You'll need to propagate mouse events to underlying windows manually.

To actually draw on top of all windows you need to create simple composite manager or if there is already CM running use it's overlay window.

From composite protocol spec:

Version 0.3 of the protocol adds the Composite Overlay Window, which provides compositing managers with a surface on which to draw without interference. This window is always above normal windows and is always below the screen saver window. It is an InputOutput window whose width and height are the screen dimensions. Its visual is the root visual and its border width is zero. Attempts to redirect it using the composite extension are ignored. This window does not appear in the reply of the QueryTree request. It is also an override redirect window. These last two features make it invisible to window managers and other X11 clients. The only way to access the XID of this window is via the CompositeGetOverlayWindow request. Initially, the Composite Overlay Window is unmapped.

CompositeGetOverlayWindow returns the XID of the Composite Overlay Window. If the window has not yet been mapped, it is mapped by this request. When all clients who have called this request have terminated their X11 connections the window is unmapped.

Composite managers may render directly to the Composite Overlay Window, or they may reparent other windows to be children of this window and render to these. Multiple clients may render to the Composite Overlay Window, create child windows of it, reshape it, and redefine its input region, but the specific arbitration rules followed by these clients is not defined by this specification; these policies should be defined by the clients themselves.