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