are we sure destroy() is never needed?
emmanueltouzery opened this issue · 9 comments
Hi,
I'm having an issue where dialog.destroy() works just fine, but dialog.close() doesn't.
I'm using relm and nested dialogs. First my dialog, which I display with run()
, then triggered from that dialog, a gtk::FileChooserDialog
, which I also trigger with run()
.
If after the run()
for the FileChooserDialog I call destroy()
on that dialog, everything works fine. No issues.
If however I call close()
then the file chooser does not close, but seems to hang. My own dialog is OK and responsive, but the file chooser dialog does repaint, but is not responsive to clicks or even window close shortcuts.
I wonder if it's my mistake for having nested dialogs with run().. or if it's the decision to make destroy()
unsafe in gtk-rs which is maybe not the right call for all the situations? I've tried turning my dialog in a gtk::Window
and then the hanging problems go away, however then my 'dialog' is displayed as a window in i3 (not floating), even if I pass GDK_WINDOW_TYPE_HINT_DIALOG.
I also tried std::mem::drop()
on the file chooser dialog, but that doesn't help, the dialog stays displayed but hung.
EDIT: as an aside, I wonder (naively for sure) whether destroy
could be made safe by changing its signature from &self
to self
-- making sure the object cannot be used afterwards.
I'm using relm and nested dialogs.
That's a bad idea. Don't use recursive main loops (i.e. dialog.run()
) but just show them and handle the response via the callback. Maybe that's the main problem?
or if it's the decision to make destroy() unsafe in gtk-rs which is maybe not the right call for all the situations?
You're free to call destroy()
if you think it's safe in your situation (that's what unsafe
blocks are for!), but in general it's unsafe to call :)
as an aside, I wonder (naively for sure) whether
destroy
could be made safe by changing its signature from&self
toself
-- making sure the object cannot be used afterwards.
That doesn't help because widgets/windows are refcounted. You could clone()
it first, then destroy the clone and have another reference that you can still use.
Generally, can you provide a minimal testcase for reproducing this problem? It might be a bug in GTK, or it might simply be because you use recursive main loops which is discouraged.
ok, i got it to work now. Sorry, I wanted some confirmation also because most of the examples in the gtk apidocs actually encourage ::run and ::destroy.. For instance https://developer.gnome.org/gtk3/stable/GtkMessageDialog.html#refsect1
Generally speaking I had several issues:
- the mistaken impression that I should either use a dialog with run() or a window with show_all (reality: it's OK to use dialog with show_all)
- it worked with destroy and the gtk apidocs mention destroy
- on top of that, the relm widget being dropped in my code, which made it stop triggering events when the "run" wouldn't block the execution, therefore making sure the relm widget wasn't dropped was pushing me towards the run() model (because it stopped working when i moved to show_all..)
Thank you for the hints, that helped!
Maybe we should add documentation about this behaviour in the Dialog documentation page? What do think @sdroege ?
Which part exactly? But sure, I just never succeed to add things to the docs in the bindings :)
It's been greatly improved. :p
But what do you want to document? run()
should also be discouraged in the C docs and probably every GTK developer would tell you that nowadays
yes, somehow it seems it's the upstream gtk docs that should be improved, because i don't see anywhere run()
being discouraged in the upstream gtk apidocs
Hum, actually maybe upstream is better... I was sure it was already marked as deprecated there...