GNOME Pinch-to-Zoom in GNOME Web and Evince

This article examines how the GNOME desktop environment handles multi-touch pinch-to-zoom gestures within GNOME Web (Epiphany) and the Evince document viewer. It details the complete input and rendering pipeline, tracing touch interactions from the Linux kernel and libinput through the Mutter Wayland compositor down to application-level GTK gesture controllers and specialized rendering engines.

The Input Pipeline: libinput and Wayland

Multi-touch gestures begin at the hardware level with a touch-sensitive surface, such as a precision touchpad or a touchscreen. The Linux kernel processes raw electrical signals and exposes them through the evdev interface. The libinput library analyzes these events, identifies multi-finger contact geometries, and classifies patterns such as two-finger pinch motions.

Once classified, libinput dispatches gesture events (LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, UPDATE, and END) to GNOME’s display server and window manager, Mutter. Under a modern Wayland session, Mutter forwards these gestures directly to the focused application using the pointer-gestures-unstable-v1 protocol extension. This protocol enables true continuous 1:1 direct manipulation, distinct from legacy X11 environments that typically translate multi-touch gestures into stepped, discrete Ctrl + Mouse Wheel scroll increments.

Pinch-to-Zoom in GNOME Web (Epiphany)

GNOME Web relies on the WebKitGTK engine to display web pages. Handling pinch-to-zoom in this environment requires balancing immediate responsiveness with the computational cost of document reflow:

  1. Gesture Capture: WebKitGTK creates GTK gesture controllers (GtkGestureZoom) bound to its main display widget. These controllers track the focal point (anchor) between fingers and compute continuous scale deltas.
  2. Compositor-Driven Scaling: To maintain 60 or 120 frames per second, WebKitGTK decouples visual scaling from page layout. When a pinch begins, the engine applies an affine scale transformation directly to the root compositing layer using the GPU. This provides instant visual feedback that moves directly with the user's fingers without waiting for DOM recalculations.
  3. Re-rasterization: Web content scaled purely by affine transforms will eventually appear blurry or pixelated if enlarged significantly. Once the gesture concludes—or dynamically during pauses in the gesture—WebKitGTK updates the viewport's device scale factor. The engine then re-rasterizes text glyphs, vector paths, and media at the new target resolution to restore crisp image quality.

Pinch-to-Zoom in Evince

Evince manages document rendering (such as PDFs, PostScript, and TIFFs) through a document view widget called EvView, which interacts directly with rendering backends like Poppler.

  1. Event Interception: EvView attaches a GtkGestureZoom controller to the document canvas. When a user executes a pinch gesture, the controller captures the anchor coordinate relative to the document page and calculates the incremental scale factor.
  2. Buffer Transformation: PDF rendering through Poppler is CPU-bound and vector-heavy, making full real-time re-rendering during active motion impractical. To achieve smooth manipulation, Evince intercepts the scale-changed signals from the gesture controller and applies a temporary 2D matrix transformation to the already-rendered Cairo surface backing the visible page. The page expands or contracts smoothly in real time relative to the focal point between the touch points.
  3. Tile Re-rendering: When the user lifts their fingers, the GtkGestureZoom controller fires an end signal. Evince locks in the new zoom percentage, recalculates the target dimensions, and invalidates the cached Cairo surface. A background job requests newly rasterized page tiles from Poppler at the target resolution, replacing the scaled buffer with sharp, native-resolution vector output.