Crash when touching entry icon
nt8r opened this issue · comments
To reproduce: construct a GtkEntry with icons and connect to the icon-pressed signal. Run the program on a device with a touchscreen (or emulate one) and touch the icon. The following panic results:
Thread 1 "vgmms" hit Breakpoint 1, 0x0000aaaaaaca3b38 in rust_panic ()
(gdb) bt
[...]
#5 0x0000aaaaaaaf8850 in core::result::Result<T,E>::unwrap (self=...) at /build/rust/src/rustc-1.46.0-src/src/libcore/result.rs:1005
#6 <gdk::event_button::EventButton as glib::translate::FromGlibPtrBorrow<*mut gdk_sys::GdkEventButton>>::from_glib_borrow (ptr=0xaaaaab571810) at /var/cache/cargo/registry/src/github.com-1ecc6299db9ec823/gdk-0.13.2/src/event.rs:419
#7 glib::translate::from_glib_borrow (ptr=0xaaaaab571810) at /var/cache/cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.10.1/src/translate.rs:1321
#8 <O as gtk::auto::entry::EntryExt>::connect_icon_press::icon_press_trampoline (this=<optimized out>, icon_pos=<optimized out>, event=0xaaaaab571810, f=0xaaaaab663700) at /var/cache/cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.9.2/src/auto/entry.rs:3613
#9 0x0000fffff6f9a304 in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
[...]
#26 0x0000fffff6e8dbb4 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#27 0x0000fffff7108dcc in g_application_run () at /usr/lib/libgio-2.0.so.0
#28 0x0000aaaaaab0af24 in <O as gio::application::ApplicationExtManual>::run (self=0xffffffffee68, argv=...) at /var/cache/cargo/registry/src/github.com-1ecc6299db9ec823/gio-0.9.1/src/application.rs:115
#29 vgmms::main () at src/main.rs:396
(gdb) frame 6
#6 <gdk::event_button::EventButton as glib::translate::FromGlibPtrBorrow<*mut gdk_sys::GdkEventButton>>::from_glib_borrow (ptr=0xaaaaab571810) at /var/cache/cargo/registry/src/github.com-1ecc6299db9ec823/gdk-0.13.2/src/event.rs:419
419 <$name as ::event::FromEvent>::from(
(gdb) print ptr
$1 = (*mut gdk_sys::GdkEventButton) 0xaaaaab571810
(gdb) print *ptr
$2 = gdk_sys::GdkEventButton {type_: 37, window: 0xaaaaab6fc370, send_event: 0, time: 53803346, x: 12.5, y: 2.5, axes: 0x0, state: 0, button: 0, device: 0x1, x_root: 4.9406564584124654e-324, y_root: 9.2711413070066954e-310}
Note that 37 corresponds to a GdkEventTouch
(per lib.rs
in gdk_sys
):
pub const GDK_TOUCH_BEGIN: GdkEventType = 37;
The relevant code in the gtk
crate is the following, in entry.rs
:
fn connect_icon_press<F: Fn(&Self, EntryIconPosition, &gdk::EventButton) + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe extern "C" fn icon_press_trampoline<
P,
F: Fn(&P, EntryIconPosition, &gdk::EventButton) + 'static,
>(
this: *mut gtk_sys::GtkEntry,
icon_pos: gtk_sys::GtkEntryIconPosition,
event: *mut gdk_sys::GdkEventButton,
f: glib_sys::gpointer,
) where
P: IsA<Entry>,
{
let f: &F = &*(f as *const F);
f(
&Entry::from_glib_borrow(this).unsafe_cast_ref(),
from_glib(icon_pos),
&from_glib_borrow(event),
)
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
b"icon-press\0".as_ptr() as *const _,
Some(transmute::<_, unsafe extern "C" fn()>(
icon_press_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
The event here is not known to be a GdkEventButton
, so the unwrap in from_glib_borrow
fails.
The same problem is present in connect_icon_release
.
Indeed, should be a generic event. Do you want to provide a PR for this?
The bug seems to be in the gir; I would think something like the following would work:
diff --git a/Gtk-3.0.gir b/Gtk-3.0.gir
index 4b49bd9..64ea747 100644
--- a/Gtk-3.0.gir
+++ b/Gtk-3.0.gir
@@ -34794,8 +34794,8 @@ is clicked.</doc>
<type name="EntryIconPosition"/>
</parameter>
<parameter name="event" transfer-ownership="none">
- <doc xml:space="preserve">the button press event</doc>
- <type name="Gdk.EventButton"/>
+ <doc xml:space="preserve">the button press or touch event</doc>
+ <type name="Gdk.Event"/>
</parameter>
</parameters>
</glib:signal>
@@ -34811,8 +34811,8 @@ mouse click over an activatable icon.</doc>
<type name="EntryIconPosition"/>
</parameter>
<parameter name="event" transfer-ownership="none">
- <doc xml:space="preserve">the button release event</doc>
- <type name="Gdk.EventButton"/>
+ <doc xml:space="preserve">the button or touch release event</doc>
+ <type name="Gdk.Event"/>
</parameter>
</parameters>
</glib:signal>
Should I pr to gtk-rs/gir-files
, or is there a different workflow? If it'd be easier, feel free to apply the fix yourself. Thanks!
You'd fix it in fix.sh
, and also in GTK (the C library) by fixing the annotation in the function's documentation. Let me know if you want to do one of those, or both. I'll take care of the remaining parts :)
Does this look sane for a gir-files patch?
diff --git a/fix.sh b/fix.sh
index 17da8a0..b27ada3 100755
--- a/fix.sh
+++ b/fix.sh
@@ -12,6 +12,12 @@ xmlstarlet ed -P -L \
-u '//*[@glib:error-domain="g-option-context-error-quark"]/@glib:error-domain' -v g-option-error-quark \
GLib-2.0.gir
+# incorrectly assumes GdkEventButton when other variants may be passed
+xmlstarlet ed -P -L \
+ -u '//glib:signal[@name="icon-press"]//_:parameter[@name="event"]/_:type[@name="Gdk.EventButton"]/@name' -v "Gdk.Event" \
+ -u '//glib:signal[@name="icon-release"]//_:parameter[@name="event"]/_:type[@name="Gdk.EventButton"]/@name' -v "Gdk.Event" \
+ Gtk-3.0.gir
+
# GtkIconSize usage
xmlstarlet ed -P -L \
-u '//_:type[@c:type="GtkIconSize"]/@name' -v "IconSize" \
Yeah, assuming it does the same as your change above :)
See #1053