Sign in Join
Wiki copytemporary

Cocoa Internals/Dialogs: what changed

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

Title: Cocoa Internals/Dialogs

OldNewLine
1+## Common Considerations
2+
3+### Modality
4+
5+None of the Cocoa dialogs (OpenFile, SaveFile, Font or Color) are modal!
6+
7+This means that one can open a dialog and keep using the other application windows and the application menu.
8+
9+This doesn't work well with the LCL design, where each dialog is opened by an **Execute** method which doesn't return until the modal dialog is closed.
10+
11+For this particular reason, Cocoa WS does the following:
12+
13+- every dialog is called as the application modal window (preventing other windows of the application from getting any user input);
14+- the application menu is disabled, until the dialog is closed;
15+- where applicable, "Ok" and "Cancel" buttons are added to dialogs to indicate to a user that the dialog can be closed to make the selection.
16+
17+### No restoration
18+
19+Starting with macOS 10.7 Cocoa will attempt to restore the Application windows between Launches.
20+
21+It's a nice user feature, which conflicts with LCL. Since LCL adds custom controls to a dialog, and the restoration requires a special "restorationClass" to be provided.
22+
23+Instead of restoring dialogs, CocoaWS explicitly forbids the restoration of them.
24+
25+### Class Override
26+
27+Unlike NSApplication, dialog classes cannot be overwritten in the following manner:
28+
29+` TCocoaColorPanel.sharedPanel`
30+
31+Doing that will cause problems using class methods of the sharedPanel (and likely something else)
32+
33+### No Tags
34+
35+macOS system is using "tags" on files. It seems to be a file system feature that's used commonly in macOS.
36+
37+LCL doesn't have a concept of tags.
38+
39+By default Save dialog is showing a user an ability to select a tag. Since LCL cannot handle it properly (it cannot return the value, nor it has APIs to save the value), the dialog hides the tag selection, by default.
40+
41+### File Type Selection
42+
43+There's no "native" file type selection in macOS dialogs. Instead, there's an opportunity to add "custom options" to an open/save dialog, known as **accessory view**.
44+
45+The accessory view is used to place the run-time file type selection into the open/save dialog.
46+
47+### File Type Filters
48+
49+There are two ways of filtering out files that can be opened. (Note that "filtering types" is not used when using Save dialog.)
50+
51+1\) Assign the list of file extensions or file types (UTI's) via the **setAllowedFileTypes:** method. Allowing "any" file can be achieved by using the **setAllowsOtherFileTypes:** method. Considerations:
52+
53+:* a filter is assigned by "generic type" rather than extension. And thus specifying "txt" as a filter, will assign "public.plain-text" type. Which might correspond to other file extensions other than "txt" file. (i.e. ".pas" files might also be allowed, as they are part of "public.plain-text" group).
54+
55+:* setAllowedFileTypes - is unable to verify compound extensions, such as "tar.gz". In which case the filter configured for ".tag.gz" and a filter configured for ".gz" will provide the exactly the same set of files for selection.
56+
57+
58+As a result of you should not rely on FilterIndex returned. Instead, you should verify the actual contents of the file selected.
59+
60+2\) Perform the file check manually through the **panel:shouldEnableURL:** method. Considerations:
61+
62+:* starting with macOS 10.15, there's a security change done in macOS. Save/Open file dialogs are executed in a separate process. Passing the information between the main process and the dialog process introduces a certain lag. If a great number of files, it becomes noticeable for the user. Thus it's possible that not all files might be "available" for the selection as the check runs slowly. (see [issue \#38399](https://bugs.freepascal.org/view.php?id=38399))
63+
64+A developer can control what method is used in the application by changing the global variable **CocoaUseUTIFilter** at CocoaWSDialogs unit.
65+
66+- CocoaUseUTIFilter = false (default) - "panel:shouldEnableURL" is used
67+- CocoaUseUTIFilter = true - macOS UTI method is used
68+
69+```Delphi
70+uses
71+ ..
72+ {$ifdef LCLCOCOA}
73+ ,CocoaWSDialogs
74+ {$endif}
75+ ...
76+
77+initialization
78+ {$ifdef LCLCOCOA}
79+ CocoaUseUTIFilter := true;
80+ {$endif}
81+```
82+
83+## File Dialog Options
84+
85+Some of the options are not supported, please refer to the table below for the implementation details
86+
87+<table>
88+<thead>
89+<tr>
90+<th><p>Options</p></th>
91+<th><p>Supported</p></th>
92+<th><p>Description</p></th>
93+</tr>
94+</thead>
95+<tbody>
96+<tr>
97+<td><p>ofReadOnly</p></td>
98+<td><p>No</p></td>
99+<td></td>
100+</tr>
101+<tr>
102+<td><p>ofOverwritePrompt</p></td>
103+<td><p>No</p></td>
104+<td><p>In macOS prior to 10.15 it was possible to implement the feature by tricking the NSSaveDialog when selecting the name.</p>
105+<p>However, this ability was removed in 10.15 (due to security considerations?)</p>
106+<p>So now, overwrite prompt will always show up</p></td>
107+</tr>
108+<tr>
109+<td><p>ofHideReadOnly</p></td>
110+<td><p>No</p></td>
111+<td><p>There's no concept of "readOnly" files in macOS filesystems.</p>
112+<p>There's also no configuration in the dialog, to hide files</p></td>
113+</tr>
114+<tr>
115+<td><p>ofNoChangeDir</p></td>
116+<td><p>No</p></td>
117+<td></td>
118+</tr>
119+<tr>
120+<td><p>ofShowHelp</p></td>
121+<td><p>No</p></td>
122+<td></td>
123+</tr>
124+<tr>
125+<td><p>ofNoValidate</p></td>
126+<td><p>No</p></td>
127+<td></td>
128+</tr>
129+<tr>
130+<td><p>ofAllowMultiSelect</p></td>
131+<td><p>Yes</p></td>
132+<td><p>NSOpenPanel.setAllowsMultipleSelection()</p></td>
133+</tr>
134+<tr>
135+<td><p>ofExtensionDifferent,</p></td>
136+<td><p>No</p></td>
137+<td></td>
138+</tr>
139+<tr>
140+<td><p>ofPathMustExist</p></td>
141+<td><p>No</p></td>
142+<td></td>
143+</tr>
144+<tr>
145+<td><p>ofFileMustExist</p></td>
146+<td><p>No</p></td>
147+<td></td>
148+</tr>
149+<tr>
150+<td><p>ofCreatePrompt</p></td>
151+<td><p>No</p></td>
152+<td></td>
153+</tr>
154+<tr>
155+<td><p>ofShareAware</p></td>
156+<td><p>No</p></td>
157+<td><p>System native dialogs are always share aware OR act within sandbox allowances</p></td>
158+</tr>
159+<tr>
160+<td><p>ofNoReadOnlyReturn</p></td>
161+<td><p>No</p></td>
162+<td><p>No concept of "readonly" file</p></td>
163+</tr>
164+<tr>
165+<td><p>ofNoTestFileCreate</p></td>
166+<td><p>No</p></td>
167+<td></td>
168+</tr>
169+<tr>
170+<td><p>ofNoNetworkButton</p></td>
171+<td><p>No</p></td>
172+<td><p>All shares and networks are available or restricted by SandBox limitations</p></td>
173+</tr>
174+<tr>
175+<td><p>ofNoLongNames</p></td>
176+<td><p>No</p></td>
177+<td><p>Any file can have long name. OSX never suffered from 8.3 limitation</p></td>
178+</tr>
179+<tr>
180+<td><p>ofOldStyleDialog</p></td>
181+<td><p>No</p></td>
182+<td><p>There's no old style on macOS ...but, there's an opportunity to use in order to allow some emulation</p></td>
183+</tr>
184+<tr>
185+<td><p>ofNoDereferenceLinks</p></td>
186+<td><p>No</p></td>
187+<td><p>Links are treated by the system.</p></td>
188+</tr>
189+<tr>
190+<td><p>ofNoResolveLinks</p></td>
191+<td><p>No</p></td>
192+<td><p>Links are treated by the system</p></td>
193+</tr>
194+<tr>
195+<td><p>ofEnableIncludeNotify</p></td>
196+<td><p>No</p></td>
197+<td></td>
198+</tr>
199+<tr>
200+<td><p>ofEnableSizing</p></td>
201+<td><p>No</p></td>
202+<td><p>Dialogs are always sizable to the macOS rules</p></td>
203+</tr>
204+<tr>
205+<td><p>ofDontAddToRecent</p></td>
206+<td><p>No</p></td>
207+<td></td>
208+</tr>
209+<tr>
210+<td><p>ofForceShowHidden</p></td>
211+<td><p>Yes</p></td>
212+<td><p>NSSaveDialog.setShowsHiddenFiles()</p></td>
213+</tr>
214+<tr>
215+<td><p>ofViewDetail</p></td>
216+<td><p>No</p></td>
217+<td></td>
218+</tr>
219+<tr>
220+<td><p>ofAutoPreview</p></td>
221+<td><p>No</p></td>
222+<td></td>
223+</tr>
224+<tr>
225+<td><p>-</p></td>
226+<td><p>(default)</p></td>
227+<td><p>canCreateDirectries</p>
228+<p>The feature controls, if a user can create directories within the dialog.</p>
229+<p>Since Windows dialogs allows creation of folders, macOS LCL dialogs also allows the creation at all times.</p></td>
230+</tr>
231+<tr>
232+<td><p>-</p></td>
233+<td><p>(default)</p></td>
234+<td><p>extensionHidden</p>
235+<p>The name of the file, selected by the user hides the extension.</p>
236+<p>Since on Windows there's no control over how the file is displayed.</p>
237+<p>The property is left to its system default.</p></td>
238+</tr>
239+<tr>
240+<td><p>-</p></td>
241+<td><p>(default)</p></td>
242+<td><p>treatsFilePackagesAsDirectories</p>
243+<p>If set to true, a user can treat (Application) bundles as directories and navigate into the bundle.</p>
244+<p>There's no such concept in LCL, the value is at system default</p></td>
245+</tr>
246+</tbody>
247+</table>
248+
249+## See Also
250+
251+- [[Cocoa Internals]]
252+
253+---
254+*From the Free Pascal wiki, page "Cocoa Internals/Dialogs", as it stood on 2021-01-30 after a change by Skalogryz, 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).*
255+Category: Cocoa
256+Category: macOS

Back to history