Sélection/masque et propagation des événements

 

Sélection des événements

C'est à votre application de définir fenêtre par fenêtre quels événements elle veut pouvoir traiter.

Il s'agit en fait d'un attribut de fenêtre:event_mask que l'on peut modifier. Il est à noter que par défaut, l'attribut event_mask d'une fenêtre est positionné à NoEventMask donc que la fenêtre ne reçoit aucun événement.

Pour le modifier, vous utiliserez la fonction XSelectInput ()

int XSelectInput(Display *display, Window w, long event_mask);

En entrée:

display comme d'habitude, il s'agit du display...soit la connexion à un serveur X
w est l'identifiant de la fenêtre pour laquelle l'on veut recevoir les événements dont la liste va suivre
event_mask la liste des événements que l'on veut recevoir

En sortie:

une valeur indiquant éventuellement qu'il y a un problème de fenêtre inexistante.

event_mask contient la liste des événements à traiter. En fait, il s'agit de masques binaires que l'on concatène en utilisant | pour faire un ou logique. Méthode que l'on retrouve souvant:suivant le type d'événement, celui-ci se retrouve avec une valeur de masque qui indique une position binaire. A cette position, 0 indique non sélectionné, 1 indique sélectionné. L'utilisation des Mask permet donc de positionner à 1 la position binaire correspondant à l'événement.

Par exemple, pour traiter les événements clic de la souris, le type d'événement est ButtonPress, le masque est ButtonPressMask

Image non trouvée !J'en profite tout de suite pour signaler un risque d'erreur: Ne pas confondre le type d'événement et le masque correspondant au type d'événement:

Il faudra bien utiliser ButtonPressMask dans XSelectInput() et surtout pas ButtonPress. Cela ne provoquera pas d'erreur à la compilation d'utiliser ButtonPress, mais les résultats seront surprenant ! Une valeur est en effet associée à ButtonPress, cette valeur pouvant représenter plusieurs positions binaires et donc plusieurs types d'événements (et pas forcement celle que l'on veut !!!)...

 

Pour connaître le déplacement du pointeur de la souris, on utilisera PointerMotionMask.

Pour recevoir l'ensemble des événements, il faudra coder : XSelectInput (diplay, w, ButtonPressMask | PointerMotionMask);

 

Image non trouvée !Il est aussi possible de modifier l'attribut event_mask d'une fenêtre via XCreateWindow() ou XChangeWindowAttributes(). Je reviendrai dessus plus tard.

 

Propagation des événements

Le principe de propagation des événements est le suivant:

Le serveur X détermine qui doit être destinataire d'un évènement (par exemple un clic de souris). Cependant, lorsqu'une fenêtre ne traite pas ce type d'événement, le serveur X va remonter dans l'arborescence des fenêtres afin de voir si la fenêtre mère peut traiter ou non ce type d'événement. L'événement remonte ainsi jusqu'à ce qu'une fenêtre mêre soit en mesure de traiter l'événement, c'est la propagation.

Lorsque la fenêtre mère est trouvée, le serveur X met dans la file des événements le type d'événement, en précisant la fenêtre cible initiale grâce au champ subwindow de l'événement.

Vous pouvez avoir un exemple de code utilisant le champ subwindow afin de déterminer si l'événement concerne la fenêtre principale ou sa fille (il s'agit en fait de l'exemple final):

Bon, c'est un peu tôt, car nous n'avons pas encore vu la phase de lecture de la file d'événements...mais pour les intrépides.

 

Eviter la propagation des événements

Il est possible de bloquer la propagation d'un événement en modifiant l'attribut de la fenêtre do_not_propagate_mask via XCreateWindow() ou en utilisant XChangeWindowAttributes(). Je reviendrai dessus plus tard.

Ainsi si une fenêtre fille ne traite pas un événement, et bloque la propagation, la fenêtre mère ne traitera pas cet événement, même si elle accepte de traiter celui-ci.

 

Remplacer la liste des événements d'une fenêtre

Il est possible de remplacer la liste des événements traités par une fenêtre durant son existance, càd supprimer ou déclarer les événements que l'on veut traiter.

Nous utiliserons pour cela la fonction XChangeWindowAttributes

XChangeWindowAttributes (Display *display, Window w, CWEventMask, XSetWindowAttributes *xattrib);

En entréee:

display et w, vous devez connaître maintenant...

CWEventMask Pour indiquer que l'on veut changer les attributs "événement" de la fenêtre

xattrib avec xattrib.event_mask renseigné avec la liste des événements que l'on veut traiter dans la fenêtre (séparé par un |). Exemple: xattrib.event_mask= ButtonPressMask | PointerMotionMask;