[Glade-users] glade and/or gtkmm, insert a FileChooserDialog inside a Notebook tab



Hi,
 
However, since the introduction of GIO and D-Bus, it is (strictly 
speaking) unsafe to use that paradigm, I don't have all the details
on this fresh on my mind, I'm sure that Ryan Lortie could explain
this in better detail. But essentially you are running a nested
mainloop in the same global GMainContext, asynchronous responses
to any D-Bus calls, possibly not triggered even by your own code,
will also be processed while the dialog is 'running', which makes
things typically hard to track.

I imagine that an application using gtk has at least one thread per
widget, certainly more than one. I'm a little aware about problems
related to asynchronous programming. It's also for that reason I'm not
very excited by the idea to use a thread to set my issue...


An example of how using gtk_dialog_run() was broken even before GIO
was introduced, is that typically people handle the application "quit"
menu by calling gtk_main_quit().

What do you suppose happens when gtk_main_quit() is triggered, while
an active dialog is running ? perhaps triggered by an exported menu
in the window manager's menubar ? That's right... the application
does not quit but the dialog exits :)

I think in gtkmm things work a little differently. There is a
"so-called" smart pointer (Glib::RefPtr), and if I understand correctly
(I can't speak under oath) if the smart pointer is destroyed everything
related to it will be destroyed as well. So if you attach all your
widgets to one same smart pointer then everything will be destroyed.
The smart pointer is automatically destroyed at the end of the
application.


The safe approach to run a modal dialog is:

  o dialog = some_dialog_new ();

    Create a dialog.

  o gtk_window_set_modal(dialog, true);

    Make sure the dialog is the only one to receive events

  o g_signal_connect (dialog, "response",
                      G_CALLBACK (response_callback),
                      user_data);

  o gtk_widget_show (dialog);


  o void
    response_callback (GtkWidget *dialog, 
                       gint response_id,
                       gpointer userdata)
    {
       /* Do something with the response */
    }

That said, I do recognize the evil temptation to "run" a Tialog, and I
do maintain code in which the evil "run" paradigm still neers to be
factored out.

Actualy your safe approach looks more the way I use in most of my
programs.

I'm using one mainloop where there is severals listeners each of them
listens one thing, mouse I/O, keyboard I/O, interface user I/O, etc.
and during each cycle of the mainloop each listener is updated.

So using a function like `run()` is not something I'm happy to do. BUT
all gtk examples I saw (so far) are using a `run()` method somewhere.

One thing you might consider, to ensure exclusivity of the file
chooser, is to not put it in a notebook tab but instead use a
GtkStack (then you might also have a nice animation bringing down the
filechooser over everything else).

So your window structure would be sort of like this:

window {

  stack {

    notebook {

      ... application pages ...
    },

    filechooserwidget
  }
}

Of course you still dont get the gtk_dialog_run() behavior, but it
solves the problem of having to show/hide notebook pages nicely... of
course if you have application programsmenu items, you would still
have to make those insensitive for the duration of the filechooser.

this is definitely interesting, I haven't seen the stack contenair in
glade, so I tested it trough my code directly, and I will use it for
some other parts of my application for sure. For the file chooser I'm
still not very sure about what I shall do.

I'm curious about something, when you are using a file chooser dialog,
I guess you are not using `run()`, but somewhere in your program you
must wait that user has decided where he want to save his file. How do
you make your program waiting ?

/nicoo




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]