Skip to content

Commit

Permalink
osx: set NSApp activation policy if required
Browse files Browse the repository at this point in the history
Currently, macOS dialogs don't work from the command-line, because the
NSApp activation policy defaults to "Prohibited" in that context. This
commit fixes that by setting the "Accessory" activation policy before
opening a dialog, if (and only if) we are in the Prohibited state.

Closes sqweek#81. Fixes sqweek#15.
  • Loading branch information
karelbilek authored and prosavage committed Mar 20, 2024
1 parent 67b9be5 commit c980765
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ an additional dialog is spawned to confirm they want to overwrite the existing f
Asks the user for a directory.

# platform details
* OSX: uses Cocoa's NSAlert/NSSavePanel/NSOpenPanel classes
* OSX: uses Cocoa's NSAlert/NSSavePanel/NSOpenPanel/NSApp classes
* requires macOS 10.6+ for `NSApplicationActivationPolicyAccessory`
* Win32: uses MessageBox/GetOpenFileName/GetSaveFileName (via package github.com/TheTitanrain/w32)
* Linux: uses Gtk's MessageDialog/FileChooserDialog (via cgo; requires gtk3 development packages)

Expand Down
16 changes: 16 additions & 0 deletions cocoa/dlg.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
return (void*)[[NSString alloc] initWithBytes:buf length:len encoding:NSUTF8StringEncoding];
}

void checkActivationPolicy() {
NSApplicationActivationPolicy policy = [NSApp activationPolicy];
// prohibited NSApp will not show the panel at all.
// It probably means that this is not run in a GUI app, that would set the policy on its own,
// but in a terminal app - setting it to accessory will allow dialogs to show
if (policy == NSApplicationActivationPolicyProhibited) {
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
}
}

void NSRelease(void* obj) {
[(NSObject*)obj release];
}
Expand Down Expand Up @@ -52,6 +62,9 @@ - (DlgResult)run {
[alert addButtonWithTitle:@"OK"];
break;
}

checkActivationPolicy();

self->result = [alert runModal] == NSAlertFirstButtonReturn ? DLG_OK : DLG_CANCEL;
return self->result;
}
Expand Down Expand Up @@ -106,6 +119,9 @@ - (NSInteger)runPanel:(NSSavePanel*)panel {
if(self->params->filename != nil) {
[panel setNameFieldStringValue:[[NSString alloc] initWithUTF8String:self->params->filename]];
}

checkActivationPolicy();

return [panel runModal];
}

Expand Down
4 changes: 0 additions & 4 deletions example/simple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ import (
)

func main() {
/* Note that spawning a dialog from a non-graphical app like this doesn't
** quite work properly in OSX. The dialog appears fine, and mouse
** interaction works but keypresses go straight through the dialog.
** I'm guessing it has something to do with not having a main loop? */
dialog.Message("%s", "Please select a file").Title("Hello world!").Info()
file, err := dialog.File().Title("Save As").Filter("All Files", "*").Save()
fmt.Println(file)
Expand Down

0 comments on commit c980765

Please sign in to comment.