MacOS: Hidden Windows cannot be fetched in NSApp

Hi,

Using purely swift programatically (no storyboard), I'm able to create an NSWindow like so:

var  window = NSWindow (contentRect: pInstruction.GetFrame (),
                    styleMask: [.miniaturizable, .closable, .resizable, .titled],
                    backing: .buffered,
                    defer: false)
window.title = "Some Title"
window.contentViewController = MyViewController ()
let windowidentifier = NSUserInterfaceItemIdentifier ("WinID1")
window.identifier = windowidentifier

window.makeKeyAndOrderFront(nil)

This works fine and I can see a window on screen. Later, when I want to access the window I can use a utility method:

 static func GetWindow(_ pWindowID: NSUserInterfaceItemIdentifier) -> NSWindow? {
        
        let windows = NSApp.windows
        for window in windows {
            if window.identifier == pWindowID {
                return window
            }
        }
        return nil
}

// Then I can call this function like so:

let windowidentifier = NSUserInterfaceItemIdentifier ("WinID1")
let window = GetWindow (windowidentifier)

This also works fine.

However, if I do window.setIsVisible(false) or window.orderOut (nil) to temporarily hide the window, then NSApp.windows returns an empty array and I'm not able to find the window object and my Utility method "GetWindow ()" doesn't work.

Any suggestions on how I can find hidden windows?

Post not yet marked as solved Up vote post of sidharth_m Down vote post of sidharth_m
193 views

Replies

Keep an array somewhere with all the windows you've created, and get them from this array.

  • Are you implying that there's no there way to do this than having my own data structure?

Add a Comment

When you hide a window using setIsVisible(false) or orderOut(nil), it indeed removes the window from the list of visible windows returned by NSApp.windows. However, you can still access hidden windows by maintaining your own reference to them. Here's how you can modify your utility method to include both visible and hidden windows:

    let windows = NSApp.windows
    for window in windows {
        if window.identifier == pWindowID {
            return window
        }
    }
    
    // If the window is not found among visible windows, try searching among hidden windows
    let hiddenWindows = NSApp.windows.filter { !$0.isVisible }
    for window in hiddenWindows {
        if window.identifier == pWindowID {
            return window
        }
    }
    
    return nil
}

With this modification, the GetWindow function first checks if the window with the given identifier is among the visible windows. If not, it then searches among the hidden windows. This should allow you to find and access both visible and hidden windows using the same utility method.

  • Thanks. But this way does not work. Since "NSApp.windows" itself yields an Empty array in case of Hidden Windows, "NSApp.windows.filter" will be trying to filter on an empty array, which again yields and empty array..

Add a Comment