apprt/gtk: handle nullable event from event controller

gtk_event_controller_get_current_event() is documented to possibly
return NULL.

Fixes: https://github.com/ghostty-org/ghostty/issues/2022
Fixes: https://github.com/ghostty-org/ghostty/issues/3088
Link: https://docs.gtk.org/gtk4/method.EventController.get_current_event.html
Signed-off-by: Tristan Partin <tristan@partin.io>
This commit is contained in:
Tristan Partin
2024-12-25 23:00:20 -06:00
parent 7027147c76
commit a38acbc11c
2 changed files with 12 additions and 13 deletions

View File

@ -386,7 +386,8 @@ fn keyEvent(
// Try to process the event as text // Try to process the event as text
const event = c.gtk_event_controller_get_current_event(@ptrCast(ec_key)); const event = c.gtk_event_controller_get_current_event(@ptrCast(ec_key));
_ = c.gtk_im_context_filter_keypress(self.im_context, event); if (event != null)
_ = c.gtk_im_context_filter_keypress(self.im_context, event);
return true; return true;
} }

View File

@ -1341,8 +1341,9 @@ fn gtkMouseDown(
y: c.gdouble, y: c.gdouble,
ud: ?*anyopaque, ud: ?*anyopaque,
) callconv(.C) void { ) callconv(.C) void {
const event = c.gtk_event_controller_get_current_event(@ptrCast(gesture)) orelse return;
const self = userdataSelf(ud.?); const self = userdataSelf(ud.?);
const event = c.gtk_event_controller_get_current_event(@ptrCast(gesture));
const gtk_mods = c.gdk_event_get_modifier_state(event); const gtk_mods = c.gdk_event_get_modifier_state(event);
const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast(gesture))); const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast(gesture)));
@ -1374,7 +1375,8 @@ fn gtkMouseUp(
_: c.gdouble, _: c.gdouble,
ud: ?*anyopaque, ud: ?*anyopaque,
) callconv(.C) void { ) callconv(.C) void {
const event = c.gtk_event_controller_get_current_event(@ptrCast(gesture)); const event = c.gtk_event_controller_get_current_event(@ptrCast(gesture)) orelse return;
const gtk_mods = c.gdk_event_get_modifier_state(event); const gtk_mods = c.gdk_event_get_modifier_state(event);
const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast(gesture))); const button = translateMouseButton(c.gtk_gesture_single_get_current_button(@ptrCast(gesture)));
@ -1393,6 +1395,8 @@ fn gtkMouseMotion(
y: c.gdouble, y: c.gdouble,
ud: ?*anyopaque, ud: ?*anyopaque,
) callconv(.C) void { ) callconv(.C) void {
const event = c.gtk_event_controller_get_current_event(@ptrCast(ec)) orelse return;
const self = userdataSelf(ud.?); const self = userdataSelf(ud.?);
const scaled = self.scaledCoordinates(x, y); const scaled = self.scaledCoordinates(x, y);
@ -1401,13 +1405,6 @@ fn gtkMouseMotion(
.y = @floatCast(scaled.y), .y = @floatCast(scaled.y),
}; };
// GTK can send spurious mouse movement events. Ignore them
// because this can cause actual issues:
// https://github.com/ghostty-org/ghostty/issues/2022
if (pos.x == self.cursor_pos.x and pos.y == self.cursor_pos.y) {
return;
}
// Our pos changed, update // Our pos changed, update
self.cursor_pos = pos; self.cursor_pos = pos;
@ -1418,7 +1415,6 @@ fn gtkMouseMotion(
} }
// Get our modifiers // Get our modifiers
const event = c.gtk_event_controller_get_current_event(@ptrCast(ec));
const gtk_mods = c.gdk_event_get_modifier_state(event); const gtk_mods = c.gdk_event_get_modifier_state(event);
const mods = gtk_key.translateMods(gtk_mods); const mods = gtk_key.translateMods(gtk_mods);
@ -1432,10 +1428,11 @@ fn gtkMouseLeave(
ec: *c.GtkEventControllerMotion, ec: *c.GtkEventControllerMotion,
ud: ?*anyopaque, ud: ?*anyopaque,
) callconv(.C) void { ) callconv(.C) void {
const event = c.gtk_event_controller_get_current_event(@ptrCast(ec)) orelse return;
const self = userdataSelf(ud.?); const self = userdataSelf(ud.?);
// Get our modifiers // Get our modifiers
const event = c.gtk_event_controller_get_current_event(@ptrCast(ec));
const gtk_mods = c.gdk_event_get_modifier_state(event); const gtk_mods = c.gdk_event_get_modifier_state(event);
const mods = gtk_key.translateMods(gtk_mods); const mods = gtk_key.translateMods(gtk_mods);
self.core_surface.cursorPosCallback(.{ .x = -1, .y = -1 }, mods) catch |err| { self.core_surface.cursorPosCallback(.{ .x = -1, .y = -1 }, mods) catch |err| {
@ -1536,11 +1533,12 @@ pub fn keyEvent(
keycode: c.guint, keycode: c.guint,
gtk_mods: c.GdkModifierType, gtk_mods: c.GdkModifierType,
) bool { ) bool {
const keyval_unicode = c.gdk_keyval_to_unicode(keyval);
const event = c.gtk_event_controller_get_current_event( const event = c.gtk_event_controller_get_current_event(
@ptrCast(ec_key), @ptrCast(ec_key),
) orelse return false; ) orelse return false;
const keyval_unicode = c.gdk_keyval_to_unicode(keyval);
// Get the unshifted unicode value of the keyval. This is used // Get the unshifted unicode value of the keyval. This is used
// by the Kitty keyboard protocol. // by the Kitty keyboard protocol.
const keyval_unicode_unshifted: u21 = gtk_key.keyvalUnicodeUnshifted( const keyval_unicode_unshifted: u21 = gtk_key.keyvalUnicodeUnshifted(