Public bug reported:
**Target:** `ubuntu/+source/gtk4` (package `libgtk-4-1`)
**File against:** `libgtk-4-1` 4.22.4+ds-0ubuntu0.1
---
## Title
gtk4 4.22.4: SIGSEGV in gdk_surface_handle_event() on a tablet-pad event
carrying no surface (GDK_PAD_GROUP_MODE) after USB re-enumeration
---
## Description
### Summary
Any running GTK4 application crashes with SIGSEGV in
`gdk_surface_handle_event()` (`gdk/gdksurface.c:2993`) when a tablet-pad
event is delivered while the client has no keyboard focus. The event is
created with a NULL surface and `GDK_SURFACE_IS_MAPPED (surface)` dereferences
it without a guard.
On this machine the crash correlates with the tablet's USB HID devices
re-enumerating, which happens on resume from suspend; four of five resumes
with Ghostty running killed it. It is not application-specific: Nautilus,
Ptyxis, gnome-system-monitor and Ghostty have all died at the same
instruction.
### How it was observed
- Ghostty 1.4.0 (GTK runtime), HUION tablet connected, suspend then resume:
SIGSEGV one second after `PM: suspend exit`, on four out of five resumes.
- Ghostty, no suspend involved: a full re-enumeration of the USB hub the
tablet is attached to killed it two seconds later (2026-11-02 08:36:41).
- Nautilus, twelve suspend/resume attempts on the same machine with the
tablet connected and Nautilus focused: no crash.
The failure is therefore timing dependent rather than a simple recipe. The
most likely condition is that the client is still processing its Wayland
socket when the pad re-registers, so GTK has not yet handled
`wl_keyboard.enter` while mutter already considers that client focused. A
faster or less loaded client processes the enter first and survives.
Locking the screen and touching the dial does **not** reproduce it. With the
lock screen up, `meta_wayland_seat_get_input_focus()` returns NULL, so mutter
assigns the pad no focus client and broadcasts nothing; the application never
receives the pad event at all.
### Steps to reproduce (best effort)
1. Connect a tablet whose pad exposes dial / touch strip / mode groups.
Tested with HUION Huion Tablet (USB ID `256c:006d`), which presents
`HUION Huion Tablet Pad`, `... Touch Strip` and `... Dial`.
2. Start a GTK4 application and leave it focused (Ghostty 1.4.0 has been the
most consistent victim here).
3. Suspend and resume, so the tablet's USB HID devices re-enumerate. Do not
touch input for a few seconds after resume.
4. The application exits with SIGSEGV and the kernel logs
`segfault at 3c ... in libgtk-4.so.1.2200.4[5a33b1,...]`.
### Expected behaviour
The application ignores a pad event it cannot associate with a surface.
### Actual behaviour
```
kernel: ghostty[84179]: segfault at 3c ip 00007845717783b1 sp ... error 4
in libgtk-4.so.1.2200.4[5a33b1,7845712a9000+571000] likely on CPU 3
```
### Backtrace
Symbolized with the `libgtk-4-1` debug info from debuginfod
(build-id `4c74ae5215a17f78b116635961e03231361bf671`):
```
#0 gdk_surface_handle_event.isra.0 (event=...) at gdk/gdksurface.c:2993
#1 _gdk_event_emit (event=...) at gdk/gdkevents.c:491
#2 gdk_event_source_dispatch (...) at gdk/gdkeventsource.c
#3 g_main_context_dispatch_unlocked
#4 g_main_context_iterate_unlocked
#5 g_main_context_iteration
#6 g_application_run
```
`gdk/gdksurface.c:2987-2994` in 4.22.4:
```c
gboolean
gdk_surface_handle_event (GdkEvent *event)
{
GdkSurface *surface = gdk_event_get_surface (event);
gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
gboolean handled = FALSE;
if (!GDK_SURFACE_IS_MAPPED (surface)) /* line 2993 */
return FALSE;
```
`GDK_SURFACE_IS_MAPPED` is `((surface)->pending_is_mapped)`
(`gdk/gdksurfaceprivate.h:172`). Disassembling the crashing instruction
confirms the mechanism:
```
5a33b1: 41 8b 4c 24 3c mov 0x3c(%r12),%ecx ; r12 == NULL
```
The fault address reported by the kernel is `0x3c`, i.e. `surface == NULL`
and `pending_is_mapped` at struct offset `0x3c`.
### Root cause
`_gdk_event_emit()` (`gdk/gdkevents.c:491`) hands every event to
`gdk_surface_handle_event()`, which assumes the event has a surface.
The Wayland backend builds tablet-pad events with `seat->keyboard_focus` as
their surface (`gdk/wayland/gdkseat-wayland.c`):
| handler | line |
|---|---|
| `tablet_pad_ring_handle_frame` | 3379 |
| `tablet_pad_strip_handle_frame` | 3456 |
| `tablet_pad_group_handle_mode_switch` | 3582 |
| `tablet_pad_dial_handle_frame` | 3619 |
| `tablet_pad_button_handle_button` | 3755 |
`seat->keyboard_focus` is NULL whenever GTK has no keyboard focus surface,
which is the case in the window between resume and the arrival of
`wl_keyboard.enter`. The pad event is then queued with `surface == NULL` and
crashes the first GTK4 client that dispatches it.
The compositor side is what makes this fire on resume. When a pad registers,
mutter assigns it the current input focus and broadcasts the pad's mode:
```c
/* src/wayland/meta-wayland-tablet-pad-group.c */
meta_wayland_tablet_pad_group_sync_focus (MetaWaylandTabletPadGroup *group)
{
...
if (!wl_list_empty (&group->focus_resource_list))
{
broadcast_group_mode (group, clutter_get_current_event_time ());
```
and `meta_wayland_tablet_seat_device_added()` picks that focus from
`meta_wayland_seat_get_input_focus (seat)` at the moment the device appears
(`src/wayland/meta-wayland-tablet-seat.c`). During resume the pad re-registers
while the seat still points at the previously focused client, but GTK has not
yet received the new keyboard enter, so `seat->keyboard_focus` is still NULL
when the `mode_switch` arrives.
Upstream GTK issue #8285 contains a gdb dump of the same event, confirming
the event type and the NULL surface:
```
(gdb) p *event
$8 = {
event_type = GDK_PAD_GROUP_MODE,
surface = 0x0,
device = 0x55e60969b4f0,
...
}
```
### Scope on this machine
Same instruction, same fault address, different applications:
```
2026-07-27 gnome-system-mo segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-09-11 ptyxis segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-09-17 ptyxis segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-09-21 nautilus segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-09-23 nautilus segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-11-01 ghostty segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-11-02 ghostty (x3) segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
2026-11-03 ghostty segfault at 3c ... libgtk-4.so.1.2200.4[5a33b1,...]
```
Four of the Ghostty crashes land one second after `PM: suspend exit`. The
remaining one (2026-11-02 08:36:41) happened during a full re-enumeration of
the USB hub the tablet is attached to, with no suspend involved, which points
at device re-enumeration rather than at power management:
```
08:36:38 usb 1-12: new high-speed USB device number 9
08:36:39 input: HUION Huion Tablet Pad as /devices/.../input/input37
08:36:39 input: HUION Huion Tablet Touch Strip as /devices/.../input/input38
08:36:39 input: HUION Huion Tablet Dial as /devices/.../input/input39
08:36:41 kernel: ghostty[67283]: segfault at 3c ...
```
### Upstream
- GNOME/gtk#8285 — "Crash during screen configuration change"
https://gitlab.gnome.org/GNOME/gtk/-/work_items/8285
- GNOME/gtk#8368 — "gdk_surface_handle_event: SIGSEGV dereferencing surface
in nautilus (GDK_SURFACE_IS_MAPPED, gdksurface.c:2993)"
https://gitlab.gnome.org/GNOME/gtk/-/work_items/8368
Both are open. The missing NULL check is still present in 4.22.4, in
4.22.5 and on the `gtk-4-22` branch, so this is not fixed by an upstream
point release at the time of filing.
No duplicate found in `ubuntu/+source/gtk4` on Launchpad.
### Proposed fix
Minimal guard, `gdk/gdksurface.c`:
```diff
GdkSurface *surface = gdk_event_get_surface (event);
gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
gboolean handled = FALSE;
+ if (surface == NULL)
+ return FALSE;
+
if (!GDK_SURFACE_IS_MAPPED (surface))
return FALSE;
```
A broader fix would be to make `_gdk_event_emit()` skip surface-bearing event
types when `gdk_event_get_surface()` returns NULL, and/or to stop using
`seat->keyboard_focus` as the surface for pad events, since pad events are
device-level and not tied to a window.
### Workaround
Unplugging the tablet before suspending prevents the crash. Setting
`GDK_BACKEND=x11` for the affected application also avoids it: the X11
backend creates no tablet-pad events at all.
### Environment
```
Ubuntu 26.04.1 LTS (resolute), amd64
libgtk-4-1 4.22.4+ds-0ubuntu0.1 (resolute-updates)
libglib2.0-0t64 2.88.0-1ubuntu0.1
libwayland-client0 1.24.0-2
gnome-shell 50.1-0ubuntu1.4
mutter 50.1
Linux 7.0.0-42-generic
GNOME on Wayland (XDG_SESSION_TYPE=wayland)
Display on AMD Granite Ridge iGPU (amdgpu); GTK uses Mesa EGL 4.6
Tablet: HUION Huion Tablet, USB 256c:006d
```
Ghostty is the classic Snap (`ghostty` v1.4.0, rev 1016), i.e. it links
against the host `libgtk-4-1`, not a bundled GTK; the crash is unrelated to
the Snap packaging.
---
## Attachments
- `journal-suspend-crash.txt` — already prepared, contains all ten crashes,
the resume window with USB re-enumeration, the non-suspend crash, the
suspend history and the tablet device list.
- No `.crash` file is attached. Ghostty is a classic Snap and Snap crashes are
not collected by apport, and the failure could not be reproduced on demand
with a packaged application (twelve suspend/resume attempts with Nautilus
produced nothing). The symbolized frame above comes from Ubuntu's
debuginfod data for build-id
`4c74ae5215a17f78b116635961e03231361bf671`.
---
## Submission notes
File with:
```
ubuntu-bug libgtk-4-1
```
or via the web form:
```
https://bugs.launchpad.net/ubuntu/+source/gtk4/+filebug
```
Paste the Title and the Description above. After filing, add bug watches
for GNOME/gtk issues #8285 and #8368 (the "Also affects project" /
"Add bug watch" links on the bug page), so the Ubuntu status tracks upstream.
Note: no `.crash` file exists for the Ghostty crashes, because Snap crashes
are not collected by apport. If a triager asks for a core dump, it can be
produced later by running a packaged GTK4 application and catching the same
race; the analysis in this report does not depend on one.
ProblemType: Bug
DistroRelease: Ubuntu 26.04
Package: libgtk-4-1 4.22.4+ds-0ubuntu0.1
ProcVersionSignature: Ubuntu 7.0.0-42.42-generic 7.0.14
Uname: Linux 7.0.0-42-generic x86_64
ApportVersion: 2.34.1-0ubuntu0.1
Architecture: amd64
CasperMD5CheckResult: unknown
CurrentDesktop: ubuntu:GNOME
Date: Tue Nov 3 06:55:14 2026
InstallationDate: Installed on 2025-02-06 (635 days ago)
InstallationMedia: Ubuntu 24.04.1 LTS "Noble Numbat" - Release amd64
(20240827.1)
ProcEnviron:
LANG=en_US.UTF-8
PATH=(custom, no user)
SHELL=/bin/bash
TERM=xterm-256color
XDG_RUNTIME_DIR=<set>
SourcePackage: gtk4
UpgradeStatus: No upgrade log present (probably fresh install)
** Affects: gtk4 (Ubuntu)
Importance: Undecided
Status: New
** Tags: amd64 apport-bug resolute wayland-session
** Attachment added: "journal-suspend-crash.txt"
https://bugs.launchpad.net/bugs/2172827/+attachment/6014645/+files/journal-suspend-crash.txt
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172827
Title:
gtk4 4.22.4: SIGSEGV in gdk_surface_handle_event() on a tablet-pad
event carrying no surface (GDK_PAD_GROUP_MODE) after USB re-
enumeration
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gtk4/+bug/2172827/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs