GtkosxApplication

## GtkosxApplication GtkosxApplication — Base class for OSX integration |

## Functions

GtkosxApplication * | gtkosx_application_get ()
void | gtkosx_application_ready ()
void | gtkosx_application_set_use_quartz_accelerators ()
gboolean | gtkosx_application_use_quartz_accelerators ()
void | gtkosx_application_set_menu_bar ()
void | gtkosx_application_sync_menubar ()
void | gtkosx_application_insert_app_menu_item ()
void | gtkosx_application_set_window_menu ()
void | gtkosx_application_set_help_menu ()
void | gtkosx_application_set_dock_menu ()
void | gtkosx_application_set_dock_icon_pixbuf ()
void | gtkosx_application_set_dock_icon_resource ()
gint | gtkosx_application_attention_request ()
void | gtkosx_application_cancel_attention_request ()
gchar * | gtkosx_application_get_bundle_path ()
gchar * | gtkosx_application_get_resource_path ()
gchar * | gtkosx_application_get_executable_path ()
gchar * | gtkosx_application_get_bundle_id ()
gchar * | gtkosx_application_get_bundle_info ()

## Signals

gboolean | NSApplicationBlockTermination | Action
void | NSApplicationDidBecomeActive | Action
gboolean | NSApplicationOpenFile | Action
void | NSApplicationWillResignActive | Action
void | NSApplicationWillTerminate | Action

## Types and Values

struct | GtkosxApplicationMenuGroup
enum | GtkosxApplicationAttentionType
#define | GTKOSX_TYPE_APPLICATION_ATTENTION_TYPE

## Object Hierarchy

        GObject
        ╰── GtkosxApplication

## Includes

    #include <gtkosxapplication.h>

## Description

Exposes to the Gtk+ program important functions of OSX's NSApplication class for use by Gtk+ applications running with the quartz Gdk backend and provides addtional functions for integrating a Gtk+ program into the OSX user environment.

Using GtkosxApplication is pretty simple. First, create an instance at startup:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    Do this early in your program, shortly after you run
    |[gtk_init()]|. Don't forget to guard it, and all other calls into
    the library, with |[#ifdef MAC_INTEGRATION]|. You don't want your
    Linux users' builds failing because of this.  The application
    object is a singleton, so you can call g_object_new as often as you
    like. You'll always get the same pointer back. There's no need to
    pass it around as an argument. Do note that all of the
    GtkosxApplication functions take theApp as an argument, even if
    they don't use it. This seems silly in C, and perhaps it is, but
    it's needed to make the Python binding logic recognize that they're
    class methods.

    Just having the application object created will get you some
    benefits, like having the Quit menu item in the dock menu work. But
    you'll obviously want more. So the next place to visit is your main
    window code. If you have a simple application, you might be
    constructing the menu by hand, but you're more likely to be using
    GtkBuilder. In either case, you need to get a pointer to the
    menubar. If you're building by hand, you've already got it lying
    around because you needed it to add the menus to. With GtkBuilder,
    you need to ask the GtkUIManager for a pointer. Once everything is
    more-or-less set up on the Gtk+ side, you need only hide the menu
    and call gtkosx_application_set_main_menu(). Here's an example with
    GtkBuilder:

    <example>
    <title>Setting the MenuBar</title>
    <programlisting>
      GtkUIManager *mgr = gtk_ui_manager_new();
      GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
      ...
      mergeid = gtk_ui_manager_add_ui_from_file(mgr, "src/testui.xml", &err);
      ...
      menubar = gtk_ui_manager_get_widget(mgr, "/menubar");
      gtk_widget_hide (menubar);
      gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(menubar));
    </programlisting>
    </example>

    There are a couple of wrinkles, though, if you use
    accelerators. First off, there are two event paths for
    accelerators: Quartz, where the keystroke is processed by OSX and
    the menu item action event is placed on the event queue by OSX, or
    Gtk, where the accelerator key event is passed through to Gtk to
    recognize. This is controlled by
    gtkosx_application_set_use_quartz_accelerators() (you can test the
    value with gtkosx_application_use_quartz_accelerators()), and the
    default is to use Quartz handling. This has two advantages:
    <itemizedlist>
    <listitem><para>It works without any extra steps</para></listitem>
    <listitem><para>
    It changes stock accelerators (like Ctrl-O for open file) to
    the stock OSX keyEquivalent (Cmd-O in that case).
    </para></listitem>
    </itemizedlist>
    If you need to use Gtk+ keyboard accelerator handling <emphasis>and</emphasis>
    you're using GtkMenuItems instead of GtkActions, you'll need to
    connect a special handler as shown in the following example:
    <example>
    <title>Enabling Accelerators on Hidden Menus</title>
    <programlisting>
    static gboolean
    can_activate_cb(GtkWidget* widget, guint signal_id, gpointer data)
    {
      return gtk_widget_is_sensitive(widget);
    }
    ...
      g_signal_connect(menubar, "can-activate-accel",
                       G_CALLBACK(can_activate_cb), NULL);
    </programlisting>
    </example>

    The next task to make your application appear more normal for Mac
    users is to move some menu items from their normal Gtk locations to
    the so-called "App" menu. That's the menu all the way at the left
    of the menubar that has the currently-running application's
    name. There are 3 menu items that normally go there:
    <itemizedlist>
    <listitem><para>Help|About</para></listitem>
    <listitem><para>Edit|Preferences</para></listitem>
    <listitem><para>File|Quit</para></listitem>
    </itemizedlist>
    File|Quit is a special case, because OSX handles it itself and
    automatically includes it, so the only thing you need do is hide it
    on the File menu so that it doesn't show up twice:
    |[gtk_widget_hide(GTK_WIDGET(file_quit_menu_item));]|
    The other two must be moved in code, and there are two functions
    for doing that. The first one creates "goups", which is just an
    easy way to manage separators, and the second adds the actual menu
    items to the groups. Here's an example:
    <example>
    <programlisting>
     GtkosxApplicationMenuGroup *group;
     GtkMenuItem *about_item, *preferences_item;
     about_item = gtk_ui_manager_get_widget(mgr, "/menubar/Help/About");
     preferences_item = gtk_ui_manager_get_widget(mgr, "/menubar/Edit/Preferences");

     group = gtkosx_application_add_app_menu_group (theApp);
     gtkosx_application_add_app_menu_item  (theApp, group,
                                            GTK_MENU_ITEM (about_item));

     group = gtkosx_application_add_app_menu_group (theApp);
     gtkosx_application_add_app_menu_item  (theApp, group,
                                            GTK_MENU_ITEM (preferences_item));
    </programlisting>
    </example>
    Once we have everything set up for as many windows as we're going
    to open before we call gtk_main_loop(), we need to tell OSX that
    we're ready:
    |[gtkosx_application_ready(theApp);]|

    If you add other windows later, you must do everything above for
    each one's menubar. Most of the time the internal notifictations
    will ensure that the GtkosxApplication is able to keep everything
    in sync. However, if you at any time disconnect or block signals
    and change the menu (perhaps because of a context change within a
    window, as with changing pages in a GtkNotebook) you need to call
    |[gtkosx_application_sync_menubar(theApp)]|

    * The dock is that bar of icons that normally lives at the bottom of
    the display on a Mac (though it can be moved to one of the other
    sides; this author likes his on the left, which is where it was
    originally on a NeXT). Each running application has a "dock tile",
    an icon on the dock. Users can, if they like, add application (or
    document) icons to the dock, and those can be used to launch the
    application. Apple allows limited customization of the dock tile,
    and GtkosxApplication has an interface for adding to the dock's
    menu and for changing the icon that is displayed for the the
    application. GtkosxApplication also provides an interface to
    AttentionRequest, which bounces the dock tile if the application
    doesn't have focus. You might want to do that at the end of a long
    task so that the user will know that it's finished if she's
    switched to another application while she waits for yours.
    They're all pretty simple, so you can just read the details below.

    * The last feature to which GtkosxApplication provides an interface
    is the bundle. Normally in OSX, graphical applications are packaged
    along with their non-standard dependencies and their resources
    (graphical elements, translations, and such) in special directory
    structures called "bundles". To easily package your Gtk+
    application, have a look at gtk-mac-bundler, also available from
    the Gtk-OSX project.

    OSX provides a variety of functions pertaining to bundles, most of which are not likely to interest someone porting a Gtk+ application. GtkosxApplication has wrapped a few that might be:
    <itemizedlist>
    <listitem><para>gtkosx_application_get_bundle_path()</para></listitem>
    <listitem><para>gtkosx_application_get_resource_path()</para></listitem>
    <listitem><para>gtkosx_application_get_executable_path()</para></listitem>
    <listitem><para>gtkosx_application_get_bundle_id()</para></listitem>
    <listitem><para>gtkosx_application_get_bundle_info()</para></listitem>
    </itemizedlist>

    The first three just get a UTF8-encoded path. An interesting note
    is that they'll return the path to the executable or the folder
    it's in regardless of whether it's actually in a bundle. To find
    out if one is actually dealing with a bundle,
    gtkosx_application_get_bundle_id() will return "" if it can't find
    the key %CFBundleIdentifier from the bundle's Info.plist -- which it
    won't if the application isn't in a bundle or wasn't launched by
    opening the bundle. (In other words, even if you have your
    application installed in Foo.app, if you launch it from the command
    line as
    |[$ Foo.app/Contents/MacOS/Foo]|
    the Info.plist won't have been opened and
    gtkosx_application_get_bundle_id() will return "". Of course, it
    will also return "" if you didn't set %CFBundleIdentifier in the
    Info.plist, so make sure that you do!

    The last function, gtkosx_application_get_bundle_info(), will
    return the value associated with an arbitrary key from Info.plist
    as long as that value is a string. If it isn't, then the function
    returns a null string ("").

    Finally, notice the signals. These are emitted in response to the
    indicated OSX notifications. Except for
    #GtkosxApplication::NSApplicationBlockTermination, most programs
    won't need to do anything with
    them. #GtkosxApplication::NSApplicationBlockTermination is telling
    you that OSX is planning to shut down your program. If you have any
    cleanup to do (like saving open files), or if you want to ask the
    user if it's OK, you should connect to the signal and do your
    cleanup. Your handler can return %TRUE to prevent the application
    from quitting.

## Functions

### gtkosx_application_get ()

    GtkosxApplication *
    gtkosx_application_get (void);

#### Returns

(transfer none) the singleton application object.

### gtkosx_application_ready ()

    void
    gtkosx_application_ready (GtkosxApplication *self);

Inform Cocoa that application initialization is complete.

#### Parameters

self | The GtkosxApplication object |

### gtkosx_application_set_use_quartz_accelerators ()

    void
    gtkosx_application_set_use_quartz_accelerators
                                   (GtkosxApplication *self,
                                    gboolean use_quartz_accelerators);

Set quartz accelerator handling; TRUE (default) uses quartz; FALSE uses Gtk+. Quartz accelerator handling is required for normal OSX accelerators (e.g., command-q to quit) to work.

#### Parameters

self | The GtkosxApplication pointer. |
use_quartz_accelerators | Gboolean |

### gtkosx_application_use_quartz_accelerators ()

    gboolean
    gtkosx_application_use_quartz_accelerators
                                   (GtkosxApplication *self);

Are we using Quartz or Gtk+ accelerator handling?

#### Parameters

self | The GtkosxApplication pointer. |

#### Returns

a gboolean

### gtkosx_application_set_menu_bar ()

    void
    gtkosx_application_set_menu_bar (GtkosxApplication *self,
                                     GtkMenuShell *menu_shell);

Set a window's menubar as the application menu bar. Call this once for each window as you create them. It works best if the menubar is reasonably fully populated before you call it. Once set, it will stay syncronized through signals as long as you don't disconnect or block them.

#### Parameters

self | The GtkosxApplication object |
menu_shell | The GtkMenuBar that you want to set. |

### gtkosx_application_sync_menubar ()

    void
    gtkosx_application_sync_menubar (GtkosxApplication *self);

Syncronize the active window's GtkMenuBar with the OSX menu bar. You should only need this if you have programmatically changed the menus with signals blocked or disconnected.

#### Parameters

self | The GtkosxApplication object |

### gtkosx_application_insert_app_menu_item ()

    void
    gtkosx_application_insert_app_menu_item
                                   (GtkosxApplication *self,
                                    GtkWidget *menu_item,
                                    gint index);

Certain menu items (About, Check for updates, and Preferences in particular) are normally found in the so-called Application menu (the first one on the menubar, named after the application) in OSX applications. This function will create a menu entry for such a menu item, removing it from its original menu in the Gtk application.

Any items inserted at index zero will have the app name appended; this is intended for the "About" menu item, so that it says "About Foo" like most Mac programs, without having to worry too much about how "About" is spelled/translated.

To group your menu items, insert GtkSeparatorMenuItem*s where you want them.

Don't use it for Quit! A Quit menu item is created automatically along with the Application menu. Just hide your Gtk Quit menu item.

#### Parameters

self | The GtkosxApplication object |
menu_item | The GtkMenuItem to add to the group. |
index | The place in the app menu that you want the item inserted. The first item is 0. |

### gtkosx_application_set_window_menu ()

    void
    gtkosx_application_set_window_menu (GtkosxApplication *self,
                                        GtkMenuItem *menu_item);

Sets a designated menu item already on the menu bar as the Window menu. This is the menu which contains a list of open windows for the application; by default it also provides menu items to minimize and zoom the current window and to bring all windows to the front. Call this after `gtk_osx_application_set_menu_bar()`. It operates on the currently active menubar. If `nenu_item` is NULL, it will create a new menu for you, which will not be gettext translatable.

#### Parameters

self | The application object |
menu_item | The menu item which will be set as the Window menu |

### gtkosx_application_set_help_menu ()

    void
    gtkosx_application_set_help_menu (GtkosxApplication *self,
                                      GtkMenuItem *menu_item);

Sets a designated menu item already on the menu bar as the Help menu. Call this after `gtk_osx_application_set_menu_bar()`, but before `gtk_osx_application_window_menu()`, especially if you're letting GtkosxApplication create a Window menu for you (it helps position the Window menu correctly). It operates on the currently active menubar. If `nenu_item` is `NULL`, it will create a new menu for you, which will not be gettext translatable.

#### Parameters

self | The application object |
menu_item | The menu item which will be set as the Window menu |

### gtkosx_application_set_dock_menu ()

    void
    gtkosx_application_set_dock_menu (GtkosxApplication *self,
                                      GtkMenuShell *menu_shell);

Set a GtkMenu as the dock menu.

This menu does not have a "sync" function, so changes made while signals are disconnected will not update the menu which appears in the dock, and may produce strange results or crashes if a GtkMenuItem or GtkAction associated with a dock menu item is deallocated.

#### Parameters

self | The GtkosxApplication object |
menu_shell | A GtkMenu (cast it with `GTK_MENU_SHELL()` when you pass it in |

### gtkosx_application_set_dock_icon_pixbuf ()

    void
    gtkosx_application_set_dock_icon_pixbuf
                                   (GtkosxApplication *self,
                                    GdkPixbuf *pixbuf);

Set the dock icon from a GdkPixbuf

#### Parameters

self | The GtkosxApplication |
pixbuf | The pixbuf. Pass NULL to reset the icon to its default. |

### gtkosx_application_set_dock_icon_resource ()

    void
    gtkosx_application_set_dock_icon_resource
                                   (GtkosxApplication *self,
                                    const gchar *name,
                                    const gchar *type,
                                    const gchar *subdir);

Set the dock icon from an image file in the bundle/

#### Parameters

self | The GtkosxApplication |
name | The ame of the image file |
type | The extension (e.g., jpg) of the filename |
subdir | The subdirectory of $Bundle/Contents/Resources in which to look for the file. |

### gtkosx_application_attention_request ()

    gint
    gtkosx_application_attention_request (GtkosxApplication *self,
                                          GtkosxApplicationAttentionType type);

Create an attention request. If type is CRITICAL_REQUEST, the dock icon will bounce until cancelled the application receives focus; otherwise it will bounce for 1 second -- but the attention request will remain asserted until cancelled or the application receives focus. This function has no effect if the application has focus.

#### Parameters

self | The GtkosxApplication pointer |
type | CRITICAL_REQUEST or INFO_REQUEST |

#### Returns

A the attention request ID. Pass this id to gtkosx_application_cancel_attention_request.

### gtkosx_application_cancel_attention_request ()

    void
    gtkosx_application_cancel_attention_request
                                   (GtkosxApplication *self,
                                    gint id);

Cancel an attention request created with gtkosx_application_attention_request.

#### Parameters

self | The application |
id | The integer attention request id returned from gtkosx_application_attention_request. |

### gtkosx_application_get_bundle_path ()

    gchar *
    gtkosx_application_get_bundle_path (void);

Return the root path of the bundle or the directory containing the executable if it isn't actually a bundle.

#### Returns

path The bundle's absolute path or `NULL` on error. `g_free()` it when done.

### gtkosx_application_get_resource_path ()

    gchar *
    gtkosx_application_get_resource_path (void);

Return the Resource path for the bundle or the directory containing the executable if it isn't actually a bundle. Use `gtkosx_application_get_bundle_id()` to check (it will return `NULL` if it's not a bundle).

#### Returns

path The absolute resource path. or `NULL` on error. `g_free()` it when done.

### gtkosx_application_get_executable_path ()

    gchar *
    gtkosx_application_get_executable_path
                                   (void);

Return the executable path, including file name

#### Returns

The path to the primary executable, or `NULL` if it can't find one. `g_free()` it when done

### gtkosx_application_get_bundle_id ()

    gchar *
    gtkosx_application_get_bundle_id (void);

Return the value of the CFBundleIdentifier key from the bundle's Info.plist

This will return NULL if it's not really a bundle, there's no Info.plist, or if Info.plist doesn't have a CFBundleIdentifier key (So if you need to detect being in a bundle, make sure that your bundle has that key!)

#### Returns

The string value of CFBundleIdentifier, or `NULL` if there is none. `g_free()` it when done.

### gtkosx_application_get_bundle_info ()

    gchar *
    gtkosx_application_get_bundle_info (const gchar *key);

Queries the bundle's Info.plist with key. If the returned object is a string, returns that; otherwise returns `NULL`.

#### Parameters

key | The key, as a normal UTF8 string. |

#### Returns

A UTF8-encoded string. `g_free()` it when done.

## Types and Values

### struct GtkosxApplicationMenuGroup

    struct GtkosxApplicationMenuGroup {
      GList *items;
    };

### enum GtkosxApplicationAttentionType

#### Members

CRITICAL_REQUEST |  |
INFO_REQUEST |  |

### GTKOSX_TYPE_APPLICATION_ATTENTION_TYPE

    #define GTKOSX_TYPE_APPLICATION_ATTENTION_TYPE (gtkosx_type_application_attention_type_get_type())

## Signal Details

### The `“NSApplicationBlockTermination”` signal

    gboolean
    user_function (GtkosxApplication *app,
                   gpointer           user_data)

Emitted by the Application Delegate when the application reeeives an NSApplicationShouldTerminate notification. Perform any cleanup you need to do (e.g., saving files) before exiting. Returning FALSE will allow further handlers to run and if none return TRUE, the application to shut down. Returning TRUE will veto shutdown and stop emission, so later handlers will not run.

#### Parameters

app | The application object |
user_data | Data appended at connection |
user_data | user data set when the signal handler was connected. |

#### Returns

Boolean indicating that further emission and application termination should be blocked.

Flags: Action

### The `“NSApplicationDidBecomeActive”` signal

    void
    user_function (GtkosxApplication *app,
                   gpointer           user_data)

Emitted by the Application Delegate when the application receives an NSApplicationDidBecomeActive notification. Connect a handler if there is anything you need to do when the application is activated.

#### Parameters

app | The application object user_data: Data appended at connection |
user_data | user data set when the signal handler was connected. |

Flags: Action

### The `“NSApplicationOpenFile”` signal

    gboolean
    user_function (GtkosxApplication *app,
                   gchar             *path,
                   gpointer           user_data)

Emitted when a OpenFile, OpenFiles, or OpenEmptyFile event is received from the operating system. This signal does not implement drops, but it does implement "open with" events from Finder. An OpenEmptyFile is received at launch in Python applications.

#### Parameters

app | The application object |
path | A UTF8-encoded file path to open. |
user_data | Data attached at connection |
user_data | user data set when the signal handler was connected. |

#### Returns

Boolean indicating success at opening the file.

Flags: Action

### The `“NSApplicationWillResignActive”` signal

    void
    user_function (GtkosxApplication *app,
                   gpointer           user_data)

This signal is emitted by the Application Delegate when the application receives an NSApplicationWillResignActive notification. Connect a handler to it if there's anything your application needs to do to prepare for inactivity.

#### Parameters

app | The application object |
user_data | Data appended at connection |
user_data | user data set when the signal handler was connected. |

Flags: Action

### The `“NSApplicationWillTerminate”` signal

    void
    user_function (GtkosxApplication *app,
                   gpointer           user_data)

Emitted by the Application Delegate when the application reeeives an NSApplicationSWillTerminate notification. Connect your final shutdown routine (the one that calls `gtk_main_quit()` here.

#### Parameters

app | The application object |
user_data | Data appended at connection |
user_data | user data set when the signal handler was connected. |

Flags: Action