gtk-rs / gtk

DEPRECATED, use https://github.com/gtk-rs/gtk3-rs repository instead!

Home Page:https://gtk-rs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 :)

PR open. Would you mind taking the upstream side?