XAnyEvent(3)

πŸ’… NAME (aka who dis)

XAnyEvent, XEvent β€” the generic X event structures, bestie. That's it, that's the whole vibe. ✨

This page lives in the XLIB FUNCTIONS section of the manual, just so you know where you are when you're scrolling at 2am. 🫢


πŸŽ€ STRUCTURES

Okay so real talk: every single event structure declared in <X11/Xlib.h> has these same common members, like they all showed up to the group chat with the same five things in their bio:

typedef struct {
        int type;
        unsigned long serial;   /* # of last request processed by server */
        Bool send_event;        /* true if this came from a SendEvent request */
        Display *display;       /* Display the event was read from */
        Window window;
} XAnyEvent;

🌸 what each of those members is giving

  • type β€” it's set to the event type constant name that uniquely identifies it, periodt. Like, when the X server reports a GraphicsExpose event to a client application, it sends an XGraphicsExposeEvent structure with the type member set to GraphicsExpose. Very "this is me, this is my identity." πŸ’…
  • display β€” set to a pointer to the display the event was read on. Where it came from, iykyk.
  • send_event β€” set to True if the event came from a SendEvent protocol request. So like, was this organic or did somebody forward it. πŸ”
  • serial β€” set from the serial number reported in the protocol, but expanded from the 16-bit least-significant bits into a full 32-bit value. glow-up from 16 to 32 bits, iconic. ⭐
  • window β€” set to the window that is most useful to toolkit dispatchers. Not necessarily the "main character" window, just the most useful one. Respect the hustle. πŸ‘‘

πŸ¦‹ the XEvent union (the whole cast)

The XEvent structure is a union of the individual structures declared for each event type. One big friend group, every member has their moment:

typedef union _XEvent {
        int type;       /* must not be changed */
        XAnyEvent xany;
        XKeyEvent xkey;
        XButtonEvent xbutton;
        XMotionEvent xmotion;
        XCrossingEvent xcrossing;
        XFocusChangeEvent xfocus;
        XExposeEvent xexpose;
        XGraphicsExposeEvent xgraphicsexpose;
        XNoExposeEvent xnoexpose;
        XVisibilityEvent xvisibility;
        XCreateWindowEvent xcreatewindow;
        XDestroyWindowEvent xdestroywindow;
        XUnmapEvent xunmap;
        XMapEvent xmap;
        XMapRequestEvent xmaprequest;
        XReparentEvent xreparent;
        XConfigureEvent xconfigure;
        XGravityEvent xgravity;
        XResizeRequestEvent xresizerequest;
        XConfigureRequestEvent xconfigurerequest;
        XCirculateEvent xcirculate;
        XCirculateRequestEvent xcirculaterequest;
        XPropertyEvent xproperty;
        XSelectionClearEvent xselectionclear;
        XSelectionRequestEvent xselectionrequest;
        XSelectionEvent xselection;
        XColormapEvent xcolormap;
        XClientMessageEvent xclient;
        XMappingEvent xmapping;
        XErrorEvent xerror;
        XKeymapEvent xkeymap;
        long pad[24];
} XEvent;

Note the type member up there: /* must not be changed */. That's not a suggestion, bestie, that is a rule. 🚨

πŸ’œ the rules (and you will be following them)

So here's the tea about the layout, and yes this matters:

  1. The first entry of an XEvent structure always is the type member, which is set to the event type.
  2. The second member always is the serial number of the protocol request that generated the event.
  3. The third member always is send_event, which is a Bool that indicates if the event was sent by a different client.
  4. The fourth member always is a display, which is the display that the event was read from.
  5. The fifth member always is a window β€” except for keymap events, where it isn't β€” and that window has been carefully selected to be useful to toolkit dispatchers.
⚠️ Do not reorder those first five entries. To avoid breaking toolkits, the order of these first five entries is not to change. Fr fr, don't touch. Toolkits are fragile and they will spiral. 😭

Also! Most events contain a time member, which is the time at which an event occurred. Clock it. πŸ•

And one more thing β€” a pointer to the generic event must be cast before it is used to access any other information in the structure. No skipping the cast, no shortcuts, that's just how it is. 🧚


πŸ”₯ SEE ALSO

The whole extended universe, go read them all or at least bookmark them, you're gonna need them:


and that's the whole page, bestie β€” you ate that πŸ’–

Sign-off time: this one comes to you courtesy of X Version 11, from libX11 1.8.14. Take care of her, she's been around. πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from