c++-gtk-utils
application.h
Go to the documentation of this file.
1 /* Copyright (C) 2011 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 
32 #include <gio/gio.h>
33 #include <gtk/gtk.h>
34 
36 #include <c++-gtk-utils/window.h>
37 #include <c++-gtk-utils/emitter.h>
39 
40 namespace Cgu {
41 
42 #if defined(DOXYGEN_PARSING) || GTK_CHECK_VERSION(2,99,0)
43 
44 /**
45  * @class Cgu::ApplicationNameError application.h c++-gtk-utils/application.h
46  * @brief This class is thrown when the program id name passed to the
47  * constructor of Cgu::Application is invalid.
48  */
49 struct ApplicationNameError: public std::exception {
50  virtual const char* what() const throw() {return "ApplicationNameError\n";}
51 };
52 
53 /**
54  * @class Cgu::Application application.h c++-gtk-utils/application.h
55  * @brief This is a class for constructing and managing GtkApplication
56  * objects.
57  *
58  * @details It is available since version 2.0.0-rc2. It is only
59  * compiled in with a GTK+3 installation.
60  *
61  * In typical usage, a Cgu::Application object is created in main(),
62  * and then a callback is attached to the 'activate', 'command_line'
63  * or 'open' emitter, depending on the flag passed to the Application
64  * object's constructor. The run() method of the Application object
65  * is then called, and a window deriving from Cgu::WinBase is
66  * constructed in the callback and added to the Application object or,
67  * if the program is a single instance program with only one main
68  * window and an instance is already running, a function is called to
69  * present that window.
70  *
71  * The gio/gtk+ documentation at the time of writing does not explain
72  * key concepts, and in particular how the GtkApplication sub-class
73  * interacts with GApplication's g_application_run(). Here is an
74  * explanation:
75  *
76  * (a) If a Cgu::Application object is constructed with the
77  * G_APPLICATION_FLAGS_NONE flag set, then calling the
78  * Cgu::Application::run() method (which hands off to
79  * g_application_run()) will cause the 'activate' emitter to emit. No
80  * command line parameter should be passed to the run method (argc
81  * should be 0 or 1), otherwise GtkApplication will cause the start-up
82  * to abort. Unlike with gtk_main(), g_application_run() (and so
83  * Cgu::Application::run()) does not consume any recognised glib/gtk+
84  * options, such as --display, but regards these as application
85  * parameters. Such stripping out can be achieved by calling
86  * gtk_init() before constructing the Cgu::Application object (but
87  * gtk_init() does not need to be called for any other purpose), or by
88  * using the GOptionGroup/GOptionEntry interface.
89  * g_application_run(), and so Cgu::Application::run(), can be called
90  * with argc and argv set to 0, and that is generally the best
91  * approach if the G_APPLICATION_FLAGS_NONE flag is set.
92  *
93  * (b) If a Cgu::Application object is constructed with the
94  * G_APPLICATION_HANDLES_OPEN flag set, then calling the
95  * Cgu::Application::run() method will cause the 'activate' emitter to
96  * emit if no command line parameters were provided when the program
97  * was started (that is, if argc is 0 or 1), or cause the 'open'
98  * emitter to emit if parameters are passed (argc > 1). Such
99  * parameters will be construed as files/uris, and will be passed to
100  * the 'open' emitter by array of GFile*'s. Unlike with gtk_main(),
101  * g_application_run() (and so Cgu::Application::run()) does not
102  * consume any recognised glib/gtk+ options, such as --display, but
103  * regards these as application parameters and so as file/uri names.
104  * Such stripping out can be achieved by calling gtk_init() before
105  * constructing the Cgu::Application object (but gtk_init() does not
106  * need to be called for any other purpose), or by using the
107  * GOptionGroup/GOptionEntry interface.
108  *
109  * (c) If a Cgu::Application object is constructed with the
110  * G_APPLICATION_HANDLES_COMMAND_LINE flag set, then calling the
111  * Cgu::Application::run() method will cause the 'command_line'
112  * emitter to emit. All the command line parameters will be passed
113  * on, and they can be obtained via the GApplicationCommandLine
114  * argument of the 'command_line' emitter. Unlike with gtk_main(),
115  * g_application_run() (and so Cgu::Application::run()) does not
116  * consume any recognised glib/gtk+ options, such as --display, but
117  * regards these as command line parameters. Such stripping out can
118  * be achieved by calling gtk_init() before constructing the
119  * Cgu::Application object (but gtk_init() does not need to be called
120  * for any other purpose), or by using the GOptionGroup/GOptionEntry
121  * interface.
122  *
123  * There is little in this class that cannot also be done using the
124  * @ref prog_presenterAnchor "Cgu::prog_present" interface, which has
125  * the advantage of being more portable (@ref prog_presenterAnchor
126  * "Cgu::prog_present" does not depend on GTK+3), but this class is
127  * more convenient to use where a program requires multiple main
128  * application windows which can be independently opened and any of
129  * which are to keep the program alive until the last one is closed.
130  *
131  * Cgu::Application objects are not singletons. It is possible to
132  * drop an Application object out of scope or destroy it in some other
133  * way after closing or removing all its windows, then construct
134  * another with a different flag and then call run() on the second one
135  * (although it would be a curious application that wanted to do so).
136  * It is also possible, but even more off-the-wall, to have two
137  * Application objects in existence in the same process at the same
138  * time provided different dbus identifiers are supplied to the
139  * constructor for each, although run() may only be called on one of
140  * them at any one time. However, this is something of a curiosity:
141  * in nearly all cases an application will only have one
142  * Cgu::Application object, since the main purpose of Cgu::Application
143  * is to facilitate single instance programs.
144  *
145  * Cgu::WinBase objects, and so Cgu::Application, can be used with
146  * widget heirarchies or top level windows created using GtkBuilder.
147  * See @ref GtkBuilder for particulars about that.
148  *
149  * Here is a compilable example, demonstrating the use of the
150  * GApplicationFlags options:
151  *
152  * @code
153  * #include <iostream>
154  * #include <ostream>
155  * #include <string>
156  *
157  * #include <gtk/gtk.h>
158  *
159  * #include <c++-gtk-utils/callback.h>
160  * #include <c++-gtk-utils/application.h>
161  * #include <c++-gtk-utils/window.h>
162  * #include <c++-gtk-utils/shared_handle.h>
163  *
164  * // SETUP HERE: uncomment the flag to be tested:
165  *
166  * //const GApplicationFlags app_flag = G_APPLICATION_FLAGS_NONE;
167  * const GApplicationFlags app_flag = G_APPLICATION_HANDLES_OPEN;
168  * //const GApplicationFlags app_flag = G_APPLICATION_HANDLES_COMMAND_LINE;
169  *
170  * using namespace Cgu;
171  *
172  * // *** Demonstration message class ***
173  *
174  * extern "C" void message_button_clicked(GtkWidget*, void*);
175  *
176  * class Message: public Cgu::WinBase {
177  * public:
178  * friend void message_button_clicked(GtkWidget*, void*);
179  * Message(const char* text);
180  * };
181  *
182  * void message_button_clicked(GtkWidget* w, void*) {
183  * std::cout << "Clicked" << std::endl;
184  * }
185  *
186  * Message::Message(const char* text): WinBase{"Message", 0, false} {
187  * GtkWidget* box = gtk_vbox_new(false, 2);
188  * gtk_container_add(GTK_CONTAINER(get_win()), box);
189  * GtkWidget* label = gtk_label_new(text);
190  * gtk_box_pack_start(GTK_BOX(box), label,
191  * true, false, 0);
192  * GtkWidget* button_box = gtk_hbutton_box_new();
193  * gtk_box_pack_start(GTK_BOX(box), button_box,
194  * false, false, 0);
195  * GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_OK);
196  * gtk_container_add(GTK_CONTAINER(button_box), button);
197  * g_signal_connect(G_OBJECT(button), "clicked",
198  * G_CALLBACK(message_button_clicked), 0);
199  * gtk_widget_set_can_default(button, true);
200  * }
201  *
202  * // *** callbacks ***
203  *
204  * void activate(Cgu::Application* app) {
205  * std::cout << "activate() called" << std::endl;
206  *
207  * // probably if no arguments are passed, only one window is wanted,
208  * // which is now to present itself if it already exists: comment this
209  * // 'if' block out if a new window is to be added on each occasion
210  * // the program is started
211  * if (app->get_win_count() > 0) {
212  * gtk_window_present(app->get_windows().front()->get_win());
213  * return;
214  * }
215  * WinBase* dialog = new Message("This is a message");
216  * app->add(dialog);
217  * dialog->show_all();
218  * }
219  *
220  * void startup(Cgu::Application*) {
221  * std::cout << "startup() called" << std::endl;
222  * }
223  *
224  * void command_line(Cgu::Application* app, GApplicationCommandLine* cl, gint&) {
225  * std::cout << "command_line() called" << std::endl;
226  *
227  * // probably if the G_APPLICATION_HANDLES_COMMAND_LINE flag is set,
228  * // only one window is wanted, which is now to present itself if it
229  * // already exists: comment this 'if' block out if a new window is to
230  * // be added on each occasion the program is started
231  * if (app->get_win_count() > 0) {
232  * gtk_window_present(app->get_windows().front()->get_win());
233  * return;
234  * }
235  * std::string text("Command line options are:\n");
236  * int argc = 0;
237  * gchar** argv = g_application_command_line_get_arguments(cl, &argc);
238  * for (int count = 0; count < argc; ++count) {
239  * try {
240  * text += argv[count];
241  * text += '\n';
242  * }
243  * catch (...) {
244  * g_strfreev(argv);
245  * throw; // exceptions will be consumed by the callback handler and
246  * // a g_critical warning issued, but let's not leak memory
247  * }
248  * }
249  * g_strfreev(argv);
250  * WinBase* dialog = new Message(text.c_str());
251  * app->add(dialog);
252  * dialog->show_all();
253  * }
254  *
255  * void open(Cgu::Application* app, std::pair<GFile**, gint> files, gchar*) {
256  * std::cout << "open() called" << std::endl;
257  *
258  * // probably if the G_APPLICATION_HANDLES_OPEN flag is set and an
259  * // argument is passed, the adding of a new window is wanted on each
260  * // occasion the program is started
261  * std::string text("Files are:\n");
262  * for (int count = 0; count < files.second; ++count) {
263  * GcharScopedHandle uri(g_file_get_uri(files.first[count]));
264  * text += uri;
265  * text += '\n';
266  * }
267  * WinBase* dialog = new Message(text.c_str());
268  * app->add(dialog);
269  * dialog->show_all();
270  * }
271  *
272  * // *** main() ***
273  *
274  * int main(int argc, char* argv[]) {
275  *
276  * // gtk_init() is only relevant for the purposes of stripping out
277  * // glib/gtk+ recognised options - gtk_application_new() (and so the
278  * // Cgu::Application constructor) will call g_type_init() if the type
279  * // system needs initialization
280  * gtk_init(&argc, &argv);
281  *
282  * Application app{"my_prog", app_flag};
283  * app.activate.connect(Callback::make(activate));
284  * app.startup.connect(Callback::make(startup));
285  * app.command_line.connect(Callback::make(command_line));
286  * app.open.connect(Callback::make(open));
287  * if (app_flag == G_APPLICATION_FLAGS_NONE)
288  * app.run(0, 0);
289  * else
290  * app.run(argc, argv);
291  *
292  * return 0;
293  * }
294  * @endcode
295  *
296  * One thing to note about this example is that the callbacks
297  * connected to the Cgu::Application object always execute in the
298  * first instance of the program to be started (the instance in which
299  * Cgu::Application::run() blocks). If the program is then restarted,
300  * Cgu::Application::run() returns in the new program instance as soon
301  * as it has invoked the existing instance via dbus, following which
302  * the new program instance exits, so immediately disposing of the
303  * Cgu::Application object and callbacks which were constructed on the
304  * restart. This is a feature of GApplication/GtkApplication: given
305  * the overhead of starting a new process, and that restarting a
306  * single-instance program is in any event an exceptional event, any
307  * additional overhead created by constructing and then destroying the
308  * Cgu::Application object and callbacks in the new instance is
309  * trivial.
310  */
311 
312 class Application {
313 
314  std::list<WinBase*> win_list;
316 
317  void* reserved; // for future use
318 public:
319 
320  typedef std::list<WinBase*>::size_type size_type;
321 
322 /**
323  * This class cannot be copied. The copy constructor is deleted.
324  */
325  Application(const Application&) = delete;
326 
327 /**
328  * This class cannot be copied. The assignment operator is deleted.
329  */
330  Application& operator=(const Application&) = delete;
331 
332 /**
333  * This SafeEmitterArg object emits (and so executes any connected
334  * callback) when the underlying GApplication object emits its
335  * @a activate signal. The argument passed to the emitter's
336  * callback(s) is a pointer to the Cgu::Application object.
337  * @note When the callback executes, thread cancellation is blocked,
338  * and any exceptions are consumed with a g_critical message issued.
339  * The callback will always execute in the main GUI thread when
340  * executed in response to the run() method. Because a SafeEmitterArg
341  * object is used, the emitter object itself is thread safe.
342  *
343  * Since 2.0.0-rc2
344  */
346 
347 /**
348  * This SafeEmitterArg object emits (and so executes any connected
349  * callback) when the underlying GApplication object emits its
350  * @a startup signal. The argument passed to the emitter's callback(s)
351  * is a pointer to the Cgu::Application object. However, you usually
352  * won't need to do anything in response to the @a startup signal.
353  * @note When the callback executes, thread cancellation is blocked,
354  * and any exceptions are consumed with a g_critical message issued.
355  * The callback will always execute in the main GUI thread when
356  * executed in response to the run() method. Because a SafeEmitterArg
357  * object is used, the emitter object itself is thread safe.
358  *
359  * Since 2.0.0-rc2
360  */
362 
363 /**
364  * This SafeEmitterArg object emits (and so executes any connected
365  * callback) when the underlying GApplication object emits its
366  * @a command-line signal. The second argument passed to the
367  * emitter's callback(s) is the one passed by that signal, that is to
368  * say the arguments are:
369  *
370  * first: a pointer to the Cgu::Application object.
371  *
372  * second: a pointer to a GApplicationCommandLine object representing
373  * the passed command line (this is owned by gio and should not be
374  * unref'ed).
375  *
376  * third: a gint& reference to which the value to be returned to the
377  * GApplication's command-line signal can be passed: if no value is
378  * assigned to it or no callback has been attached to the signal, 0
379  * will be returned, except that if an exception from a callback is
380  * consumed, -1 will be returned. If more than one callback is
381  * attached to the signal and no exception is consumed, the last one
382  * to assign a value will be have its value returned.
383  *
384  * @note When the callback executes, thread cancellation is blocked,
385  * and any exceptions are consumed with a g_critical message issued
386  * and a return value of -1 set. The callback will always execute in
387  * the main GUI thread when executed in response to the run() method.
388  * Because a SafeEmitterArg object is used, the emitter object itself
389  * is thread safe.
390  *
391  * Since 2.0.0-rc2
392  */
394 
395 /**
396  * This SafeEmitterArg object emits (and so executes any connected
397  * callback) when the underlying GApplication object emits its @a open
398  * signal. The second and third arguments passed to the emitter's
399  * callback(s) are those passed by that signal, that is to say the
400  * arguments are:
401  *
402  * first: a pointer to the Cgu::Application object.
403  *
404  * second: a std::pair object where the first member is an array of
405  * GFile*'s representing the files/uris passed as arguments, and the
406  * second member is the length of that array (the array is owned by
407  * gio and should not be freed).
408  *
409  * third: a gchar* argument comprising the text of the "hint" (this is
410  * owned by gio and should not be freed).
411  *
412  * @note When the callback executes, thread cancellation is blocked,
413  * and any exceptions are consumed with a g_critical message issued.
414  * The callback will always execute in the main GUI thread when
415  * executed in response to the run() method. Because a SafeEmitterArg
416  * object is used, the emitter object itself is thread safe.
417  *
418  * Since 2.0.0-rc2
419  */
421 
422 /**
423  * Add a Cgu::WinBase object to the Cgu::Application object, and so
424  * also add its managed GtkWindow object to the GtkApplication object.
425  * Any Cgu::WinBase object passed to this method should not normally
426  * be modal and must have been constructed on free store with the new
427  * expression, and will be self owning, although if it is removed from
428  * this Cgu::Application object with remove(), the delete expression
429  * can (and normally should) be called on it. If a delete event
430  * occurs on the WinBase object so that the WinBase object destroys
431  * itself (say, by clicking on the window's close/delete button), or
432  * it destroys itself in some other way (say, by calling the
433  * WinBase::close() method), it will automatically be removed from
434  * this Application object without further action being necessary.
435  * The WinBase::exec() method should never be called on a WinBase
436  * object which has been added to an Application object. The
437  * Cgu::Application class, and thus this method, does not employ
438  * mutexes to make it thread safe, as there should never be a reason
439  * to call Cgu::Application methods in other than the main GUI thread.
440  * @param win The Cgu::WinBase object to be added.
441  * @exception std::bad_alloc This method might throw std::bad_alloc if
442  * memory is exhausted and the system throws in that case.
443  * @note As well as this method only being called in the main GUI
444  * thread, if the program by which it is called calls GTK+ directly in
445  * more than one thread and thus employs
446  * gdk_threads_enter()/gdk_threads_leave() (rather than, say,
447  * Cgu::Notifier or Cgu::Callback::post()), it must be surrounded by
448  * gdk_threads_enter()/gdk_threads_leave() if called otherwise than in
449  * a GTK+ signal handler. (The best approach however is for a program
450  * only to address GTK+/GDK in the main program thread, for which
451  * purpose this library provides various functions and classes for
452  * inter-thread communication, such as Cgu::Notifier and
453  * Cgu::Callback::post(): see @ref Threading for particulars about
454  * GTK+ thread safety.)
455  *
456  * Since 2.0.0-rc2
457  */
458  void add(Cgu::WinBase* win);
459 
460 /**
461  * Remove a Cgu::WinBase object from the Cgu::Application object, and
462  * so also remove its managed GtkWindow object from the GtkApplication
463  * object. This method will not throw assuming that merely iterating
464  * through a list does not throw (as it would not on any sane
465  * implementation). The Cgu::Application class, and thus this method,
466  * does not employ mutexes to make it thread safe, as there should
467  * never be a reason to call Cgu::Application methods in other than
468  * the main GUI thread. Calling this method does not destroy the
469  * WinBase object.
470  * @param win The Cgu::WinBase object to be removed.
471  * @return true if the Cgu::WinBase object was found in the
472  * Cgu::Application object and so removed, otherwise false.
473  * @note As well as this method only being called in the main GUI
474  * thread, if the program by which it is called calls GTK+ directly in
475  * more than one thread and thus employs
476  * gdk_threads_enter()/gdk_threads_leave() (rather than, say,
477  * Cgu::Notifier or Cgu::Callback::post()), it must be surrounded by
478  * gdk_threads_enter()/gdk_threads_leave() if called otherwise than in
479  * a GTK+ signal handler. (The best approach however is for a program
480  * only to address GTK+/GDK in the main program thread, for which
481  * purpose this library provides various functions and classes for
482  * inter-thread communication, such as Cgu::Notifier and
483  * Cgu::Callback::post(): see @ref Threading for particulars about
484  * GTK+ thread safety.)
485  *
486  * Since 2.0.0-rc2
487  */
488  bool remove(Cgu::WinBase* win);
489 
490 /**
491  * Calls g_application_run() in respect of the underlying
492  * GtkApplication object, so invoking one of this Cgu::Application
493  * class's emitters (the exact behaviour depends on the GApplication
494  * flags passed to the constructor and is explained in the
495  * introductory remarks above). This method is thread safe (although
496  * that is irrelevant to its purpose) and will not throw. In
497  * addition, if a callback connected to an emitter throws, the
498  * exception is consumed and a g_critical warning issued. This
499  * function blocks until the last WinBase object associated with this
500  * Application object is destroyed or removed.
501  * @param argc The argc from main() or 0.
502  * @param argv The argv from main() or 0.
503  * @return The exit status from g_application_run().
504  *
505  * Since 2.0.0-rc2
506  */
507  int run(int argc, char** argv) {
508  return g_application_run(G_APPLICATION(app.get()), argc, argv);
509  }
510 
511 /**
512  * Get the underlying GApplication object (note, not the
513  * GtkApplication object, although the GApplication object can be cast
514  * to GtkApplication), so allowing any of gio's g_application_*()
515  * functions to be applied to it. In normal usage it will not be
516  * necessary to call this method. This method is thread safe and will
517  * not throw.
518  * @return The underlying GApplication object.
519  *
520  * Since 2.0.0-rc2
521  */
522  GApplication* get_g_app() const {return (GApplication*)app.get();}
523 
524 /**
525  * Get the list of Cgu::WinBase objects associated with the
526  * application. The Cgu::Application class, and thus this method,
527  * does not employ mutexes to make it thread safe, as there should
528  * never be a reason to call Cgu::Application methods in other than
529  * the main GUI thread.
530  * @return A list of the top level Cgu::WinBase objects associated
531  * with the application, which will appear in the order in which they
532  * were added. If you need to access these, you will probably want to
533  * do a dynamic_cast or static_cast to the child type.
534  * @exception std::bad_alloc This method might throw std::bad_alloc if
535  * memory is exhausted and the system throws in that case.
536  *
537  * Since 2.0.0-rc2
538  */
539  std::list<Cgu::WinBase*> get_windows() const {return win_list;}
540 
541 /**
542  * Gets the current count of Cgu::WinBase objects associated with this
543  * Cgu::Application object. When it reaches 0, the application will
544  * normally end (but this can be prevented by calling
545  * g_application_hold()/g_application_release() on the GApplication
546  * object returned by get_g_app()). This method can be used in the
547  * callback of one of this class's emitters to determine whether this
548  * is the first instance of a program to be started (assuming the
549  * first instance calls add() to bring up a window), because in that
550  * case it will return 0 until add() is called. Calling
551  * get_windows().size() will give the same result, but using this
552  * method is more efficient as it will avoid a copy of the list of
553  * windows. This method will not throw assuming that calling
554  * std::list::size() does not throw (as it would not on any sane
555  * implementation). The Cgu::Application class, and thus this method,
556  * does not employ mutexes to make it thread safe, as there should
557  * never be a reason to call Cgu::Application methods in other than
558  * the main GUI thread.
559  * @return The number of Cgu::WinBase objects currently associated
560  * with this Cgu::Application object.
561  *
562  * Since 2.0.0-rc2
563  */
564  size_type get_win_count() const {return win_list.size();}
565 
566 /**
567  * This constructor will, via gtk_application_new(), cause
568  * g_type_init() to be called. If any GTK+ functions are to be called
569  * before an Application object is constructed, g_type_init() (or
570  * gtk_init()) must be called explicitly.
571  * @param prog_name An identifier name. This can comprise any valid
572  * ASCII characters "[A-Z][a-z][0-9]_-", although it is usually best
573  * to pass the program name. Unlike with gtk_application_new(), it
574  * does not need to comprise a full dbus bus name: this method will
575  * construct its own valid dbus bus name from prog_name in the org.cgu
576  * domain.
577  * @param flags The GApplicationFlags to be passed to the
578  * Cgu::Application object. This class does not contain its own
579  * sub-class of GApplication to customize this, but adopts the
580  * behaviour of GtkApplication. That behaviour is explained in the
581  * introductory remarks.
582  * @exception Cgu::ApplicationNameError This exception will be thrown
583  * if the prog_name parameter does not meet the requirements referred
584  * to above.
585  * @exception std::bad_alloc This method might throw std::bad_alloc if
586  * memory is exhausted and the system throws in that case.
587  *
588  * Since 2.0.0-rc2
589  */
590  Application(const char* prog_name, GApplicationFlags flags);
591 
592 /**
593  * From version 2.0.0-rc3, as a safety feature the destructor removes
594  * any remaining WinBase objects associated with this Application
595  * object (this would only be relevant if the user constructs the
596  * Application object on free store, and then deletes it while the
597  * run() method is still blocking for the purpose of constructing a
598  * different Application object, but does not call the remove() method
599  * on all associated WinBase objects before doing so: constructing an
600  * Application object on free store in this way would be highly
601  * unusual however).
602  *
603  * Since 2.0.0-rc3
604  */
605  ~Application() {while (!win_list.empty()) remove(win_list.front());}
606 
607 /* Only has effect if --with-glib-memory-slices-compat or
608  * --with-glib-memory-slices-no-compat option picked */
610 };
611 
612 #endif // GTK_CHECK_VERSION(2,99,0)
613 
614 } // namespace Cgu
615 
616 #endif // CGU_APPLICATION_H