0

Because I´m writting a "generic" application behaving completely different when facing other configurations, I´m forced to show gtk windows even if I dont yet know them at startup. There might also be the requirement that multiple windows need to be visisble (not modal dialogs but standalone windows) at the same time. But, it would be great if one can simply start one gtk event loop at startup.

Is is somehow possible to add windows to that loop after it has been started? While I found the Gtk::Application class which seems to support exactly the indented behaviour I´m restricted to use the Gtk::Main class.

Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
  • Doesn't a top level window(which is the default window type) attach itself to the main event loop when you create it? – Ivarpoiss Jun 04 '12 at 18:54
  • It just works if it was created before invoking the Main::run method which starts the event loop. Im asking whether theres a way to attach a window after the loop was started. – Sebastian Hoffmann Jun 04 '12 at 20:02
  • You can add windows after the Main::run the same way(in the event loop). There's no point starting the event loop without any windows. If you really want to do that, theres Main::iteration. Make the loop tick manually. – Ivarpoiss Jun 04 '12 at 20:51
  • Unfortunately it does not work for me. Of course I´m running the loop in a separate thread (otherwise I could not create other windows). I´m using gtkmm-2.4 – Sebastian Hoffmann Jun 04 '12 at 20:55

1 Answers1

1

There's only a single Gtk::Main object allowed. Widgets should be created in the same thread the main event loop is being run in. To work around this limitation you need to develop a way to pass your window creation commands to the gtk thread.

The simplest way is to use Glib::Dispatcher

struct WindowBuilder {
    /**/
    Glib::Dispatcher* signal_create;

    void create_window() {
        //From main thread...
        signal_create->emit();
    }
}

void create_mainWnd() {
    new Ui::MainWnd();
}

//From Gtk thread...
builder->signal_create->connect(sigc::ptr_fun(create_mainWnd));

Gtk::Main::run();

Glib::Dispatcher doesn't take any arguments with it, so next step is to figure out how to pass arguments around between threads.

For different types of windows you can just use different disptachers.

boost::asio::io_service can help you pass messages around.

while(!exit) {
    io_service.reset();
    io_service.poll();
    while(Gtk::Main::events_pending())
        Gtk::Main::iteration();
    Sleep(0);
}
Ivarpoiss
  • 1,025
  • 1
  • 10
  • 18