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 gtk.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.Application : GioApplication = Application; 32 private import gio.Menu; 33 private import gio.MenuModel; 34 private import glib.ConstructionException; 35 private import glib.ListG; 36 private import glib.Str; 37 private import glib.Variant; 38 private import gobject.ObjectG; 39 private import gobject.Signals; 40 private import gtk.Window; 41 private import gtkc.gtk; 42 public import gtkc.gtktypes; 43 private import std.algorithm; 44 45 46 /** 47 * #GtkApplication is a class that handles many important aspects 48 * of a GTK+ application in a convenient fashion, without enforcing 49 * a one-size-fits-all application model. 50 * 51 * Currently, GtkApplication handles GTK+ initialization, application 52 * uniqueness, session management, provides some basic scriptability and 53 * desktop shell integration by exporting actions and menus and manages a 54 * list of toplevel windows whose life-cycle is automatically tied to the 55 * life-cycle of your application. 56 * 57 * While GtkApplication works fine with plain #GtkWindows, it is recommended 58 * to use it together with #GtkApplicationWindow. 59 * 60 * When GDK threads are enabled, GtkApplication will acquire the GDK 61 * lock when invoking actions that arrive from other processes. The GDK 62 * lock is not touched for local action invocations. In order to have 63 * actions invoked in a predictable context it is therefore recommended 64 * that the GDK lock be held while invoking actions locally with 65 * g_action_group_activate_action(). The same applies to actions 66 * associated with #GtkApplicationWindow and to the “activate” and 67 * “open” #GApplication methods. 68 * 69 * ## Automatic resources ## {#automatic-resources} 70 * 71 * #GtkApplication will automatically load menus from the #GtkBuilder 72 * resource located at "gtk/menus.ui", relative to the application's 73 * resource base path (see g_application_set_resource_base_path()). The 74 * menu with the ID "app-menu" is taken as the application's app menu 75 * and the menu with the ID "menubar" is taken as the application's 76 * menubar. Additional menus (most interesting submenus) can be named 77 * and accessed via gtk_application_get_menu_by_id() which allows for 78 * dynamic population of a part of the menu structure. 79 * 80 * If the resources "gtk/menus-appmenu.ui" or "gtk/menus-traditional.ui" are 81 * present then these files will be used in preference, depending on the value 82 * of gtk_application_prefers_app_menu(). If the resource "gtk/menus-common.ui" 83 * is present it will be loaded as well. This is useful for storing items that 84 * are referenced from both "gtk/menus-appmenu.ui" and 85 * "gtk/menus-traditional.ui". 86 * 87 * It is also possible to provide the menus manually using 88 * gtk_application_set_app_menu() and gtk_application_set_menubar(). 89 * 90 * #GtkApplication will also automatically setup an icon search path for 91 * the default icon theme by appending "icons" to the resource base 92 * path. This allows your application to easily store its icons as 93 * resources. See gtk_icon_theme_add_resource_path() for more 94 * information. 95 * 96 * If there is a resource located at "gtk/help-overlay.ui" which 97 * defines a #GtkShortcutsWindow with ID "help_overlay" then GtkApplication 98 * associates an instance of this shortcuts window with each 99 * #GtkApplicationWindow and sets up keyboard accelerators (Control-F1 100 * and Control-?) to open it. To create a menu item that displays the 101 * shortcuts window, associate the item with the action win.show-help-overlay. 102 * 103 * ## A simple application ## {#gtkapplication} 104 * 105 * [A simple example](https://git.gnome.org/browse/gtk+/tree/examples/bp/bloatpad.c) 106 * 107 * GtkApplication optionally registers with a session manager 108 * of the users session (if you set the #GtkApplication:register-session 109 * property) and offers various functionality related to the session 110 * life-cycle. 111 * 112 * An application can block various ways to end the session with 113 * the gtk_application_inhibit() function. Typical use cases for 114 * this kind of inhibiting are long-running, uninterruptible operations, 115 * such as burning a CD or performing a disk backup. The session 116 * manager may not honor the inhibitor, but it can be expected to 117 * inform the user about the negative consequences of ending the 118 * session while inhibitors are present. 119 * 120 * ## See Also ## {#seealso} 121 * [HowDoI: Using GtkApplication](https://wiki.gnome.org/HowDoI/GtkApplication), 122 * [Getting Started with GTK+: Basics](https://developer.gnome.org/gtk3/stable/gtk-getting-started.html#id-1.2.3.3) 123 */ 124 public class Application : GioApplication 125 { 126 /** the main Gtk struct */ 127 protected GtkApplication* gtkApplication; 128 129 /** Get the main Gtk struct */ 130 public GtkApplication* getGtkApplicationStruct() 131 { 132 return gtkApplication; 133 } 134 135 /** the main Gtk struct as a void* */ 136 protected override void* getStruct() 137 { 138 return cast(void*)gtkApplication; 139 } 140 141 protected override void setStruct(GObject* obj) 142 { 143 gtkApplication = cast(GtkApplication*)obj; 144 super.setStruct(obj); 145 } 146 147 /** 148 * Sets our main struct and passes it to the parent class. 149 */ 150 public this (GtkApplication* gtkApplication, bool ownedRef = false) 151 { 152 this.gtkApplication = gtkApplication; 153 super(cast(GApplication*)gtkApplication, ownedRef); 154 } 155 156 /** 157 * Sets zero or more keyboard accelerators that will trigger the 158 * given action. The first item in accels will be the primary 159 * accelerator, which may be displayed in the UI. 160 * 161 * To remove all accelerators for an action, use an empty 162 * array for accels. 163 * 164 * Params: 165 * detailedActionName = a detailed action name, specifying an action 166 * and target to associate accelerators with 167 * accels = a list of accelerators in the format 168 * understood by gtk_accelerator_parse() 169 * 170 * Since: 3.12 171 */ 172 public void setAccelsForAction(string detailedActionName, string[] accels) 173 { 174 char** accel; 175 176 if (accels) 177 accel = Str.toStringzArray(accels); 178 else 179 accel = [cast(char*)null].ptr; 180 181 gtk_application_set_accels_for_action(gtkApplication, Str.toStringz(detailedActionName), accel); 182 } 183 184 /** 185 */ 186 187 /** */ 188 public static GType getType() 189 { 190 return gtk_application_get_type(); 191 } 192 193 /** 194 * Creates a new #GtkApplication instance. 195 * 196 * When using #GtkApplication, it is not necessary to call gtk_init() 197 * manually. It is called as soon as the application gets registered as 198 * the primary instance. 199 * 200 * Concretely, gtk_init() is called in the default handler for the 201 * #GApplication::startup signal. Therefore, #GtkApplication subclasses should 202 * chain up in their #GApplication::startup handler before using any GTK+ API. 203 * 204 * Note that commandline arguments are not passed to gtk_init(). 205 * All GTK+ functionality that is available via commandline arguments 206 * can also be achieved by setting suitable environment variables 207 * such as `G_DEBUG`, so this should not be a big 208 * problem. If you absolutely must support GTK+ commandline arguments, 209 * you can explicitly call gtk_init() before creating the application 210 * instance. 211 * 212 * If non-%NULL, the application ID must be valid. See 213 * g_application_id_is_valid(). 214 * 215 * If no application ID is given then some features (most notably application 216 * uniqueness) will be disabled. A null application ID is only allowed with 217 * GTK+ 3.6 or later. 218 * 219 * Params: 220 * applicationId = The application ID. 221 * flags = the application flags 222 * 223 * Returns: a new #GtkApplication instance 224 * 225 * Since: 3.0 226 * 227 * Throws: ConstructionException GTK+ fails to create the object. 228 */ 229 public this(string applicationId, GApplicationFlags flags) 230 { 231 auto p = gtk_application_new(Str.toStringz(applicationId), flags); 232 233 if(p is null) 234 { 235 throw new ConstructionException("null returned by new"); 236 } 237 238 this(cast(GtkApplication*) p, true); 239 } 240 241 /** 242 * Installs an accelerator that will cause the named action 243 * to be activated when the key combination specificed by @accelerator 244 * is pressed. 245 * 246 * @accelerator must be a string that can be parsed by gtk_accelerator_parse(), 247 * e.g. "<Primary>q" or “<Control><Alt>p”. 248 * 249 * @action_name must be the name of an action as it would be used 250 * in the app menu, i.e. actions that have been added to the application 251 * are referred to with an “app.” prefix, and window-specific actions 252 * with a “win.” prefix. 253 * 254 * GtkApplication also extracts accelerators out of “accel” attributes 255 * in the #GMenuModels passed to gtk_application_set_app_menu() and 256 * gtk_application_set_menubar(), which is usually more convenient 257 * than calling this function for each accelerator. 258 * 259 * Deprecated: Use gtk_application_set_accels_for_action() instead 260 * 261 * Params: 262 * accelerator = accelerator string 263 * actionName = the name of the action to activate 264 * parameter = parameter to pass when activating the action, 265 * or %NULL if the action does not accept an activation parameter 266 * 267 * Since: 3.4 268 */ 269 public void addAccelerator(string accelerator, string actionName, Variant parameter) 270 { 271 gtk_application_add_accelerator(gtkApplication, Str.toStringz(accelerator), Str.toStringz(actionName), (parameter is null) ? null : parameter.getVariantStruct()); 272 } 273 274 /** 275 * Adds a window to @application. 276 * 277 * This call can only happen after the @application has started; 278 * typically, you should add new application windows in response 279 * to the emission of the #GApplication::activate signal. 280 * 281 * This call is equivalent to setting the #GtkWindow:application 282 * property of @window to @application. 283 * 284 * Normally, the connection between the application and the window 285 * will remain until the window is destroyed, but you can explicitly 286 * remove it with gtk_application_remove_window(). 287 * 288 * GTK+ will keep the @application running as long as it has 289 * any windows. 290 * 291 * Params: 292 * window = a #GtkWindow 293 * 294 * Since: 3.0 295 */ 296 public void addWindow(Window window) 297 { 298 gtk_application_add_window(gtkApplication, (window is null) ? null : window.getWindowStruct()); 299 } 300 301 /** 302 * Gets the accelerators that are currently associated with 303 * the given action. 304 * 305 * Params: 306 * detailedActionName = a detailed action name, specifying an action 307 * and target to obtain accelerators for 308 * 309 * Returns: accelerators for @detailed_action_name, as 310 * a %NULL-terminated array. Free with g_strfreev() when no longer needed 311 * 312 * Since: 3.12 313 */ 314 public string[] getAccelsForAction(string detailedActionName) 315 { 316 auto retStr = gtk_application_get_accels_for_action(gtkApplication, Str.toStringz(detailedActionName)); 317 318 scope(exit) Str.freeStringArray(retStr); 319 return Str.toStringArray(retStr); 320 } 321 322 /** 323 * Returns the list of actions (possibly empty) that @accel maps to. 324 * Each item in the list is a detailed action name in the usual form. 325 * 326 * This might be useful to discover if an accel already exists in 327 * order to prevent installation of a conflicting accelerator (from 328 * an accelerator editor or a plugin system, for example). Note that 329 * having more than one action per accelerator may not be a bad thing 330 * and might make sense in cases where the actions never appear in the 331 * same context. 332 * 333 * In case there are no actions for a given accelerator, an empty array 334 * is returned. %NULL is never returned. 335 * 336 * It is a programmer error to pass an invalid accelerator string. 337 * If you are unsure, check it with gtk_accelerator_parse() first. 338 * 339 * Params: 340 * accel = an accelerator that can be parsed by gtk_accelerator_parse() 341 * 342 * Returns: a %NULL-terminated array of actions for @accel 343 * 344 * Since: 3.14 345 */ 346 public string[] getActionsForAccel(string accel) 347 { 348 auto retStr = gtk_application_get_actions_for_accel(gtkApplication, Str.toStringz(accel)); 349 350 scope(exit) Str.freeStringArray(retStr); 351 return Str.toStringArray(retStr); 352 } 353 354 /** 355 * Gets the “active” window for the application. 356 * 357 * The active window is the one that was most recently focused (within 358 * the application). This window may not have the focus at the moment 359 * if another application has it — this is just the most 360 * recently-focused window within this application. 361 * 362 * Returns: the active window 363 * 364 * Since: 3.6 365 */ 366 public Window getActiveWindow() 367 { 368 auto p = gtk_application_get_active_window(gtkApplication); 369 370 if(p is null) 371 { 372 return null; 373 } 374 375 return ObjectG.getDObject!(Window)(cast(GtkWindow*) p); 376 } 377 378 /** 379 * Returns the menu model that has been set with 380 * gtk_application_set_app_menu(). 381 * 382 * Returns: the application menu of @application 383 * or %NULL if no application menu has been set. 384 * 385 * Since: 3.4 386 */ 387 public MenuModel getAppMenu() 388 { 389 auto p = gtk_application_get_app_menu(gtkApplication); 390 391 if(p is null) 392 { 393 return null; 394 } 395 396 return ObjectG.getDObject!(MenuModel)(cast(GMenuModel*) p); 397 } 398 399 /** 400 * Gets a menu from automatically loaded resources. 401 * See [Automatic resources][automatic-resources] 402 * for more information. 403 * 404 * Params: 405 * id = the id of the menu to look up 406 * 407 * Returns: Gets the menu with the 408 * given id from the automatically loaded resources 409 * 410 * Since: 3.14 411 */ 412 public Menu getMenuById(string id) 413 { 414 auto p = gtk_application_get_menu_by_id(gtkApplication, Str.toStringz(id)); 415 416 if(p is null) 417 { 418 return null; 419 } 420 421 return ObjectG.getDObject!(Menu)(cast(GMenu*) p); 422 } 423 424 /** 425 * Returns the menu model that has been set with 426 * gtk_application_set_menubar(). 427 * 428 * Returns: the menubar for windows of @application 429 * 430 * Since: 3.4 431 */ 432 public MenuModel getMenubar() 433 { 434 auto p = gtk_application_get_menubar(gtkApplication); 435 436 if(p is null) 437 { 438 return null; 439 } 440 441 return ObjectG.getDObject!(MenuModel)(cast(GMenuModel*) p); 442 } 443 444 /** 445 * Returns the #GtkApplicationWindow with the given ID. 446 * 447 * The ID of a #GtkApplicationWindow can be retrieved with 448 * gtk_application_window_get_id(). 449 * 450 * Params: 451 * id = an identifier number 452 * 453 * Returns: the window with ID @id, or 454 * %NULL if there is no window with this ID 455 * 456 * Since: 3.6 457 */ 458 public Window getWindowById(uint id) 459 { 460 auto p = gtk_application_get_window_by_id(gtkApplication, id); 461 462 if(p is null) 463 { 464 return null; 465 } 466 467 return ObjectG.getDObject!(Window)(cast(GtkWindow*) p); 468 } 469 470 /** 471 * Gets a list of the #GtkWindows associated with @application. 472 * 473 * The list is sorted by most recently focused window, such that the first 474 * element is the currently focused window. (Useful for choosing a parent 475 * for a transient window.) 476 * 477 * The list that is returned should not be modified in any way. It will 478 * only remain valid until the next focus change or window creation or 479 * deletion. 480 * 481 * Returns: a #GList of #GtkWindow 482 * 483 * Since: 3.0 484 */ 485 public ListG getWindows() 486 { 487 auto p = gtk_application_get_windows(gtkApplication); 488 489 if(p is null) 490 { 491 return null; 492 } 493 494 return new ListG(cast(GList*) p); 495 } 496 497 /** 498 * Inform the session manager that certain types of actions should be 499 * inhibited. This is not guaranteed to work on all platforms and for 500 * all types of actions. 501 * 502 * Applications should invoke this method when they begin an operation 503 * that should not be interrupted, such as creating a CD or DVD. The 504 * types of actions that may be blocked are specified by the @flags 505 * parameter. When the application completes the operation it should 506 * call gtk_application_uninhibit() to remove the inhibitor. Note that 507 * an application can have multiple inhibitors, and all of them must 508 * be individually removed. Inhibitors are also cleared when the 509 * application exits. 510 * 511 * Applications should not expect that they will always be able to block 512 * the action. In most cases, users will be given the option to force 513 * the action to take place. 514 * 515 * Reasons should be short and to the point. 516 * 517 * If @window is given, the session manager may point the user to 518 * this window to find out more about why the action is inhibited. 519 * 520 * Params: 521 * window = a #GtkWindow, or %NULL 522 * flags = what types of actions should be inhibited 523 * reason = a short, human-readable string that explains 524 * why these operations are inhibited 525 * 526 * Returns: A non-zero cookie that is used to uniquely identify this 527 * request. It should be used as an argument to gtk_application_uninhibit() 528 * in order to remove the request. If the platform does not support 529 * inhibiting or the request failed for some reason, 0 is returned. 530 * 531 * Since: 3.4 532 */ 533 public uint inhibit(Window window, GtkApplicationInhibitFlags flags, string reason) 534 { 535 return gtk_application_inhibit(gtkApplication, (window is null) ? null : window.getWindowStruct(), flags, Str.toStringz(reason)); 536 } 537 538 /** 539 * Determines if any of the actions specified in @flags are 540 * currently inhibited (possibly by another application). 541 * 542 * Params: 543 * flags = what types of actions should be queried 544 * 545 * Returns: %TRUE if any of the actions specified in @flags are inhibited 546 * 547 * Since: 3.4 548 */ 549 public bool isInhibited(GtkApplicationInhibitFlags flags) 550 { 551 return gtk_application_is_inhibited(gtkApplication, flags) != 0; 552 } 553 554 /** 555 * Lists the detailed action names which have associated accelerators. 556 * See gtk_application_set_accels_for_action(). 557 * 558 * Returns: a %NULL-terminated array of strings, 559 * free with g_strfreev() when done 560 * 561 * Since: 3.12 562 */ 563 public string[] listActionDescriptions() 564 { 565 auto retStr = gtk_application_list_action_descriptions(gtkApplication); 566 567 scope(exit) Str.freeStringArray(retStr); 568 return Str.toStringArray(retStr); 569 } 570 571 /** 572 * Determines if the desktop environment in which the application is 573 * running would prefer an application menu be shown. 574 * 575 * If this function returns %TRUE then the application should call 576 * gtk_application_set_app_menu() with the contents of an application 577 * menu, which will be shown by the desktop environment. If it returns 578 * %FALSE then you should consider using an alternate approach, such as 579 * a menubar. 580 * 581 * The value returned by this function is purely advisory and you are 582 * free to ignore it. If you call gtk_application_set_app_menu() even 583 * if the desktop environment doesn't support app menus, then a fallback 584 * will be provided. 585 * 586 * Applications are similarly free not to set an app menu even if the 587 * desktop environment wants to show one. In that case, a fallback will 588 * also be created by the desktop environment (GNOME, for example, uses 589 * a menu with only a "Quit" item in it). 590 * 591 * The value returned by this function never changes. Once it returns a 592 * particular value, it is guaranteed to always return the same value. 593 * 594 * You may only call this function after the application has been 595 * registered and after the base startup handler has run. You're most 596 * likely to want to use this from your own startup handler. It may 597 * also make sense to consult this function while constructing UI (in 598 * activate, open or an action activation handler) in order to determine 599 * if you should show a gear menu or not. 600 * 601 * This function will return %FALSE on Mac OS and a default app menu 602 * will be created automatically with the "usual" contents of that menu 603 * typical to most Mac OS applications. If you call 604 * gtk_application_set_app_menu() anyway, then this menu will be 605 * replaced with your own. 606 * 607 * Returns: %TRUE if you should set an app menu 608 * 609 * Since: 3.14 610 */ 611 public bool prefersAppMenu() 612 { 613 return gtk_application_prefers_app_menu(gtkApplication) != 0; 614 } 615 616 /** 617 * Removes an accelerator that has been previously added 618 * with gtk_application_add_accelerator(). 619 * 620 * Deprecated: Use gtk_application_set_accels_for_action() instead 621 * 622 * Params: 623 * actionName = the name of the action to activate 624 * parameter = parameter to pass when activating the action, 625 * or %NULL if the action does not accept an activation parameter 626 * 627 * Since: 3.4 628 */ 629 public void removeAccelerator(string actionName, Variant parameter) 630 { 631 gtk_application_remove_accelerator(gtkApplication, Str.toStringz(actionName), (parameter is null) ? null : parameter.getVariantStruct()); 632 } 633 634 /** 635 * Remove a window from @application. 636 * 637 * If @window belongs to @application then this call is equivalent to 638 * setting the #GtkWindow:application property of @window to 639 * %NULL. 640 * 641 * The application may stop running as a result of a call to this 642 * function. 643 * 644 * Params: 645 * window = a #GtkWindow 646 * 647 * Since: 3.0 648 */ 649 public void removeWindow(Window window) 650 { 651 gtk_application_remove_window(gtkApplication, (window is null) ? null : window.getWindowStruct()); 652 } 653 654 /** 655 * Sets or unsets the application menu for @application. 656 * 657 * This can only be done in the primary instance of the application, 658 * after it has been registered. #GApplication::startup is a good place 659 * to call this. 660 * 661 * The application menu is a single menu containing items that typically 662 * impact the application as a whole, rather than acting on a specific 663 * window or document. For example, you would expect to see 664 * “Preferences” or “Quit” in an application menu, but not “Save” or 665 * “Print”. 666 * 667 * If supported, the application menu will be rendered by the desktop 668 * environment. 669 * 670 * Use the base #GActionMap interface to add actions, to respond to the user 671 * selecting these menu items. 672 * 673 * Params: 674 * appMenu = a #GMenuModel, or %NULL 675 * 676 * Since: 3.4 677 */ 678 public void setAppMenu(MenuModel appMenu) 679 { 680 gtk_application_set_app_menu(gtkApplication, (appMenu is null) ? null : appMenu.getMenuModelStruct()); 681 } 682 683 /** 684 * Sets or unsets the menubar for windows of @application. 685 * 686 * This is a menubar in the traditional sense. 687 * 688 * This can only be done in the primary instance of the application, 689 * after it has been registered. #GApplication::startup is a good place 690 * to call this. 691 * 692 * Depending on the desktop environment, this may appear at the top of 693 * each window, or at the top of the screen. In some environments, if 694 * both the application menu and the menubar are set, the application 695 * menu will be presented as if it were the first item of the menubar. 696 * Other environments treat the two as completely separate — for example, 697 * the application menu may be rendered by the desktop shell while the 698 * menubar (if set) remains in each individual window. 699 * 700 * Use the base #GActionMap interface to add actions, to respond to the 701 * user selecting these menu items. 702 * 703 * Params: 704 * menubar = a #GMenuModel, or %NULL 705 * 706 * Since: 3.4 707 */ 708 public void setMenubar(MenuModel menubar) 709 { 710 gtk_application_set_menubar(gtkApplication, (menubar is null) ? null : menubar.getMenuModelStruct()); 711 } 712 713 /** 714 * Removes an inhibitor that has been established with gtk_application_inhibit(). 715 * Inhibitors are also cleared when the application exits. 716 * 717 * Params: 718 * cookie = a cookie that was returned by gtk_application_inhibit() 719 * 720 * Since: 3.4 721 */ 722 public void uninhibit(uint cookie) 723 { 724 gtk_application_uninhibit(gtkApplication, cookie); 725 } 726 727 protected class OnWindowAddedDelegateWrapper 728 { 729 static OnWindowAddedDelegateWrapper[] listeners; 730 void delegate(Window, Application) dlg; 731 gulong handlerId; 732 733 this(void delegate(Window, Application) dlg) 734 { 735 this.dlg = dlg; 736 this.listeners ~= this; 737 } 738 739 void remove(OnWindowAddedDelegateWrapper source) 740 { 741 foreach(index, wrapper; listeners) 742 { 743 if (wrapper.handlerId == source.handlerId) 744 { 745 listeners[index] = null; 746 listeners = std.algorithm.remove(listeners, index); 747 break; 748 } 749 } 750 } 751 } 752 753 /** 754 * Emitted when a #GtkWindow is added to @application through 755 * gtk_application_add_window(). 756 * 757 * Params: 758 * window = the newly-added #GtkWindow 759 * 760 * Since: 3.2 761 */ 762 gulong addOnWindowAdded(void delegate(Window, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 763 { 764 auto wrapper = new OnWindowAddedDelegateWrapper(dlg); 765 wrapper.handlerId = Signals.connectData( 766 this, 767 "window-added", 768 cast(GCallback)&callBackWindowAdded, 769 cast(void*)wrapper, 770 cast(GClosureNotify)&callBackWindowAddedDestroy, 771 connectFlags); 772 return wrapper.handlerId; 773 } 774 775 extern(C) static void callBackWindowAdded(GtkApplication* applicationStruct, GtkWindow* window, OnWindowAddedDelegateWrapper wrapper) 776 { 777 wrapper.dlg(ObjectG.getDObject!(Window)(window), wrapper.outer); 778 } 779 780 extern(C) static void callBackWindowAddedDestroy(OnWindowAddedDelegateWrapper wrapper, GClosure* closure) 781 { 782 wrapper.remove(wrapper); 783 } 784 785 protected class OnWindowRemovedDelegateWrapper 786 { 787 static OnWindowRemovedDelegateWrapper[] listeners; 788 void delegate(Window, Application) dlg; 789 gulong handlerId; 790 791 this(void delegate(Window, Application) dlg) 792 { 793 this.dlg = dlg; 794 this.listeners ~= this; 795 } 796 797 void remove(OnWindowRemovedDelegateWrapper source) 798 { 799 foreach(index, wrapper; listeners) 800 { 801 if (wrapper.handlerId == source.handlerId) 802 { 803 listeners[index] = null; 804 listeners = std.algorithm.remove(listeners, index); 805 break; 806 } 807 } 808 } 809 } 810 811 /** 812 * Emitted when a #GtkWindow is removed from @application, 813 * either as a side-effect of being destroyed or explicitly 814 * through gtk_application_remove_window(). 815 * 816 * Params: 817 * window = the #GtkWindow that is being removed 818 * 819 * Since: 3.2 820 */ 821 gulong addOnWindowRemoved(void delegate(Window, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 822 { 823 auto wrapper = new OnWindowRemovedDelegateWrapper(dlg); 824 wrapper.handlerId = Signals.connectData( 825 this, 826 "window-removed", 827 cast(GCallback)&callBackWindowRemoved, 828 cast(void*)wrapper, 829 cast(GClosureNotify)&callBackWindowRemovedDestroy, 830 connectFlags); 831 return wrapper.handlerId; 832 } 833 834 extern(C) static void callBackWindowRemoved(GtkApplication* applicationStruct, GtkWindow* window, OnWindowRemovedDelegateWrapper wrapper) 835 { 836 wrapper.dlg(ObjectG.getDObject!(Window)(window), wrapper.outer); 837 } 838 839 extern(C) static void callBackWindowRemovedDestroy(OnWindowRemovedDelegateWrapper wrapper, GClosure* closure) 840 { 841 wrapper.remove(wrapper); 842 } 843 }