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