"Fossies" - the Fresh Open Source Software Archive

Member "glibmm-2.74.0/gio/src/application.hg" (19 Sep 2022, 21944 Bytes) of package /linux/misc/glibmm-2.74.0.tar.xz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 /* Copyright (C) 2007 The gtkmm Development Team
    2  *
    3  * This library is free software; you can redistribute it and/or
    4  * modify it under the terms of the GNU Lesser General Public
    5  * License as published by the Free Software Foundation; either
    6  * version 2.1 of the License, or (at your option) any later version.
    7  *
    8  * This library is distributed in the hope that it will be useful,
    9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   11  * Lesser General Public License for more details.
   12  *
   13  * You should have received a copy of the GNU Lesser General Public
   14  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
   15  */
   16 
   17 _CONFIGINCLUDE(giommconfig.h)
   18 
   19 #include <giomm/actiongroup.h>
   20 #include <giomm/actionmap.h>
   21 #include <giomm/applicationcommandline.h>
   22 #include <giomm/file.h>
   23 #include <glibmm/object.h>
   24 #include <glibmm/optionentry.h>
   25 #include <glibmm/optiongroup.h>
   26 #include <glibmm/variant.h>
   27 #include <glibmm/variantdict.h>
   28 #include <giomm/dbusconnection.h>
   29 #include <giomm/notification.h>
   30 
   31 _DEFS(giomm,gio)
   32 _PINCLUDE(glibmm/private/object_p.h)
   33 
   34 namespace Gio
   35 {
   36 
   37 
   38 /** Application - Core application class.
   39  * An Application is the foundation of an application, unique for a given
   40  * application identifier. The Application class wraps some low-level
   41  * platform-specific services and is intended to act as the foundation for
   42  * higher-level application classes such as Gtk::Application or MxApplication.
   43  * In general, you should not use this class outside of a higher level
   44  * framework.
   45  *
   46  * One of the core features that Application provides is process uniqueness,
   47  * in the context of a "session". The session concept is platform-dependent,
   48  * but corresponds roughly to a graphical desktop login. When your application
   49  * is launched again, its arguments are passed through platform communication
   50  * to the already running program. The already running instance of the program
   51  * is called the <i>primary instance</i>.
   52  *
   53  * Before using Application, you must choose an "application identifier". The
   54  * expected form of an application identifier is very close to that of of a
   55  * <a href="
   56  * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface">DBus
   57  * bus name</a>. Examples include: "com.example.MyApp",
   58  * "org.example.internal-apps.Calculator". For details on valid application
   59  * identifiers, see id_is_valid().
   60  *
   61  * Application provides convenient life cycle management by maintaining a
   62  * <i>use count</i> for the primary application instance. The use count can be
   63  * changed using hold() and release(). If it drops to zero, the application
   64  * exits.
   65  *
   66  * Application also implements the ActionGroup and ActionMap
   67  * interfaces and lets you easily export actions by adding them with
   68  * Gio::ActionMap::add_action(). When invoking an action by calling
   69  * Gio::ActionGroup::activate_action() on the application, it is always
   70  * invoked in the primary instance.
   71  *
   72  * There is a number of different entry points into an Application:
   73  *
   74  * - via 'Activate' (i.e. just starting the application)
   75  * - via 'Open' (i.e. opening some files)
   76  * - via activating an action
   77  *
   78  * The signal_startup() signal lets you handle the application initialization
   79  * for all of these in a single place.
   80  *
   81  * See the C API docs for an example.
   82  *
   83  * @newin{2,32}
   84  */
   85 class GIOMM_API Application : public Glib::Object, public ActionGroup, public ActionMap
   86 {
   87   _CLASS_GOBJECT(Application, GApplication, G_APPLICATION, Glib::Object, GObject, , , GIOMM_API)
   88   _IMPLEMENTS_INTERFACE(ActionGroup)
   89   _IMPLEMENTS_INTERFACE(ActionMap)
   90 
   91 public:
   92   _WRAP_ENUM(Flags, GApplicationFlags, s#^FLAGS_##, decl_prefix GIOMM_API)
   93 
   94 protected:
   95   /** Constructs an application instance.
   96    * If no application ID is given then some features (most notably application uniqueness) will be disabled.
   97    *
   98    * @param application_id The application ID.
   99    * @param flags The application flags.
  100    */
  101   explicit Application(const Glib::ustring& application_id = {}, Flags flags = Flags::NONE);
  102   _IGNORE(g_application_new)
  103 
  104 public:
  105   _CUSTOM_DTOR()
  106 
  107   // Application::OptionType wraps GOptionArg, but _WRAP_ENUM can't be used here.
  108   // GOptionArg is defined in glib_enums.defs, not in gio_enums.defs.
  109   /** The OptionType enum values determine the expected type of a command line option.
  110    * If an option expects an extra argument, it can be specified in several ways;
  111    * with a short option: "-x arg", with a long option: "--name arg" or combined
  112    * in a single argument: "--name=arg". All option types except OptionType::BOOL
  113    * expect an extra argument. OptionType::STRING_VECTOR and
  114    * OptionType::FILENAME_VECTOR accept more than one extra argument.
  115    *
  116    * The descriptions of the enum values show what type of Glib::Variant<>
  117    * is stored in a Glib::VariantDict.
  118    *
  119    * @newin{2,42}
  120    *
  121    * @ingroup glibmmEnums
  122    */
  123   enum class OptionType
  124   {
  125     BOOL,   ///< bool
  126     STRING, ///< Glib::ustring
  127     INT,    ///< gint32
  128     // CALLBACK,
  129     FILENAME = INT+2, ///< std::string
  130     STRING_VECTOR,    ///< std::vector<Glib::ustring>
  131     FILENAME_VECTOR,  ///< std::vector<std::string>
  132     DOUBLE,           ///< double
  133     INT64             ///< gint64
  134   };
  135 
  136   /** Creates an application instance.
  137    * If no application ID is given then some features (most notably application uniqueness) will be disabled.
  138    *
  139    * @param application_id The application ID.
  140    * @param flags The application flags.
  141    */
  142   _WRAP_CREATE(const Glib::ustring& application_id = {}, Flags flags = Flags::NONE)
  143 
  144   _WRAP_METHOD(static bool id_is_valid(const Glib::ustring& application_id), g_application_id_is_valid)
  145 
  146   _WRAP_METHOD(Glib::ustring get_id() const, g_application_get_application_id)
  147   _WRAP_METHOD(void set_id(const Glib::ustring& application_id), g_application_set_application_id)
  148 
  149 
  150   _WRAP_METHOD(Glib::RefPtr<DBus::Connection> get_dbus_connection(), g_application_get_dbus_connection, refreturn)
  151   _WRAP_METHOD(Glib::RefPtr<const DBus::Connection> get_dbus_connection() const, g_application_get_dbus_connection, refreturn, constversion)
  152 
  153   _WRAP_METHOD(Glib::ustring get_dbus_object_path() const, g_application_get_dbus_object_path)
  154 
  155   _WRAP_METHOD(guint get_inactivity_timeout() const, g_application_get_inactivity_timeout)
  156   _WRAP_METHOD(void set_inactivity_timeout(guint inactivity_timeout), g_application_set_inactivity_timeout)
  157 
  158   _WRAP_METHOD(Flags get_flags() const, g_application_get_flags)
  159   _WRAP_METHOD(void set_flags(Flags flags), g_application_set_flags)
  160 
  161   _WRAP_METHOD(std::string get_resource_base_path() const, g_application_get_resource_base_path, newin "2,44")
  162   _WRAP_METHOD(void set_resource_base_path(const std::string& resource_path), g_application_set_resource_base_path, newin "2,44")
  163 
  164   /** Disable automatic resource loading functionality.
  165    * See set_resource_base_path().
  166    * @newin{2,44}
  167    */
  168   void unset_resource_base_path();
  169 
  170   _IGNORE(g_application_set_action_group)
  171 
  172   //Note: We would like to add a group, not just some entries,
  173   //so we can do pre and post parsing. See https://bugzilla.gnome.org/show_bug.cgi?id=727602
  174   //but instead we need to use the VariantDict passed to the handle_local_options signal
  175   //and provided by ApplicationCommandLine::get_options_dict() in on_command_line().
  176 
  177   /** Adds a main option entry to be handled by the Application.
  178    *
  179    * This function is comparable to Glib::OptionGroup::add_entry() +
  180    * Glib::OptionContext::set_main_group().
  181    *
  182    * After the commandline arguments are parsed, the
  183    * signal_handle_local_options() signal will be emitted.  At this
  184    * point, the application can inspect the parsed values.
  185    *
  186    * Unlike OptionGroup + OptionContext, Application packs the arguments
  187    * into a Glib::VariantDict which is passed to the
  188    * signal_handle_local_options() handler, where it can be
  189    * inspected and modified. If Gio::Application::Flags::HANDLES_COMMAND_LINE is
  190    * set, then the resulting dictionary is sent to the primary instance,
  191    * where Gio::ApplicationCommandLine::get_options_dict() will return it.
  192    * This "packing" is done according to the type of the argument --
  193    * booleans for normal flags, Glib::ustring's for strings, std::string's for
  194    * filenames, etc.  The packing only occurs if the flag is given (ie: we
  195    * do not pack a "false" Variant in the case that a flag is missing).
  196    *
  197    * In general, it is recommended that all commandline arguments are
  198    * parsed locally.  The options dictionary should then be used to
  199    * transmit the result of the parsing to the primary instance, where
  200    * Glib::VariantDict::lookup_value() can be used.  For local options, it is
  201    * possible to consult (and potentially remove) the option from the options dictionary.
  202    *
  203    * This function is new in GLib 2.40.  Before then, the only real choice
  204    * was to send all of the commandline arguments (options and all) to the
  205    * primary instance for handling.  Application ignored them completely
  206    * on the local side.  Calling this function "opts in" to the new
  207    * behaviour, and in particular, means that unrecognised options will be
  208    * treated as errors.  Unrecognised options have never been ignored when
  209    * Gio::Application::Flags::HANDLES_COMMAND_LINE is unset.
  210    *
  211    * If signal_handle_local_options() needs to see the list of
  212    * filenames, then the use of G_OPTION_REMAINING as @a long_name is recommended.
  213    * G_OPTION_REMAINING can be used as a key into
  214    * the options dictionary.  If you do use G_OPTION_REMAINING then you
  215    * need to handle these arguments for yourself because once they are
  216    * consumed, they will no longer be visible to the default handling
  217    * (which treats them as filenames to be opened).
  218    *
  219    * @newin{2,42}
  220    *
  221    * @param arg_type A Gio::Application::OptionType.
  222    * @param long_name The long name of an option can be used to specify it
  223    *     in a commandline as `--long_name`. Every option must have a
  224    *     long name.
  225    * @param short_name If an option has a short name, it can be specified
  226    *     `-short_name` in a commandline. @a short_name must be a printable
  227    *     ASCII character different from '-', or '\0' if the option has no
  228    *     short name.
  229    * @param description The description for the option in `--help` output.
  230    * @param arg_description The placeholder to use for the extra argument parsed
  231    *     by the option in `--help` output.
  232    * @param flags Flags from Glib::OptionEntry::Flags. Do not set OptionEntry::Flags::FILENAME.
  233    *     Character encoding is chosen with @a arg_type.
  234    */
  235   void add_main_option_entry(OptionType arg_type, const Glib::ustring& long_name,
  236     gchar short_name = '\0', const Glib::ustring& description = {},
  237     const Glib::ustring& arg_description = {},
  238     Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
  239   _IGNORE(g_application_add_main_option_entries, g_application_add_main_option)
  240 
  241   /** Adds a main option entry to be handled by the Application.
  242    *
  243    * Adds a string option entry, but lets the callback @a slot parse the extra
  244    * argument instead of having it packed in a Glib::VariantDict.
  245    *
  246    * If you create more than one Application instance (unusual),
  247    * one Application instance can't add an option with the same name as
  248    * another instance adds. This restriction does not apply to the
  249    * add_main_option_entry() that takes an OptionType parameter.
  250    *
  251    * @newin{2,42}
  252    *
  253    * @see add_main_option_entry(OptionType, const Glib::ustring&,
  254    *   gchar, const Glib::ustring&, const Glib::ustring&, Glib::OptionEntry::Flags)
  255    */
  256   void add_main_option_entry(const Glib::OptionGroup::SlotOptionArgString& slot,
  257     const Glib::ustring& long_name,
  258     gchar short_name = '\0', const Glib::ustring& description = {},
  259     const Glib::ustring& arg_description = {},
  260     Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
  261 
  262   /** Adds a main option entry to be handled by the Application.
  263    *
  264    * Adds a filename option entry, but lets the callback @a slot parse the extra
  265    * argument instead of having it packed in a Glib::VariantDict.
  266    *
  267    * If you create more than one Application instance (unusual),
  268    * one Application instance can't add an option with the same name as
  269    * another instance adds. This restriction does not apply to the
  270    * add_main_option_entry() that takes an OptionType parameter.
  271    *
  272    * @newin{2,42}
  273    *
  274    * @see add_main_option_entry(OptionType, const Glib::ustring&,
  275    *   gchar, const Glib::ustring&, const Glib::ustring&, Glib::OptionEntry::Flags)
  276    */
  277   void add_main_option_entry_filename(const Glib::OptionGroup::SlotOptionArgFilename& slot,
  278     const Glib::ustring& long_name,
  279     gchar short_name = '\0', const Glib::ustring& description = {},
  280     const Glib::ustring& arg_description = {},
  281     Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
  282 
  283   // GApplication takes ownership of the GOptionGroup, unrefing it later.
  284 #m4 _CONVERSION(`Glib::OptionGroup&',`GOptionGroup*',`($3).gobj_copy()')
  285   /** Adds a Glib::OptionGroup to the commandline handling of the application.
  286    *
  287    * This function is comparable to Glib::OptionContext::add_group().
  288    *
  289    * Unlike add_main_option_entry(), this function never transmits options to the
  290    * primary instance.
  291    *
  292    * The reason for that is because, by the time the options arrive at the
  293    * primary instance, it is typically too late to do anything with them.
  294    * Taking the GTK option group as an example: GTK will already have been
  295    * initialised by the time the signal_command_line() handler runs.
  296    * In the case that this is not the first-running instance of the
  297    * application, the existing instance may already have been running for
  298    * a very long time.
  299    *
  300    * This means that the options from Glib::OptionGroup are only really usable
  301    * in the case that the instance of the application being run is the
  302    * first instance. Passing options like `--display=` or `--gdk-debug=`
  303    * on future runs will have no effect on the existing primary instance.
  304    *
  305    * Calling this function will cause the options in the supplied option
  306    * group to be parsed, but it does not cause you to be "opted in" to the
  307    * new functionality whereby unrecognised options are rejected even if
  308    * Gio::Application::Flags::HANDLES_COMMAND_LINE was given.
  309    *
  310    * @newin{2,62}
  311    *
  312    * @param group A Glib::OptionGroup.
  313    * @note The group will not be copied, so it should exist for as long as the application exists.
  314    */
  315   _WRAP_METHOD(void add_option_group(Glib::OptionGroup& group), g_application_add_option_group)
  316 
  317   _WRAP_METHOD(void set_option_context_parameter_string(const Glib::ustring& parameter_string{NULL}), g_application_set_option_context_parameter_string)
  318   _WRAP_METHOD(void set_option_context_summary(const Glib::ustring& summary{NULL}), g_application_set_option_context_summary)
  319   _WRAP_METHOD(void set_option_context_description(const Glib::ustring& description{NULL}), g_application_set_option_context_description)
  320 
  321   _WRAP_METHOD(bool is_registered() const, g_application_get_is_registered)
  322   _WRAP_METHOD(bool is_remote() const, g_application_get_is_remote)
  323 
  324   //Renamed from register() because that is a C++ keyword.
  325   _WRAP_METHOD(bool register_application(const Glib::RefPtr<Gio::Cancellable>& cancellable{?}), g_application_register, errthrow)
  326   _IGNORE(g_application_impl_register)
  327 
  328   _WRAP_METHOD(void hold(), g_application_hold)
  329   _WRAP_METHOD(void release(), g_application_release)
  330   _WRAP_METHOD(void activate(), g_application_activate)
  331 
  332   using type_vec_files = std::vector< Glib::RefPtr<File> >;
  333 
  334   /* Opens the given files.
  335    *
  336    * In essence, this results in the open signal being emitted
  337    * in the primary instance.
  338    *
  339    * @a hint is simply passed through to the open signal.  It is
  340    * intended to be used by applications that have multiple modes for
  341    * opening files (eg: "view" vs "edit", etc).
  342    *
  343    * The application must be registered before calling this method
  344    * and it must have the Application::Flags::HANDLES_OPEN flag set.
  345    *
  346    * @param files The files to open. This must be non-empty.
  347    * @param hint A hint.
  348    *
  349    * @newin{2,32}
  350    */
  351   void open(const type_vec_files& files, const Glib::ustring& hint = {});
  352   _IGNORE(g_application_open)
  353 
  354   /* Opens the given file.
  355    *
  356    * In essence, this results in the open signal being emitted
  357    * in the primary instance.
  358    *
  359    * @a hint is simply passed through to the open signal.  It is
  360    * intended to be used by applications that have multiple modes for
  361    * opening files (eg: "view" vs "edit", etc).
  362    *
  363    * The application must be registered before calling this method
  364    * and it must have the Application::Flags::HANDLES_OPEN flag set.
  365    *
  366    * @param file The file to open. This must be non-empty.
  367    * @param hint A hint.
  368    *
  369    * @newin{2,32}
  370    */
  371   void open(const Glib::RefPtr<Gio::File>& file, const Glib::ustring& hint = {});
  372 
  373   _WRAP_METHOD(int run(int argc, char** argv), g_application_run)
  374 
  375   _WRAP_METHOD(void quit(), g_application_quit)
  376 
  377   _WRAP_METHOD(static void set_default(const Glib::RefPtr<Application>& application), g_application_set_default)
  378 
  379   /// Unsets any existing default application.
  380   static void unset_default();
  381 
  382   _WRAP_METHOD(static Glib::RefPtr<Application> get_default(), g_application_get_default, refreturn)
  383 
  384   _WRAP_METHOD(void mark_busy(), g_application_mark_busy)
  385   _WRAP_METHOD(void unmark_busy(), g_application_unmark_busy)
  386   _WRAP_METHOD(bool get_is_busy() const, g_application_get_is_busy)
  387 
  388   _WRAP_METHOD(void send_notification(const Glib::ustring& id{?}, const Glib::RefPtr<Notification>& notification), g_application_send_notification)
  389   _WRAP_METHOD(void withdraw_notification(const Glib::ustring& id), g_application_withdraw_notification)
  390 
  391 //TODO: Glib::RefPtr<Glib::ObjectBase>, Glib::ObjectBase, or both?
  392 //#m4 _CONVERSION(`const Glib::RefPtr<Glib::ObjectBase>&', `gpointer', `($3)->gobj()')
  393 //  _WRAP_METHOD(void bind_busy_property(const Glib::RefPtr<Glib::ObjectBase>& object, const Glib::ustring& property), g_application_bind_busy_property)
  394 //  _WRAP_METHOD(void unbind_busy_property(const Glib::RefPtr<Glib::ObjectBase>& object, const Glib::ustring& property), g_application_unbind_busy_property)
  395 
  396   _IGNORE_PROPERTY("action-group")
  397   _WRAP_PROPERTY("application-id", Glib::ustring)
  398   _WRAP_PROPERTY("flags", Flags)
  399   _WRAP_PROPERTY("inactivity-timeout", guint)
  400   _WRAP_PROPERTY("is-registered", bool)
  401   _WRAP_PROPERTY("is-remote", bool)
  402   _WRAP_PROPERTY("resource-base-path", std::string, newin "2,44")
  403   _WRAP_PROPERTY("is-busy", bool)
  404 
  405   _WRAP_SIGNAL(void startup(), "startup")
  406   _WRAP_SIGNAL(void shutdown(), "shutdown", newin "2,46")
  407   _WRAP_SIGNAL(void activate(), "activate")
  408 
  409   //We wrap the open signal without _WRAP_SIGNAL(), because we need to change its parameters.
  410   //See bug https://bugzilla.gnome.org/show_bug.cgi?id=637457
  411   Glib::SignalProxy<void(const type_vec_files&, const Glib::ustring&)> signal_open();
  412   _IGNORE_SIGNAL(open)
  413 
  414 #m4 _CONVERSION(`GApplicationCommandLine*', `const Glib::RefPtr<ApplicationCommandLine>&',`Glib::wrap($3, true)')
  415   _WRAP_SIGNAL(int command_line(const Glib::RefPtr<ApplicationCommandLine>& command_line), "command-line")
  416 
  417   //TODO: Avoid the use of the Variants in the VariantDict?
  418   //options must be non-const. The handler is meant to modify it. See the description
  419   //of add_main_option_entry(OptionType, ...).
  420 #m4 _CONVERSION(`GVariantDict*',`const Glib::RefPtr<Glib::VariantDict>&',`Glib::wrap($3, true)')
  421 #m4 _CONVERSION(`const Glib::RefPtr<Glib::VariantDict>&',`GVariantDict*',__CONVERT_REFPTR_TO_P)
  422   _WRAP_SIGNAL(int handle_local_options(const Glib::RefPtr<Glib::VariantDict>& options), "handle-local-options")
  423 
  424   _WRAP_SIGNAL(bool name_lost(), "name-lost")
  425 
  426 protected:
  427   virtual void on_open(const type_vec_files& files, const Glib::ustring& hint);
  428 
  429 #m4begin
  430   _PUSH(SECTION_PCC_CLASS_INIT_DEFAULT_SIGNAL_HANDLERS)
  431   klass->open = &open_callback;
  432   _SECTION(SECTION_PH_DEFAULT_SIGNAL_HANDLERS)
  433   static void open_callback(GApplication* self, GFile** files, gint n_files, const gchar* hint);
  434   _POP()
  435 #m4end
  436 
  437 #m4 _CONVERSION(`char**&', `gchar***',`&($3)')
  438 #m4 _CONVERSION(`gchar***', `char**&',`*($3)')
  439   _WRAP_VFUNC(bool local_command_line(char**& arguments, int& exit_status), local_command_line)
  440 
  441 #m4 _CONVERSION(`GVariant*',`const Glib::VariantBase&',`Glib::wrap($3,true)')
  442   _WRAP_VFUNC(void before_emit(const Glib::VariantBase& platform_data), "before_emit")
  443   _WRAP_VFUNC(void after_emit(const Glib::VariantBase& platform_data), "after_emit")
  444 
  445   //TODO: File a bug about GVariantBuilder not being registered with the GType system first:
  446   //_WRAP_VFUNC(void add_platform_data(Glib::VariantBuilder* builder), "add_platform_data")
  447 
  448   _WRAP_VFUNC(void quit_mainloop(), "quit_mainloop")
  449   _WRAP_VFUNC(void run_mainloop(), "run_mainloop")
  450 
  451 #m4 _CONVERSION(`GDBusConnection*', `const Glib::RefPtr<DBus::connection>&', `Glib::wrap($3, true)')
  452 #m4 _CONVERSION(`const Glib::RefPtr<DBus::Connection>&',`GDBusConnection*',__CONVERT_REFPTR_TO_P)
  453   _WRAP_VFUNC(bool dbus_register(const Glib::RefPtr<DBus::Connection>& connection, const Glib::ustring& object_path), "dbus_register", errthrow)
  454   _WRAP_VFUNC(void dbus_unregister(const Glib::RefPtr<DBus::Connection>& connection, const Glib::ustring& object_path), "dbus_unregister")
  455 
  456 private:
  457   /** This is just a way to call Glib::init() before calling a Glib::Object ctor,
  458    * so that glibmm's GQuarks are created before they are used.
  459    */
  460   const Glib::Class& custom_class_init();
  461 
  462   // Code, common to the public add_main_option_entry*() methods with a callback slot.
  463   void add_main_option_entry_private(const gchar* long_name, gchar short_name,
  464     const gchar* description, const gchar* arg_description,
  465     Glib::OptionEntry::Flags flags);
  466 };
  467 
  468 } // namespace Gio