GApplication: fix inactivity-timeout
[platform/upstream/glib.git] / gio / gapplication.c
1 /*
2  * Copyright © 2010 Codethink Limited
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published
6  * by the Free Software Foundation; either version 2 of the licence or (at
7  * your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 /* Prologue {{{1 */
23 #include "gapplication.h"
24
25 #include "gapplicationimpl.h"
26
27 #include "gioenumtypes.h"
28 #include "gio-marshal.h"
29 #include "gioenums.h"
30 #include "gfile.h"
31
32 #include <string.h>
33
34 struct _GApplicationPrivate
35 {
36   GApplicationFlags  flags;
37   gchar             *id;
38
39   GHashTable        *actions; /* string -> GApplicationAction */
40   GMainLoop         *mainloop;
41
42   guint              inactivity_timeout_id;
43   guint              inactivity_timeout;
44   guint              use_count;
45
46   guint              is_registered : 1;
47   guint              is_remote : 1;
48
49   GApplicationImpl  *impl;
50 };
51
52 enum
53 {
54   PROP_NONE,
55   PROP_APPLICATION_ID,
56   PROP_FLAGS,
57   PROP_IS_REGISTERED,
58   PROP_IS_REMOTE,
59   PROP_INACTIVITY_TIMEOUT
60 };
61
62 enum
63 {
64   SIGNAL_STARTUP,
65   SIGNAL_ACTIVATE,
66   SIGNAL_OPEN,
67   SIGNAL_ACTION,
68   SIGNAL_COMMAND_LINE,
69   NR_SIGNALS
70 };
71
72 static guint g_application_signals[NR_SIGNALS];
73
74 G_DEFINE_TYPE (GApplication, g_application, G_TYPE_OBJECT)
75
76 /* vfunc defaults {{{1 */
77 static void
78 g_application_real_before_emit (GApplication *application,
79                                 GVariant     *platform_data)
80 {
81 }
82
83 static void
84 g_application_real_after_emit (GApplication *application,
85                                GVariant     *platform_data)
86 {
87 }
88
89 static void
90 g_application_real_startup (GApplication *application)
91 {
92 }
93
94 static void
95 g_application_real_activate (GApplication *application)
96 {
97   if (!g_signal_has_handler_pending (application,
98                                      g_application_signals[SIGNAL_ACTIVATE],
99                                      0, TRUE))
100     {
101       static gboolean warned;
102
103       if (warned)
104         return;
105
106       g_warning ("Your application does not implement "
107                  "g_application_activate() and has no handlers connected "
108                  "to the 'activate' signal.  It should do one of these.");
109       warned = TRUE;
110     }
111 }
112
113 static void
114 g_application_real_open (GApplication  *application,
115                          GFile        **files,
116                          gint           n_files,
117                          const gchar   *hint)
118 {
119   if (!g_signal_has_handler_pending (application,
120                                      g_application_signals[SIGNAL_OPEN],
121                                      0, TRUE))
122     {
123       static gboolean warned;
124
125       if (warned)
126         return;
127
128       g_warning ("Your application claims to support opening files "
129                  "but does not implement g_application_open() and has no "
130                  "handlers connected to the 'open' signal.");
131       warned = TRUE;
132     }
133 }
134
135 static gboolean
136 g_application_real_local_command_line (GApplication  *application,
137                                        GVariant     **arguments,
138                                        int           *exit_status)
139 {
140   if (0)
141     return FALSE;
142
143   else
144     {
145       GError *error = NULL;
146       gint n_args;
147
148       if (!g_application_register (application, NULL, &error))
149         {
150           g_critical ("%s", error->message);
151           g_error_free (error);
152           *exit_status = 1;
153           return TRUE;
154         }
155
156       n_args = g_variant_n_children (*arguments);
157
158       if (application->priv->flags & G_APPLICATION_FLAGS_IS_SERVICE)
159         {
160           if (n_args > 1)
161             {
162               g_printerr ("GApplication service mode takes no arguments.\n");
163               application->priv->flags &= ~G_APPLICATION_FLAGS_IS_SERVICE;
164             }
165
166           return TRUE;
167         }
168
169       if (n_args <= 1)
170         {
171           g_application_activate (application);
172           *exit_status = 0;
173         }
174
175       else
176         {
177           if (~application->priv->flags & G_APPLICATION_FLAGS_HANDLES_OPEN)
178             {
179               g_critical ("This application can not open files.");
180               *exit_status = 1;
181             }
182           else
183             {
184               GFile **files;
185               gint n_files;
186               gint i;
187
188               n_files = n_args - 1;
189               files = g_new (GFile *, n_files);
190
191               for (i = 0; i < n_files; i++)
192                 {
193                   const gchar *arg;
194
195                   g_variant_get_child (*arguments, i + 1, "^&ay", &arg);
196                   files[i] = g_file_new_for_commandline_arg (arg);
197                 }
198
199               g_application_open (application, files, n_files, "");
200
201               for (i = 0; i < n_files; i++)
202                 g_object_unref (files[i]);
203               g_free (files);
204
205               *exit_status = 0;
206             }
207         }
208
209       return TRUE;
210     }
211 }
212
213 static void
214 g_application_real_add_platform_data (GApplication    *application,
215                                       GVariantBuilder *builder)
216 {
217 }
218
219 static void
220 g_application_real_quit_mainloop (GApplication *application)
221 {
222   if (application->priv->mainloop != NULL)
223     g_main_loop_quit (application->priv->mainloop);
224 }
225
226 static void
227 g_application_real_run_mainloop (GApplication *application)
228 {
229   if (application->priv->mainloop == NULL)
230     application->priv->mainloop = g_main_loop_new (NULL, FALSE);
231
232   g_main_loop_run (application->priv->mainloop);
233 }
234
235 /* GObject implementation stuff {{{1 */
236 static void
237 g_application_set_property (GObject *object, guint prop_id,
238                             const GValue *value, GParamSpec *pspec)
239 {
240   GApplication *application = G_APPLICATION (object);
241
242   switch (prop_id)
243     {
244     case PROP_APPLICATION_ID:
245       g_application_set_application_id (application,
246                                         g_value_get_string (value));
247       break;
248
249     case PROP_FLAGS:
250       g_application_set_flags (application, g_value_get_flags (value));
251       break;
252
253     case PROP_INACTIVITY_TIMEOUT:
254       g_application_set_inactivity_timeout (application,
255                                             g_value_get_uint (value));
256       break;
257
258     default:
259       g_assert_not_reached ();
260     }
261 }
262
263 static void
264 g_application_get_property (GObject *object, guint prop_id,
265                             GValue *value, GParamSpec *pspec)
266 {
267   GApplication *application = G_APPLICATION (object);
268
269   switch (prop_id)
270     {
271     case PROP_APPLICATION_ID:
272       g_value_set_string (value,
273                           g_application_get_application_id (application));
274       break;
275
276     case PROP_FLAGS:
277       g_value_set_flags (value,
278                          g_application_get_flags (application));
279       break;
280
281     case PROP_IS_REGISTERED:
282       g_value_set_boolean (value,
283                            g_application_get_is_registered (application));
284       break;
285
286     case PROP_IS_REMOTE:
287       g_value_set_boolean (value,
288                            g_application_get_is_remote (application));
289       break;
290
291     case PROP_INACTIVITY_TIMEOUT:
292       g_value_set_uint (value,
293                         g_application_get_inactivity_timeout (application));
294       break;
295
296     default:
297       g_assert_not_reached ();
298     }
299 }
300
301 static void
302 g_application_constructed (GObject *object)
303 {
304   GApplication *application = G_APPLICATION (object);
305
306   g_assert (application->priv->id != NULL);
307 }
308
309 static void
310 g_application_finalize (GObject *object)
311 {
312   GApplication *application = G_APPLICATION (object);
313
314   if (application->priv->impl)
315     g_application_impl_destroy (application->priv->impl);
316   g_free (application->priv->id);
317
318   if (application->priv->mainloop)
319     g_main_loop_unref (application->priv->mainloop);
320
321   G_OBJECT_CLASS (g_application_parent_class)
322     ->finalize (object);
323 }
324
325 static void
326 g_application_init (GApplication *application)
327 {
328   application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application,
329                                                    G_TYPE_APPLICATION,
330                                                    GApplicationPrivate);
331 }
332
333 static void
334 g_application_class_init (GApplicationClass *class)
335 {
336   GObjectClass *object_class = G_OBJECT_CLASS (class);
337
338   object_class->constructed = g_application_constructed;
339   object_class->finalize = g_application_finalize;
340   object_class->get_property = g_application_get_property;
341   object_class->set_property = g_application_set_property;
342
343   class->before_emit = g_application_real_before_emit;
344   class->after_emit = g_application_real_after_emit;
345   class->startup = g_application_real_startup;
346   class->activate = g_application_real_activate;
347   class->open = g_application_real_open;
348   class->local_command_line = g_application_real_local_command_line;
349   class->add_platform_data = g_application_real_add_platform_data;
350   class->quit_mainloop = g_application_real_quit_mainloop;
351   class->run_mainloop = g_application_real_run_mainloop;
352
353   g_object_class_install_property (object_class, PROP_APPLICATION_ID,
354     g_param_spec_string ("application-id", "application identifier",
355                          "Unique identifier for the application",
356                          NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
357                          G_PARAM_STATIC_STRINGS));
358
359   g_object_class_install_property (object_class, PROP_FLAGS,
360     g_param_spec_flags ("flags", "application flags",
361                         "Flags specifying the behaviour of the application",
362                          G_TYPE_APPLICATION_FLAGS, G_APPLICATION_FLAGS_NONE,
363                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
364
365   g_object_class_install_property (object_class, PROP_IS_REGISTERED,
366     g_param_spec_boolean ("is-registered", "is registered",
367                           "If g_application_register() has been called",
368                           FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
369
370   g_object_class_install_property (object_class, PROP_IS_REMOTE,
371     g_param_spec_boolean ("is-remote", "is remote",
372                           "If this application instance is remote",
373                           FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
374
375   g_object_class_install_property (object_class, PROP_INACTIVITY_TIMEOUT,
376     g_param_spec_boolean ("inactivity-timeout", "inactivity timeout",
377                           "time (ms) to stay alive after becoming idle",
378                           0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
379
380
381   g_application_signals[SIGNAL_STARTUP] =
382     g_signal_new ("startup", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
383                   G_STRUCT_OFFSET (GApplicationClass, startup),
384                   NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
385
386   g_application_signals[SIGNAL_ACTIVATE] =
387     g_signal_new ("activate", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
388                   G_STRUCT_OFFSET (GApplicationClass, activate),
389                   NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
390
391   g_application_signals[SIGNAL_OPEN] =
392     g_signal_new ("open", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
393                   G_STRUCT_OFFSET (GApplicationClass, open),
394                   NULL, NULL, _gio_marshal_VOID__POINTER_INT_STRING,
395                   G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING);
396
397   g_type_class_add_private (class, sizeof (GApplicationPrivate));
398 }
399
400 static GVariant *
401 get_platform_data (GApplication *application)
402 {
403   GVariantBuilder *builder;
404   GVariant *result;
405
406   builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
407
408   {
409     gchar *cwd = g_get_current_dir ();
410     g_variant_builder_add (builder, "{sv}", "cwd",
411                            g_variant_new_bytestring (cwd));
412     g_free (cwd);
413   }
414
415   G_APPLICATION_GET_CLASS (application)->
416     add_platform_data (application, builder);
417
418   result = g_variant_builder_end (builder);
419   g_variant_builder_unref (builder);
420
421   return result;
422 }
423
424 /* Application ID validity {{{1 */
425
426 /**
427  * g_application_id_is_valid:
428  * @application_id: a potential application identifier
429  * @returns: %TRUE if @application_id is valid
430  *
431  * Checks if @application_id is a valid application ID.  A valid ID is
432  * required for calls to g_application_new() and
433  * g_application_set_application_id().
434  **/
435 gboolean
436 g_application_id_is_valid (const gchar *application_id)
437 {
438   gboolean allow_dot;
439
440   if (strlen (application_id) > 255)
441     return FALSE;
442
443   if (!g_ascii_isalpha (*application_id))
444     return FALSE;
445
446   application_id++;
447   allow_dot = FALSE;
448   for (; *application_id; application_id++)
449     {
450       if (g_ascii_isalnum (*application_id) ||
451           (*application_id == '-') ||
452           (*application_id == '_'))
453         allow_dot = TRUE;
454       else if (allow_dot && *application_id == '.')
455         allow_dot = FALSE;
456       else
457         return FALSE;
458     }
459
460   return TRUE;
461 }
462
463 /* Public Constructor {{{1 */
464 /**
465  * g_application_new:
466  * @application_id: the application id
467  * @flags: the application flags
468  * @returns: a new #GApplication instance
469  *
470  * Creates a new #GApplication instance.
471  *
472  * This function calls g_type_init() for you.
473  *
474  * The application id must be valid.  See g_application_id_is_valid().
475  **/
476 GApplication *
477 g_application_new (const gchar       *application_id,
478                    GApplicationFlags  flags)
479 {
480   g_return_val_if_fail (g_application_id_is_valid (application_id), NULL);
481
482   g_type_init ();
483
484   return g_object_new (G_TYPE_APPLICATION,
485                        "application-id", application_id,
486                        "flags", flags,
487                        NULL);
488 }
489
490 /* Simple get/set: application id, flags, inactivity timeout {{{1 */
491 /**
492  * g_application_get_application_id:
493  * @application: a #GApplication
494  * @returns: the identifier for @application, owned by @application
495  *
496  * Gets the unique identifier for @application.
497  *
498  * Since: 2.28
499  **/
500 const gchar *
501 g_application_get_application_id (GApplication *application)
502 {
503   g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
504
505   return application->priv->id;
506 }
507
508 /**
509  * g_application_set_application_id:
510  * @application: a #GApplication
511  * @application_id: the identifier for @application
512  *
513  * Sets the unique identifier for @application.
514  *
515  * The application id can only be modified if @application has not yet
516  * been registered.
517  *
518  * The application id must be valid.  See g_application_id_is_valid().
519  *
520  * Since: 2.28
521  **/
522 void
523 g_application_set_application_id (GApplication *application,
524                                   const gchar  *application_id)
525 {
526   g_return_if_fail (G_IS_APPLICATION (application));
527
528   if (g_strcmp0 (application->priv->id, application_id) != 0)
529     {
530       g_return_if_fail (g_application_id_is_valid (application_id));
531       g_return_if_fail (!application->priv->is_registered);
532
533       g_free (application->priv->id);
534       application->priv->id = g_strdup (application_id);
535
536       g_object_notify (G_OBJECT (application), "application-id");
537     }
538 }
539
540 /**
541  * g_application_get_flags:
542  * @application: a #GApplication
543  * @returns: the flags for @application
544  *
545  * Gets the flags for @application.
546  *
547  * See #GApplicationFlags.
548  *
549  * Since: 2.28
550  **/
551 GApplicationFlags
552 g_application_get_flags (GApplication *application)
553 {
554   g_return_val_if_fail (G_IS_APPLICATION (application), 0);
555
556   return application->priv->flags;
557 }
558
559 /**
560  * g_application_set_flags:
561  * @application: a #GApplication
562  * @flags: the flags for @application
563  *
564  * Sets the flags for @application.
565  *
566  * The flags can only be modified if @application has not yet been
567  * registered.
568  *
569  * See #GApplicationFlags.
570  *
571  * Since: 2.28
572  **/
573 void
574 g_application_set_flags (GApplication      *application,
575                          GApplicationFlags  flags)
576 {
577   g_return_if_fail (G_IS_APPLICATION (application));
578
579   if (application->priv->flags != flags)
580     {
581       g_return_if_fail (!application->priv->is_registered);
582
583       application->priv->flags = flags;
584
585       g_object_notify (G_OBJECT (application), "flags");
586     }
587 }
588
589 /**
590  * g_application_get_inactivity_timeout:
591  * @application: a #GApplication
592  *
593  * Gets the current inactivity timeout for the application.
594  *
595  * This is the amount of time (in milliseconds) after the last call to
596  * g_application_release() before the application stops running.
597  *
598  * Returns: the timeout, in milliseconds
599  *
600  * Since: 2.28
601  **/
602 guint
603 g_application_get_inactivity_timeout (GApplication *application)
604 {
605   g_return_val_if_fail (G_IS_APPLICATION (application), 0);
606
607   return application->priv->inactivity_timeout;
608 }
609
610 /**
611  * g_application_set_inactivity_timeout:
612  * @application: a #GApplication
613  * @inactivity_timeout: the timeout, in milliseconds
614  *
615  * Sets the current inactivity timeout for the application.
616  *
617  * This is the amount of time (in milliseconds) after the last call to
618  * g_application_release() before the application stops running.
619  *
620  * This call has no side effects of its own.  The value set here is only
621  * used for next time g_application_release() drops the use count to
622  * zero.  Any timeouts currently in progress are not impacted.
623  *
624  * Returns: the timeout, in milliseconds
625  *
626  * Since: 2.28
627  **/
628 void
629 g_application_set_inactivity_timeout (GApplication *application,
630                                       guint         inactivity_timeout)
631 {
632   g_return_if_fail (G_IS_APPLICATION (application));
633
634   if (application->priv->inactivity_timeout != inactivity_timeout)
635     {
636       application->priv->inactivity_timeout = inactivity_timeout;
637
638       g_object_notify (G_OBJECT (application), "inactivity-timeout");
639     }
640 }
641 /* Read-only property getters (is registered, is remote) {{{1 */
642 /**
643  * g_application_get_is_registered:
644  * @application: a #GApplication
645  * @returns: %TRUE if @application is registered
646  *
647  * Checks if @application is registered.
648  *
649  * An application is registered if g_application_register() has been
650  * successfully called.
651  *
652  * Since: 2.28
653  **/
654 gboolean
655 g_application_get_is_registered (GApplication *application)
656 {
657   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
658
659   return application->priv->is_registered;
660 }
661
662 /**
663  * g_application_get_is_remote:
664  * @application: a #GApplication
665  * @returns: %TRUE if @application is remote
666  *
667  * Checks if @application is remote.
668  *
669  * If @application is remote then it means that another instance of
670  * application already exists (the 'primary' instance).  Calls to
671  * perform actions on @application will result in the actions being
672  * performed by the primary instance.
673  *
674  * The value of this property can not be accessed before
675  * g_application_register() has been called.  See
676  * g_application_get_is_registered().
677  *
678  * Since: 2.28
679  **/
680 gboolean
681 g_application_get_is_remote (GApplication *application)
682 {
683   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
684   g_return_val_if_fail (application->priv->is_registered, FALSE);
685
686   return application->priv->is_remote;
687 }
688
689 /* Register {{{1 */
690 /**
691  * g_application_register:
692  * @application: a #GApplication
693  * @cancellable: a #GCancellable, or %NULL
694  * @error: a pointer to a NULL #GError, or %NULL
695  * @returns: %TRUE if registration succeeded
696  *
697  * Attempts registration of the application.
698  *
699  * This is the point at which the application discovers if it is the
700  * primary instance or merely acting as a remote for an already-existing
701  * primary instance.
702  *
703  * If the application has already been registered then %TRUE is
704  * returned with no work performed.
705  *
706  * The startup() virtual function is invoked if registration succeeds
707  * and @application is the primary instance.
708  *
709  * In the event of an error (such as @cancellable being cancelled, or a
710  * failure to connect to the session bus), %FALSE is returned and @error
711  * is set appropriately.
712  *
713  * Note: the return value of this function is not an indicator that this
714  * instance is or is not the primary instance of the application.  See
715  * g_application_get_is_remote() for that.
716  *
717  * Since: 2.28
718  **/
719 gboolean
720 g_application_register (GApplication  *application,
721                         GCancellable  *cancellable,
722                         GError       **error)
723 {
724   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
725
726   if (!application->priv->is_registered)
727     {
728       gboolean is_remote;
729       gboolean try;
730
731       /* don't try to be the primary instance if
732        * G_APPLICATION_FLAGS_IS_LAUNCHER was specified.
733        */
734       try = !(application->priv->flags & G_APPLICATION_FLAGS_IS_LAUNCHER);
735
736       application->priv->impl =
737         g_application_impl_register (application, application->priv->id,
738                                      application->priv->flags,
739                                      &is_remote, cancellable, error);
740
741       if (application->priv->impl == NULL)
742         return FALSE;
743
744       application->priv->is_remote = is_remote;
745       application->priv->is_registered = TRUE;
746
747       g_object_notify (G_OBJECT (application), "is-registered");
748
749       if (!is_remote)
750         g_signal_emit (application, g_application_signals[SIGNAL_STARTUP], 0);
751     }
752
753   return TRUE;
754 }
755
756 /* Hold/release {{{1 */
757 /**
758  * g_application_hold:
759  * @application: a #GApplication
760  *
761  * Increases the use count of @application.
762  *
763  * Use this function to indicate that the application has a reason to
764  * continue to run.  For example, g_application_hold() is called by Gtk
765  * when a toplevel window is on the screen.
766  *
767  * To cancel the hold, call g_application_release().
768  **/
769 void
770 g_application_hold (GApplication *application)
771 {
772   if (application->priv->inactivity_timeout_id)
773     {
774       g_source_remove (application->priv->inactivity_timeout_id);
775       application->priv->inactivity_timeout_id = 0;
776     }
777
778   application->priv->use_count++;
779 }
780
781 static gboolean
782 inactivity_timeout_expired (gpointer data)
783 {
784   GApplication *application = G_APPLICATION (data);
785
786   G_APPLICATION_GET_CLASS (application)
787     ->quit_mainloop (application);
788
789   return FALSE;
790 }
791
792
793 /**
794  * g_application_release:
795  * @application: a #GApplication
796  *
797  * Decrease the use count of @application.
798  *
799  * When the use count reaches zero, the application will stop running.
800  *
801  * Never call this function except to cancel the effect of a previous
802  * call to g_application_hold().
803  **/
804 void
805 g_application_release (GApplication *application)
806 {
807   application->priv->use_count--;
808
809   if (application->priv->use_count == 0)
810     {
811       if (application->priv->inactivity_timeout)
812         application->priv->inactivity_timeout_id =
813           g_timeout_add (application->priv->inactivity_timeout,
814                          inactivity_timeout_expired, application);
815
816       else
817         G_APPLICATION_GET_CLASS (application)
818           ->quit_mainloop (application);
819     }
820 }
821
822 /* Activate, Open {{{1 */
823 /**
824  * g_application_activate:
825  * @application: a #GApplication
826  *
827  * Activates the application.
828  *
829  * In essence, this results in the activate() virtual function being
830  * invoked in the primary instance.
831  *
832  * The application must be registered before calling this function.
833  *
834  * Since: 2.28
835  **/
836 void
837 g_application_activate (GApplication *application)
838 {
839   g_return_if_fail (G_IS_APPLICATION (application));
840   g_return_if_fail (application->priv->is_registered);
841
842   if (application->priv->is_remote)
843     g_application_impl_activate (application->priv->impl,
844                                  get_platform_data (application));
845
846   else
847     g_signal_emit (application, g_application_signals[SIGNAL_ACTIVATE], 0);
848 }
849
850 /**
851  * g_application_open:
852  * @application: a #GApplication
853  * @files: an array of #GFile<!-- -->s to open
854  * @n_files: the length of the @files array
855  * @hint: a hint (or ""), but never %NULL
856  *
857  * Opens the given files.
858  *
859  * In essence, this results in the open() virtual function being invoked
860  * in the primary instance.
861  *
862  * @n_files must be greater than zero.
863  *
864  * @hint is simply passed through to the open() virtual function.  It is
865  * intended to be used by applications that have multiple modes for
866  * opening files (eg: "view" vs "edit", etc).  Unless you have a need
867  * for this functionality, you should use "".
868  *
869  * The application must be registered before calling this function and
870  * it must have the %G_APPLICATION_FLAGS_CAN_OPEN flag set.  The open()
871  * virtual function should also be implemented in order for anything
872  * meaningful to happen.
873  *
874  * Since: 2.28
875  **/
876 void
877 g_application_open (GApplication  *application,
878                     GFile        **files,
879                     gint           n_files,
880                     const gchar   *hint)
881 {
882   g_return_if_fail (G_IS_APPLICATION (application));
883   g_return_if_fail (application->priv->flags &
884                     G_APPLICATION_FLAGS_HANDLES_OPEN);
885   g_return_if_fail (application->priv->is_registered);
886
887   if (application->priv->is_remote)
888     g_application_impl_open (application->priv->impl,
889                              files, n_files, hint,
890                              get_platform_data (application));
891
892   else
893     g_signal_emit (application, g_application_signals[SIGNAL_OPEN],
894                    0, files, n_files, hint);
895 }
896
897 /* Run {{{1 */
898 /**
899  * g_application_run:
900  * @application: a #GApplication
901  * @argc: the argc from main()
902  * @argv: the argv from main()
903  * @returns: the exit status
904  *
905  * Runs the application.
906  *
907  * This function is intended to be run from main() and its return value
908  * is intended to be returned by main().
909  *
910  * First, the handle_command_line() virtual function is invoked.  This
911  * function always runs on the local instance.  If that function returns
912  * %FALSE then the application is registered and the command_line()
913  * virtual function is invoked in the primary instance (which may or may
914  * not be this instance).
915  *
916  * If the application has the %G_APPLICATION_FLAGS_REMOTE_COMMAND_LINE
917  * flag set then the default implementation of handle_command_line()
918  * always returns %FALSE immediately, resulting in the commandline
919  * always being handled in the primary instance.
920  *
921  * Otherwise, the default implementation of handle_command_line() tries
922  * to do a couple of things that are probably reasoanble for most
923  * applications.  First, g_application_register() is called to attempt
924  * to register the application.  If that works, then the command line
925  * arguments are inspected.  If no commandline arguments are given, then
926  * g_application_activate() is called.  If commandline arguments are
927  * given and the %G_APPLICATION_FLAGS_CAN_OPEN flags is set then they
928  * are assumed to be filenames and g_application_open() is called.
929  *
930  * If you are interested in doing more complicated local handling of the
931  * commandline then you should override handle_command_line().
932  *
933  * If, after the above is done, the use count of the application is zero
934  * then the exit status is returned immediately.  If the use count is
935  * non-zero then the mainloop is run until the use count falls to zero,
936  * at which point 0 is returned.
937  *
938  * Since: 2.28
939  **/
940 int
941 g_application_run (GApplication  *application,
942                    int            argc,
943                    char         **argv)
944 {
945   g_return_val_if_fail (G_IS_APPLICATION (application), 1);
946   g_return_val_if_fail (argc == 0 || argv != NULL, 1);
947
948   return g_application_run_with_arguments (application,
949     g_variant_new_bytestring_array ((const gchar **) argv, argc));
950 }
951
952 /**
953  * g_application_run_with_arguments:
954  * @application: a #GApplication
955  * @arguments: a bytestring array #GVariant
956  * @returns: the exit status
957  *
958  * This is a bindings-friendly version of g_application_run().
959  *
960  * This function will consume @arguments if it is floating.
961  **/
962 int
963 g_application_run_with_arguments (GApplication *application,
964                                   GVariant     *arguments)
965 {
966   int status;
967
968   g_return_val_if_fail (G_IS_APPLICATION (application), 1);
969   g_return_val_if_fail (G_IS_APPLICATION (application), 1);
970
971   g_variant_ref_sink (arguments);
972
973   if (g_get_prgname () == NULL && g_variant_n_children (arguments))
974     {
975       const gchar *argv0;
976       gchar *prgname;
977
978       g_variant_get_child (arguments, 0, "^&ay", &argv0);
979       prgname = g_path_get_basename (argv0);
980       g_set_prgname (prgname);
981       g_free (prgname);
982     }
983
984   if (!G_APPLICATION_GET_CLASS (application)
985         ->local_command_line (application, &arguments, &status))
986     {
987       g_assert_not_reached ();
988     }
989
990   g_variant_unref (arguments);
991
992   if (application->priv->flags & G_APPLICATION_FLAGS_IS_SERVICE &&
993       !application->priv->use_count &&
994       !application->priv->inactivity_timeout_id)
995     {
996       application->priv->inactivity_timeout_id =
997         g_timeout_add (10000, inactivity_timeout_expired, application);
998     }
999
1000   if (application->priv->use_count ||
1001       application->priv->inactivity_timeout_id)
1002     {
1003       G_APPLICATION_GET_CLASS (application)
1004         ->run_mainloop (application);
1005       status = 0;
1006     }
1007
1008   if (application->priv->impl)
1009     g_application_impl_flush (application->priv->impl);
1010
1011   return status;
1012 }
1013
1014 /* Epilogue {{{1 */
1015 /* vim:set foldmethod=marker: */