---
title: Events
sidebar_position: 3
---

# Events

## Selecting events with eventMask

The X server only delivers the events you ask for. You opt in per window
with an *event mask* — a bitwise OR of flags from `x11.eventMask` — either
at window creation time or later with `ChangeWindowAttributes`:

```js
const x11 = require('x11');

x11.createClient((err, display) => {
  const X = display.client;
  const wid = X.AllocID();
  X.CreateWindow(wid, display.screen[0].root, 100, 100, 400, 300);
  X.ChangeWindowAttributes(wid, {
    eventMask: x11.eventMask.PointerMotion | x11.eventMask.KeyPress,
  });
  X.MapWindow(wid);
  X.on('event', ev => {
    if (ev.type === 2) // KeyPress
      X.terminate();
    console.log(ev);
  });
});
```

Commonly used mask bits include `Exposure`, `KeyPress`, `KeyRelease`,
`ButtonPress`, `ButtonRelease`, `PointerMotion`, `EnterWindow`,
`LeaveWindow`, `StructureNotify`, `SubstructureNotify`,
`SubstructureRedirect`, `PropertyChange` and `FocusChange`.

The demo below selects a deliberately broad mask and prints every event the
server sends. Click and type inside the X screen and watch the console fill —
then narrow the mask in the editor, press Run, and see what stops arriving:

<LiveDemo demo="event-log" compact />

## Event delivery

All events arrive through a single `'event'` emitter on the client. Every
event object carries:

- `name` — the event name, e.g. `'MotionNotify'`, `'Expose'`, `'KeyPress'`
- `type` — the numeric event code (e.g. 2 = KeyPress, 6 = MotionNotify,
  12 = Expose)
- `seq` — the sequence number of the last request processed by the server
- event-specific fields (`wid`, `x`, `y`, `rootx`, `rooty`, `keycode`,
  `buttons`, …)
- `rawData` — the raw 32-byte wire packet (useful to forward with
  `SendEvent`)

Dispatch on `ev.name` for readability:

```js
X.on('event', ev => {
  switch (ev.name) {
    case 'Expose':
      redraw();
      break;
    case 'MotionNotify':
      console.log(ev.x, ev.y);
      break;
  }
});
```

Pointer events carry both window-relative (`x`, `y`) and screen-relative
(`rootx`, `rooty`) coordinates. Drag inside this one to paint with them:

<LiveDemo demo="pointer-paint" compact />

Keyboard events are lower-level than you may expect: a `KeyPress` carries a
*keycode*, which is a physical key number, not a character. Turning it into
something printable means looking up the keysym through
`GetKeyboardMapping` and applying the modifier state yourself:

<LiveDemo demo="keyboard" compact />

Every core event and its fields is documented in the
[core events reference](../reference/core-events.md).

## Redirection

Two mask bits are not notifications but *interceptions*. A client holding
`SubstructureRedirect` on a window receives `MapRequest`, `ConfigureRequest`
and `CirculateRequest` for its children **instead of those requests taking
effect** — the server asks permission rather than reporting a fact.

That is the entire mechanism a window manager is built from. There is no
privileged API and no special connection: selecting one event mask on the root
window is what makes a program a window manager, and only one client at a time
may hold it (a second gets `BadAccess`, which is how a WM discovers another is
already running).

A client's own requests are never redirected back to itself, so the demo below
opens **two** connections — one managing the screen, one for the toy
applications. Drag either window by its title bar; neither application drew
that bar, or knows it exists:

<LiveDemo demo="window-manager" compact />

Redirection is also skipped for override-redirect windows, which is how menus
and tooltips escape being framed.

## Extension events

Extension events are delivered through the same `'event'` emitter once the
extension has been initialised with `X.require()` — requiring the extension
registers its event parsers. GenericEvents (X Generic Event Extension, used
by Present and XInput 2) are framed by their length field and dispatched to
per-extension parsers registered in `X.geEventParsers`.
