1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.Application; 26 27 private import gio.ActionGroupIF; 28 private import gio.ActionGroupT; 29 private import gio.ActionMapIF; 30 private import gio.ActionMapT; 31 private import gio.ApplicationCommandLine; 32 private import gio.Cancellable; 33 private import gio.DBusConnection; 34 private import gio.File; 35 private import gio.FileIF; 36 private import gio.Notification; 37 private import glib.ConstructionException; 38 private import glib.ErrorG; 39 private import glib.GException; 40 private import glib.OptionGroup; 41 private import glib.Str; 42 private import glib.VariantDict; 43 private import gobject.ObjectG; 44 private import gobject.Signals; 45 public import gtkc.gdktypes; 46 private import gtkc.gio; 47 public import gtkc.giotypes; 48 private import std.algorithm; 49 50 51 /** 52 * A #GApplication is the foundation of an application. It wraps some 53 * low-level platform-specific services and is intended to act as the 54 * foundation for higher-level application classes such as 55 * #GtkApplication or #MxApplication. In general, you should not use 56 * this class outside of a higher level framework. 57 * 58 * GApplication provides convenient life cycle management by maintaining 59 * a "use count" for the primary application instance. The use count can 60 * be changed using g_application_hold() and g_application_release(). If 61 * it drops to zero, the application exits. Higher-level classes such as 62 * #GtkApplication employ the use count to ensure that the application 63 * stays alive as long as it has any opened windows. 64 * 65 * Another feature that GApplication (optionally) provides is process 66 * uniqueness. Applications can make use of this functionality by 67 * providing a unique application ID. If given, only one application 68 * with this ID can be running at a time per session. The session 69 * concept is platform-dependent, but corresponds roughly to a graphical 70 * desktop login. When your application is launched again, its 71 * arguments are passed through platform communication to the already 72 * running program. The already running instance of the program is 73 * called the "primary instance"; for non-unique applications this is 74 * the always the current instance. On Linux, the D-Bus session bus 75 * is used for communication. 76 * 77 * The use of #GApplication differs from some other commonly-used 78 * uniqueness libraries (such as libunique) in important ways. The 79 * application is not expected to manually register itself and check 80 * if it is the primary instance. Instead, the main() function of a 81 * #GApplication should do very little more than instantiating the 82 * application instance, possibly connecting signal handlers, then 83 * calling g_application_run(). All checks for uniqueness are done 84 * internally. If the application is the primary instance then the 85 * startup signal is emitted and the mainloop runs. If the application 86 * is not the primary instance then a signal is sent to the primary 87 * instance and g_application_run() promptly returns. See the code 88 * examples below. 89 * 90 * If used, the expected form of an application identifier is very close 91 * to that of of a 92 * [DBus bus name](http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface). 93 * Examples include: "com.example.MyApp", "org.example.internal-apps.Calculator". 94 * For details on valid application identifiers, see g_application_id_is_valid(). 95 * 96 * On Linux, the application identifier is claimed as a well-known bus name 97 * on the user's session bus. This means that the uniqueness of your 98 * application is scoped to the current session. It also means that your 99 * application may provide additional services (through registration of other 100 * object paths) at that bus name. The registration of these object paths 101 * should be done with the shared GDBus session bus. Note that due to the 102 * internal architecture of GDBus, method calls can be dispatched at any time 103 * (even if a main loop is not running). For this reason, you must ensure that 104 * any object paths that you wish to register are registered before #GApplication 105 * attempts to acquire the bus name of your application (which happens in 106 * g_application_register()). Unfortunately, this means that you cannot use 107 * g_application_get_is_remote() to decide if you want to register object paths. 108 * 109 * GApplication also implements the #GActionGroup and #GActionMap 110 * interfaces and lets you easily export actions by adding them with 111 * g_action_map_add_action(). When invoking an action by calling 112 * g_action_group_activate_action() on the application, it is always 113 * invoked in the primary instance. The actions are also exported on 114 * the session bus, and GIO provides the #GDBusActionGroup wrapper to 115 * conveniently access them remotely. GIO provides a #GDBusMenuModel wrapper 116 * for remote access to exported #GMenuModels. 117 * 118 * There is a number of different entry points into a GApplication: 119 * 120 * - via 'Activate' (i.e. just starting the application) 121 * 122 * - via 'Open' (i.e. opening some files) 123 * 124 * - by handling a command-line 125 * 126 * - via activating an action 127 * 128 * The #GApplication::startup signal lets you handle the application 129 * initialization for all of these in a single place. 130 * 131 * Regardless of which of these entry points is used to start the 132 * application, GApplication passes some "platform data from the 133 * launching instance to the primary instance, in the form of a 134 * #GVariant dictionary mapping strings to variants. To use platform 135 * data, override the @before_emit or @after_emit virtual functions 136 * in your #GApplication subclass. When dealing with 137 * #GApplicationCommandLine objects, the platform data is 138 * directly available via g_application_command_line_get_cwd(), 139 * g_application_command_line_get_environ() and 140 * g_application_command_line_get_platform_data(). 141 * 142 * As the name indicates, the platform data may vary depending on the 143 * operating system, but it always includes the current directory (key 144 * "cwd"), and optionally the environment (ie the set of environment 145 * variables and their values) of the calling process (key "environ"). 146 * The environment is only added to the platform data if the 147 * %G_APPLICATION_SEND_ENVIRONMENT flag is set. #GApplication subclasses 148 * can add their own platform data by overriding the @add_platform_data 149 * virtual function. For instance, #GtkApplication adds startup notification 150 * data in this way. 151 * 152 * To parse commandline arguments you may handle the 153 * #GApplication::command-line signal or override the local_command_line() 154 * vfunc, to parse them in either the primary instance or the local instance, 155 * respectively. 156 * 157 * For an example of opening files with a GApplication, see 158 * [gapplication-example-open.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-open.c). 159 * 160 * For an example of using actions with GApplication, see 161 * [gapplication-example-actions.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-actions.c). 162 * 163 * For an example of using extra D-Bus hooks with GApplication, see 164 * [gapplication-example-dbushooks.c](https://git.gnome.org/browse/glib/tree/gio/tests/gapplication-example-dbushooks.c). 165 * 166 * Since: 2.28 167 */ 168 public class Application : ObjectG, ActionGroupIF, ActionMapIF 169 { 170 /** the main Gtk struct */ 171 protected GApplication* gApplication; 172 173 /** Get the main Gtk struct */ 174 public GApplication* getApplicationStruct() 175 { 176 return gApplication; 177 } 178 179 /** the main Gtk struct as a void* */ 180 protected override void* getStruct() 181 { 182 return cast(void*)gApplication; 183 } 184 185 protected override void setStruct(GObject* obj) 186 { 187 gApplication = cast(GApplication*)obj; 188 super.setStruct(obj); 189 } 190 191 /** 192 * Sets our main struct and passes it to the parent class. 193 */ 194 public this (GApplication* gApplication, bool ownedRef = false) 195 { 196 this.gApplication = gApplication; 197 super(cast(GObject*)gApplication, ownedRef); 198 } 199 200 // add the ActionGroup capabilities 201 mixin ActionGroupT!(GApplication); 202 203 // add the ActionMap capabilities 204 mixin ActionMapT!(GApplication); 205 206 protected class ScopedOnCommandLineDelegateWrapper 207 { 208 int delegate(Scoped!ApplicationCommandLine, Application) dlg; 209 gulong handlerId; 210 ConnectFlags flags; 211 this(int delegate(Scoped!ApplicationCommandLine, Application) dlg, gulong handlerId, ConnectFlags flags) 212 { 213 this.dlg = dlg; 214 this.handlerId = handlerId; 215 this.flags = flags; 216 } 217 } 218 219 protected ScopedOnCommandLineDelegateWrapper[] scopedOnCommandLineListeners; 220 221 /** 222 * The ::command-line signal is emitted on the primary instance when 223 * a commandline is not handled locally. See g_application_run() and 224 * the #GApplicationCommandLine documentation for more information. 225 * 226 * Params: 227 * commandLine = a #GApplicationCommandLine representing the 228 * passed commandline 229 * 230 * Return: An integer that is set as the exit status for the calling 231 * process. See g_application_command_line_set_exit_status(). 232 */ 233 gulong addOnCommandLine(int delegate(Scoped!ApplicationCommandLine, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 234 { 235 scopedOnCommandLineListeners ~= new ScopedOnCommandLineDelegateWrapper(dlg, 0, connectFlags); 236 onCommandLineListeners[scopedOnCommandLineListeners.length - 1].handlerId = Signals.connectData( 237 this, 238 "command-line", 239 cast(GCallback)&callBackScopedCommandLine, 240 cast(void*)scopedOnCommandLineListeners[scopedOnCommandLineListeners.length - 1], 241 cast(GClosureNotify)&callBackScopedCommandLineDestroy, 242 connectFlags); 243 return scopedOnCommandLineListeners[scopedOnCommandLineListeners.length - 1].handlerId; 244 } 245 246 extern(C) static int callBackScopedCommandLine(GApplication* applicationStruct, GApplicationCommandLine* commandLine, ScopedOnCommandLineDelegateWrapper wrapper) 247 { 248 return wrapper.dlg(scoped!ApplicationCommandLine(commandLine), wrapper.outer); 249 } 250 251 extern(C) static void callBackScopedCommandLineDestroy(OnCommandLineDelegateWrapper wrapper, GClosure* closure) 252 { 253 wrapper.outer.internalRemoveOnCommandLine(wrapper); 254 } 255 256 protected void internalRemoveOnCommandLine(ScopedOnCommandLineDelegateWrapper source) 257 { 258 foreach(index, wrapper; scopedOnCommandLineListeners) 259 { 260 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 261 { 262 scopedOnCommandLineListeners[index] = null; 263 scopedOnCommandLineListeners = std.algorithm.remove(scopedOnCommandLineListeners, index); 264 break; 265 } 266 } 267 } 268 269 /** 270 */ 271 272 /** */ 273 public static GType getType() 274 { 275 return g_application_get_type(); 276 } 277 278 /** 279 * Creates a new #GApplication instance. 280 * 281 * If non-%NULL, the application id must be valid. See 282 * g_application_id_is_valid(). 283 * 284 * If no application ID is given then some features of #GApplication 285 * (most notably application uniqueness) will be disabled. 286 * 287 * Params: 288 * applicationId = the application id 289 * flags = the application flags 290 * 291 * Return: a new #GApplication instance 292 * 293 * Throws: ConstructionException GTK+ fails to create the object. 294 */ 295 public this(string applicationId, GApplicationFlags flags) 296 { 297 auto p = g_application_new(Str.toStringz(applicationId), flags); 298 299 if(p is null) 300 { 301 throw new ConstructionException("null returned by new"); 302 } 303 304 this(cast(GApplication*) p, true); 305 } 306 307 /** 308 * Returns the default #GApplication instance for this process. 309 * 310 * Normally there is only one #GApplication per process and it becomes 311 * the default when it is created. You can exercise more control over 312 * this by using g_application_set_default(). 313 * 314 * If there is no default application then %NULL is returned. 315 * 316 * Return: the default application for this process, or %NULL 317 * 318 * Since: 2.32 319 */ 320 public static Application getDefault() 321 { 322 auto p = g_application_get_default(); 323 324 if(p is null) 325 { 326 return null; 327 } 328 329 return ObjectG.getDObject!(Application)(cast(GApplication*) p); 330 } 331 332 /** 333 * Checks if @application_id is a valid application identifier. 334 * 335 * A valid ID is required for calls to g_application_new() and 336 * g_application_set_application_id(). 337 * 338 * For convenience, the restrictions on application identifiers are 339 * reproduced here: 340 * 341 * - Application identifiers must contain only the ASCII characters 342 * "[A-Z][a-z][0-9]_-." and must not begin with a digit. 343 * 344 * - Application identifiers must contain at least one '.' (period) 345 * character (and thus at least three elements). 346 * 347 * - Application identifiers must not begin or end with a '.' (period) 348 * character. 349 * 350 * - Application identifiers must not contain consecutive '.' (period) 351 * characters. 352 * 353 * - Application identifiers must not exceed 255 characters. 354 * 355 * Params: 356 * applicationId = a potential application identifier 357 * 358 * Return: %TRUE if @application_id is valid 359 */ 360 public static bool idIsValid(string applicationId) 361 { 362 return g_application_id_is_valid(Str.toStringz(applicationId)) != 0; 363 } 364 365 /** 366 * Activates the application. 367 * 368 * In essence, this results in the #GApplication::activate signal being 369 * emitted in the primary instance. 370 * 371 * The application must be registered before calling this function. 372 * 373 * Since: 2.28 374 */ 375 public void activate() 376 { 377 g_application_activate(gApplication); 378 } 379 380 /** 381 * Add an option to be handled by @application. 382 * 383 * Calling this function is the equivalent of calling 384 * g_application_add_main_option_entries() with a single #GOptionEntry 385 * that has its arg_data member set to %NULL. 386 * 387 * The parsed arguments will be packed into a #GVariantDict which 388 * is passed to #GApplication::handle-local-options. If 389 * %G_APPLICATION_HANDLES_COMMAND_LINE is set, then it will also 390 * be sent to the primary instance. See 391 * g_application_add_main_option_entries() for more details. 392 * 393 * See #GOptionEntry for more documentation of the arguments. 394 * 395 * Params: 396 * longName = the long name of an option used to specify it in a commandline 397 * shortName = the short name of an option 398 * flags = flags from #GOptionFlags 399 * arg = the type of the option, as a #GOptionArg 400 * description = the description for the option in `--help` output 401 * argDescription = the placeholder to use for the extra argument 402 * parsed by the option in `--help` output 403 * 404 * Since: 2.42 405 */ 406 public void addMainOption(string longName, char shortName, GOptionFlags flags, GOptionArg arg, string description, string argDescription) 407 { 408 g_application_add_main_option(gApplication, Str.toStringz(longName), shortName, flags, arg, Str.toStringz(description), Str.toStringz(argDescription)); 409 } 410 411 /** 412 * Adds main option entries to be handled by @application. 413 * 414 * This function is comparable to g_option_context_add_main_entries(). 415 * 416 * After the commandline arguments are parsed, the 417 * #GApplication::handle-local-options signal will be emitted. At this 418 * point, the application can inspect the values pointed to by @arg_data 419 * in the given #GOptionEntrys. 420 * 421 * Unlike #GOptionContext, #GApplication supports giving a %NULL 422 * @arg_data for a non-callback #GOptionEntry. This results in the 423 * argument in question being packed into a #GVariantDict which is also 424 * passed to #GApplication::handle-local-options, where it can be 425 * inspected and modified. If %G_APPLICATION_HANDLES_COMMAND_LINE is 426 * set, then the resulting dictionary is sent to the primary instance, 427 * where g_application_command_line_get_options_dict() will return it. 428 * This "packing" is done according to the type of the argument -- 429 * booleans for normal flags, strings for strings, bytestrings for 430 * filenames, etc. The packing only occurs if the flag is given (ie: we 431 * do not pack a "false" #GVariant in the case that a flag is missing). 432 * 433 * In general, it is recommended that all commandline arguments are 434 * parsed locally. The options dictionary should then be used to 435 * transmit the result of the parsing to the primary instance, where 436 * g_variant_dict_lookup() can be used. For local options, it is 437 * possible to either use @arg_data in the usual way, or to consult (and 438 * potentially remove) the option from the options dictionary. 439 * 440 * This function is new in GLib 2.40. Before then, the only real choice 441 * was to send all of the commandline arguments (options and all) to the 442 * primary instance for handling. #GApplication ignored them completely 443 * on the local side. Calling this function "opts in" to the new 444 * behaviour, and in particular, means that unrecognised options will be 445 * treated as errors. Unrecognised options have never been ignored when 446 * %G_APPLICATION_HANDLES_COMMAND_LINE is unset. 447 * 448 * If #GApplication::handle-local-options needs to see the list of 449 * filenames, then the use of %G_OPTION_REMAINING is recommended. If 450 * @arg_data is %NULL then %G_OPTION_REMAINING can be used as a key into 451 * the options dictionary. If you do use %G_OPTION_REMAINING then you 452 * need to handle these arguments for yourself because once they are 453 * consumed, they will no longer be visible to the default handling 454 * (which treats them as filenames to be opened). 455 * 456 * It is important to use the proper GVariant format when retrieving 457 * the options with g_variant_dict_lookup(): 458 * - for %G_OPTION_ARG_NONE, use b 459 * - for %G_OPTION_ARG_STRING, use &s 460 * - for %G_OPTION_ARG_INT, use i 461 * - for %G_OPTION_ARG_INT64, use x 462 * - for %G_OPTION_ARG_DOUBLE, use d 463 * - for %G_OPTION_ARG_FILENAME, use ^ay 464 * - for %G_OPTION_ARG_STRING_ARRAY, use &as 465 * - for %G_OPTION_ARG_FILENAME_ARRAY, use ^aay 466 * 467 * Params: 468 * entries = a 469 * %NULL-terminated list of #GOptionEntrys 470 * 471 * Since: 2.40 472 */ 473 public void addMainOptionEntries(GOptionEntry[] entries) 474 { 475 g_application_add_main_option_entries(gApplication, entries.ptr); 476 } 477 478 /** 479 * Adds a #GOptionGroup to the commandline handling of @application. 480 * 481 * This function is comparable to g_option_context_add_group(). 482 * 483 * Unlike g_application_add_main_option_entries(), this function does 484 * not deal with %NULL @arg_data and never transmits options to the 485 * primary instance. 486 * 487 * The reason for that is because, by the time the options arrive at the 488 * primary instance, it is typically too late to do anything with them. 489 * Taking the GTK option group as an example: GTK will already have been 490 * initialised by the time the #GApplication::command-line handler runs. 491 * In the case that this is not the first-running instance of the 492 * application, the existing instance may already have been running for 493 * a very long time. 494 * 495 * This means that the options from #GOptionGroup are only really usable 496 * in the case that the instance of the application being run is the 497 * first instance. Passing options like `--display=` or `--gdk-debug=` 498 * on future runs will have no effect on the existing primary instance. 499 * 500 * Calling this function will cause the options in the supplied option 501 * group to be parsed, but it does not cause you to be "opted in" to the 502 * new functionality whereby unrecognised options are rejected even if 503 * %G_APPLICATION_HANDLES_COMMAND_LINE was given. 504 * 505 * Params: 506 * group = a #GOptionGroup 507 * 508 * Since: 2.40 509 */ 510 public void addOptionGroup(OptionGroup group) 511 { 512 g_application_add_option_group(gApplication, (group is null) ? null : group.getOptionGroupStruct()); 513 } 514 515 /** 516 * Marks @application as busy (see g_application_mark_busy()) while 517 * @property on @object is %TRUE. 518 * 519 * The binding holds a reference to @application while it is active, but 520 * not to @object. Instead, the binding is destroyed when @object is 521 * finalized. 522 * 523 * Params: 524 * object = a #GObject 525 * property = the name of a boolean property of @object 526 * 527 * Since: 2.44 528 */ 529 public void bindBusyProperty(ObjectG object, string property) 530 { 531 g_application_bind_busy_property(gApplication, (object is null) ? null : object.getObjectGStruct(), Str.toStringz(property)); 532 } 533 534 /** 535 * Gets the unique identifier for @application. 536 * 537 * Return: the identifier for @application, owned by @application 538 * 539 * Since: 2.28 540 */ 541 public string getApplicationId() 542 { 543 return Str.toString(g_application_get_application_id(gApplication)); 544 } 545 546 /** 547 * Gets the #GDBusConnection being used by the application, or %NULL. 548 * 549 * If #GApplication is using its D-Bus backend then this function will 550 * return the #GDBusConnection being used for uniqueness and 551 * communication with the desktop environment and other instances of the 552 * application. 553 * 554 * If #GApplication is not using D-Bus then this function will return 555 * %NULL. This includes the situation where the D-Bus backend would 556 * normally be in use but we were unable to connect to the bus. 557 * 558 * This function must not be called before the application has been 559 * registered. See g_application_get_is_registered(). 560 * 561 * Return: a #GDBusConnection, or %NULL 562 * 563 * Since: 2.34 564 */ 565 public DBusConnection getDbusConnection() 566 { 567 auto p = g_application_get_dbus_connection(gApplication); 568 569 if(p is null) 570 { 571 return null; 572 } 573 574 return ObjectG.getDObject!(DBusConnection)(cast(GDBusConnection*) p); 575 } 576 577 /** 578 * Gets the D-Bus object path being used by the application, or %NULL. 579 * 580 * If #GApplication is using its D-Bus backend then this function will 581 * return the D-Bus object path that #GApplication is using. If the 582 * application is the primary instance then there is an object published 583 * at this path. If the application is not the primary instance then 584 * the result of this function is undefined. 585 * 586 * If #GApplication is not using D-Bus then this function will return 587 * %NULL. This includes the situation where the D-Bus backend would 588 * normally be in use but we were unable to connect to the bus. 589 * 590 * This function must not be called before the application has been 591 * registered. See g_application_get_is_registered(). 592 * 593 * Return: the object path, or %NULL 594 * 595 * Since: 2.34 596 */ 597 public string getDbusObjectPath() 598 { 599 return Str.toString(g_application_get_dbus_object_path(gApplication)); 600 } 601 602 /** 603 * Gets the flags for @application. 604 * 605 * See #GApplicationFlags. 606 * 607 * Return: the flags for @application 608 * 609 * Since: 2.28 610 */ 611 public GApplicationFlags getFlags() 612 { 613 return g_application_get_flags(gApplication); 614 } 615 616 /** 617 * Gets the current inactivity timeout for the application. 618 * 619 * This is the amount of time (in milliseconds) after the last call to 620 * g_application_release() before the application stops running. 621 * 622 * Return: the timeout, in milliseconds 623 * 624 * Since: 2.28 625 */ 626 public uint getInactivityTimeout() 627 { 628 return g_application_get_inactivity_timeout(gApplication); 629 } 630 631 /** 632 * Gets the application's current busy state, as set through 633 * g_application_mark_busy() or g_application_bind_busy_property(). 634 * 635 * Return: %TRUE if @application is currenty marked as busy 636 * 637 * Since: 2.44 638 */ 639 public bool getIsBusy() 640 { 641 return g_application_get_is_busy(gApplication) != 0; 642 } 643 644 /** 645 * Checks if @application is registered. 646 * 647 * An application is registered if g_application_register() has been 648 * successfully called. 649 * 650 * Return: %TRUE if @application is registered 651 * 652 * Since: 2.28 653 */ 654 public bool getIsRegistered() 655 { 656 return g_application_get_is_registered(gApplication) != 0; 657 } 658 659 /** 660 * Checks if @application is remote. 661 * 662 * If @application is remote then it means that another instance of 663 * application already exists (the 'primary' instance). Calls to 664 * perform actions on @application will result in the actions being 665 * performed by the primary instance. 666 * 667 * The value of this property cannot be accessed before 668 * g_application_register() has been called. See 669 * g_application_get_is_registered(). 670 * 671 * Return: %TRUE if @application is remote 672 * 673 * Since: 2.28 674 */ 675 public bool getIsRemote() 676 { 677 return g_application_get_is_remote(gApplication) != 0; 678 } 679 680 /** 681 * Gets the resource base path of @application. 682 * 683 * See g_application_set_resource_base_path() for more information. 684 * 685 * Return: the base resource path, if one is set 686 * 687 * Since: 2.42 688 */ 689 public string getResourceBasePath() 690 { 691 return Str.toString(g_application_get_resource_base_path(gApplication)); 692 } 693 694 /** 695 * Increases the use count of @application. 696 * 697 * Use this function to indicate that the application has a reason to 698 * continue to run. For example, g_application_hold() is called by GTK+ 699 * when a toplevel window is on the screen. 700 * 701 * To cancel the hold, call g_application_release(). 702 */ 703 public void hold() 704 { 705 g_application_hold(gApplication); 706 } 707 708 /** 709 * Increases the busy count of @application. 710 * 711 * Use this function to indicate that the application is busy, for instance 712 * while a long running operation is pending. 713 * 714 * The busy state will be exposed to other processes, so a session shell will 715 * use that information to indicate the state to the user (e.g. with a 716 * spinner). 717 * 718 * To cancel the busy indication, use g_application_unmark_busy(). 719 * 720 * Since: 2.38 721 */ 722 public void markBusy() 723 { 724 g_application_mark_busy(gApplication); 725 } 726 727 /** 728 * Opens the given files. 729 * 730 * In essence, this results in the #GApplication::open signal being emitted 731 * in the primary instance. 732 * 733 * @n_files must be greater than zero. 734 * 735 * @hint is simply passed through to the ::open signal. It is 736 * intended to be used by applications that have multiple modes for 737 * opening files (eg: "view" vs "edit", etc). Unless you have a need 738 * for this functionality, you should use "". 739 * 740 * The application must be registered before calling this function 741 * and it must have the %G_APPLICATION_HANDLES_OPEN flag set. 742 * 743 * Params: 744 * files = an array of #GFiles to open 745 * nFiles = the length of the @files array 746 * hint = a hint (or ""), but never %NULL 747 * 748 * Since: 2.28 749 */ 750 public void open(FileIF[] files, string hint) 751 { 752 GFile*[] filesArray = new GFile*[files.length]; 753 for ( int i = 0; i < files.length; i++ ) 754 { 755 filesArray[i] = files[i].getFileStruct(); 756 } 757 758 g_application_open(gApplication, filesArray.ptr, cast(int)files.length, Str.toStringz(hint)); 759 } 760 761 /** 762 * Immediately quits the application. 763 * 764 * Upon return to the mainloop, g_application_run() will return, 765 * calling only the 'shutdown' function before doing so. 766 * 767 * The hold count is ignored. 768 * 769 * The result of calling g_application_run() again after it returns is 770 * unspecified. 771 * 772 * Since: 2.32 773 */ 774 public void quit() 775 { 776 g_application_quit(gApplication); 777 } 778 779 /** 780 * Attempts registration of the application. 781 * 782 * This is the point at which the application discovers if it is the 783 * primary instance or merely acting as a remote for an already-existing 784 * primary instance. This is implemented by attempting to acquire the 785 * application identifier as a unique bus name on the session bus using 786 * GDBus. 787 * 788 * If there is no application ID or if %G_APPLICATION_NON_UNIQUE was 789 * given, then this process will always become the primary instance. 790 * 791 * Due to the internal architecture of GDBus, method calls can be 792 * dispatched at any time (even if a main loop is not running). For 793 * this reason, you must ensure that any object paths that you wish to 794 * register are registered before calling this function. 795 * 796 * If the application has already been registered then %TRUE is 797 * returned with no work performed. 798 * 799 * The #GApplication::startup signal is emitted if registration succeeds 800 * and @application is the primary instance (including the non-unique 801 * case). 802 * 803 * In the event of an error (such as @cancellable being cancelled, or a 804 * failure to connect to the session bus), %FALSE is returned and @error 805 * is set appropriately. 806 * 807 * Note: the return value of this function is not an indicator that this 808 * instance is or is not the primary instance of the application. See 809 * g_application_get_is_remote() for that. 810 * 811 * Params: 812 * cancellable = a #GCancellable, or %NULL 813 * 814 * Return: %TRUE if registration succeeded 815 * 816 * Since: 2.28 817 * 818 * Throws: GException on failure. 819 */ 820 public bool register(Cancellable cancellable) 821 { 822 GError* err = null; 823 824 auto p = g_application_register(gApplication, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err) != 0; 825 826 if (err !is null) 827 { 828 throw new GException( new ErrorG(err) ); 829 } 830 831 return p; 832 } 833 834 /** 835 * Decrease the use count of @application. 836 * 837 * When the use count reaches zero, the application will stop running. 838 * 839 * Never call this function except to cancel the effect of a previous 840 * call to g_application_hold(). 841 */ 842 public void release() 843 { 844 g_application_release(gApplication); 845 } 846 847 /** 848 * Runs the application. 849 * 850 * This function is intended to be run from main() and its return value 851 * is intended to be returned by main(). Although you are expected to pass 852 * the @argc, @argv parameters from main() to this function, it is possible 853 * to pass %NULL if @argv is not available or commandline handling is not 854 * required. Note that on Windows, @argc and @argv are ignored, and 855 * g_win32_get_command_line() is called internally (for proper support 856 * of Unicode commandline arguments). 857 * 858 * #GApplication will attempt to parse the commandline arguments. You 859 * can add commandline flags to the list of recognised options by way of 860 * g_application_add_main_option_entries(). After this, the 861 * #GApplication::handle-local-options signal is emitted, from which the 862 * application can inspect the values of its #GOptionEntrys. 863 * 864 * #GApplication::handle-local-options is a good place to handle options 865 * such as `--version`, where an immediate reply from the local process is 866 * desired (instead of communicating with an already-running instance). 867 * A #GApplication::handle-local-options handler can stop further processing 868 * by returning a non-negative value, which then becomes the exit status of 869 * the process. 870 * 871 * What happens next depends on the flags: if 872 * %G_APPLICATION_HANDLES_COMMAND_LINE was specified then the remaining 873 * commandline arguments are sent to the primary instance, where a 874 * #GApplication::command-line signal is emitted. Otherwise, the 875 * remaining commandline arguments are assumed to be a list of files. 876 * If there are no files listed, the application is activated via the 877 * #GApplication::activate signal. If there are one or more files, and 878 * %G_APPLICATION_HANDLES_OPEN was specified then the files are opened 879 * via the #GApplication::open signal. 880 * 881 * If you are interested in doing more complicated local handling of the 882 * commandline then you should implement your own #GApplication subclass 883 * and override local_command_line(). In this case, you most likely want 884 * to return %TRUE from your local_command_line() implementation to 885 * suppress the default handling. See 886 * [gapplication-example-cmdline2.c][gapplication-example-cmdline2] 887 * for an example. 888 * 889 * If, after the above is done, the use count of the application is zero 890 * then the exit status is returned immediately. If the use count is 891 * non-zero then the default main context is iterated until the use count 892 * falls to zero, at which point 0 is returned. 893 * 894 * If the %G_APPLICATION_IS_SERVICE flag is set, then the service will 895 * run for as much as 10 seconds with a use count of zero while waiting 896 * for the message that caused the activation to arrive. After that, 897 * if the use count falls to zero the application will exit immediately, 898 * except in the case that g_application_set_inactivity_timeout() is in 899 * use. 900 * 901 * This function sets the prgname (g_set_prgname()), if not already set, 902 * to the basename of argv[0]. 903 * 904 * Much like g_main_loop_run(), this function will acquire the main context 905 * for the duration that the application is running. 906 * 907 * Since 2.40, applications that are not explicitly flagged as services 908 * or launchers (ie: neither %G_APPLICATION_IS_SERVICE or 909 * %G_APPLICATION_IS_LAUNCHER are given as flags) will check (from the 910 * default handler for local_command_line) if "--gapplication-service" 911 * was given in the command line. If this flag is present then normal 912 * commandline processing is interrupted and the 913 * %G_APPLICATION_IS_SERVICE flag is set. This provides a "compromise" 914 * solution whereby running an application directly from the commandline 915 * will invoke it in the normal way (which can be useful for debugging) 916 * while still allowing applications to be D-Bus activated in service 917 * mode. The D-Bus service file should invoke the executable with 918 * "--gapplication-service" as the sole commandline argument. This 919 * approach is suitable for use by most graphical applications but 920 * should not be used from applications like editors that need precise 921 * control over when processes invoked via the commandline will exit and 922 * what their exit status will be. 923 * 924 * Params: 925 * argc = the argc from main() (or 0 if @argv is %NULL) 926 * argv = the argv from main(), or %NULL 927 * 928 * Return: the exit status 929 * 930 * Since: 2.28 931 */ 932 public int run(string[] argv) 933 { 934 return g_application_run(gApplication, cast(int)argv.length, Str.toStringzArray(argv)); 935 } 936 937 /** 938 * Sends a notification on behalf of @application to the desktop shell. 939 * There is no guarantee that the notification is displayed immediately, 940 * or even at all. 941 * 942 * Notifications may persist after the application exits. It will be 943 * D-Bus-activated when the notification or one of its actions is 944 * activated. 945 * 946 * Modifying @notification after this call has no effect. However, the 947 * object can be reused for a later call to this function. 948 * 949 * @id may be any string that uniquely identifies the event for the 950 * application. It does not need to be in any special format. For 951 * example, "new-message" might be appropriate for a notification about 952 * new messages. 953 * 954 * If a previous notification was sent with the same @id, it will be 955 * replaced with @notification and shown again as if it was a new 956 * notification. This works even for notifications sent from a previous 957 * execution of the application, as long as @id is the same string. 958 * 959 * @id may be %NULL, but it is impossible to replace or withdraw 960 * notifications without an id. 961 * 962 * If @notification is no longer relevant, it can be withdrawn with 963 * g_application_withdraw_notification(). 964 * 965 * Params: 966 * id = id of the notification, or %NULL 967 * notification = the #GNotification to send 968 * 969 * Since: 2.40 970 */ 971 public void sendNotification(string id, Notification notification) 972 { 973 g_application_send_notification(gApplication, Str.toStringz(id), (notification is null) ? null : notification.getNotificationStruct()); 974 } 975 976 /** 977 * This used to be how actions were associated with a #GApplication. 978 * Now there is #GActionMap for that. 979 * 980 * Deprecated: Use the #GActionMap interface instead. Never ever 981 * mix use of this API with use of #GActionMap on the same @application 982 * or things will go very badly wrong. This function is known to 983 * introduce buggy behaviour (ie: signals not emitted on changes to the 984 * action group), so you should really use #GActionMap instead. 985 * 986 * Params: 987 * actionGroup = a #GActionGroup, or %NULL 988 * 989 * Since: 2.28 990 */ 991 public void setActionGroup(ActionGroupIF actionGroup) 992 { 993 g_application_set_action_group(gApplication, (actionGroup is null) ? null : actionGroup.getActionGroupStruct()); 994 } 995 996 /** 997 * Sets the unique identifier for @application. 998 * 999 * The application id can only be modified if @application has not yet 1000 * been registered. 1001 * 1002 * If non-%NULL, the application id must be valid. See 1003 * g_application_id_is_valid(). 1004 * 1005 * Params: 1006 * applicationId = the identifier for @application 1007 * 1008 * Since: 2.28 1009 */ 1010 public void setApplicationId(string applicationId) 1011 { 1012 g_application_set_application_id(gApplication, Str.toStringz(applicationId)); 1013 } 1014 1015 /** 1016 * Sets or unsets the default application for the process, as returned 1017 * by g_application_get_default(). 1018 * 1019 * This function does not take its own reference on @application. If 1020 * @application is destroyed then the default application will revert 1021 * back to %NULL. 1022 * 1023 * Since: 2.32 1024 */ 1025 public void setDefault() 1026 { 1027 g_application_set_default(gApplication); 1028 } 1029 1030 /** 1031 * Sets the flags for @application. 1032 * 1033 * The flags can only be modified if @application has not yet been 1034 * registered. 1035 * 1036 * See #GApplicationFlags. 1037 * 1038 * Params: 1039 * flags = the flags for @application 1040 * 1041 * Since: 2.28 1042 */ 1043 public void setFlags(GApplicationFlags flags) 1044 { 1045 g_application_set_flags(gApplication, flags); 1046 } 1047 1048 /** 1049 * Sets the current inactivity timeout for the application. 1050 * 1051 * This is the amount of time (in milliseconds) after the last call to 1052 * g_application_release() before the application stops running. 1053 * 1054 * This call has no side effects of its own. The value set here is only 1055 * used for next time g_application_release() drops the use count to 1056 * zero. Any timeouts currently in progress are not impacted. 1057 * 1058 * Params: 1059 * inactivityTimeout = the timeout, in milliseconds 1060 * 1061 * Since: 2.28 1062 */ 1063 public void setInactivityTimeout(uint inactivityTimeout) 1064 { 1065 g_application_set_inactivity_timeout(gApplication, inactivityTimeout); 1066 } 1067 1068 /** 1069 * Sets (or unsets) the base resource path of @application. 1070 * 1071 * The path is used to automatically load various [application 1072 * resources][gresource] such as menu layouts and action descriptions. 1073 * The various types of resources will be found at fixed names relative 1074 * to the given base path. 1075 * 1076 * By default, the resource base path is determined from the application 1077 * ID by prefixing '/' and replacing each '.' with '/'. This is done at 1078 * the time that the #GApplication object is constructed. Changes to 1079 * the application ID after that point will not have an impact on the 1080 * resource base path. 1081 * 1082 * As an example, if the application has an ID of "org.example.app" then 1083 * the default resource base path will be "/org/example/app". If this 1084 * is a #GtkApplication (and you have not manually changed the path) 1085 * then Gtk will then search for the menus of the application at 1086 * "/org/example/app/gtk/menus.ui". 1087 * 1088 * See #GResource for more information about adding resources to your 1089 * application. 1090 * 1091 * You can disable automatic resource loading functionality by setting 1092 * the path to %NULL. 1093 * 1094 * Changing the resource base path once the application is running is 1095 * not recommended. The point at which the resource path is consulted 1096 * for forming paths for various purposes is unspecified. When writing 1097 * a sub-class of #GApplication you should either set the 1098 * #GApplication:resource-base-path property at construction time, or call 1099 * this function during the instance initialization. Alternatively, you 1100 * can call this function in the #GApplicationClass.startup virtual function, 1101 * before chaining up to the parent implementation. 1102 * 1103 * Params: 1104 * resourcePath = the resource path to use 1105 * 1106 * Since: 2.42 1107 */ 1108 public void setResourceBasePath(string resourcePath) 1109 { 1110 g_application_set_resource_base_path(gApplication, Str.toStringz(resourcePath)); 1111 } 1112 1113 /** 1114 * Destroys a binding between @property and the busy state of 1115 * @application that was previously created with 1116 * g_application_bind_busy_property(). 1117 * 1118 * Params: 1119 * object = a #GObject 1120 * property = the name of a boolean property of @object 1121 * 1122 * Since: 2.44 1123 */ 1124 public void unbindBusyProperty(ObjectG object, string property) 1125 { 1126 g_application_unbind_busy_property(gApplication, (object is null) ? null : object.getObjectGStruct(), Str.toStringz(property)); 1127 } 1128 1129 /** 1130 * Decreases the busy count of @application. 1131 * 1132 * When the busy count reaches zero, the new state will be propagated 1133 * to other processes. 1134 * 1135 * This function must only be called to cancel the effect of a previous 1136 * call to g_application_mark_busy(). 1137 * 1138 * Since: 2.38 1139 */ 1140 public void unmarkBusy() 1141 { 1142 g_application_unmark_busy(gApplication); 1143 } 1144 1145 /** 1146 * Withdraws a notification that was sent with 1147 * g_application_send_notification(). 1148 * 1149 * This call does nothing if a notification with @id doesn't exist or 1150 * the notification was never sent. 1151 * 1152 * This function works even for notifications sent in previous 1153 * executions of this application, as long @id is the same as it was for 1154 * the sent notification. 1155 * 1156 * Note that notifications are dismissed when the user clicks on one 1157 * of the buttons in a notification or triggers its default action, so 1158 * there is no need to explicitly withdraw the notification in that case. 1159 * 1160 * Params: 1161 * id = id of a previously sent notification 1162 * 1163 * Since: 2.40 1164 */ 1165 public void withdrawNotification(string id) 1166 { 1167 g_application_withdraw_notification(gApplication, Str.toStringz(id)); 1168 } 1169 1170 protected class OnActivateDelegateWrapper 1171 { 1172 void delegate(Application) dlg; 1173 gulong handlerId; 1174 ConnectFlags flags; 1175 this(void delegate(Application) dlg, gulong handlerId, ConnectFlags flags) 1176 { 1177 this.dlg = dlg; 1178 this.handlerId = handlerId; 1179 this.flags = flags; 1180 } 1181 } 1182 protected OnActivateDelegateWrapper[] onActivateListeners; 1183 1184 /** 1185 * The ::activate signal is emitted on the primary instance when an 1186 * activation occurs. See g_application_activate(). 1187 */ 1188 gulong addOnActivate(void delegate(Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1189 { 1190 onActivateListeners ~= new OnActivateDelegateWrapper(dlg, 0, connectFlags); 1191 onActivateListeners[onActivateListeners.length - 1].handlerId = Signals.connectData( 1192 this, 1193 "activate", 1194 cast(GCallback)&callBackActivate, 1195 cast(void*)onActivateListeners[onActivateListeners.length - 1], 1196 cast(GClosureNotify)&callBackActivateDestroy, 1197 connectFlags); 1198 return onActivateListeners[onActivateListeners.length - 1].handlerId; 1199 } 1200 1201 extern(C) static void callBackActivate(GApplication* applicationStruct,OnActivateDelegateWrapper wrapper) 1202 { 1203 wrapper.dlg(wrapper.outer); 1204 } 1205 1206 extern(C) static void callBackActivateDestroy(OnActivateDelegateWrapper wrapper, GClosure* closure) 1207 { 1208 wrapper.outer.internalRemoveOnActivate(wrapper); 1209 } 1210 1211 protected void internalRemoveOnActivate(OnActivateDelegateWrapper source) 1212 { 1213 foreach(index, wrapper; onActivateListeners) 1214 { 1215 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 1216 { 1217 onActivateListeners[index] = null; 1218 onActivateListeners = std.algorithm.remove(onActivateListeners, index); 1219 break; 1220 } 1221 } 1222 } 1223 1224 1225 protected class OnCommandLineDelegateWrapper 1226 { 1227 int delegate(ApplicationCommandLine, Application) dlg; 1228 gulong handlerId; 1229 ConnectFlags flags; 1230 this(int delegate(ApplicationCommandLine, Application) dlg, gulong handlerId, ConnectFlags flags) 1231 { 1232 this.dlg = dlg; 1233 this.handlerId = handlerId; 1234 this.flags = flags; 1235 } 1236 } 1237 protected OnCommandLineDelegateWrapper[] onCommandLineListeners; 1238 1239 /** 1240 * The ::command-line signal is emitted on the primary instance when 1241 * a commandline is not handled locally. See g_application_run() and 1242 * the #GApplicationCommandLine documentation for more information. 1243 * 1244 * Params: 1245 * commandLine = a #GApplicationCommandLine representing the 1246 * passed commandline 1247 * 1248 * Return: An integer that is set as the exit status for the calling 1249 * process. See g_application_command_line_set_exit_status(). 1250 */ 1251 gulong addOnCommandLine(int delegate(ApplicationCommandLine, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1252 { 1253 onCommandLineListeners ~= new OnCommandLineDelegateWrapper(dlg, 0, connectFlags); 1254 onCommandLineListeners[onCommandLineListeners.length - 1].handlerId = Signals.connectData( 1255 this, 1256 "command-line", 1257 cast(GCallback)&callBackCommandLine, 1258 cast(void*)onCommandLineListeners[onCommandLineListeners.length - 1], 1259 cast(GClosureNotify)&callBackCommandLineDestroy, 1260 connectFlags); 1261 return onCommandLineListeners[onCommandLineListeners.length - 1].handlerId; 1262 } 1263 1264 extern(C) static int callBackCommandLine(GApplication* applicationStruct, GApplicationCommandLine* commandLine,OnCommandLineDelegateWrapper wrapper) 1265 { 1266 return wrapper.dlg(ObjectG.getDObject!(ApplicationCommandLine)(commandLine), wrapper.outer); 1267 } 1268 1269 extern(C) static void callBackCommandLineDestroy(OnCommandLineDelegateWrapper wrapper, GClosure* closure) 1270 { 1271 wrapper.outer.internalRemoveOnCommandLine(wrapper); 1272 } 1273 1274 protected void internalRemoveOnCommandLine(OnCommandLineDelegateWrapper source) 1275 { 1276 foreach(index, wrapper; onCommandLineListeners) 1277 { 1278 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 1279 { 1280 onCommandLineListeners[index] = null; 1281 onCommandLineListeners = std.algorithm.remove(onCommandLineListeners, index); 1282 break; 1283 } 1284 } 1285 } 1286 1287 1288 protected class OnHandleLocalOptionsDelegateWrapper 1289 { 1290 int delegate(VariantDict, Application) dlg; 1291 gulong handlerId; 1292 ConnectFlags flags; 1293 this(int delegate(VariantDict, Application) dlg, gulong handlerId, ConnectFlags flags) 1294 { 1295 this.dlg = dlg; 1296 this.handlerId = handlerId; 1297 this.flags = flags; 1298 } 1299 } 1300 protected OnHandleLocalOptionsDelegateWrapper[] onHandleLocalOptionsListeners; 1301 1302 /** 1303 * The ::handle-local-options signal is emitted on the local instance 1304 * after the parsing of the commandline options has occurred. 1305 * 1306 * You can add options to be recognised during commandline option 1307 * parsing using g_application_add_main_option_entries() and 1308 * g_application_add_option_group(). 1309 * 1310 * Signal handlers can inspect @options (along with values pointed to 1311 * from the @arg_data of an installed #GOptionEntrys) in order to 1312 * decide to perform certain actions, including direct local handling 1313 * (which may be useful for options like --version). 1314 * 1315 * In the event that the application is marked 1316 * %G_APPLICATION_HANDLES_COMMAND_LINE the "normal processing" will 1317 * send the @options dictionary to the primary instance where it can be 1318 * read with g_application_command_line_get_options_dict(). The signal 1319 * handler can modify the dictionary before returning, and the 1320 * modified dictionary will be sent. 1321 * 1322 * In the event that %G_APPLICATION_HANDLES_COMMAND_LINE is not set, 1323 * "normal processing" will treat the remaining uncollected command 1324 * line arguments as filenames or URIs. If there are no arguments, 1325 * the application is activated by g_application_activate(). One or 1326 * more arguments results in a call to g_application_open(). 1327 * 1328 * If you want to handle the local commandline arguments for yourself 1329 * by converting them to calls to g_application_open() or 1330 * g_action_group_activate_action() then you must be sure to register 1331 * the application first. You should probably not call 1332 * g_application_activate() for yourself, however: just return -1 and 1333 * allow the default handler to do it for you. This will ensure that 1334 * the `--gapplication-service` switch works properly (i.e. no activation 1335 * in that case). 1336 * 1337 * Note that this signal is emitted from the default implementation of 1338 * local_command_line(). If you override that function and don't 1339 * chain up then this signal will never be emitted. 1340 * 1341 * You can override local_command_line() if you need more powerful 1342 * capabilities than what is provided here, but this should not 1343 * normally be required. 1344 * 1345 * Params: 1346 * options = the options dictionary 1347 * 1348 * Return: an exit code. If you have handled your options and want 1349 * to exit the process, return a non-negative option, 0 for success, 1350 * and a positive value for failure. To continue, return -1 to let 1351 * the default option processing continue. 1352 * 1353 * Since: 2.40 1354 */ 1355 gulong addOnHandleLocalOptions(int delegate(VariantDict, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1356 { 1357 onHandleLocalOptionsListeners ~= new OnHandleLocalOptionsDelegateWrapper(dlg, 0, connectFlags); 1358 onHandleLocalOptionsListeners[onHandleLocalOptionsListeners.length - 1].handlerId = Signals.connectData( 1359 this, 1360 "handle-local-options", 1361 cast(GCallback)&callBackHandleLocalOptions, 1362 cast(void*)onHandleLocalOptionsListeners[onHandleLocalOptionsListeners.length - 1], 1363 cast(GClosureNotify)&callBackHandleLocalOptionsDestroy, 1364 connectFlags); 1365 return onHandleLocalOptionsListeners[onHandleLocalOptionsListeners.length - 1].handlerId; 1366 } 1367 1368 extern(C) static int callBackHandleLocalOptions(GApplication* applicationStruct, GVariantDict* options,OnHandleLocalOptionsDelegateWrapper wrapper) 1369 { 1370 return wrapper.dlg(new VariantDict(options), wrapper.outer); 1371 } 1372 1373 extern(C) static void callBackHandleLocalOptionsDestroy(OnHandleLocalOptionsDelegateWrapper wrapper, GClosure* closure) 1374 { 1375 wrapper.outer.internalRemoveOnHandleLocalOptions(wrapper); 1376 } 1377 1378 protected void internalRemoveOnHandleLocalOptions(OnHandleLocalOptionsDelegateWrapper source) 1379 { 1380 foreach(index, wrapper; onHandleLocalOptionsListeners) 1381 { 1382 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 1383 { 1384 onHandleLocalOptionsListeners[index] = null; 1385 onHandleLocalOptionsListeners = std.algorithm.remove(onHandleLocalOptionsListeners, index); 1386 break; 1387 } 1388 } 1389 } 1390 1391 1392 protected class OnOpenDelegateWrapper 1393 { 1394 void delegate(void*, int, string, Application) dlg; 1395 gulong handlerId; 1396 ConnectFlags flags; 1397 this(void delegate(void*, int, string, Application) dlg, gulong handlerId, ConnectFlags flags) 1398 { 1399 this.dlg = dlg; 1400 this.handlerId = handlerId; 1401 this.flags = flags; 1402 } 1403 } 1404 protected OnOpenDelegateWrapper[] onOpenListeners; 1405 1406 /** 1407 * The ::open signal is emitted on the primary instance when there are 1408 * files to open. See g_application_open() for more information. 1409 * 1410 * Params: 1411 * files = an array of #GFiles 1412 * nFiles = the length of @files 1413 * hint = a hint provided by the calling instance 1414 */ 1415 gulong addOnOpen(void delegate(void*, int, string, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1416 { 1417 onOpenListeners ~= new OnOpenDelegateWrapper(dlg, 0, connectFlags); 1418 onOpenListeners[onOpenListeners.length - 1].handlerId = Signals.connectData( 1419 this, 1420 "open", 1421 cast(GCallback)&callBackOpen, 1422 cast(void*)onOpenListeners[onOpenListeners.length - 1], 1423 cast(GClosureNotify)&callBackOpenDestroy, 1424 connectFlags); 1425 return onOpenListeners[onOpenListeners.length - 1].handlerId; 1426 } 1427 1428 extern(C) static void callBackOpen(GApplication* applicationStruct, void* files, int nFiles, char* hint,OnOpenDelegateWrapper wrapper) 1429 { 1430 wrapper.dlg(files, nFiles, Str.toString(hint), wrapper.outer); 1431 } 1432 1433 extern(C) static void callBackOpenDestroy(OnOpenDelegateWrapper wrapper, GClosure* closure) 1434 { 1435 wrapper.outer.internalRemoveOnOpen(wrapper); 1436 } 1437 1438 protected void internalRemoveOnOpen(OnOpenDelegateWrapper source) 1439 { 1440 foreach(index, wrapper; onOpenListeners) 1441 { 1442 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 1443 { 1444 onOpenListeners[index] = null; 1445 onOpenListeners = std.algorithm.remove(onOpenListeners, index); 1446 break; 1447 } 1448 } 1449 } 1450 1451 1452 protected class OnShutdownDelegateWrapper 1453 { 1454 void delegate(Application) dlg; 1455 gulong handlerId; 1456 ConnectFlags flags; 1457 this(void delegate(Application) dlg, gulong handlerId, ConnectFlags flags) 1458 { 1459 this.dlg = dlg; 1460 this.handlerId = handlerId; 1461 this.flags = flags; 1462 } 1463 } 1464 protected OnShutdownDelegateWrapper[] onShutdownListeners; 1465 1466 /** 1467 * The ::shutdown signal is emitted only on the registered primary instance 1468 * immediately after the main loop terminates. 1469 */ 1470 gulong addOnShutdown(void delegate(Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1471 { 1472 onShutdownListeners ~= new OnShutdownDelegateWrapper(dlg, 0, connectFlags); 1473 onShutdownListeners[onShutdownListeners.length - 1].handlerId = Signals.connectData( 1474 this, 1475 "shutdown", 1476 cast(GCallback)&callBackShutdown, 1477 cast(void*)onShutdownListeners[onShutdownListeners.length - 1], 1478 cast(GClosureNotify)&callBackShutdownDestroy, 1479 connectFlags); 1480 return onShutdownListeners[onShutdownListeners.length - 1].handlerId; 1481 } 1482 1483 extern(C) static void callBackShutdown(GApplication* applicationStruct,OnShutdownDelegateWrapper wrapper) 1484 { 1485 wrapper.dlg(wrapper.outer); 1486 } 1487 1488 extern(C) static void callBackShutdownDestroy(OnShutdownDelegateWrapper wrapper, GClosure* closure) 1489 { 1490 wrapper.outer.internalRemoveOnShutdown(wrapper); 1491 } 1492 1493 protected void internalRemoveOnShutdown(OnShutdownDelegateWrapper source) 1494 { 1495 foreach(index, wrapper; onShutdownListeners) 1496 { 1497 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 1498 { 1499 onShutdownListeners[index] = null; 1500 onShutdownListeners = std.algorithm.remove(onShutdownListeners, index); 1501 break; 1502 } 1503 } 1504 } 1505 1506 1507 protected class OnStartupDelegateWrapper 1508 { 1509 void delegate(Application) dlg; 1510 gulong handlerId; 1511 ConnectFlags flags; 1512 this(void delegate(Application) dlg, gulong handlerId, ConnectFlags flags) 1513 { 1514 this.dlg = dlg; 1515 this.handlerId = handlerId; 1516 this.flags = flags; 1517 } 1518 } 1519 protected OnStartupDelegateWrapper[] onStartupListeners; 1520 1521 /** 1522 * The ::startup signal is emitted on the primary instance immediately 1523 * after registration. See g_application_register(). 1524 */ 1525 gulong addOnStartup(void delegate(Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1526 { 1527 onStartupListeners ~= new OnStartupDelegateWrapper(dlg, 0, connectFlags); 1528 onStartupListeners[onStartupListeners.length - 1].handlerId = Signals.connectData( 1529 this, 1530 "startup", 1531 cast(GCallback)&callBackStartup, 1532 cast(void*)onStartupListeners[onStartupListeners.length - 1], 1533 cast(GClosureNotify)&callBackStartupDestroy, 1534 connectFlags); 1535 return onStartupListeners[onStartupListeners.length - 1].handlerId; 1536 } 1537 1538 extern(C) static void callBackStartup(GApplication* applicationStruct,OnStartupDelegateWrapper wrapper) 1539 { 1540 wrapper.dlg(wrapper.outer); 1541 } 1542 1543 extern(C) static void callBackStartupDestroy(OnStartupDelegateWrapper wrapper, GClosure* closure) 1544 { 1545 wrapper.outer.internalRemoveOnStartup(wrapper); 1546 } 1547 1548 protected void internalRemoveOnStartup(OnStartupDelegateWrapper source) 1549 { 1550 foreach(index, wrapper; onStartupListeners) 1551 { 1552 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 1553 { 1554 onStartupListeners[index] = null; 1555 onStartupListeners = std.algorithm.remove(onStartupListeners, index); 1556 break; 1557 } 1558 } 1559 } 1560 1561 }