c++-gtk-utils
|
This is a class for constructing and managing GtkApplication objects. More...
#include <c++-gtk-utils/application.h>
Public Types | |
typedef std::list< WinBase * > ::size_type | size_type |
Public Member Functions | |
Application (const Application &)=delete | |
Application & | operator= (const Application &)=delete |
void | add (Cgu::WinBase *win) |
bool | remove (Cgu::WinBase *win) |
int | run (int argc, char **argv) |
GApplication * | get_g_app () const |
std::list< Cgu::WinBase * > | get_windows () const |
size_type | get_win_count () const |
Application (const char *prog_name, GApplicationFlags flags) | |
~Application () | |
Public Attributes | |
Cgu::SafeEmitterArg < Cgu::Application * > | activate |
Cgu::SafeEmitterArg < Cgu::Application * > | startup |
Cgu::SafeEmitterArg < Cgu::Application *, GApplicationCommandLine *, gint & > | command_line |
Cgu::SafeEmitterArg < Cgu::Application *, std::pair< GFile **, gint > , gchar * > | open |
This is a class for constructing and managing GtkApplication objects.
It is available since version 2.0.0-rc2. It is only compiled in with a GTK+3 installation, and if the library is not configured with the --without-gtk option.
In typical usage, a Cgu::Application object is created in main(), and then a callback is attached to the 'activate', 'command_line' or 'open' emitter, depending on the flag passed to the Application object's constructor. The run() method of the Application object is then called, and a window deriving from Cgu::WinBase is constructed in the callback and added to the Application object or, if the program is a single instance program with only one main window and an instance is already running, a function is called to present that window.
The gio/gtk+ documentation at the time of writing does not explain key concepts, and in particular how the GtkApplication sub-class interacts with GApplication's g_application_run(). Here is an explanation:
There is little in this class that cannot also be done using the Cgu::prog_present interface, which has the advantage of being more portable (Cgu::prog_present does not depend on GTK+3), but this class is more convenient to use where a program requires multiple main application windows which can be independently opened and any of which are to keep the program alive until the last one is closed.
Cgu::Application objects are not singletons. It is possible to drop an Application object out of scope or destroy it in some other way after closing or removing all its windows, then construct another with a different flag and then call run() on the second one (although it would be a curious application that wanted to do so). It is also possible, but even more off-the-wall, to have two Application objects in existence in the same process at the same time provided different dbus identifiers are supplied to the constructor for each, although run() may only be called on one of them at any one time. However, this is something of a curiosity: in nearly all cases an application will only have one Cgu::Application object, since the main purpose of Cgu::Application is to facilitate single instance programs.
Cgu::WinBase objects, and so Cgu::Application, can be used with widget heirarchies or top level windows created using GtkBuilder. See Using c++-gtk-utils with GtkBuilder for particulars about that.
Here is a compilable example, demonstrating the use of the GApplicationFlags options:
One thing to note about this example is that the callbacks connected to the Cgu::Application object always execute in the first instance of the program to be started (the instance in which Cgu::Application::run() blocks). If the program is then restarted, Cgu::Application::run() returns in the new program instance as soon as it has invoked the existing instance via dbus, following which the new program instance exits, so immediately disposing of the Cgu::Application object and callbacks which were constructed on the restart. This is a feature of GApplication/GtkApplication: given the overhead of starting a new process, and that restarting a single-instance program is in any event an exceptional event, any additional overhead created by constructing and then destroying the Cgu::Application object and callbacks in the new instance is trivial.
typedef std::list<WinBase*>::size_type Cgu::Application::size_type |
|
delete |
This class cannot be copied. The copy constructor is deleted.
Cgu::Application::Application | ( | const char * | prog_name, |
GApplicationFlags | flags | ||
) |
This constructor will, via gtk_application_new(), cause g_type_init() to be called. If any GTK+ functions are to be called before an Application object is constructed, g_type_init() (or gtk_init()) must be called explicitly.
prog_name | An identifier name. This can comprise any valid ASCII characters "[A-Z][a-z][0-9]_-", although it is usually best to pass the program name. Unlike with gtk_application_new(), it does not need to comprise a full dbus bus name: this method will construct its own valid dbus bus name from prog_name in the org.cgu domain. |
flags | The GApplicationFlags to be passed to the Cgu::Application object. This class does not contain its own sub-class of GApplication to customize this, but adopts the behaviour of GtkApplication. That behaviour is explained in the introductory remarks. |
Cgu::ApplicationNameError | This exception will be thrown if the prog_name parameter does not meet the requirements referred to above. |
std::bad_alloc | This method might throw std::bad_alloc if memory is exhausted and the system throws in that case. |
Since 2.0.0-rc2
|
inline |
From version 2.0.0-rc3, as a safety feature the destructor removes any remaining WinBase objects associated with this Application object (this would only be relevant if the user constructs the Application object on free store, and then deletes it while the run() method is still blocking for the purpose of constructing a different Application object, but does not call the remove() method on all associated WinBase objects before doing so: constructing an Application object on free store in this way would be highly unusual however).
Since 2.0.0-rc3
void Cgu::Application::add | ( | Cgu::WinBase * | win | ) |
Add a Cgu::WinBase object to the Cgu::Application object, and so also add its managed GtkWindow object to the GtkApplication object. Any Cgu::WinBase object passed to this method should not normally be modal and must have been constructed on free store with the new expression, and will be self owning, although if it is removed from this Cgu::Application object with remove(), the delete expression can (and normally should) be called on it. If a delete event occurs on the WinBase object so that the WinBase object destroys itself (say, by clicking on the window's close/delete button), or it destroys itself in some other way (say, by calling the WinBase::close() method), it will automatically be removed from this Application object without further action being necessary. The WinBase::exec() method should never be called on a WinBase object which has been added to an Application object. The Cgu::Application class, and thus this method, does not employ mutexes to make it thread safe, as there should never be a reason to call Cgu::Application methods in other than the main GUI thread.
win | The Cgu::WinBase object to be added. |
std::bad_alloc | This method might throw std::bad_alloc if memory is exhausted and the system throws in that case. |
Since 2.0.0-rc2
|
inline |
Get the underlying GApplication object (note, not the GtkApplication object, although the GApplication object can be cast to GtkApplication), so allowing any of gio's g_application_*() functions to be applied to it. In normal usage it will not be necessary to call this method. This method is thread safe and will not throw.
Since 2.0.0-rc2
|
inline |
Gets the current count of Cgu::WinBase objects associated with this Cgu::Application object. When it reaches 0, the application will normally end (but this can be prevented by calling g_application_hold()/g_application_release() on the GApplication object returned by get_g_app()). This method can be used in the callback of one of this class's emitters to determine whether this is the first instance of a program to be started (assuming the first instance calls add() to bring up a window), because in that case it will return 0 until add() is called. Calling get_windows().size() will give the same result, but using this method is more efficient as it will avoid a copy of the list of windows. This method will not throw assuming that calling std::list::size() does not throw (as it would not on any sane implementation). The Cgu::Application class, and thus this method, does not employ mutexes to make it thread safe, as there should never be a reason to call Cgu::Application methods in other than the main GUI thread.
Since 2.0.0-rc2
|
inline |
Get the list of Cgu::WinBase objects associated with the application. The Cgu::Application class, and thus this method, does not employ mutexes to make it thread safe, as there should never be a reason to call Cgu::Application methods in other than the main GUI thread.
std::bad_alloc | This method might throw std::bad_alloc if memory is exhausted and the system throws in that case. |
Since 2.0.0-rc2
|
delete |
This class cannot be copied. The assignment operator is deleted.
bool Cgu::Application::remove | ( | Cgu::WinBase * | win | ) |
Remove a Cgu::WinBase object from the Cgu::Application object, and so also remove its managed GtkWindow object from the GtkApplication object. This method will not throw assuming that merely iterating through a list does not throw (as it would not on any sane implementation). The Cgu::Application class, and thus this method, does not employ mutexes to make it thread safe, as there should never be a reason to call Cgu::Application methods in other than the main GUI thread. Calling this method does not destroy the WinBase object.
win | The Cgu::WinBase object to be removed. |
Since 2.0.0-rc2
|
inline |
Calls g_application_run() in respect of the underlying GtkApplication object, so invoking one of this Cgu::Application class's emitters (the exact behaviour depends on the GApplication flags passed to the constructor and is explained in the introductory remarks above). This method is thread safe (although that is irrelevant to its purpose) and will not throw. In addition, if a callback connected to an emitter throws, the exception is consumed and a g_critical warning issued. This function blocks until the last WinBase object associated with this Application object is destroyed or removed.
argc | The argc from main() or 0. |
argv | The argv from main() or 0. |
Since 2.0.0-rc2
Cgu::SafeEmitterArg<Cgu::Application*> Cgu::Application::activate |
This SafeEmitterArg object emits (and so executes any connected callback) when the underlying GApplication object emits its activate signal. The argument passed to the emitter's callback(s) is a pointer to the Cgu::Application object.
Since 2.0.0-rc2
Cgu::SafeEmitterArg<Cgu::Application*, GApplicationCommandLine*, gint&> Cgu::Application::command_line |
This SafeEmitterArg object emits (and so executes any connected callback) when the underlying GApplication object emits its command-line signal. The second argument passed to the emitter's callback(s) is the one passed by that signal, that is to say the arguments are:
first: a pointer to the Cgu::Application object.
second: a pointer to a GApplicationCommandLine object representing the passed command line (this is owned by gio and should not be unref'ed).
third: a gint& reference to which the value to be returned to the GApplication's command-line signal can be passed: if no value is assigned to it or no callback has been attached to the signal, 0 will be returned, except that if an exception from a callback is consumed, -1 will be returned. If more than one callback is attached to the signal and no exception is consumed, the last one to assign a value will be have its value returned.
Since 2.0.0-rc2
Cgu::SafeEmitterArg<Cgu::Application*, std::pair<GFile**, gint>, gchar*> Cgu::Application::open |
This SafeEmitterArg object emits (and so executes any connected callback) when the underlying GApplication object emits its open signal. The second and third arguments passed to the emitter's callback(s) are those passed by that signal, that is to say the arguments are:
first: a pointer to the Cgu::Application object.
second: a std::pair object where the first member is an array of GFile*'s representing the files/uris passed as arguments, and the second member is the length of that array (the array is owned by gio and should not be freed).
third: a gchar* argument comprising the text of the "hint" (this is owned by gio and should not be freed).
Since 2.0.0-rc2
Cgu::SafeEmitterArg<Cgu::Application*> Cgu::Application::startup |
This SafeEmitterArg object emits (and so executes any connected callback) when the underlying GApplication object emits its startup signal. The argument passed to the emitter's callback(s) is a pointer to the Cgu::Application object. However, you usually won't need to do anything in response to the startup signal.
Since 2.0.0-rc2