Sign in Join
Wiki copytemporary

macOS Application Dock Menu: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: macOS Application Dock Menu

OldNewLine
1+## Overview
2+
3+Mac OS X v10.1 (Puma) added the ability to add custom menu items to an application's dock icon. Dock items like Options, Show All Windows, Hide ands Quit are provided automatically by the dock, so all we need to do is add our custom items. By adding menu items to your application's dock icon, you can provide the user with quick access to commonly used features.
4+
5+Another possibility is modifying the application's dock menu while the application is running to produce a dynamic menu with, for example, a status update. This is easily done by not assigning an action selector when creating the menu item. This also greys out the menu item so that it cannot be selected. There is an example included in the example code below.
6+
7+## Example code
8+
9+``` pascal
10+unit Unit1;
11+
12+{$mode objfpc}{$H+}
13+{$modeswitch objectivec1}
14+
15+interface
16+
17+uses
18+ Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
19+ CocoaAll;
20+
21+type
22+
23+ { TForm1 }
24+
25+ TForm1 = class(TForm)
26+ Button1: TButton;
27+ procedure Button1Click(Sender: TObject);
28+ procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
29+ procedure FormCreate(Sender: TObject);
30+ private
31+
32+ public
33+
34+ end;
35+
36+ TMyAppDelegate = objcclass(NSObject)
37+ private
38+
39+ public
40+ function applicationDockMenu (sender: NSApplication): NSMenu;
41+ message 'applicationDockMenu:';
42+ procedure menuItemHello1;
43+ message 'menuItemHello1';
44+ procedure menuItemHello2;
45+ message 'menuItemHello2';
46+ end;
47+
48+var
49+ Form1: TForm1;
50+ myAppDelegate: TMyAppDelegate;
51+
52+implementation
53+
54+{$R *.lfm}
55+
56+{ TForm1 }
57+
58+procedure TMyAppDelegate.menuItemHello1;
59+begin
60+ NSLog(NSStr('hello menu item 1'));
61+end;
62+
63+procedure TMyAppDelegate.menuItemHello2;
64+begin
65+ NSLog(NSStr('hello menu item 2'));
66+end;
67+
68+function TMyAppDelegate.applicationDockMenu(sender: NSApplication): NSMenu;
69+var
70+ aSel, bSel: SEL;
71+ myMenu: NSMenu;
72+ myMenuItem0: NSMenuItem;
73+ myMenuItem1: NSMenuItem;
74+ myMenuItem2: NSMenuItem;
75+begin
76+ NSLog(NSStr('dock menu'));
77+
78+ aSel := ObjCSelector(TMyAppDelegate.menuItemHello1);
79+ bSel := ObjCSelector(TMyAppDelegate.menuItemHello2);
80+
81+ myMenu := NSMenu.alloc.init.autorelease;
82+ myMenuItem0 := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(NSStr('My Dock Menu'), Nil, NSStr('')).autorelease;
83+ myMenuItem1 := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(NSStr('Hello Item 1'), aSel, NSStr('')).autorelease;
84+ myMenuItem2 := NSMenuItem.alloc.initWithTitle_action_keyEquivalent(NSStr('Hello Item 2'), bSel, NSStr('')).autorelease;
85+ myMenu.addItem(myMenuItem0);
86+ myMenu.addItem(myMenuItem1);
87+ myMenu.addItem(myMenuItem2);
88+ Result := myMenu;
89+end;
90+
91+procedure TForm1.Button1Click(Sender: TObject);
92+begin
93+ NSLog(NSStr('Closing'));
94+ Close;
95+end;
96+
97+procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
98+begin
99+ NSLog(NSStr('Leaving...'));
100+
101+ if(NSApp.isActive) then
102+ begin
103+ NSLog(NSStr('exiting'));
104+ exit;
105+ end
106+ else
107+ // needed if any part of form is occluded or does not quit
108+ // until dock icon clicked when quitting via dock menu
109+ begin
110+ NSLog(NSStr('activating'));
111+ Application.BringToFront;
112+ CloseAction := TCloseAction.caFree;
113+ end;
114+end;
115+
116+procedure TForm1.FormCreate(Sender: TObject);
117+begin
118+ // NSApp
119+ // - The global variable for the shared application instance.
120+ // NSApplication.sharedApplication
121+ // - Returns the application instance, creating it if it doesn’t exist yet.
122+ NSApp := NSApplication.sharedApplication;
123+ NSApp.setDelegate(myAppDelegate);
124+end;
125+
126+Initialization
127+ myAppDelegate := TMyAppDelegate.alloc.init;
128+
129+Finalization
130+ myAppDelegate.Release;
131+end.
132+```
133+
134+Typical log output when the executable is started from an Applications \> Utilities \> Terminal and the two added menu items are clicked before using the dock menu to quit:
135+
136+`trev@macmini7 [/Users/trev/Programming/LAZARUS/laz_dockmenu] $ ./project1.app/Contents/MacOS/project1`\
137+`2021-03-02 19:35:58.366 project1[1483:110782] dock menu`\
138+`2021-03-02 19:36:05.700 project1[1483:110782] dock menu`\
139+`2021-03-02 19:36:10.862 project1[1483:110782] hello menu item 1`\
140+`2021-03-02 19:36:12.644 project1[1483:110782] dock menu`\
141+`2021-03-02 19:36:14.360 project1[1483:110782] hello menu item 2`\
142+`2021-03-02 19:36:15.915 project1[1483:110782] dock menu`\
143+`2021-03-02 19:36:17.061 project1[1483:110782] Leaving...`\
144+`2021-03-02 19:36:17.061 project1[1483:110782] activating`
145+
146+Alternatively, you can view the output using the Applications \> Utilities \> Console.
147+
148+## See also
149+
150+- [[Apple-specific UI elements]]
151+- [[Application disable resize over Dock]]
152+- [[Bounce Application Icon in Dock]]
153+- [[Hiding a macOS app from the Dock]]
154+- [[macOS NSStatusBar]]
155+- [[Show Badge on Application Icon in Dock]]
156+
157+## External links
158+
159+- [Apple: NSApplication](https://developer.apple.com/documentation/appkit/nsapplication).
160+- [Apple: NSMenu](https://developer.apple.com/documentation/appkit/nsmenu).
161+- [Apple: NSMenuItem](https://developer.apple.com/documentation/appkit/nsmenuitem).
162+- [Apple: applicationDockMenu:](https://developer.apple.com/documentation/appkit/nsapplicationdelegate/1428564-applicationdockmenu).
163+
164+---
165+*From the Free Pascal wiki, page "macOS Application Dock Menu", as it stood on 2021-12-15 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history