3

I'm developing a swift Mac OS app that works only in the status bar (with a popover) with Application is background only set to true.

Inside the popover the user can interact with a button to save an image, more specifically the following function is triggered:

@IBAction func saveImage(sender: NSButton) {
    self.closePopover()

    let dialog = NSSavePanel()

    let date = Date()
    let formattedDate = getFormattedDate(date: date, format: "yyyy-MM-dd")
    let formattedTime = getFormattedDate(date: date, format: "HH.mm.ss")
    dialog.level = .modalPanel
    dialog.title                    = "Choose a destination"
    dialog.nameFieldStringValue     = "Screenshot \(formattedDate) at \(formattedTime)"
    dialog.showsResizeIndicator     = true
    dialog.showsHiddenFiles         = false
    dialog.canCreateDirectories     = true
    dialog.allowedFileTypes         = ["png"]

    if (dialog.runModal() == .OK) {
        // Pathname of the file
        if let result = dialog.url {
            self.screenshot!.savePNGRepresentationToURL(url: result)
        }
    } else {
        // User clicked on "Cancel"
        return
    }
}

The problem is that:

  • If I put Application is background only = true:
    I can't interact with the NSSavePanel (can't change the save as field) and if I write inside that box, the text is written in the last application I was interacting (the focus is not really on the modal).
  • If I put Application is background only = false:
    the NSSavePanel works perfectly fine but that is not a good solution because I don't want to have the icon to appear in the dock

So the problem is clearly linked to the Application is background only but I didn't find a way to have both:

  • no app icon in the dock
  • good interaction with the NSSavePanel
madx
  • 6,723
  • 4
  • 55
  • 59
  • 1
    You would probably need to launch another app. Take a look how Dropbox menu works. It is background only but sometimes it launches its app. – Leo Dabus Feb 11 '20 at 14:11
  • For dropbox "sync issue" section you are right. This could be a way to solve it. I was looking for a way to programmatically turn off the is background only and then turn it on again after the selection has been done... But probably your suggestion is better. – madx Feb 11 '20 at 16:27
  • Using `NSApplication.shared.setActivationPolicy` it worked, I'll post my answer – madx Feb 12 '20 at 12:49

1 Answers1

0

I solved using the NSApplication.shared.setActivationPolicy method like this:

@IBAction func saveImage(sender: NSButton) {
    self.closePopover()

    NSApplication.shared.setActivationPolicy(.regular)

    let dialog = NSSavePanel()

    let date = Date()
    let formattedDate = getFormattedDate(date: date, format: "yyyy-MM-dd")
    let formattedTime = getFormattedDate(date: date, format: "HH.mm.ss")
    dialog.level = .modalPanel
    dialog.title                    = "Choose a destination"
    dialog.nameFieldStringValue     = "Screenshot \(formattedDate) at \(formattedTime)"
    dialog.showsResizeIndicator     = true
    dialog.showsHiddenFiles         = false
    dialog.canCreateDirectories     = true
    dialog.allowedFileTypes         = ["png"]

    if (dialog.runModal() == .OK) {
        // Pathname of the file
        if let result = dialog.url {
            self.screenshot!.savePNGRepresentationToURL(url: result)
        }
    } else {
        // User clicked on "Cancel"
    }

    NSApplication.shared.setActivationPolicy(.accessory)
}
madx
  • 6,723
  • 4
  • 55
  • 59