/* Copyright (C) 2007 The gtkmm Development Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*/
_CONFIGINCLUDE(giommconfig.h)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
_DEFS(giomm,gio)
_PINCLUDE(glibmm/private/object_p.h)
namespace Gio
{
/** Application - Core application class.
* An Application is the foundation of an application, unique for a given
* application identifier. The Application class wraps some low-level
* platform-specific services and is intended to act as the foundation for
* higher-level application classes such as Gtk::Application or MxApplication.
* In general, you should not use this class outside of a higher level
* framework.
*
* One of the core features that Application provides is process uniqueness,
* in the context of a "session". The session concept is platform-dependent,
* but corresponds roughly to a graphical desktop login. When your application
* is launched again, its arguments are passed through platform communication
* to the already running program. The already running instance of the program
* is called the primary instance.
*
* Before using Application, you must choose an "application identifier". The
* expected form of an application identifier is very close to that of of a
* DBus
* bus name. Examples include: "com.example.MyApp",
* "org.example.internal-apps.Calculator". For details on valid application
* identifiers, see id_is_valid().
*
* Application provides convenient life cycle management by maintaining a
* use count for the primary application instance. The use count can be
* changed using hold() and release(). If it drops to zero, the application
* exits.
*
* Application also implements the ActionGroup and ActionMap
* interfaces and lets you easily export actions by adding them with
* Gio::ActionMap::add_action(). When invoking an action by calling
* Gio::ActionGroup::activate_action() on the application, it is always
* invoked in the primary instance.
*
* There is a number of different entry points into an Application:
*
* - via 'Activate' (i.e. just starting the application)
* - via 'Open' (i.e. opening some files)
* - via activating an action
*
* The signal_startup() signal lets you handle the application initialization
* for all of these in a single place.
*
* See the C API docs for an example.
*
* @newin{2,32}
*/
class GIOMM_API Application : public Glib::Object, public ActionGroup, public ActionMap
{
_CLASS_GOBJECT(Application, GApplication, G_APPLICATION, Glib::Object, GObject, , , GIOMM_API)
_IMPLEMENTS_INTERFACE(ActionGroup)
_IMPLEMENTS_INTERFACE(ActionMap)
public:
_WRAP_ENUM(Flags, GApplicationFlags, s#^FLAGS_##, decl_prefix GIOMM_API)
protected:
/** Constructs an application instance.
* If no application ID is given then some features (most notably application uniqueness) will be disabled.
*
* @param application_id The application ID.
* @param flags The application flags.
*/
explicit Application(const Glib::ustring& application_id = {}, Flags flags = Flags::NONE);
_IGNORE(g_application_new)
public:
_CUSTOM_DTOR()
// Application::OptionType wraps GOptionArg, but _WRAP_ENUM can't be used here.
// GOptionArg is defined in glib_enums.defs, not in gio_enums.defs.
/** The OptionType enum values determine the expected type of a command line option.
* If an option expects an extra argument, it can be specified in several ways;
* with a short option: "-x arg", with a long option: "--name arg" or combined
* in a single argument: "--name=arg". All option types except OptionType::BOOL
* expect an extra argument. OptionType::STRING_VECTOR and
* OptionType::FILENAME_VECTOR accept more than one extra argument.
*
* The descriptions of the enum values show what type of Glib::Variant<>
* is stored in a Glib::VariantDict.
*
* @newin{2,42}
*
* @ingroup glibmmEnums
*/
enum class OptionType
{
BOOL, ///< bool
STRING, ///< Glib::ustring
INT, ///< gint32
// CALLBACK,
FILENAME = INT+2, ///< std::string
STRING_VECTOR, ///< std::vector
FILENAME_VECTOR, ///< std::vector
DOUBLE, ///< double
INT64 ///< gint64
};
/** Creates an application instance.
* If no application ID is given then some features (most notably application uniqueness) will be disabled.
*
* @param application_id The application ID.
* @param flags The application flags.
*/
_WRAP_CREATE(const Glib::ustring& application_id = {}, Flags flags = Flags::NONE)
_WRAP_METHOD(static bool id_is_valid(const Glib::ustring& application_id), g_application_id_is_valid)
_WRAP_METHOD(Glib::ustring get_id() const, g_application_get_application_id)
_WRAP_METHOD(void set_id(const Glib::ustring& application_id), g_application_set_application_id)
_WRAP_METHOD(Glib::RefPtr get_dbus_connection(), g_application_get_dbus_connection, refreturn)
_WRAP_METHOD(Glib::RefPtr get_dbus_connection() const, g_application_get_dbus_connection, refreturn, constversion)
_WRAP_METHOD(Glib::ustring get_dbus_object_path() const, g_application_get_dbus_object_path)
_WRAP_METHOD(guint get_inactivity_timeout() const, g_application_get_inactivity_timeout)
_WRAP_METHOD(void set_inactivity_timeout(guint inactivity_timeout), g_application_set_inactivity_timeout)
_WRAP_METHOD(Flags get_flags() const, g_application_get_flags)
_WRAP_METHOD(void set_flags(Flags flags), g_application_set_flags)
_WRAP_METHOD(std::string get_resource_base_path() const, g_application_get_resource_base_path, newin "2,44")
_WRAP_METHOD(void set_resource_base_path(const std::string& resource_path), g_application_set_resource_base_path, newin "2,44")
/** Disable automatic resource loading functionality.
* See set_resource_base_path().
* @newin{2,44}
*/
void unset_resource_base_path();
_IGNORE(g_application_set_action_group)
//Note: We would like to add a group, not just some entries,
//so we can do pre and post parsing. See https://bugzilla.gnome.org/show_bug.cgi?id=727602
//but instead we need to use the VariantDict passed to the handle_local_options signal
//and provided by ApplicationCommandLine::get_options_dict() in on_command_line().
/** Adds a main option entry to be handled by the Application.
*
* This function is comparable to Glib::OptionGroup::add_entry() +
* Glib::OptionContext::set_main_group().
*
* After the commandline arguments are parsed, the
* signal_handle_local_options() signal will be emitted. At this
* point, the application can inspect the parsed values.
*
* Unlike OptionGroup + OptionContext, Application packs the arguments
* into a Glib::VariantDict which is passed to the
* signal_handle_local_options() handler, where it can be
* inspected and modified. If Gio::Application::Flags::HANDLES_COMMAND_LINE is
* set, then the resulting dictionary is sent to the primary instance,
* where Gio::ApplicationCommandLine::get_options_dict() will return it.
* This "packing" is done according to the type of the argument --
* booleans for normal flags, Glib::ustring's for strings, std::string's for
* filenames, etc. The packing only occurs if the flag is given (ie: we
* do not pack a "false" Variant in the case that a flag is missing).
*
* In general, it is recommended that all commandline arguments are
* parsed locally. The options dictionary should then be used to
* transmit the result of the parsing to the primary instance, where
* Glib::VariantDict::lookup_value() can be used. For local options, it is
* possible to consult (and potentially remove) the option from the options dictionary.
*
* This function is new in GLib 2.40. Before then, the only real choice
* was to send all of the commandline arguments (options and all) to the
* primary instance for handling. Application ignored them completely
* on the local side. Calling this function "opts in" to the new
* behaviour, and in particular, means that unrecognised options will be
* treated as errors. Unrecognised options have never been ignored when
* Gio::Application::Flags::HANDLES_COMMAND_LINE is unset.
*
* If signal_handle_local_options() needs to see the list of
* filenames, then the use of G_OPTION_REMAINING as @a long_name is recommended.
* G_OPTION_REMAINING can be used as a key into
* the options dictionary. If you do use G_OPTION_REMAINING then you
* need to handle these arguments for yourself because once they are
* consumed, they will no longer be visible to the default handling
* (which treats them as filenames to be opened).
*
* @newin{2,42}
*
* @param arg_type A Gio::Application::OptionType.
* @param long_name The long name of an option can be used to specify it
* in a commandline as `--long_name`. Every option must have a
* long name.
* @param short_name If an option has a short name, it can be specified
* `-short_name` in a commandline. @a short_name must be a printable
* ASCII character different from '-', or '\0' if the option has no
* short name.
* @param description The description for the option in `--help` output.
* @param arg_description The placeholder to use for the extra argument parsed
* by the option in `--help` output.
* @param flags Flags from Glib::OptionEntry::Flags. Do not set OptionEntry::Flags::FILENAME.
* Character encoding is chosen with @a arg_type.
*/
void add_main_option_entry(OptionType arg_type, const Glib::ustring& long_name,
gchar short_name = '\0', const Glib::ustring& description = {},
const Glib::ustring& arg_description = {},
Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
_IGNORE(g_application_add_main_option_entries, g_application_add_main_option)
/** Adds a main option entry to be handled by the Application.
*
* Adds a string option entry, but lets the callback @a slot parse the extra
* argument instead of having it packed in a Glib::VariantDict.
*
* If you create more than one Application instance (unusual),
* one Application instance can't add an option with the same name as
* another instance adds. This restriction does not apply to the
* add_main_option_entry() that takes an OptionType parameter.
*
* @newin{2,42}
*
* @see add_main_option_entry(OptionType, const Glib::ustring&,
* gchar, const Glib::ustring&, const Glib::ustring&, Glib::OptionEntry::Flags)
*/
void add_main_option_entry(const Glib::OptionGroup::SlotOptionArgString& slot,
const Glib::ustring& long_name,
gchar short_name = '\0', const Glib::ustring& description = {},
const Glib::ustring& arg_description = {},
Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
/** Adds a main option entry to be handled by the Application.
*
* Adds a filename option entry, but lets the callback @a slot parse the extra
* argument instead of having it packed in a Glib::VariantDict.
*
* If you create more than one Application instance (unusual),
* one Application instance can't add an option with the same name as
* another instance adds. This restriction does not apply to the
* add_main_option_entry() that takes an OptionType parameter.
*
* @newin{2,42}
*
* @see add_main_option_entry(OptionType, const Glib::ustring&,
* gchar, const Glib::ustring&, const Glib::ustring&, Glib::OptionEntry::Flags)
*/
void add_main_option_entry_filename(const Glib::OptionGroup::SlotOptionArgFilename& slot,
const Glib::ustring& long_name,
gchar short_name = '\0', const Glib::ustring& description = {},
const Glib::ustring& arg_description = {},
Glib::OptionEntry::Flags flags = Glib::OptionEntry::Flags::NONE);
// GApplication takes ownership of the GOptionGroup, unrefing it later.
#m4 _CONVERSION(`Glib::OptionGroup&',`GOptionGroup*',`($3).gobj_copy()')
/** Adds a Glib::OptionGroup to the commandline handling of the application.
*
* This function is comparable to Glib::OptionContext::add_group().
*
* Unlike add_main_option_entry(), this function never transmits options to the
* primary instance.
*
* The reason for that is because, by the time the options arrive at the
* primary instance, it is typically too late to do anything with them.
* Taking the GTK option group as an example: GTK will already have been
* initialised by the time the signal_command_line() handler runs.
* In the case that this is not the first-running instance of the
* application, the existing instance may already have been running for
* a very long time.
*
* This means that the options from Glib::OptionGroup are only really usable
* in the case that the instance of the application being run is the
* first instance. Passing options like `--display=` or `--gdk-debug=`
* on future runs will have no effect on the existing primary instance.
*
* Calling this function will cause the options in the supplied option
* group to be parsed, but it does not cause you to be "opted in" to the
* new functionality whereby unrecognised options are rejected even if
* Gio::Application::Flags::HANDLES_COMMAND_LINE was given.
*
* @newin{2,62}
*
* @param group A Glib::OptionGroup.
* @note The group will not be copied, so it should exist for as long as the application exists.
*/
_WRAP_METHOD(void add_option_group(Glib::OptionGroup& group), g_application_add_option_group)
_WRAP_METHOD(void set_option_context_parameter_string(const Glib::ustring& parameter_string{NULL}), g_application_set_option_context_parameter_string)
_WRAP_METHOD(void set_option_context_summary(const Glib::ustring& summary{NULL}), g_application_set_option_context_summary)
_WRAP_METHOD(void set_option_context_description(const Glib::ustring& description{NULL}), g_application_set_option_context_description)
_WRAP_METHOD(bool is_registered() const, g_application_get_is_registered)
_WRAP_METHOD(bool is_remote() const, g_application_get_is_remote)
//Renamed from register() because that is a C++ keyword.
_WRAP_METHOD(bool register_application(const Glib::RefPtr& cancellable{?}), g_application_register, errthrow)
_IGNORE(g_application_impl_register)
_WRAP_METHOD(void hold(), g_application_hold)
_WRAP_METHOD(void release(), g_application_release)
_WRAP_METHOD(void activate(), g_application_activate)
using type_vec_files = std::vector< Glib::RefPtr >;
/* Opens the given files.
*
* In essence, this results in the open signal being emitted
* in the primary instance.
*
* @a hint is simply passed through to the open signal. It is
* intended to be used by applications that have multiple modes for
* opening files (eg: "view" vs "edit", etc).
*
* The application must be registered before calling this method
* and it must have the Application::Flags::HANDLES_OPEN flag set.
*
* @param files The files to open. This must be non-empty.
* @param hint A hint.
*
* @newin{2,32}
*/
void open(const type_vec_files& files, const Glib::ustring& hint = {});
_IGNORE(g_application_open)
/* Opens the given file.
*
* In essence, this results in the open signal being emitted
* in the primary instance.
*
* @a hint is simply passed through to the open signal. It is
* intended to be used by applications that have multiple modes for
* opening files (eg: "view" vs "edit", etc).
*
* The application must be registered before calling this method
* and it must have the Application::Flags::HANDLES_OPEN flag set.
*
* @param file The file to open. This must be non-empty.
* @param hint A hint.
*
* @newin{2,32}
*/
void open(const Glib::RefPtr& file, const Glib::ustring& hint = {});
_WRAP_METHOD(int run(int argc, char** argv), g_application_run)
_WRAP_METHOD(void quit(), g_application_quit)
_WRAP_METHOD(static void set_default(const Glib::RefPtr& application), g_application_set_default)
/// Unsets any existing default application.
static void unset_default();
_WRAP_METHOD(static Glib::RefPtr get_default(), g_application_get_default, refreturn)
_WRAP_METHOD(void mark_busy(), g_application_mark_busy)
_WRAP_METHOD(void unmark_busy(), g_application_unmark_busy)
_WRAP_METHOD(bool get_is_busy() const, g_application_get_is_busy)
_WRAP_METHOD(void send_notification(const Glib::ustring& id{?}, const Glib::RefPtr& notification), g_application_send_notification)
_WRAP_METHOD(void withdraw_notification(const Glib::ustring& id), g_application_withdraw_notification)
//TODO: Glib::RefPtr, Glib::ObjectBase, or both?
//#m4 _CONVERSION(`const Glib::RefPtr&', `gpointer', `($3)->gobj()')
// _WRAP_METHOD(void bind_busy_property(const Glib::RefPtr& object, const Glib::ustring& property), g_application_bind_busy_property)
// _WRAP_METHOD(void unbind_busy_property(const Glib::RefPtr& object, const Glib::ustring& property), g_application_unbind_busy_property)
_IGNORE_PROPERTY("action-group")
_WRAP_PROPERTY("application-id", Glib::ustring)
_WRAP_PROPERTY("flags", Flags)
_WRAP_PROPERTY("inactivity-timeout", guint)
_WRAP_PROPERTY("is-registered", bool)
_WRAP_PROPERTY("is-remote", bool)
_WRAP_PROPERTY("resource-base-path", std::string, newin "2,44")
_WRAP_PROPERTY("is-busy", bool)
_WRAP_SIGNAL(void startup(), "startup")
_WRAP_SIGNAL(void shutdown(), "shutdown", newin "2,46")
_WRAP_SIGNAL(void activate(), "activate")
//We wrap the open signal without _WRAP_SIGNAL(), because we need to change its parameters.
//See bug https://bugzilla.gnome.org/show_bug.cgi?id=637457
Glib::SignalProxy signal_open();
_IGNORE_SIGNAL(open)
#m4 _CONVERSION(`GApplicationCommandLine*', `const Glib::RefPtr&',`Glib::wrap($3, true)')
_WRAP_SIGNAL(int command_line(const Glib::RefPtr& command_line), "command-line")
//TODO: Avoid the use of the Variants in the VariantDict?
//options must be non-const. The handler is meant to modify it. See the description
//of add_main_option_entry(OptionType, ...).
#m4 _CONVERSION(`GVariantDict*',`const Glib::RefPtr&',`Glib::wrap($3, true)')
#m4 _CONVERSION(`const Glib::RefPtr&',`GVariantDict*',__CONVERT_REFPTR_TO_P)
_WRAP_SIGNAL(int handle_local_options(const Glib::RefPtr& options), "handle-local-options")
_WRAP_SIGNAL(bool name_lost(), "name-lost")
protected:
virtual void on_open(const type_vec_files& files, const Glib::ustring& hint);
#m4begin
_PUSH(SECTION_PCC_CLASS_INIT_DEFAULT_SIGNAL_HANDLERS)
klass->open = &open_callback;
_SECTION(SECTION_PH_DEFAULT_SIGNAL_HANDLERS)
static void open_callback(GApplication* self, GFile** files, gint n_files, const gchar* hint);
_POP()
#m4end
#m4 _CONVERSION(`char**&', `gchar***',`&($3)')
#m4 _CONVERSION(`gchar***', `char**&',`*($3)')
_WRAP_VFUNC(bool local_command_line(char**& arguments, int& exit_status), local_command_line)
#m4 _CONVERSION(`GVariant*',`const Glib::VariantBase&',`Glib::wrap($3,true)')
_WRAP_VFUNC(void before_emit(const Glib::VariantBase& platform_data), "before_emit")
_WRAP_VFUNC(void after_emit(const Glib::VariantBase& platform_data), "after_emit")
//TODO: File a bug about GVariantBuilder not being registered with the GType system first:
//_WRAP_VFUNC(void add_platform_data(Glib::VariantBuilder* builder), "add_platform_data")
_WRAP_VFUNC(void quit_mainloop(), "quit_mainloop")
_WRAP_VFUNC(void run_mainloop(), "run_mainloop")
#m4 _CONVERSION(`GDBusConnection*', `const Glib::RefPtr&', `Glib::wrap($3, true)')
#m4 _CONVERSION(`const Glib::RefPtr&',`GDBusConnection*',__CONVERT_REFPTR_TO_P)
_WRAP_VFUNC(bool dbus_register(const Glib::RefPtr& connection, const Glib::ustring& object_path), "dbus_register", errthrow)
_WRAP_VFUNC(void dbus_unregister(const Glib::RefPtr& connection, const Glib::ustring& object_path), "dbus_unregister")
private:
/** This is just a way to call Glib::init() before calling a Glib::Object ctor,
* so that glibmm's GQuarks are created before they are used.
*/
const Glib::Class& custom_class_init();
// Code, common to the public add_main_option_entry*() methods with a callback slot.
void add_main_option_entry_private(const gchar* long_name, gchar short_name,
const gchar* description, const gchar* arg_description,
Glib::OptionEntry::Flags flags);
};
} // namespace Gio