5

First of all, I am completely new to Swift and I am sorry if my problem looks trivial.

I would like to have a very simple command line program that opens a dialog to choose a file or a folder. This tool must not run an actual full app with an icon bouncing in the Dock, but rather something subtle. That's it. What I have done produces exactly this, except the Panel cannot get focus. When I click on the Panel, it stays greyed out. Interestingly, it is possible to click on buttons, or drag and drop files, but exploring the file system is not possible. Keyboard events are not captured neither.

import AppKit

let dialog = NSOpenPanel()

dialog.title                   = "Choose a .tif file or a folder";
dialog.showsResizeIndicator    = true;
dialog.showsHiddenFiles        = false;
dialog.canChooseDirectories    = true;
dialog.canCreateDirectories    = true;
dialog.allowsMultipleSelection = false;
dialog.allowedFileTypes        = ["tif", "tiff"];
dialog.isFloatingPanel         = true;

if (dialog.runModal() == NSApplication.ModalResponse.OK)
{
  let result = dialog.url // Pathname of the file
  if (result != nil)
  {
    let path = result!.path
    print(path)
    exit(0)
  }
}

exit(1)

How could I display a NSOpenPanel that behaves normally? i.e.: can get the focus, can interact with mouse and keyboard, ...

The NSOpenPanel without focus

Slagt
  • 589
  • 2
  • 10

1 Answers1

5

In this context (app without a window) you need to set the NSApplication activation policy to .accessory to activate the panel (there's also .regular but it would show a Dock icon and a menu bar).

import AppKit

NSApplication.shared.setActivationPolicy(.accessory)

let dialog = NSOpenPanel()

dialog.title                   = "Choose a .tif file or a folder"
dialog.showsResizeIndicator    = true
dialog.showsHiddenFiles        = false
dialog.canChooseDirectories    = true
dialog.canCreateDirectories    = true
dialog.allowsMultipleSelection = false
dialog.allowedFileTypes        = ["tif", "tiff"]
dialog.isFloatingPanel         = true


if (dialog.runModal() == NSApplication.ModalResponse.OK)
{
    let result = dialog.url // Pathname of the file
    if (result != nil)
    {
        let path = result!.path
        print(path)
        exit(0)
    }
}

exit(1)
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • Thank you for your answer! You pointed me in the right direction. Your answer does not fully address my problem, because the application appears in the Dock and shows a menu bar (which I don't want). But by using `NSApplication.shared.setActivationPolicy(.accessory)` it works. The window s not activated by default and the user has to click on it first, but it works! Thank you! – Slagt Jun 12 '20 at 06:49
  • And it works with both `AppKit` or `Cocoa`. Not sure what's the difference in this case :/ – Slagt Jun 12 '20 at 06:56
  • 1
    I've edited the answer, so that future readers are not confused. – Eric Aya Jun 12 '20 at 07:44