Transient windows

Glynn Clements glynn at gclements.plus.com
Thu Oct 2 13:51:12 PDT 2008


Jérôme Guilmette wrote:

> I just hope I'm writing to the right mailing list to ask about 
> development using the X Window System, if not, please redirect me. 
> Here's my situation:
> 
> I'm currently developing a software that is taking images from a 
> selected X window in order to process the data and put it back in a 
> different window. I'm doing a XGetImage() on a backing pixmap to avoid 
> the overlapping and "out of sight" windows effects and I'm now 
> interested to follow up the windows mapped from my processed window. By 
> example, when I put the mouse over one of the window's buttons, a small 
> window is appearing or when I slide through the window's menu, menu 
> windows are mapped. Those windows are very interesting because they are 
> part of the same application and my software would be incomplete without 
> them.
> 
> I first thought that those windows were created by the "mother" on which 
> I'm doing data processing but I discovered that  many of them are only 
> mapped, like if they were previously created. After doing a XQueryTree 
> on windows mapped from the processed window menu, I saw that their 
> parent is in fact the root window itself. So there is no way I can tell 
> that this window is in fact called by my processed window.

Windows aren't created by another window, they are created by a
client.

> After yet another search, I discovered that those windows are what is 
> called "transient" windows and many windows like pop-ups or dialog boxes 
> are in fact transients. I still don't clearly understand the ideas 
> behind the transient principle, the documentation that I've found is 
> light and examples aren't many on the web or won't go too deep into the 
> matter. I don't know if you have any link to suggest me, if any, I'd be 
> glad.

The concept of a "transient" window is essentially a matter of
convention rather than having any signficant technical basis. The
concept refers to a window with the WM_TRANSIENT_FOR property set to
the XID of another window.

The exact consequences of setting this property depend upon the window
manager (WM) in use, but the window may have fewer buttons in the
title bar, and the transient window may be iconified automatically if
the window referred to by the WM_TRANSIENT_FOR property is itself
iconified.

More details on standard properties can be found in the Inter-Client
Communication Conventions Manual (ICCCM).

Windows which don't have a title bar, border etc (e.g. popup menus,
tooltips) are typically override-redirect windows. This means that the
WM doesn't "manage" them.

Whereas the transient-for property is simply a property attached to a
window, and is only effective insofar as the WM pays attention to it,
the override-redirect flag is part of the core X protocol. If a window
has this flag, any requests to map, unmap, move, resize, raise or
lower the window are acted upon directly, rather than being delegated
("redirected") to the WM.

> So I would like to know if there is a way to know from any type of 
> windows created from the processed window, that this window is in fact 
> called from the application that is mapped on the processed window. By 
> example, to know that the "File or Tools menu window" is in fact created 
> by the application running on the processed window. Knowing this, I'd be 
> able to take this newly mapped window, take the data and process them. 
> Is this related with the transient property or to another one?

You can determine the client which created a window (or pixmap,
cursor, or anything else referenced by an XID) from the XID itself. An
XID is split into a client part and a resource part, similar to the
way that IP addresses are split into network and host parts.

You can find how XIDs are allocated amongst clients using
XResQueryClients(), e.g. (link with -lXRes):

	#include <X11/X.h>
	#include <X11/Xlib.h>
	#include <X11/extensions/XRes.h>
	
	int main(void)
	{
		Display *dpy;
		int num_clients;
		XResClient *clients;
		int i;
	
		dpy = XOpenDisplay(NULL);
		if (!dpy)
			return 1;
	
		XResQueryClients(dpy, &num_clients,  &clients);
	
		for (i = 0; i < num_clients; i++)
		{
		    XResClient *c = &clients[i];
		    printf("%08x %08x\n", c->resource_base, c->resource_mask);
		}
	
		return 0;
	}

For a given client, all XIDs which refer to objects created by that
client will have "(xid & ~c->resource_mask) == c->resource_base"
evaluate to true.

A client can obtain its own resource base and mask from the "Display"
structure, e.g.:

	#include <X11/Xlibint.h>
	...
	struct _XDisplay *priv;
	...
	priv = (struct _XDisplay *) dpy;

	printf("self: %08x %08x\n", priv->resource_base, priv->resource_mask);

This will allow you to determine whether a particular XID refers to a
resource which the itself client created.

Any direct children of the root window which don't have the
override-redirect flag set will normally be owned by the WM, with the
grandchildren and their descendents owned by individual clients. 
override-redirect windows will normally be direct children of the root
window, and owned by individual clients.

-- 
Glynn Clements <glynn at gclements.plus.com>



More information about the xorg mailing list