c++-gtk-utils
application.h
Go to the documentation of this file.
1 /* Copyright (C) 2011 and 2013 Chris Vine
2 
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation; either version 2.1 of
10  the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License, version 2.1, for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License, version 2.1, along with this library (see the file LGPL.TXT
19  which came with this source code package in the c++-gtk-utils
20  sub-directory); if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 */
24 
25 #ifndef CGU_APPLICATION_H
26 #define CGU_APPLICATION_H
27 
28 #include <list>
29 #include <exception>
30 #include <utility>
31 
33 
34 #ifdef CGU_USE_GTK
35 #include <gtk/gtk.h>
36 #endif
37 
38 #include <gio/gio.h>
39 
41 #include <c++-gtk-utils/window.h>
42 #include <c++-gtk-utils/emitter.h>
43 #include <c++-gtk-utils/param.h>
44 
45 namespace Cgu {
46 
47 #if defined(DOXYGEN_PARSING) || defined(CGU_USE_GTK)
48 #if defined(DOXYGEN_PARSING) || GTK_CHECK_VERSION(2,99,0)
49 
50 /**
51  * @class Cgu::ApplicationNameError application.h c++-gtk-utils/application.h
52  * @brief This class is thrown when the program id name passed to the
53  * constructor of Cgu::Application is invalid.
54  */
55 struct ApplicationNameError: public std::exception {
56  virtual const char* what() const throw() {return "ApplicationNameError\n";}
57 };
58 
59 /**
60  * @class Cgu::Application application.h c++-gtk-utils/application.h
61  * @brief This is a class for constructing and managing GtkApplication
62  * objects.
63  *
64  * @details It is available since version 1.2.12. It is only compiled
65  * in with a GTK+3 installation, and if the library is not configured
66  * with the \--without-gtk option.
67  *
68  * In typical usage, a Cgu::Application object is created in main(),
69  * and then a callback is attached to the 'activate', 'command_line'
70  * or 'open' emitter, depending on the flag passed to the Application
71  * object's constructor. The run() method of the Application object
72  * is then called, and a window deriving from Cgu::WinBase is
73  * constructed in the callback and added to the Application object or,
74  * if the program is a single instance program with only one main
75  * window and an instance is already running, a function is called to
76  * present that window.
77  *
78  * Here is a brief explanation of how the flag options passed to the
79  * Cgu::Application object (and so to the underlying GApplication
80  * object) work:
81  *
82  * @par
83  * (a) If a Cgu::Application object is constructed with the
84  * G_APPLICATION_FLAGS_NONE flag set, then calling the
85  * Cgu::Application::run() method (which hands off to
86  * g_application_run()) will cause the 'activate' emitter to emit. No
87  * command line parameter should be passed to the run method (argc
88  * should be 0 or 1), otherwise GtkApplication will cause the start-up
89  * to abort, except that from glib>=2.40 and gtk+>=3.12 recognised
90  * gtk+ command line options can be passed in for stripping out and
91  * consumption by gtk+. g_application_run(), and so
92  * Cgu::Application::run(), can be called with argc and argv set to 0
93  * where such aborting must be avoided.
94  * @par
95  * (b) If a Cgu::Application object is constructed with the
96  * G_APPLICATION_HANDLES_OPEN flag set, then calling the
97  * Cgu::Application::run() method will cause the 'activate' emitter to
98  * emit if no command line parameters were provided when the program
99  * was started, or cause the 'open' emitter to emit if parameters are
100  * passed. Such parameters will be construed as files/uris, and will
101  * be passed to the 'open' emitter by array of GFile*'s.
102  * @par
103  * (c) If a Cgu::Application object is constructed with the
104  * G_APPLICATION_HANDLES_COMMAND_LINE flag set, then calling the
105  * Cgu::Application::run() method will cause the 'command_line'
106  * emitter to emit. All the command line parameters not handled
107  * locally in the new instance will be passed on, and they can be
108  * obtained via the GApplicationCommandLine argument of the
109  * 'command_line' emitter.
110  *
111  * Prior to glib-2.40/gtk+-3.12 g_application_run() (and so
112  * Cgu::Application::run()) does not consume any recognised glib/gtk+
113  * options such as \--display. Such options can be stripped out (and
114  * acted on by gtk+) by calling gtk_init() before constructing the
115  * Cgu::Application object (but gtk_init() does not need to be called
116  * for any other purpose), or by using the GOptionGroup/GOptionEntry
117  * interface.
118  *
119  * There is no emitter provided for GApplication's 'shutdown' and
120  * 'handle-local-options' signals ('handle-local-options' is provided
121  * from glib-2.40 onwards). There is only very rarely a need to use
122  * the 'shutdown' signal in C++ code, which should not normally keep
123  * naked resources (the question whether clean-up on shutdown is
124  * needed is usually not just answered by whether we are in the first
125  * instance of the program to start, but whether particular state has
126  * accumulated in consequence of the program running, which is a
127  * question best answered by the object(s) managing the state, say on
128  * destruction on stack unwinding); but where the 'shutdown' signal is
129  * useful, GApplication's C level API is available via
130  * Cgu::Application::get_g_app(). If using 'handle-local-options' you
131  * will normally have hooked into local option handling using
132  * g_application_add_main_option_entries() or
133  * g_application_add_option_group(). In that case the option
134  * handling, including connecting where relevent to
135  * 'handle-local-options', is also best done at GApplication's C level
136  * by obtaining the GApplication object with
137  * Cgu::Application::get_g_app().
138  *
139  * There is little in this class that cannot also be done using the
140  * @ref prog_presenterAnchor "Cgu::prog_present" interface, which has
141  * the advantage of being more portable (@ref prog_presenterAnchor
142  * "Cgu::prog_present" does not depend on GTK+3), but this class is
143  * more convenient to use where a program requires multiple main
144  * application windows which can be independently opened and any of
145  * which are to keep the program alive until the last one is closed,
146  * or if an application menu is to be provided for, say, the gnome
147  * shell.
148  *
149  * Cgu::Application objects are not singletons. It is possible to
150  * drop an Application object out of scope or destroy it in some other
151  * way after closing or removing all its windows, then construct
152  * another with a different flag and then call run() on the second one
153  * (although it would be a curious application that wanted to do so).
154  * It is also possible, but even more off-the-wall, to have two
155  * Application objects in existence in the same process at the same
156  * time provided different dbus identifiers are supplied to the
157  * constructor for each, although run() may only be called on one of
158  * them at any one time. However, this is something of a curiosity:
159  * in nearly all cases an application will only have one
160  * Cgu::Application object, since the main purpose of Cgu::Application
161  * is to facilitate single instance programs.
162  *
163  * Cgu::WinBase objects, and so Cgu::Application, can be used with
164  * widget heirarchies or top level windows created using GtkBuilder.
165  * See @ref GtkBuilder for particulars about that.
166  *
167  * Here is a compilable example, demonstrating the use of the
168  * GApplicationFlags options. It uses a GtkApplicationWindow object,
169  * as provided by GTK+ >= 3.4, so that it can provide an application
170  * menu for, say, the gnome shell. For earlier versions of GTK+-3,
171  * the Message class can be constructed from a standard GtkWindow
172  * object, and the application and window menu code in the startup()
173  * callback can be omitted.
174  *
175  * @code
176  * #include <iostream>
177  * #include <ostream>
178  * #include <string>
179  * #include <list>
180  *
181  * #include <gtk/gtk.h>
182  *
183  * #include <c++-gtk-utils/callback.h>
184  * #include <c++-gtk-utils/application.h>
185  * #include <c++-gtk-utils/window.h>
186  * #include <c++-gtk-utils/shared_handle.h>
187  * #include <c++-gtk-utils/gobj_handle.h>
188  *
189  * // SETUP HERE: uncomment the flag to be tested:
190  *
191  * //const GApplicationFlags app_flag = G_APPLICATION_FLAGS_NONE;
192  * const GApplicationFlags app_flag = G_APPLICATION_HANDLES_OPEN;
193  * //const GApplicationFlags app_flag = G_APPLICATION_HANDLES_COMMAND_LINE;
194  *
195  * using namespace Cgu;
196  *
197  * // *** Demonstration Message class ***
198  *
199  * extern "C" void message_button_clicked(GtkWidget*, void*);
200  *
201  * class Message: public Cgu::WinBase {
202  * public:
203  * friend void message_button_clicked(GtkWidget*, void*);
204  * Message(const char* text, GApplication* app);
205  * };
206  *
207  * // *** for Message menu actions ***
208  *
209  * extern "C" {
210  * static void win_beep(GSimpleAction*, GVariant*, void*) {
211  * gdk_beep();
212  * }
213  *
214  * static GActionEntry win_entries[] = {
215  * { "beep", win_beep, NULL, NULL, NULL },
216  * };
217  * } // extern "C"
218  *
219  * // *** Message callbacks ***
220  *
221  * void message_button_clicked(GtkWidget* w, void*) {
222  * std::cout << "Clicked" << std::endl;
223  * }
224  *
225  * // *** Message implementation ***
226  *
227  * Message::Message(const char* text, GApplication* app):
228  * WinBase("Message", 0, false, 0,
229  * GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(app)))) {
230  * g_action_map_add_action_entries(G_ACTION_MAP(get_win()),
231  * win_entries,
232  * G_N_ELEMENTS(win_entries),
233  * static_cast<void*>(0));
234  * GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
235  * gtk_box_set_homogeneous(GTK_BOX(box), false);
236  * gtk_container_add(GTK_CONTAINER(get_win()), box);
237  * GtkWidget* label = gtk_label_new(text);
238  * gtk_box_pack_start(GTK_BOX(box), label,
239  * true, false, 0);
240  * GtkWidget* button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
241  * gtk_box_pack_start(GTK_BOX(box), button_box,
242  * false, false, 0);
243  * GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_OK);
244  * gtk_container_add(GTK_CONTAINER(button_box), button);
245  * g_signal_connect(G_OBJECT(button), "clicked",
246  * G_CALLBACK(message_button_clicked), 0);
247  * gtk_widget_set_can_default(button, true);
248  * }
249  *
250  * // *** for application actions ***
251  *
252  * extern "C" {
253  * static void app_beep(GSimpleAction*, GVariant*, void*) {
254  * gdk_beep();
255  * }
256  *
257  * static void app_quit(GSimpleAction*, GVariant*, void* data) {
258  * Cgu::Application* app = static_cast<Cgu::Application*>(data);
259  * std::list<Cgu::WinBase*> wins = app->get_windows();
260  * for (std::list<Cgu::WinBase*>::iterator iter = wins.begin(); iter != wins.end(); ++iter) {
261  * delete *iter; // this will also remove the Message object from
262  * // the Cgu::Application object
263  * }
264  * }
265  *
266  * static GActionEntry app_entries[] = {
267  * { "beep", app_beep, NULL, NULL, NULL },
268  * { "quit", app_quit, NULL, NULL, NULL },
269  * };
270  * } // extern "C"
271  *
272  * // *** application callbacks ***
273  *
274  * namespace {
275  *
276  * void startup(Cgu::Application* app) {
277  * std::cout << "startup() called" << std::endl;
278  *
279  * g_action_map_add_action_entries(G_ACTION_MAP(app->get_g_app()),
280  * app_entries,
281  * G_N_ELEMENTS(app_entries),
282  * app);
283  * Cgu::GobjHandle<GMenu> app_menu(g_menu_new());
284  * g_menu_append(app_menu, "Beep", "app.beep");
285  * g_menu_append(app_menu, "_Quit", "app.quit");
286  * gtk_application_set_app_menu(GTK_APPLICATION(app->get_g_app()),
287  * G_MENU_MODEL(app_menu.get()));
288  *
289  * Cgu::GobjHandle<GMenu> win_menu(g_menu_new());
290  * Cgu::GobjHandle<GMenu> sub_menu(g_menu_new());
291  * g_menu_append_submenu(win_menu, "Menu1", G_MENU_MODEL(sub_menu.get()));
292  * g_menu_append(sub_menu, "More beep", "win.beep"); // see Message::Message() for actions
293  * gtk_application_set_menubar(GTK_APPLICATION(app->get_g_app()),
294  * G_MENU_MODEL(win_menu.get()));
295  * }
296  *
297  * void activate(Cgu::Application* app) {
298  * std::cout << "activate() called" << std::endl;
299  *
300  * // probably if no arguments are passed, only one window is wanted,
301  * // which is now to present itself if it already exists: comment this
302  * // 'if' block out if a new window is to be added on each occasion
303  * // the program is started
304  * if (app->get_win_count() > 0) {
305  * gtk_window_present(app->get_windows().front()->get_win());
306  * return;
307  * }
308  * WinBase* dialog = new Message("This is a message", app->get_g_app());
309  * app->add(dialog);
310  * dialog->show_all();
311  * }
312  *
313  * void command_line(Cgu::Application* app, GApplicationCommandLine* cl, gint&) {
314  * std::cout << "command_line() called" << std::endl;
315  *
316  * // probably if the G_APPLICATION_HANDLES_COMMAND_LINE flag is set,
317  * // only one window is wanted, which is now to present itself if it
318  * // already exists: comment this 'if' block out if a new window is to
319  * // be added on each occasion the program is started
320  * if (app->get_win_count() > 0) {
321  * gtk_window_present(app->get_windows().front()->get_win());
322  * return;
323  * }
324  * std::string text("Command line options are:\n");
325  * int argc = 0;
326  * gchar** argv = g_application_command_line_get_arguments(cl, &argc);
327  * for (int count = 0; count < argc; ++count) {
328  * try {
329  * text += argv[count];
330  * text += '\n';
331  * }
332  * catch (...) {
333  * g_strfreev(argv);
334  * throw; // exceptions will be consumed by the callback handler and
335  * // a g_critical warning issued, but let's not leak memory
336  * }
337  * }
338  * g_strfreev(argv);
339  * WinBase* dialog = new Message(text.c_str(), app->get_g_app());
340  * app->add(dialog);
341  * dialog->show_all();
342  * }
343  *
344  * void open(Cgu::Application* app, std::pair<GFile**, gint> files, gchar*) {
345  * std::cout << "open() called" << std::endl;
346  *
347  * // probably if the G_APPLICATION_HANDLES_OPEN flag is set and an
348  * // argument is passed, the adding of a new window is wanted on each
349  * // occasion the program is started
350  * std::string text("Files are:\n");
351  * for (int count = 0; count < files.second; ++count) {
352  * GcharScopedHandle uri(g_file_get_uri(files.first[count]));
353  * text += uri;
354  * text += '\n';
355  * }
356  * WinBase* dialog = new Message(text.c_str(), app->get_g_app());
357  * app->add(dialog);
358  * dialog->show_all();
359  * }
360  *
361  * } // unnamed namespace
362  *
363  * // *** main() ***
364  *
365  * int main(int argc, char* argv[]) {
366  *
367  * // gtk_init() is only relevant for the purposes of stripping out
368  * // and acting on glib/gtk+ recognised options, either where
369  * // glib < 2.40 and gtk+ < 3.12 are used or where you want to pass
370  * // no arguments to Cgu::Application::run() when
371  * // G_APPLICATION_FLAGS_NONE is set in order to ensure that the
372  * // program does not abort with unrecognised options -
373  * // gtk_application_new() (and so the Cgu::Application constructor)
374  * // will call g_type_init() if the type system needs initialization
375  * gtk_init(&argc, &argv);
376  *
377  * Application app("my_prog", app_flag);
378  * app.startup.connect(Callback::make(startup));
379  * app.activate.connect(Callback::make(activate));
380  * app.command_line.connect(Callback::make(command_line));
381  * app.open.connect(Callback::make(open));
382  * if (app_flag == G_APPLICATION_FLAGS_NONE)
383  * return app.run(0, 0);
384  * else
385  * return app.run(argc, argv);
386  * }
387  * @endcode
388  *
389  * One thing to note about this example is that the callbacks
390  * connected to the Cgu::Application object execute in the first
391  * instance of the program to be started (the instance in which
392  * Cgu::Application::run() blocks). If the program is then restarted,
393  * Cgu::Application::run() returns in the new program instance as soon
394  * as it has invoked the existing instance via dbus, following which
395  * the new program instance exits, so immediately disposing of the
396  * Cgu::Application object and callbacks which were constructed on the
397  * restart. This is a feature of GApplication/GtkApplication: given
398  * the overhead of starting a new process, and that restarting a
399  * single-instance program is in any event an exceptional event, any
400  * additional overhead created by constructing and then destroying the
401  * Cgu::Application object and callbacks in the new instance is
402  * trivial. (As mentioned above, from glib-2.40 the
403  * 'handle-local-options' signal can be used to hook into the
404  * GApplication object constructed in the new program instance, but
405  * this is intended to assist option parsing in the new instance.)
406  */
407 
408 class Application {
409 
410  std::list<WinBase*> win_list;
412 
413  void* reserved; // for future use
414 
415  // Application objects cannot be copied
416  Application(const Application&);
417  Application& operator=(const Application&);
418 public:
419 
420  typedef std::list<WinBase*>::size_type size_type;
421 
422 /**
423  * This SafeEmitterArg object emits (and so executes any connected
424  * callback) when the underlying GApplication object emits its
425  * @a activate signal. The argument passed to the emitter's
426  * callback(s) is a pointer to the Cgu::Application object.
427  * @note When the callback executes, thread cancellation is blocked,
428  * and any exceptions are consumed with a g_critical message issued.
429  * The callback will always execute in the main GUI thread when
430  * executed in response to the run() method. Because a SafeEmitterArg
431  * object is used, the emitter object itself is thread safe.
432  *
433  * Since 1.2.12
434  */
436 
437 /**
438  * This SafeEmitterArg object emits (and so executes any connected
439  * callback) when the underlying GApplication object emits its @a
440  * startup signal (which, unless the G_APPLICATION_NON_UNIQUE flag has
441  * been set in the Cgu::Application object's constructor, it will
442  * normally do once, on the first occasion that run() is called). The
443  * argument passed to the emitter's callback(s) is a pointer to the
444  * Cgu::Application object. This signal can be used to set up a
445  * desktop application menu, or a menu bar for WinBase objects
446  * constructed from a GtkApplicationWindow object.
447  * @note When the callback executes, thread cancellation is blocked,
448  * and any exceptions are consumed with a g_critical message issued.
449  * The callback will always execute in the main GUI thread when
450  * executed in response to the run() method. Because a SafeEmitterArg
451  * object is used, the emitter object itself is thread safe.
452  *
453  * Since 1.2.12
454  */
456 
457 /**
458  * This SafeEmitterArg object emits (and so executes any connected
459  * callback) when the underlying GApplication object emits its
460  * @a command-line signal. The second argument passed to the
461  * emitter's callback(s) is the one passed by that signal, that is to
462  * say the arguments are:
463  *
464  * first: a pointer to the Cgu::Application object.
465  *
466  * second: a pointer to a GApplicationCommandLine object representing
467  * the passed command line (this is owned by gio and should not be
468  * unref'ed unless it has previously been explicitly ref'ed to keep
469  * the GApplicationCommandLine object alive even after the connected
470  * callback has returned).
471  *
472  * third: a gint& reference to which the value to be returned to the
473  * GApplication's command-line signal can be passed: if no value is
474  * assigned to it or no callback has been attached to the signal, 0
475  * will be returned, except that if an exception from a callback is
476  * consumed, -1 will be returned. If more than one callback is
477  * attached to the signal and no exception is consumed, the last one
478  * to assign a value will be have its value returned.
479  *
480  * @note 1. When the callback executes, thread cancellation is
481  * blocked, and any exceptions are consumed with a g_critical message
482  * issued and a return value of -1 set. The callback will always
483  * execute in the main GUI thread when executed in response to the
484  * run() method. Because a SafeEmitterArg object is used, the emitter
485  * object itself is thread safe.
486  *
487  * @note 2. Callbacks for this emitter, which would take more than one
488  * unbound argument, are not available if the library was configured
489  * with the \--without-type-tuple-args option.
490  *
491  * Since 1.2.12
492  */
494 
495 /**
496  * This SafeEmitterArg object emits (and so executes any connected
497  * callback) when the underlying GApplication object emits its @a open
498  * signal. The second and third arguments passed to the emitter's
499  * callback(s) are those passed by that signal, that is to say the
500  * arguments are:
501  *
502  * first: a pointer to the Cgu::Application object.
503  *
504  * second: a std::pair object where the first member is an array of
505  * GFile*'s representing the files/uris passed as arguments, and the
506  * second member is the length of that array (the array is owned by
507  * gio and should not be freed).
508  *
509  * third: a gchar* argument comprising the text of the "hint" (this is
510  * owned by gio and should not be freed).
511  *
512  * @note 1. When the callback executes, thread cancellation is
513  * blocked, and any exceptions are consumed with a g_critical message
514  * issued. The callback will always execute in the main GUI thread
515  * when executed in response to the run() method. Because a
516  * SafeEmitterArg object is used, the emitter object itself is thread
517  * safe.
518  *
519  * @note 2. Callbacks for this emitter, which would take more than one
520  * unbound argument, are not available if the library was configured
521  * with the \--without-type-tuple-args option.
522  *
523  * Since 1.2.12
524  */
526 
527 /**
528  * Add a Cgu::WinBase object to the Cgu::Application object, and so
529  * also add its managed GtkWindow object to the GtkApplication object.
530  * Any Cgu::WinBase object passed to this method should not normally
531  * be modal and must have been constructed on free store with the new
532  * expression. It is passed by pointer because it will be self-owning
533  * (its lifetime would normally be determined by user action, not by
534  * the program), although if it is removed from this Cgu::Application
535  * object with remove(), the delete expression can (and normally
536  * should) be called on it. If a delete event occurs on the WinBase
537  * object so that the WinBase object destroys itself (say, by the user
538  * clicking on the window's close/delete button), or it destroys
539  * itself in some other way (say, by calling the WinBase::close()
540  * method), it will automatically be removed from this Application
541  * object without further action being necessary. The WinBase::exec()
542  * method should never be called on a WinBase object which has been
543  * added to an Application object. The Cgu::Application class, and
544  * thus this method, does not employ mutexes to make it thread safe,
545  * as there should never be a reason to call Cgu::Application methods
546  * in other than the main GUI thread.
547  * @param win The Cgu::WinBase object to be added.
548  * @exception std::bad_alloc This method might throw std::bad_alloc if
549  * memory is exhausted and the system throws in that case, in which
550  * case the WinBase object passed in will not be added. If such an
551  * exception is thrown and program recovery is to be attempted (which
552  * is usually a waste of time as glib/gtk+ will terminate the program
553  * if unable to obtain memory from the operating system), it would be
554  * best to delete the Cgu::WinBase object passed in and start again.
555  * An alternative is to show the window to the user for the user to
556  * dispose of (windows passed to this method are self-owning); but if
557  * that is done note that if the contained GtkWindow object is a
558  * GtkApplicationWindow object, then it will already be associated
559  * with a GtkApplication object when constructed, so it would usually
560  * be best also to call gtk_application_remove_window() on it via
561  * Cgu::Application::get_g_app() and Cgu::WinBase::get_win() before or
562  * after it is shown so the Cgu::Application and GtkApplication
563  * objects remain in sync.
564  * @note As well as this method only being called in the main GUI
565  * thread, if the program by which it is called calls GTK+ directly in
566  * more than one thread and thus employs
567  * gdk_threads_enter()/gdk_threads_leave() (rather than, say,
568  * Cgu::Notifier or Cgu::Callback::post()), it must be surrounded by
569  * gdk_threads_enter()/gdk_threads_leave() if called otherwise than in
570  * a GTK+ signal handler. (The best approach however is for a program
571  * only to address GTK+/GDK in the main program thread, for which
572  * purpose this library provides various functions and classes for
573  * inter-thread communication, such as Cgu::Notifier and
574  * Cgu::Callback::post(): see @ref Threading for particulars about
575  * GTK+ thread safety.)
576  *
577  * Since 1.2.12
578  */
579  void add(Cgu::WinBase* win);
580 
581 /**
582  * Remove a Cgu::WinBase object from the Cgu::Application object, and
583  * so also remove its managed GtkWindow object from the GtkApplication
584  * object. This method will not throw assuming that merely iterating
585  * through a list does not throw (as it would not on any sane
586  * implementation). The Cgu::Application class, and thus this method,
587  * does not employ mutexes to make it thread safe, as there should
588  * never be a reason to call Cgu::Application methods in other than
589  * the main GUI thread. Calling this method does not destroy the
590  * WinBase object.
591  * @param win The Cgu::WinBase object to be removed.
592  * @return true if the Cgu::WinBase object was found in the
593  * Cgu::Application object and so removed, otherwise false.
594  * @note As well as this method only being called in the main GUI
595  * thread, if the program by which it is called calls GTK+ directly in
596  * more than one thread and thus employs
597  * gdk_threads_enter()/gdk_threads_leave() (rather than, say,
598  * Cgu::Notifier or Cgu::Callback::post()), it must be surrounded by
599  * gdk_threads_enter()/gdk_threads_leave() if called otherwise than in
600  * a GTK+ signal handler. (The best approach however is for a program
601  * only to address GTK+/GDK in the main program thread, for which
602  * purpose this library provides various functions and classes for
603  * inter-thread communication, such as Cgu::Notifier and
604  * Cgu::Callback::post(): see @ref Threading for particulars about
605  * GTK+ thread safety.)
606  *
607  * Since 1.2.12
608  */
609  bool remove(Cgu::WinBase* win);
610 
611 /**
612  * Calls g_application_run() in respect of the underlying
613  * GtkApplication object, so invoking some of the Cgu::Application
614  * class's emitters (normally in the first instance of the program to
615  * be started): the exact behaviour depends on the GApplication flags
616  * passed to the constructor and is explained in the introductory
617  * remarks above. This method is thread safe (although that is
618  * irrelevant to its purpose) and will not throw. In addition, if a
619  * callback connected to an emitter throws, the exception is consumed
620  * and a g_critical warning issued. This function blocks until the
621  * last WinBase object associated with this Application object is
622  * destroyed or removed.
623  * @param argc The argc from main() or 0.
624  * @param argv The argv from main() or 0.
625  * @return The exit status from g_application_run().
626  *
627  * Since 1.2.12
628  */
629  int run(int argc, char** argv) {
630  return g_application_run((GApplication*)app.get(), argc, argv);
631  }
632 
633 /**
634  * Get the underlying GApplication object (note, not the
635  * GtkApplication object, although the GApplication object can be cast
636  * to GtkApplication), so allowing any of gio's g_application_*()
637  * functions to be applied to it. In normal usage it will not be
638  * necessary to call this method. This method is thread safe and will
639  * not throw.
640  * @return The underlying GApplication object.
641  *
642  * Since 1.2.12
643  */
644  GApplication* get_g_app() const {return (GApplication*)app.get();}
645 
646 /**
647  * Get the list of Cgu::WinBase objects associated with the
648  * application. The Cgu::Application class, and thus this method,
649  * does not employ mutexes to make it thread safe, as there should
650  * never be a reason to call Cgu::Application methods in other than
651  * the main GUI thread.
652  * @return A list of the top level Cgu::WinBase objects associated
653  * with the application, which will appear in the order in which they
654  * were added. If you need to access these, you will probably want to
655  * do a dynamic_cast or static_cast to the child type.
656  * @exception std::bad_alloc This method might throw std::bad_alloc if
657  * memory is exhausted and the system throws in that case.
658  *
659  * Since 1.2.12
660  */
661  std::list<Cgu::WinBase*> get_windows() const {return win_list;}
662 
663 /**
664  * Gets the current count of Cgu::WinBase objects associated with this
665  * Cgu::Application object. When it reaches 0, the application will
666  * normally end (but this can be prevented by calling
667  * g_application_hold()/g_application_release() on the GApplication
668  * object returned by get_g_app()). This method can be used in the
669  * callback of one of this class's emitters to determine whether this
670  * is the first instance of a program to be started (assuming the
671  * first instance calls add() to bring up a window), because in that
672  * case it will return 0 until add() is called. Calling
673  * get_windows().size() will give the same result, but using this
674  * method is more efficient as it will avoid a copy of the list of
675  * windows. This method will not throw assuming that calling
676  * std::list::size() does not throw (as it would not on any sane
677  * implementation). The Cgu::Application class, and thus this method,
678  * does not employ mutexes to make it thread safe, as there should
679  * never be a reason to call Cgu::Application methods in other than
680  * the main GUI thread.
681  * @return The number of Cgu::WinBase objects currently associated
682  * with this Cgu::Application object.
683  *
684  * Since 1.2.12
685  */
686  size_type get_win_count() const {return win_list.size();}
687 
688 /**
689  * This constructor will, via gtk_application_new(), cause
690  * g_type_init() to be called. If any GTK+ functions are to be called
691  * before an Application object is constructed, g_type_init() (or
692  * gtk_init()) must be called explicitly.
693  * @param prog_name An identifier name. This can comprise any valid
694  * ASCII characters "[A-Z][a-z][0-9]_-", although it is usually best
695  * to pass the program name. Unlike with gtk_application_new(), it
696  * does not need to comprise a full dbus bus name: this method will
697  * construct its own valid dbus bus name from prog_name in the org.cgu
698  * domain.
699  * @param flags The GApplicationFlags to be passed to the
700  * Cgu::Application object. This class does not contain its own
701  * sub-class of GApplication to customize this, but adopts the
702  * behaviour of GtkApplication. That behaviour is explained in the
703  * introductory remarks.
704  * @exception Cgu::ApplicationNameError This exception will be thrown
705  * if the prog_name parameter does not meet the requirements referred
706  * to above.
707  * @exception std::bad_alloc This method might throw std::bad_alloc if
708  * memory is exhausted and the system throws in that case.
709  *
710  * Since 1.2.12
711  */
712  Application(const char* prog_name, GApplicationFlags flags);
713 
714 /**
715  * From version 1.2.13, as a safety feature the destructor removes any
716  * remaining WinBase objects associated with this Application object
717  * (this would only be relevant if the user constructs the Application
718  * object on free store, and then deletes it while the run() method is
719  * still blocking for the purpose of constructing a different
720  * Application object, but does not call the remove() method on all
721  * associated WinBase objects before doing so: constructing an
722  * Application object on free store in this way would be highly
723  * unusual however).
724  *
725  * Since 1.2.13
726  */
727  ~Application() {while (!win_list.empty()) remove(win_list.front());}
728 
729 /* Only has effect if --with-glib-memory-slices-compat or
730  * --with-glib-memory-slices-no-compat option picked */
732 };
733 
734 #endif // GTK_CHECK_VERSION
735 #endif // CGU_USE_GTK
736 
737 } // namespace Cgu
738 
739 #endif // CGU_APPLICATION_H
Cgu::WinBase
This is a class for managing the lifetime of top level widgets.
Definition: window.h:225
Cgu
Definition: application.h:45
Cgu::Application::remove
bool remove(Cgu::WinBase *win)
Cgu::ApplicationNameError
This class is thrown when the program id name passed to the constructor of Cgu::Application is invali...
Definition: application.h:55
Cgu::Application::~Application
~Application()
Definition: application.h:727
Cgu::GobjHandle< GtkApplication >
Cgu::Application
This is a class for constructing and managing GtkApplication objects.
Definition: application.h:408
Cgu::ApplicationNameError::what
virtual const char * what() const
Definition: application.h:56
Cgu::Application::add
void add(Cgu::WinBase *win)
Cgu::Application::startup
Cgu::SafeEmitterArg< Cgu::Application * > startup
Definition: application.h:455
gobj_handle.h
Cgu::Application::open
Cgu::SafeEmitterArg< TypeTuple< Cgu::Application *, std::pair< GFile **, gint >, gchar * > > open
Definition: application.h:525
Cgu::Application::get_windows
std::list< Cgu::WinBase * > get_windows() const
Definition: application.h:661
param.h
Cgu::SafeEmitterArg< Cgu::Application * >
Cgu::GobjHandle::get
T * get() const
Definition: gobj_handle.h:265
CGU_GLIB_MEMORY_SLICES_FUNCS
#define CGU_GLIB_MEMORY_SLICES_FUNCS
Definition: cgu_config.h:84
Cgu::Application::get_win_count
size_type get_win_count() const
Definition: application.h:686
Cgu::Application::size_type
std::list< WinBase * >::size_type size_type
Definition: application.h:420
Cgu::Application::get_g_app
GApplication * get_g_app() const
Definition: application.h:644
window.h
Cgu::Application::command_line
Cgu::SafeEmitterArg< TypeTuple< Cgu::Application *, GApplicationCommandLine *, gint & > > command_line
Definition: application.h:493
Cgu::Application::run
int run(int argc, char **argv)
Definition: application.h:629
emitter.h
This file provides a thread-safe signal/slot mechanism, with automatic disconnection.
cgu_config.h
Cgu::Application::activate
Cgu::SafeEmitterArg< Cgu::Application * > activate
Definition: application.h:435