pile de fenêtres soeurs

/* pile.c */

/* pile de sous-fenetres */

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

GC      gc; 
Display *display; 
int     screen; 
Window  win, subwin[3], root; 
unsigned long white_pixel, black_pixel;  
int i, nbre;
char chaine[20], num;
KeySym touche;
 
 
main() { 
  if ((display = XOpenDisplay ("")) == NULL) { 
    fprintf (stderr, "Can't open Display\n"); 
    exit (1); 
  } 
  gc = DefaultGC (display, screen); 
  screen = DefaultScreen (display); 
  root = RootWindow (display, screen); 
  white_pixel = WhitePixel (display, screen); 
  black_pixel = BlackPixel (display, screen); 
  win = XCreateSimpleWindow (display, root, 200, 300, 200, 100, 1, 
	                       black_pixel, white_pixel);
  XSelectInput (display, win, KeyPressMask); 
  XStoreName (display, win, "pile");
  for (i = 0 ; i < 3 ; ++i) {
    subwin[i] = XCreateSimpleWindow (display, win, 10 + i * 20, 10 + i * 20,
				     40, 40, 1, black_pixel, white_pixel); 
    XSelectInput (display, subwin[i], ExposureMask | ButtonPressMask); 
  }
  XMapSubwindows (display, win); 
  XMapRaised (display, win); 
 
  for (;;) { 
    XEvent ev; 
    XNextEvent (display, &ev); 
    switch (ev.type) { 
    case Expose : 
      if (ev.xexpose.count == 0)
	for (i = 0 ; i < 3 ; ++i) {
	  num = (char)('0'+i) ;
	  XDrawString (display, subwin[i], gc, 30, 12, &num, 1); 
	}   
      break; 
    case ButtonPress  : 
      if (ev.xbutton.button == Button1)
	XRaiseWindow(display, ev.xbutton.window);
      else if (ev.xbutton.button == Button3)
	XLowerWindow(display, ev.xbutton.window);
      break; 
    case KeyPress :
      nbre = XLookupString(&ev, chaine, 20, &touche, 0);
      if (nbre == 1) 
	switch (chaine[0]) {
	case 'q': 
	  exit(0);
	case 'r':
	  XRestackWindows(display, subwin, 3);
	  break;
	case 'u':
	  XCirculateSubwindowsUp(display, win);
	  break;
	case 'd':
	  XCirculateSubwindowsDown(display, win);
	  break;
	}
    default : 
      break;            
    } 
  } 
}

Exécution:

Cliquez dans les sous-fenêtres : Button1 pour les passer en premier plan, Button3 pour le dernier plan ; Tapez q pour finir, r pour les réorganiser selon l'ordre 1-2-3, u pour déclencher une permutation circulaire de la pile des sous-fenêtres vers le haut, d vers le bas.

Fonctionnement de ce programme :

Les fenêtres soeurs, cad de même fenêtre mère, sont visibles à l'écran (donc se recouvrent éventuellement) selon une pile. Rappelons qu'elles ne sont visibles qu'à l'intérieur de la fenêtre mère.
L'empilage initial est déterminé par l'ordre des XCreate(Simple)Window.

L'ordre de cette pile, donc l'ordre de recouvrement, peut être modifié par certaines fonctions de la XLib ou par le W.M. (qui utilise ces mêmes fonctions) :

XMapSubwindows affiche toutes les descendantes de la fenêtre en commençant par celle au sommet de la pile. Elles ne peuvent être visibles que si la fenêtre mère le devient.
XMapRaised affiche la fenêtre en l'ayant empilée au dessus de la pile de ses parentes.
XRaiseWindow la place au sommet de sa pile.
XLowerWindow la place en bas de sa pile.
XCirculateSubwindowsUp déclenche une permutation circulaire de la pile des sous-fenêtres vers le haut de la pile.
XCirculateSubwindowsDown déclenche une permutation circulaire de la pile des sous-fenêtres vers le bas de la pile.
XRestackWindows réorganise la pile de toutes les fenêtres du tableau passé en paramètre en commençant par la première qui sera au sommet de la pile. Elles doivent être parente, et celles absentes du tableau seront empilées en dessous.

programme suivant index général fonctions de la XLib événements types dans XLib