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