Skip to content
This repository has been archived by the owner on Jun 8, 2021. It is now read-only.

GtkWindow "set-focus" Signal Parameter is Nullable #985

Closed
misson20000 opened this issue Apr 12, 2020 · 9 comments · Fixed by #986
Closed

GtkWindow "set-focus" Signal Parameter is Nullable #985

misson20000 opened this issue Apr 12, 2020 · 9 comments · Fixed by #986

Comments

@misson20000
Copy link
Contributor

It is poorly (read: not) documented, but the "set-focus" on GtkWindow signal's widget parameter can be null.

The “set-focus” signal

void
user_function (GtkWindow *window,
               GtkWidget *widget,
               gpointer   user_data)

https://developer.gnome.org/gtk3/stable/GtkWindow.html

I know this because I had it happen to me. See (ptr=0x0) in the backtrace.

(gdb) bt
#0  rust_panic () at src/libstd/panicking.rs:563
#1  0x00005555556b8f45 in std::panicking::rust_panic_with_hook () at src/libstd/panicking.rs:533
#2  0x00005555556ae7b1 in std::panicking::begin_panic (msg=...) at /rustc/76b11980ad416c3ad6143504c2277757ecacf9b5/src/libstd/panicking.rs:438
#3  0x00005555556804fd in <gtk::auto::widget::Widget as glib::translate::FromGlibPtrBorrow<*mut gtk_sys::GtkWidget>>::from_glib_borrow (ptr=0x0) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.9.3/src/object.rs:902
#4  0x000055555567c34e in glib::translate::from_glib_borrow (ptr=0x0) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.9.3/src/translate.rs:1228
#5  0x000055555559c19e in <O as gtk::auto::window::GtkWindowExt>::connect_set_focus::set_focus_trampoline (this=0x555555ac42b0, object=0x0, f=0x555555b5c2b0) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.1/src/auto/window.rs:2161
#6  0x00007ffff733d61a in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
#7  0x00007ffff731e97e in  () at /usr/lib/libgobject-2.0.so.0
#8  0x00007ffff7321ab9 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#9  0x00007ffff73236b0 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#10 0x00007ffff78d59c0 in  () at /usr/lib/libgtk-3.so.0
#11 0x00007ffff78ecfbe in gtk_widget_set_child_visible () at /usr/lib/libgtk-3.so.0
#12 0x00007ffff7a10896 in  () at /usr/lib/libgtk-3.so.0
#13 0x00007ffff733d61a in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
#14 0x00007ffff731e0e8 in  () at /usr/lib/libgobject-2.0.so.0
#15 0x00007ffff7321ab9 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#16 0x00007ffff73236b0 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#17 0x00007ffff7a1432c in gtk_notebook_set_current_page () at /usr/lib/libgtk-3.so.0
#18 0x00005555555b9292 in <O as gtk::notebook::NotebookExtManual>::set_current_page (self=0x555555b6de48, page_num=...) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.1/src/notebook.rs:254

The signature of gtk::GtkWindowExt::connect_set_focus's callback probably needs to be changed to take a Option<&Widget>. Or, (and I expect this to be the more preferable option), the code generator needs to somehow be informed that this value is nullable. Not sure how to do that myself or I'd PR it.

@misson20000
Copy link
Contributor Author

Here's a backtrace with better symbols. The null focus comes from _gtk_window_unset_focus_and_default.

#0  rust_panic () at src/libstd/panicking.rs:563
#1  0x00005555556b8f45 in std::panicking::rust_panic_with_hook () at src/libstd/panicking.rs:533
#2  0x00005555556ae7b1 in std::panicking::begin_panic (msg=...) at /rustc/76b11980ad416c3ad6143504c2277757ecacf9b5/src/libstd/panicking.rs:438
#3  0x00005555556804fd in <gtk::auto::widget::Widget as glib::translate::FromGlibPtrBorrow<*mut gtk_sys::GtkWidget>>::from_glib_borrow (ptr=0x0) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.9.3/src/object.rs:902
#4  0x000055555567c34e in glib::translate::from_glib_borrow (ptr=0x0) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/glib-0.9.3/src/translate.rs:1228
#5  0x000055555559c19e in <O as gtk::auto::window::GtkWindowExt>::connect_set_focus::set_focus_trampoline (this=0x555555abe2b0, object=0x0, f=0x555555ab5a90) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.1/src/auto/window.rs:2161
#6  0x00007ffff734b61a in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
#7  0x00007ffff732c97e in  () at /usr/lib/libgobject-2.0.so.0
#8  0x00007ffff732fab9 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#9  0x00007ffff73316b0 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#10 0x00007ffff78e7257 in _gtk_window_unset_focus_and_default (window=0x555555abe2b0, widget=0x555555a71210) at ../gtk/gtk/gtkwindow.c:9125
#11 0x00007ffff78fde8a in gtk_widget_set_child_visible (widget=0x555555a71210, is_visible=0) at ../gtk/gtk/gtkwidget.c:10815
#12 0x00007ffff7a19e93 in gtk_notebook_real_switch_page (notebook=0x555555ad82b0, child=<optimized out>, page_num=<optimized out>) at ../gtk/gtk/gtknotebook.c:6209
#13 0x00007ffff734b61a in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
#14 0x00007ffff732c0e8 in  () at /usr/lib/libgobject-2.0.so.0
#15 0x00007ffff732fab9 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#16 0x00007ffff73316b0 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#17 0x00007ffff7a15ce0 in gtk_notebook_switch_page (notebook=<optimized out>, page=<optimized out>) at ../gtk/gtk/gtknotebook.c:6264
#18 0x00007ffff7a1d7c9 in gtk_notebook_set_current_page (notebook=0x555555ad82b0, page_num=<optimized out>) at ../gtk/gtk/gtknotebook.c:6847
#19 0x00005555555b9292 in <O as gtk::notebook::NotebookExtManual>::set_current_page (self=0x555555b93ad8, page_num=...) at /home/misson20000/.cargo/registry/src/github.com-1ecc6299db9ec823/gtk-0.8.1/src/notebook.rs:254

@misson20000
Copy link
Contributor Author

And a minimal case:

extern crate gio;
extern crate gtk;

use gio::prelude::*;
use gtk::prelude::*;

use std::env::args;

fn build_ui(application: &gtk::Application) {
    let window = gtk::ApplicationWindow::new(application);

    window.set_title("null poc");
    window.set_border_width(10);
    window.set_position(gtk::WindowPosition::Center);
    window.set_default_size(350, 70);

    let button = gtk::Button::new_with_label("Click me!");
    window.add(&button);

    window.show_all();

    button.grab_focus();
    window.connect_set_focus(|_, _| println!("got set focus signal"));
    button.hide();
}

fn main() {
    let application =
        gtk::Application::new(None, Default::default())
            .expect("Initialization failed.");

    application.connect_activate(|app| {
        build_ui(app);
    });

    application.run(&args().collect::<Vec<_>>());
}

@misson20000
Copy link
Contributor Author

Seems to be an upstream issue caused by someone having botched the formatting on the signal's annotation GNOME/gtk@93bcca7. There is one colon where in every other annotation there are two.

@misson20000
Copy link
Contributor Author

Ugh, but this signal seems to have actually recently been entirely removed from mainline GTK in favor of the focus-widget property.

@misson20000
Copy link
Contributor Author

And the story continues to develop, since the focus-widget property doesn't exist in release versions of GTK yet. Looks like we're stuck between versions here. Not sure what to do about that.

@misson20000 misson20000 reopened this Apr 12, 2020
@sdroege
Copy link
Member

sdroege commented Apr 12, 2020

git master of GTK is GTK 4, GTK 3 is maintained in a branch. These bindings are for GTK 3.

So two steps are needed here: 1) report this to GTK against their GTK 3 branch, ideally as a MR, 2) fix it on our side by adding the nullable annotation via Gir.toml.

@sdroege sdroege mentioned this issue Apr 12, 2020
40 tasks
@sdroege
Copy link
Member

sdroege commented Apr 12, 2020

Probably also want to do a short check with grep if there are other such documentation/annotation mistakes in GTK.

@misson20000
Copy link
Contributor Author

Fixed upstream: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1677.
Couldn't find any other mistakes.

@misson20000
Copy link
Contributor Author

Perhaps this issue should be left open so that we don't forget to remove the workaround when the upstream fix makes its way into gir-files.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants