After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 637445 - Finish Gtk::Application
Finish Gtk::Application
Status: RESOLVED FIXED
Product: gtkmm
Classification: Bindings
Component: general
2.91.x
Other Linux
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on: 643468 643470 643478 643649 643650 644113 659236
Blocks:
 
 
Reported: 2010-12-17 09:35 UTC by Yannick.Guesnet
Modified: 2012-03-27 14:57 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Remove critical warning in examples for non existant files (9.73 KB, patch)
2011-08-11 06:43 UTC, Yannick.Guesnet
none Details | Review
0001-Application-Avoid-the-need-to-use-Gtk-Main.patch (4.83 KB, patch)
2012-02-10 12:09 UTC, Murray Cumming
committed Details | Review
Patchi to allow gtkmm initialization before Gtk::Application construction. (4.19 KB, patch)
2012-02-14 23:53 UTC, José Alburquerque
committed Details | Review
Application: Constructor: Receive argc and argv params by reference. (3.57 KB, patch)
2012-02-16 22:33 UTC, José Alburquerque
committed Details | Review
Application screenshot (11.89 KB, image/png)
2012-03-25 21:19 UTC, José Alburquerque
  Details

Description Yannick.Guesnet 2010-12-17 09:35:14 UTC
Perhaps that it would be helpful to have a protected constructor Gtk::Application(const Glib::ustring& application_id, ApplicationFlags flags=APPLICATION_FLAGS_NONE) as it is done for Gio::Application.
Comment 1 Murray Cumming 2010-12-17 12:18:49 UTC
Yes, we should indeed do that. We don't need to call gtk_application_new() itself, because it only calls g_object_new(), as it should:

Fixed in this commit:
http://git.gnome.org/browse/gtkmm/commit/?id=d8ac3a7bb88b8a0d33e79fbb1154e3d9c8e8d508

Thanks. I am glad that you are playing with this API. Maybe you would even like to create a small example.
Comment 2 Yannick.Guesnet 2010-12-17 14:50:44 UTC
(In reply to comment #1)
> Yes, we should indeed do that. We don't need to call gtk_application_new()
> itself, because it only calls g_object_new(), as it should:
> 
> Fixed in this commit:
> http://git.gnome.org/browse/gtkmm/commit/?id=d8ac3a7bb88b8a0d33e79fbb1154e3d9c8e8d508
> 
> Thanks. I am glad that you are playing with this API. Maybe you would even like
> to create a small example.

Thanks for your response (and your celerity).

I will be glad to help. Indeed, I try to adapt the example I've found in the gtk+ doc : http://library.gnome.org/devel/gtk/unstable/GtkApplication.html#gtkapplication
I'm not sure that bugzilla is the right place to begin a discussion on an example, could you indicate me where to send the example (the mailing list ?)

Finally,  please note that :
- I'm not an expert in gtkmm nor even C++, you will probably need to correct my code ;
- I'm french and, as you have probably remarked,  I'm not sure that my frenglish is very clear...
Comment 3 Murray Cumming 2011-01-19 10:47:52 UTC
I have made some changes to allow Gtk::Application to be used as a complete replacement for Gtk::Main. However, there are some issues that I will probably have to work around. You might be interested

Bug #639925 (already worked around, though it's not ideal.)
Bug #639931 (Can be worked around by handling the Window's close signal ourselves.)
Comment 4 Yannick.Guesnet 2011-01-19 19:18:57 UTC
Thanks. But have you omitted to push the changes in gtkmm ? The book/base/base.cc example does not compile anymore.
Comment 5 Murray Cumming 2011-01-20 08:47:09 UTC
Sorry. Done.
Comment 6 Yannick.Guesnet 2011-01-20 15:13:40 UTC
Well, it seems to me that there is a little problem in Application::run(Window& window, *) since you consider that the signal activate will be send.
But, if I have correctly understanded the C API, if we give some parameters in argv and the flag Gio::APPLICATION_HANDLES_OPEN is set, then this is the signal open which is sent and not activate.
Thus we will remain with a hide window attached to the application.

Moreover, peharps that an Application::run() method with no argument will be helpful too.

Finally, I don't understand the init_gtkmm_internals() at the end of the run methods (if it is really needed why call the method so late).
Comment 7 Murray Cumming 2011-01-21 13:41:04 UTC
(In reply to comment #6)
> Well, it seems to me that there is a little problem in Application::run(Window&
> window, *) since you consider that the signal activate will be send.
> But, if I have correctly understanded the C API, if we give some parameters in
> argv and the flag Gio::APPLICATION_HANDLES_OPEN is set, then this is the signal
> open which is sent and not activate.

In this example, both signals are emitted:
http://library.gnome.org/devel//gtk/unstable/GtkApplication.html

But I'd appreciate if you tested your theory to be sure.

> Thus we will remain with a hide window attached to the application.
> 
> Moreover, peharps that an Application::run() method with no argument will be
> helpful too.

Agreed. I have just added one.

> Finally, I don't understand the init_gtkmm_internals() at the end of the run
> methods (if it is really needed why call the method so late).

Ah, yes, that's a problem. I'm calling it after g_application_run(), which won't even return until the very end of the program. I wonder what we can do instead, considering that we can't call init_gtkmm_internals() until gtk_init() has been called. Maybe we just need to call gtk_init() ourselves and not give the argc/argv to g_application_run(), or give it again, though that seems risky.
Comment 8 Yannick.Guesnet 2011-01-21 15:36:02 UTC
(In reply to comment #7)
>
> In this example, both signals are emitted:
> http://library.gnome.org/devel//gtk/unstable/GtkApplication.html
> 
> But I'd appreciate if you tested your theory to be sure.
> 
I have tried the example and with my version of Gtk+, if I launch the application with, for example :
# example main.cc
then I notice only the "open" signal (I have just added some g_print in the signal handlers). I can't explain the difference of behaviour of our examples...

> Ah, yes, that's a problem. I'm calling it after g_application_run(), which
> won't even return until the very end of the program. I wonder what we can do
> instead, considering that we can't call init_gtkmm_internals() until gtk_init()
> has been called. Maybe we just need to call gtk_init() ourselves and not give
> the argc/argv to g_application_run(), or give it again, though that seems
> risky.

But why init_gtkmm_internals is really needed in run ?
Normally we have already call it in the construtor of Gtk::Application (with argc, argv).
If we have call the constructor Application(const Glib::ustring& application_id, Gio::ApplicationFlags flags) then the normal way is to call Gtk::Main(argc, argv) before.
Am I clear ? Have I lost something ?
Comment 9 Murray Cumming 2011-02-22 09:27:34 UTC
> But why init_gtkmm_internals is really needed in run ?
> Normally we have already call it in the construtor of Gtk::Application (with
> argc, argv).

It's needed in run(argc, argv) because you would only be calling that if you did not provide argc/argv to the constructor. If you did then you could call run() instead.


> If we have call the constructor Application(const Glib::ustring&
> application_id, Gio::ApplicationFlags flags) then the normal way is to call
> Gtk::Main(argc, argv) before.
> Am I clear ? Have I lost something ?

Well, it's all rather unclear to me. I've asked for some clarification on the gtk-devel-list:
http://mail.gnome.org/archives/gtk-devel-list/2011-February/msg00087.html

When I know more then I can try again.
Comment 10 Murray Cumming 2011-03-02 08:34:26 UTC
I have filed several GApplication documentation bugs. I don't feel confident about freezing the Gtk::Application API before most of these are fixed: See bugs #643649, #643650, #643478, #643470, #643468.

I've also filed an extra patch in bug #640042 which removes another unnecessary warning, though it's probably not relevant to our API.

A while ago I filed this bug #637457 too, but it didn't get a response and it must be too late to fix that now.

At the moment, I'm likely to remove Gtk::Application from gtkmm 3.0 because I don't think we can make sure that the API is ideal or working while we don't know how the API should behave. If we understand it better later then we could add it to gtkmm 3.1/3.2.
Comment 11 Murray Cumming 2011-03-04 11:39:16 UTC
We are making a little progress, thanks to Matthias' response on those bugs, though I have not yet thought properly about how to avoid use of Gtk::Main.

This is our simple example in progress, which seems to work:
http://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/application
Comment 12 Yannick.Guesnet 2011-03-06 08:13:14 UTC
Yes, the example progress, thanks.

I see that it overrides now the on_command_line method: Is it always necessary to override on_activate and on_open ?

I say that but I can't test by myself since the example does not compile: The file "exampleoptiongroup.h" is missing (and probably "exampleoptiongroup.cc").

And, peharps, it is not really disturbing to have to call Gtk::Main before creating the application.
Comment 13 Murray Cumming 2011-03-07 11:59:54 UTC
(In reply to comment #12)
> Yes, the example progress, thanks.
> 
> I see that it overrides now the on_command_line method: Is it always necessary
> to override on_activate and on_open ?

Probably not for an example that overrides on_command_line(). But I think that on_activate() and on_open() might be generally useful as handlers for standard "actions", though that's all rather unclear to me. See my documentation bug #644113.

> I say that but I can't test by myself since the example does not compile: The
> file "exampleoptiongroup.h" is missing (and probably "exampleoptiongroup.cc").

Sorry. Fixed.
 
> And, peharps, it is not really disturbing to have to call Gtk::Main before
> creating the application.

If it makes sense, I'd like to deprecate Gtk::Main, replacing it with Gtk::Application, which does some of the same things, but better and without us needing code in gtkmm. We might not be quite there yet.
Comment 14 Yannick.Guesnet 2011-03-07 19:23:39 UTC
(In reply to comment #13)
> Probably not for an example that overrides on_command_line(). But I think that
> on_activate() and on_open() might be generally useful as handlers for standard
> "actions", though that's all rather unclear to me. See my documentation bug
> #644113.
> 
Now in the example, the on_activate() is no more used and on_open() is only used with one file. We can peharps write two examples:
- One "simple" example which uses the default command line handling and where the 
on_activate() and on_open() methods will be useful
- Another "advanced" example where the on_command_line() method is overrided.

> Sorry. Fixed.
> 
> 
> If it makes sense, I'd like to deprecate Gtk::Main, replacing it with
> Gtk::Application, which does some of the same things, but better and without us
> needing code in gtkmm. We might not be quite there yet.

Yes, this sounds well.
Comment 15 Murray Cumming 2011-03-09 12:21:39 UTC
Yes, I plan to split it into two examples.
Comment 16 Murray Cumming 2011-03-19 12:50:58 UTC
(In reply to comment #15)
> Yes, I plan to split it into two examples.

Done. I also have a patch to stop using open() from on_command_line(), but I'm not sure that the change is useful. I've asked about that in bug #643468#c11.
Comment 17 Murray Cumming 2011-03-19 13:06:25 UTC
I think it's time to remove Gtk::Application from the gtkmm 3.0 API because there are too many open issues with it. Maybe we can add it back for gtkmm 3.2.

Here are some open issues, partly with GtkApplication and partly with our wrapper:

1. There is no real explanation about why GtkApplication pushes us towards a single-instance architecture. I've tried asking but I've received no convincing answers:
  http://mail.gnome.org/archives/gtk-devel-list/2011-March/msg00053.html
There is a general suggestion that it is this way because it's what GNOME 3's gnome-shell expects, though a) I haven't seen an explanation of why gnome-shell wants that, and c) Gtk::Application apparently just doesn't work on non-Linux platforms:
  http://mail.gnome.org/archives/gtk-devel-list/2011-March/msg00036.html 

2. Bug #644113: No real explanation of "actions".
This might be the major reason for 1., but I don't want to just assume that, and it might not be relevant to applications that are not single-window anyway.

3. We need some way to initialize gtkmm only in the remote (main) instance, when Gio::Application::run() is called on a Gtk::Application, to avoid use of X11 in a local application that just asks the remote instance to do something. But we need gtkmm to be initialized for our Gtk::Application() constructor to work, I think.
We apparently need some way to initialize gtkmm between calling new Gtk::Application() and Gtk::Application's constructor calling the Glib::ObjectBase() constructor (which it calls before any other base class or member variable's constructor).

4. As I understand it, calling ./example sometestdoc.txt twice should just result in one window being shown and then re-shown. But with our example code we currently get two windows (instances?) showing the same document contents.

5. I've seen some warnings about multiple Glib main loops, though I can't reproduce that right now.

6. GtkApplication seems to be a singleton. So maybe we should really wrap it like Gtk::Main, with static methods, instead of requiring use of Gtk::Application::create().
Comment 18 Murray Cumming 2011-08-03 08:37:02 UTC
I have added the code back to gtkmm master (and glibmm master and gtkmm-documentation master).

I noticed that there is a critical warning when running the gtkmm-documentation/examples/book/application/simple/ example like so:
  ./example some-non-existant-file
:

bool ExampleWindow::load_file(const Glib::RefPtr<Gio::File>&): exception while opening file: file:///home/murrayc/checkouts/gnome30/gtkmm-documentation/examples/book/application/simple/somefile
  exception: Error opening file: No such file or directory

Breakpoint 1, g_log (log_domain=0xc0c09f "Gtk", log_level=G_LOG_LEVEL_CRITICAL, 
    format=0x128273c "%s: assertion `%s' failed") at gmessages.c:590
590	  va_start (args, format);
(gdb) bt
  • #0 g_log
    at gmessages.c line 590
  • #1 g_return_if_fail_warning
    at gmessages.c line 600
  • #2 gtk_main_quit
    at gtkmain.c line 1406
  • #3 gtk_application_quit_mainloop
    at gtkapplication.c line 106
  • #4 g_application_release
    at gapplication.c line 1095
  • #5 gtk_application_window_removed
    at gtkapplication.c line 193
  • #6 g_cclosure_marshal_VOID__OBJECT
    at gmarshal.c line 644
  • #7 g_type_class_meta_marshal
    at gclosure.c line 884
  • #8 g_closure_invoke
    at gclosure.c line 773
  • #9 signal_emit_unlocked_R
    at gsignal.c line 3201
  • #10 g_signal_emit_valist
    at gsignal.c line 3002
  • #11 g_signal_emit
    at gsignal.c line 3059
  • #12 gtk_application_remove_window
    at gtkapplication.c line 333
  • #13 Gtk::Application::remove_window
    at application.cc line 301
  • #14 Gtk::Application::on_window_hide
    at application.cc line 110
  • #15 sigc::bound_mem_functor1<void, Gtk::Application, Gtk::Window*>::operator()
    at /opt/gnome30/include/sigc++-2.0/sigc++/functors/mem_fun.h line 1851
  • #16 sigc::adaptor_functor<sigc::bound_mem_functor1<void, Gtk::Application, Gtk::Window*> >::operator()<Gtk::Window*&>
    at /opt/gnome30/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h line 84
  • #17 sigc::bind_functor<-0x00000000000000001, sigc::bound_mem_functor1<void, Gtk::Application, Gtk::Window*>, Gtk::Window*, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil>::operator()
    at /opt/gnome30/include/sigc++-2.0/sigc++/adaptors/bind.h line 1110
  • #18 sigc::internal::slot_call0<sigc::bind_functor<-0x00000000000000001, sigc::bound_mem_functor1<void, Gtk::Application, Gtk::Window*>, Gtk::Window*, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil>, void>::call_it
    at /opt/gnome30/include/sigc++-2.0/sigc++/functors/slot.h line 103
  • #19 sigc::slot0<void>::operator()
    at /opt/gnome30/include/sigc++-2.0/sigc++/functors/slot.h line 440
  • #20 Glib::SignalProxyNormal::slot0_void_callback
    at signalproxy.cc line 95
  • #21 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 85
  • #22 g_closure_invoke
    at gclosure.c line 773
  • #23 signal_emit_unlocked_R
    at gsignal.c line 3341
  • #24 g_signal_emit_valist
    at gsignal.c line 3002
  • #25 g_signal_emit
    at gsignal.c line 3059
  • #26 gtk_widget_hide
    at gtkwidget.c line 4003
  • #27 Gtk::Widget::hide
    at widget.cc line 5766
  • #28 ExampleWindow::load_file
    at book/application/simple/examplewindow.cc line 60
  • #29 ExampleApplication::create_window
    at book/application/simple/exampleapplication.cc line 52
  • #30 ExampleApplication::on_open
    at book/application/simple/exampleapplication.cc line 85
  • #31 Gio::Application_Class::open_callback
    at application.cc line 157
  • #32 ffi_call_SYSV
    at ../src/x86/sysv.S line 61
  • #33 ffi_call
  • #34 g_cclosure_marshal_generic
    at gclosure.c line 1146
  • #35 g_type_class_meta_marshal
    at gclosure.c line 884
  • #36 g_closure_invoke
    at gclosure.c line 773
  • #37 signal_emit_unlocked_R
    at gsignal.c line 3309
  • #38 g_signal_emit_valist
    at gsignal.c line 3002
  • #39 g_signal_emit
    at gsignal.c line 3059
  • #40 g_application_open
    at gapplication.c line 1168
  • #41 g_application_real_local_command_line
  • #42 Gio::Application::local_command_line_vfunc
    at application.cc line 786
  • #43 Gio::Application_Class::local_command_line_vfunc_callback
    at application.cc line 384
  • #44 g_application_run
    at gapplication.c line 1276
  • #45 Gio::Application::run
    at application.cc line 662
  • #46 Gtk::Application::run
    at application.cc line 127
  • #47 main
    at book/application/simple/main.cc line 33

Comment 19 Murray Cumming 2011-08-03 08:59:29 UTC
This is apparently because the local_command_line() vfunc is run before the run_mainloop() vfunc, in g_application_run(). I will try to create a C test case, though maybe this is intentional.
Comment 20 Yannick.Guesnet 2011-08-11 06:43:58 UTC
Created attachment 193612 [details] [review]
Remove critical warning in examples for non existant files

In the examples, we create a window before loading files. Thus, if the file does not exist, we must destroy the window. This is probably not the better way to load a file.
I have changed the examples in order to load file first and then, if it is needed, create a window.
Comment 21 Yannick.Guesnet 2011-08-11 06:47:11 UTC
(In reply to comment #19)
> This is apparently because the local_command_line() vfunc is run before the
> run_mainloop() vfunc, in g_application_run(). I will try to create a C test
> case, though maybe this is intentional.

I assume that it is intentional since, in the doc, they say that the main loop is launched only if the use count is greater than 0. Thus, I suspect that  local_command_line() vfunc has to be called before in order to determine if the use count has to be increment.
Comment 22 Murray Cumming 2011-09-06 08:07:16 UTC
(In reply to comment #20)
> Created an attachment (id=193612) [details] [review]
> Remove critical warning in examples for non existant files
> 
> In the examples, we create a window before loading files. Thus, if the file
> does not exist, we must destroy the window. This is probably not the better way
> to load a file.
> I have changed the examples in order to load file first and then, if it is
> needed, create a window.

If possible, I'd like to allow people to still do their file-parsing in a derived Gtk::Window class. It's not pure non-UI/UI separation, but it's convenient, and what many people will do first.
Comment 23 Murray Cumming 2011-09-06 08:11:42 UTC
(In reply to comment #21)
> (In reply to comment #19)
> > This is apparently because the local_command_line() vfunc is run before the
> > run_mainloop() vfunc, in g_application_run(). I will try to create a C test
> > case, though maybe this is intentional.
> 
> I assume that it is intentional since, in the doc, they say that the main loop
> is launched only if the use count is greater than 0. Thus, I suspect that 
> local_command_line() vfunc has to be called before in order to determine if the
> use count has to be increment.

Yes, this documentation 
  http://developer.gnome.org/gio/unstable/GApplication.html
says
"
If, after the above is done, the use count of the application is zero then the exit status is returned immediately. If the use count is non-zero then the mainloop is run until the use count falls to zero, at which point 0 is returned.
"

But surely it's quite normal to want to use a Mainloop (or even GTK+) while doing local command-line processing?
Comment 24 Murray Cumming 2011-09-16 12:29:55 UTC
I filed GTK+ bug #659236 about this. We can't really proceed until that's clarified.
Comment 25 Murray Cumming 2011-09-19 09:00:23 UTC
Actually, I don't see that warning anymore. Maybe it was fixed by GTK+ or somewhere else.

And it was not about local command-line processing. It was happening while handling the open signal, as seen in the backtrace in comment #16.

So, does anyone else still see this warning, or know of any other problem with the new API?
Comment 26 José Alburquerque 2011-09-20 04:52:09 UTC
I don't see the warning either.  There's some related API that could be added.  I could add those if you'd like.
Comment 27 Murray Cumming 2011-09-20 10:22:21 UTC
(In reply to comment #26)
> There's some related API that could be added. 
> I could add those if you'd like.

Yes, please, of course.
Comment 28 Yannick.Guesnet 2011-09-21 05:49:54 UTC
(In reply to comment #25)
> Actually, I don't see that warning anymore. Maybe it was fixed by GTK+ or
> somewhere else.
> 
> And it was not about local command-line processing. It was happening while
> handling the open signal, as seen in the backtrace in comment #16.
> 
> So, does anyone else still see this warning, or know of any other problem with
> the new API?

I don't see the warning anymore. This is probably due to the commit "GApplication: don't create a mainloop" (http://git.gnome.org/browse/glib/commit/gio/gapplication.c?id=43007aa2d2f0d1fe3e63f7c61abb927dccaf799b).

GApplication don't create a main_loop but iterate the main context directly. The main loop is no more destroyed in g_application_release() which seems to be connected to our warning.
Comment 29 Murray Cumming 2011-09-26 14:30:04 UTC
I have removed this again, because we were too late to test it properly for glibmm 2.30.0 and gtkmm 3.2.0. These are the commits that we can revert later in master:

http://git.gnome.org/browse/glibmm/commit/?id=5eb941ae0f290ccafd4757c0536a9742ca3a8084

and

http://git.gnome.org/browse/gtkmm/commit/?id=569895eddfcf66af7c28dd80a92b82d273d27a54

Let's branch in a week or so after gtkmm 3.2.0 and try again in master.
Comment 31 Murray Cumming 2011-11-25 20:56:21 UTC
(In reply to comment #28)
> (In reply to comment #25)
> > Actually, I don't see that warning anymore. Maybe it was fixed by GTK+ or
> > somewhere else.
> > 
> > And it was not about local command-line processing. It was happening while
> > handling the open signal, as seen in the backtrace in comment #16.
> > 
> > So, does anyone else still see this warning, or know of any other problem with
> > the new API?
> 
> I don't see the warning anymore. This is probably due to the commit
> "GApplication: don't create a mainloop"
> (http://git.gnome.org/browse/glib/commit/gio/gapplication.c?id=43007aa2d2f0d1fe3e63f7c61abb927dccaf799b).

Yes, and GtkApplication has stopped using gtk_main() and gtk_main_quit():
http://git.gnome.org/browse/gtk+/commit/gtk/gtkapplication.c?id=7e22a5350ca50a1e190f32f52b45380b76a059a9

That sounds generally good, but we will need to revise our code that tried to work around that.

The examples in gtkmm-documentation/examples/book/application/ seem to work fine, though I don't like that we give argc/argv to both Gtk::Main() and Application::run().
Comment 32 Murray Cumming 2012-02-09 08:38:07 UTC
Does anyone have any thoughts about the current state of this API?
Comment 33 José Alburquerque 2012-02-09 21:55:53 UTC
There is some related API (like GAction, GMenu) not wrapped yet for glibmm.  I can do those if desired.

There's also some related API not wrapped yet for gtkmm (like GtkApplicationWindow).  I can do those also.

I've been running a few errands today.  Sorry for the late reply.
Comment 34 Murray Cumming 2012-02-10 08:48:33 UTC
Yes, of course, any help would be much appreciated.
Comment 35 Murray Cumming 2012-02-10 12:09:37 UTC
Created attachment 207241 [details] [review]
0001-Application-Avoid-the-need-to-use-Gtk-Main.patch

Does anyone have an objection to this patch? I don't like requiring people to call init_gtkmm() in their derived create() methods, but I can't see another way to avoid the need for Gtk::Main(). With this, we could probably deprecate Gtk::Main.

Application: Avoid the need to use Gtk::Main.

	* gtk/src/application.[hg|cc]: Add an init_gtkmm() method, for use in
	the create() methods of derived Application classes. This is necessary
	to allow the Application constructor to succeed, because it uses 
	g_object_new().
	create(): Use it here too, though I wonder if anyone would actually use
	Gtk::Application without deriving.
	This lets developers no use Gtk::Main at all, as long as they call their
	Application's create() method at the same early point in their code.
	
	This does not allow the developer to defer GTK+ initialization to when they 
	call g_application_run(), and even to avoid GTK+ initialization compeletely
	in the local instance, as is possible with the C API, but we did not allow 
	that before either.
Comment 36 José Alburquerque 2012-02-10 15:12:15 UTC
(In reply to comment #35)
> Does anyone have an objection to this patch? I don't like requiring people to
> call init_gtkmm() in their derived create() methods, but I can't see another
> way to avoid the need for Gtk::Main(). With this, we could probably deprecate
> Gtk::Main.

This might be a simple question, but would it make a difference if somehow the GType system is initialized in the Glib::ObjectBase constructors?  The Application constructor would then succeed because the Glib::ObjectBase constructors always run first.
Comment 37 José Alburquerque 2012-02-10 15:14:00 UTC
(In reply to comment #36)
> This might be a simple question, but would it make a difference if somehow the
> GType system is initialized in the Glib::ObjectBase constructors?  The
> Application constructor would then succeed because the Glib::ObjectBase
> constructors always run first.

The idea would be to have each Glib::ObjectBase constructor have a static boolean signaling that they have initialized the GType system (and glibmm appropriately if necessary).  When the constructors first run, each would call a method that does the initialization (avoiding initialization if the method has already been called).
Comment 38 José Alburquerque 2012-02-10 15:19:25 UTC
I guess having the extra lines of execution in the constructors would probably make applications slower which would not be desirable.
Comment 39 Murray Cumming 2012-02-10 15:21:35 UTC
s(In reply to comment #36)
> This might be a simple question, but would it make a difference if somehow the
> GType system is initialized in the Glib::ObjectBase constructors?  The
> Application constructor would then succeed because the Glib::ObjectBase
> constructors always run first.

Do you mean, during the call to Glib::ObjectBase() in the derived classes' constructor's initializer lists?
Comment 40 José Alburquerque 2012-02-10 15:34:08 UTC
Yes.  glibmm's wrap regestering system could be initialized as well that way when a derived GObject class' constructor taking a Glib::ConstructParams is used, the call to the derived class init() method would also succeed.  Just a thought.
Comment 41 José Alburquerque 2012-02-10 15:35:56 UTC
(In reply to comment #40)
> Just a thought.

I mean it's what I'm thinking.
Comment 42 Murray Cumming 2012-02-10 15:37:00 UTC
Maybe it would not be slow if the whole system had been (optionally) initialized already using the existing system. It could be worth a try, but I don't have time for it myself, and I don't think we would have time to get it in for the next stable release.
Comment 43 José Alburquerque 2012-02-10 15:43:32 UTC
Well, I might be able to provide a patch for it later.
Comment 44 José Alburquerque 2012-02-10 15:47:03 UTC
However, as you said, probably using the existing patch would suffice.  If it's worth it, I could certainly try and provide an updated patch later.
Comment 45 Murray Cumming 2012-02-13 08:58:52 UTC
Comment on attachment 207241 [details] [review]
0001-Application-Avoid-the-need-to-use-Gtk-Main.patch

I have pushed this. We can deprecate the new (protected) method later if we can make this unnecessary.
Comment 46 José Alburquerque 2012-02-14 23:53:29 UTC
Created attachment 207604 [details] [review]
Patchi to allow gtkmm initialization before Gtk::Application construction.

I think it's possible to use the static init_gtkmm_internals() function in Gtk::Application's custom class init method (Gtk::Application::custom_class_init()) and not require the protected init_gtkmm() methods to be used in the Gtk::Application::create() methods.  Gtk::Application::custom_class_init() already initializes glibmm (so any initialization in the Glib::ObjectBase constructors would be redundant).  However, it's possible to initialize gtkmm in that method (using init_gtkmm_internals()) which would allow Gtk::Application's constructors to succeed after.

The gtk+ docs[1] say that gtk_application_new()[1] calls gtk_init() so it would not be necessary to call it for the non-command line argument constructor of Gtk::Application.  However, for argument parsing, Gtk::Application's command line argument constructor can include a call to gtk_init() to parse the arguments (this call would take place before the one that GtkApplication does because the docs say that that call takes place in the "startup" signal's default handler which only happens when the application is registered[2] and that would occur after construction).

[1] http://developer.gnome.org/gtk3/3.3/GtkApplication.html#gtk-application-new
[2] http://developer.gnome.org/gio/unstable/GApplication.html#g-application-register

Here's an updated patch.
Comment 47 Murray Cumming 2012-02-15 09:41:49 UTC
That looks good, and it works in gtkmm-documentation and in my glom branch that uses Gtk::Application.

I have pushed it. Many thanks.


Maybe now is the time for us to try to deprecated Gtk::Main.
Comment 48 José Alburquerque 2012-02-16 22:33:09 UTC
Created attachment 207818 [details] [review]
Application: Constructor: Receive argc and argv params by reference.

Maybe the Gtk::Application constructor taking argc and argv parameters should receive them by reference in case the call to gtk_init() modifies the values?  This patch does that.
Comment 49 Murray Cumming 2012-02-17 08:08:56 UTC
Yes, please push that.
Comment 51 José Alburquerque 2012-02-24 06:55:27 UTC
Most of the GApplication related API has been wrapped:

http://developer.gnome.org/gio/2.31/application.html

Just a few comments:

1) The "add_platform_data" virtual function of GApplication has not been wrapped because it takes a GVariantBuilder and that type has not been wrapped yet because it is not a type that is registered with the GType system.  A bug would probably have to be filed about that.

2) The g_action_map_add_action_entries() function (Gio::ActionMap::add_action_entries()) is not wrapped yet because it takes an array of GActionEntry[1] and wrapping that structure has to be done by hand.  I think I can do it it by adapting code from Gio::DBus::InterfaceVTable or Gio::DBus::SubtreeVTable if it should be wrapped.  (The Gio::SimpleActionGroup::add_entries() method is not wrapped yet for this same reason.)

[1] http://developer.gnome.org/gio/2.31/GActionMap.html#GActionEntry

3) Gio::DBus::ActionGroup::create() and Gio::DBus::MenuModel::create() don't use _WRAP_CREATE() (with respective constructors) because the C API just provides "getter" functions and not *_new() functions for the C types.  The API also doesn't seem to make it possible to construct the types with just g_object_new().  A bug would probably have to be filed about that.

Finally, in gtk+ there is a new GtkActionable[2] interface that seems to be related to GtkApplication.  It seems that quite a few widgets[3] implement this new interface.  I can add the interface, but I think having the widgets derive from it would be a break of some sort so I'm not sure what to do in this case.  The docs[4] say that what's important are the properties so maybe just wrapping the new properties in the relevant widgets would be enough.

[2] http://developer.gnome.org/gtk3/3.3/GtkActionable.html
[3] http://developer.gnome.org/gtk3/3.3/GtkActionable.html#GtkActionable.implementations
[4] http://developer.gnome.org/gtk3/3.3/GtkActionable.html#GtkActionable.description
Comment 52 Murray Cumming 2012-02-24 09:31:23 UTC
(In reply to comment #51)
> Most of the GApplication related API has been wrapped:
> 
> http://developer.gnome.org/gio/2.31/application.html
> 
> Just a few comments:
> 
> 1) The "add_platform_data" virtual function of GApplication has not been
> wrapped because it takes a GVariantBuilder and that type has not been wrapped
> yet because it is not a type that is registered with the GType system.  A bug
> would probably have to be filed about that.

Yes, please file a glib bug about that.
However, I am not very concerned about that for glibmm. It seems to be just a way to implement GtkApplication rather than something that application developers would use.
 
> 2) The g_action_map_add_action_entries() function
> (Gio::ActionMap::add_action_entries()) is not wrapped yet because it takes an
> array of GActionEntry[1] and wrapping that structure has to be done by hand.  I
> think I can do it it by adapting code from Gio::DBus::InterfaceVTable or
> Gio::DBus::SubtreeVTable if it should be wrapped.  (The
> Gio::SimpleActionGroup::add_entries() method is not wrapped yet for this same
> reason.)
> 
> [1] http://developer.gnome.org/gio/2.31/GActionMap.html#GActionEntry

g_action_map_add_action_entries() seems to be a C convenience function. It looks like multiple calls to g_action_map_add_action() can do the same thing. So maybe we can just not wrap this.

> 3) Gio::DBus::ActionGroup::create()

I don't see that here:
http://git.gnome.org/browse/glibmm/tree/gio/src/dbusactiongroup.ccg

> and Gio::DBus::MenuModel::create()

or this:
http://git.gnome.org/browse/glibmm/tree/gio/src/dbusmenumodel.ccg

> don't
> use _WRAP_CREATE() (with respective constructors) because the C API just
> provides "getter" functions and not *_new() functions for the C types.  The API
> also doesn't seem to make it possible to construct the types with just
> g_object_new().

That doesn't seem like a problem. We can just have a static get() method. I'm sure there are other existing glibmm or gtkmm classes that only have static ::get() or ::get_default() methods.

> Finally, in gtk+ there is a new GtkActionable[2] interface that seems to be
> related to GtkApplication.  It seems that quite a few widgets[3] implement this
> new interface.  I can add the interface, but I think having the widgets derive
> from it would be a break of some sort so I'm not sure what to do in this case.

Yes, that would be an ABI break. We had the same problem with the Gtk::Buildable interface. For now, we should add the interface, but not use it in existing classes yet. We can use it in some future ABI break.

> The docs[4] say that what's important are the properties so maybe just wrapping
> the new properties in the relevant widgets would be enough.

I would prefer not to do that because it confuses the API. People can use the C API if necessary. Or we can do something else if we find that people really use this API a lot.
Comment 53 José Alburquerque 2012-02-27 00:40:31 UTC
(In reply to comment #52)
> (In reply to comment #51)
> > Most of the GApplication related API has been wrapped:
> > 
> > http://developer.gnome.org/gio/2.31/application.html
> > 
> > Just a few comments:
> > 
> > 1) The "add_platform_data" virtual function of GApplication has not been
> > wrapped because it takes a GVariantBuilder and that type has not been wrapped
> > yet because it is not a type that is registered with the GType system.  A bug
> > would probably have to be filed about that.
> 
> Yes, please file a glib bug about that.
> However, I am not very concerned about that for glibmm. It seems to be just a
> way to implement GtkApplication rather than something that application
> developers would use.

Done:
https://bugzilla.gnome.org/show_bug.cgi?id=670856

> 
> > 2) The g_action_map_add_action_entries() function
> > (Gio::ActionMap::add_action_entries()) is not wrapped yet because it takes an
> > array of GActionEntry[1] and wrapping that structure has to be done by hand.  I
> > think I can do it it by adapting code from Gio::DBus::InterfaceVTable or
> > Gio::DBus::SubtreeVTable if it should be wrapped.  (The
> > Gio::SimpleActionGroup::add_entries() method is not wrapped yet for this same
> > reason.)
> > 
> > [1] http://developer.gnome.org/gio/2.31/GActionMap.html#GActionEntry
> 
> g_action_map_add_action_entries() seems to be a C convenience function. It
> looks like multiple calls to g_action_map_add_action() can do the same thing.
> So maybe we can just not wrap this.

Okay.  Sounds reasonable.

> 
> > 3) Gio::DBus::ActionGroup::create()
> 
> I don't see that here:
> http://git.gnome.org/browse/glibmm/tree/gio/src/dbusactiongroup.ccg
> 
> > and Gio::DBus::MenuModel::create()
> 
> or this:
> http://git.gnome.org/browse/glibmm/tree/gio/src/dbusmenumodel.ccg
> 
> > don't
> > use _WRAP_CREATE() (with respective constructors) because the C API just
> > provides "getter" functions and not *_new() functions for the C types.  The API
> > also doesn't seem to make it possible to construct the types with just
> > g_object_new().
> 
> That doesn't seem like a problem. We can just have a static get() method. I'm
> sure there are other existing glibmm or gtkmm classes that only have static
> ::get() or ::get_default() methods.

Done in git:
http://git.gnome.org/browse/glibmm/commit/?id=a98cb0356c7e1c2f4121d6d87bca8a08c0cf7e0d

> 
> > Finally, in gtk+ there is a new GtkActionable[2] interface that seems to be
> > related to GtkApplication.  It seems that quite a few widgets[3] implement this
> > new interface.  I can add the interface, but I think having the widgets derive
> > from it would be a break of some sort so I'm not sure what to do in this case.
> 
> Yes, that would be an ABI break. We had the same problem with the
> Gtk::Buildable interface. For now, we should add the interface, but not use it
> in existing classes yet. We can use it in some future ABI break.

Also done in git:
http://git.gnome.org/browse/gtkmm/commit/?id=2adad4a910253795725f03007d47fd1287986419

> 
> > The docs[4] say that what's important are the properties so maybe just wrapping
> > the new properties in the relevant widgets would be enough.
> 
> I would prefer not to do that because it confuses the API. People can use the C
> API if necessary. Or we can do something else if we find that people really use
> this API a lot.
Comment 54 Murray Cumming 2012-03-13 09:02:43 UTC
Is there any reason to keep this bug open?
Comment 55 José Alburquerque 2012-03-13 16:33:46 UTC
No.  Closing.
Comment 56 Murray Cumming 2012-03-22 20:30:31 UTC
I have tried to use set_app_menu(), but I'm getting some errors that suggest a refcount problem:

Could someone else try it too, please?
http://git.gnome.org/browse/gtkmm-documentation/commit/?id=87bbeb4cbea30beb7f7ed9f9c3afbb280855cc87
Comment 57 Murray Cumming 2012-03-23 20:51:36 UTC
(In reply to comment #56)
> I have tried to use set_app_menu(), but I'm getting some errors that suggest a
> refcount problem:

I fixed that with this in glibmm:
  http://git.gnome.org/browse/glibmm/commit/?id=b40f9a7014fac162b3e76a4ee987e3d4801be96a
and this in the example:
  http://git.gnome.org/browse/gtkmm-documentation/commit/?id=0da2cd8615dfd54a1b486f668cc6c00fcc30837d

However, I still don't actually see an application menu here in GNOME 3.2.
Comment 58 José Alburquerque 2012-03-25 21:19:30 UTC
Created attachment 210593 [details]
Application screenshot

Having built the jhbuild sources as of today, I see a menu.  Here's the screenshot.
Comment 59 Murray Cumming 2012-03-27 14:57:07 UTC
OK. Thanks. Closing again then.

That screenshot looks odd, but maybe it's just a matter of how gnome-shell is setup. Let's check again when GNOME 3.4 is in a distro.