Public bug reported:
GTK4 apps on Xorg segfault in gdk_x11_device_xi2_store_axes when the
touchscreen is touched after any input device was disabled or unplugged
(Ubuntu x11-touch patch dereferences a NULL logical touch device)
Ghostty (a GTK4 terminal, installed from the mkasberg/ghostty-ubuntu PPA)
segfaulted inside
libgtk-4-1 while I touched the laptop's touchscreen. The crash is entirely
inside GDK's X11
backend and, specifically, inside code added by Ubuntu's
debian/patches/x11-touch/xi2-Expose-a-logical-touch-device.patch. Ghostty's own
code is not
involved (its only frame is the GLib main loop), so I am filing against gtk4.
Every GTK4
application running on Xorg on a machine with a touchscreen is affected.
Environment:
- Ubuntu 26.04.1 LTS (resolute), kernel 7.0.0-30-generic
- libgtk-4-1 4.22.4+ds-0ubuntu0.1 (the x11-touch patches were introduced in
4.22.1+ds-1)
- xserver-xorg-core 2:21.1.22-1ubuntu1, xserver-xorg-input-libinput
1.5.0-1build1, libinput10 1.31.1-1ubuntu1.1
- XFCE 4.20 session on Xorg (XDG_SESSION_TYPE=x11)
- Dell laptop with a built-in touchscreen: X device "SAPS2101:00 1FD2:B010",
XITouchClass mode direct, 10 touch points; GDK classifies it as
GDK_SOURCE_TOUCHSCREEN
- Crashing application: ghostty 1.3.1~ppa2-resolute1 (any GTK4 app will do;
baobab reproduces it)
What happened:
1. Ghostty started at 18:40 with the touchscreen attached to the Virtual core
pointer. At
startup the patch creates a "logical touch device" named "Virtual core
pointer touch" for
the seat (its name string is still present in the core dump).
2. At 19:08 a USB graphics tablet was plugged in and at 19:22 unplugged (kernel
log). The
unplug produced XIDeviceDisabled hierarchy events; the patch's
remove_device() calls
remove_logical_touch_device(), which unconditionally drops the seat's
logical touch device
whatever device was removed. It is only re-created by
ensure_logical_touch_device() when a
touchscreen is added or attached, which never happened again.
3. Next morning at 09:45:33 a finger touched the screen over a Ghostty window.
The X server
delivered a pointer-emulated XI_Motion (flags = XIPointerEmulated, deviceid
= 2 "Virtual core
pointer", sourceid = 12, the touchscreen). The patched XI_Motion case
replaced `device` with
the seat's logical touch device, which is NULL, and passed it to
translate_axes().
gdk_device_get_n_axes(NULL) logged
"Gdk: gdk_device_get_n_axes: assertion 'GDK_IS_DEVICE (device)' failed" and
returned 0,
then gdk_x11_device_xi2_store_axes(NULL, ...) did g_free(device->last_axes)
and died with
SIGSEGV at address 0x88.
Backtrace (full version with the decoded XI event, seat state and device table
in the
attachment; line numbers are from the Ubuntu source tree, upstream 4.22.4 plus
debian/patches):
```
#0 gdk_x11_device_xi2_store_axes (device=0x0, axes=0x5d369828ba10, n_axes=0)
at ../../../gdk/x11/gdkdevice-xi2.c:824
#1 translate_axes (device=device@entry=0x0, x=865.602783203125,
y=71.981201171875, valuators=valuators@entry=0x5d369949a060,
surface=0x5d3699557130) at ../../../gdk/x11/gdkdevicemanager-xi2.c:1291
#2 0x00007e1970d28714 in gdk_x11_device_manager_xi2_translate_event
(translator=<optimized out>, display=0x5d36939a9180, xevent=<optimized out>) at
../../../gdk/x11/gdkdevicemanager-xi2.c:1890
#3 0x00007e1970d47efe in gdk_event_source_translate_event
(x11_display=0x5d36939a9180, xevent=0x7fffe58e7f30) at
../../../gdk/x11/gdkeventsource.c:277
#4 gdk_event_source_xevent (x11_display=0x5d36939a9180, xevent=0x7fffe58e7f30)
at ../../../gdk/x11/gdkeventsource.c:329
#5 0x00007e19708f522a in _gtk_marshal_BOOLEAN__STRING (...) at
gtk/gtkmarshalers.c:1607
...
#10 0x00007e1970d49b65 in _gdk_x11_display_queue_events
(display=0x5d36939a9180) at ../../../gdk/x11/gdkeventsource.c:409
#11 0x00007e1970cfbd13 in gdk_display_get_event (display=0x5d36939a9180) at
../../../gdk/gdkdisplay.c:535
#15 0x00007e19714073c3 in g_main_context_iteration () from
/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
```
Frame 2 locals in the core: device = 0x0, source_device = the touchscreen
(name "SAPS2101:00 1FD2:B010", source GDK_SOURCE_TOUCHSCREEN), ev->evtype = 6
(XI_Motion),
ev->flags = 0x10000 (XIPointerEmulated). The seat, cast to GdkX11SeatXI2, has
logical_touch = 0x0. The device manager's device list still contains ids 2 to
24, including the
touchscreen, so the id_table lookups themselves succeeded; only the substituted
logical touch
device is missing.
Kernel log line:
```
ghostty[10637]: segfault at 88 ip 00007e1970d258b0 sp 00007fffe58e76b0 error 4
in libgtk-4.so.1.2200.4[5258b0,7e19708d4000+571000]
```
Analysis of debian/patches/x11-touch/xi2-Expose-a-logical-touch-
device.patch:
The XI_Motion case substitutes the logical touch device without checking for
NULL
(patched file, lines 1880 to 1890):
```c
#ifdef XINPUT_2_2
if (xev->flags & XIPointerEmulated &&
gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
{
/* Touch drag&drop */
GdkSeat *seat = gdk_device_get_seat (device);
device = gdk_x11_seat_xi2_get_logical_touch (GDK_X11_SEAT_XI2
(seat));
}
#endif
axes = translate_axes (device, ...
```
The XI_TouchBegin/XI_TouchEnd and XI_TouchUpdate cases and get_event_surface()
do the same
substitution, also without a NULL check, so a touch crashes through whichever
event arrives
first.
The logical touch device is dropped on any device removal, not only when a
touchscreen goes
away:
```c
static void
remove_logical_touch_device (GdkX11DeviceManagerXI2 *device_manager,
GdkDevice *associated)
{
GdkSeat *seat;
GdkDevice *logical_touch;
seat = gdk_device_get_seat (associated);
if (!seat)
return;
logical_touch = gdk_x11_seat_xi2_get_logical_touch (GDK_X11_SEAT_XI2 (seat));
device_manager->devices = g_list_remove (device_manager->devices,
logical_touch);
gdk_x11_seat_xi2_set_logical_touch (GDK_X11_SEAT_XI2 (seat), NULL);
}
```
called unconditionally from remove_device():
```c
if (device)
{
remove_logical_touch_device (device_manager, device);
detach_from_seat (device);
```
while ensure_logical_touch_device() returns early for anything that is
not a touchscreen:
```c
if (gdk_device_get_source (physical) != GDK_SOURCE_TOUCHSCREEN)
return;
```
So the sequence "app running with a touchscreen, then any input device (mouse,
keyboard,
tablet, dock) is disabled or unplugged, then the touchscreen is touched over
the app's window"
crashes every GTK4 app on Xorg.
Suggested fix:
1. In remove_logical_touch_device(), only drop the logical touch device when
the removed
device is a touchscreen, and preferably only when no other touchscreen
remains attached to
that seat.
2. At the four substitution sites, keep the logical pointer device when
gdk_x11_seat_xi2_get_logical_touch() returns NULL (or call
ensure_logical_touch_device()
lazily) instead of passing NULL on.
**Steps to reproduce (Xorg session, touchscreen enabled and attached to
the core pointer):**
1. Start a GTK4 app, for example `baobab`, and place its window on the
touchscreen.
2. Tap inside the window with a finger: no crash (control).
3. Disable or unplug any other input device, for example
`xinput disable "PS/2 Generic Mouse"` or unplug the USB mouse.
4. Tap inside the window again: the app segfaults in
gdk_x11_device_xi2_store_axes and
the journal shows "gdk_device_get_n_axes: assertion 'GDK_IS_DEVICE (device)'
failed".
5. `xinput disable <touchscreen>` followed by `xinput enable <touchscreen>`
re-creates the
logical touch device in running apps and makes touches safe again.
Workaround: disable the touchscreen (`xinput disable "SAPS2101:00 1FD2:B010"`,
or untick
"Enable this device" for it in XFCE's Mouse and Touchpad settings).
Impact: in a GTK4 terminal like Ghostty, which runs all windows in one
single-instance
process, the crash also kills every shell and every program running in those
shells.
ProblemType: Bug
DistroRelease: Ubuntu 26.04
Package: libgtk-4-1 4.22.4+ds-0ubuntu0.1
ProcVersionSignature: Ubuntu 7.0.0-30.30-generic 7.0.12
Uname: Linux 7.0.0-30-generic x86_64
ApportVersion: 2.34.1-0ubuntu0.1
Architecture: amd64
CasperMD5CheckResult: pass
CurrentDesktop: XFCE
Date: Thu Sep 3 11:09:26 2026
InstallationDate: Installed on 2026-06-08 (87 days ago)
InstallationMedia: Xubuntu 26.04 "Resolute Raccoon" - Release amd64 (20260423.1)
SourcePackage: gtk4
UpgradeStatus: No upgrade log present (probably fresh install)
** Affects: gtk4 (Ubuntu)
Importance: Undecided
Status: New
** Tags: amd64 apport-bug resolute
** Attachment added: "ghostty-gtk4-crash-backtrace.txt"
https://bugs.launchpad.net/bugs/2166322/+attachment/5997206/+files/ghostty-gtk4-crash-backtrace.txt
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2166322
Title:
GTK4 apps on Xorg crash on touchscreen touch after any input device is
unplugged
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gtk4/+bug/2166322/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs