BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

Window position MacOS

Forums > SwiftUI

At App-startup I want the opening window to be in an exact position, but till now I failed to find relevant documentation. So, how to set the window position in code, probably somewhere in the Scene definition. The frame settings are derived from the content of the window, but that's all inside the window. There is no init on window with position settings and as far as my information goes there aren't any modifiers to window (windowGroup) to change the start position. All bits of info on the subject are about positioning views, not windows. Any help will be appreciated.

1      

I do not think you can position a window in a specific place on a user screen. The same as VisionOS!

You can make a minimum size of window and position views within that window, but it up to the user where they move/place the window.

1      

Thank you for the answer @NigelGee,

In that case I'l have to rethink how to configure my interface. It is quite complex with a main window, with general information and one or several editor windows that are not supposed to overlap, so it will be a nightmare to position them on screen without any tools to position them directly. This wil be quite a puzzle.........., or go back to cocoa (old school), because in the old way you could do exactly what I want. But I'd rather do it in SwiftUI. So a lot to figure out.

Thanx

1      

Have you taken a look at the .defaultPosition modifier? Does it do what you want?

https://developer.apple.com/documentation/swiftui/scene/defaultposition(_:)

1      

You could create a NSViewRepresentable with a custom NSView that overrides viewDidMoveToWindow(). Once you add this view to the scene, you'll then have access to the NSWindow and can specifiy window corordinates there. However I don't know at what time SwiftUI sets a Window's location, so you might find yourself fighting the framework.

Oh and one other thing. Mac Coordinates start from the bottom, whereas I believe SwiftUI starts from the top, so you may need to flip your dimensions by the screen height.

I'll see if I can find some time to whip up an example if you need one.

Edit: Added some sample code, which I forgot I was using in a project already.

public class NSWindowBridge: NSView {
    let executeBlock: (_ window: NSWindow? ) -> ()

    init(_ inConfigFunction: @escaping (_ window: NSWindow? ) -> () ) {
        executeBlock = inConfigFunction
        super.init( frame: NSRect() )
    }

    required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }

    public override func viewDidMoveToWindow() {
        super.viewDidMoveToWindow()
        executeBlock( self.window ) // We pass it through even if it is nil.
    }
}

public struct WindowConfigurator: NSViewRepresentable {
    var configCode: (_ window: NSWindow? ) -> ()

    public init(_ configCode: @escaping (_: NSWindow?) -> Void) { self.configCode = configCode }
    public func makeNSView(context: Context) -> NSView   { return NSWindowBridge( configCode ) }
    public func updateNSView(_ nsView: NSView, context: Context) {}
}

I'm using it like below to capture the window

            ContentViewPR2( controller )
                .background( WindowConfigurator( { inWindow in
                    guard let window = inWindow else { return }
                    controller.parentWindow = window
                }) )

p.s. You'll have to excuse my code, I've only been writing Swift/SwiftUI for a few months.

1      

It sounds like you're trying to set the initial position of the window in your SwiftUI app. While SwiftUI doesn't provide direct APIs to set the window position, you can achieve this by using the AppKit framework from macOS.

Here's a basic outline of how you can accomplish this:

  1. Import AppKit at the top of your SwiftUI file:

    import AppKit
  2. Use the NSApp object to access the main application window and set its position. You can do this in the onAppear modifier of your main view:

    .onAppear {
       if let window = NSApp.mainWindow {
           // Set the desired position of the window
           window.setFrameOrigin(NSPoint(x: desiredX, y: desiredY))
       }
    }

Replace desiredX and desiredY with the coordinates where you want the window to appear.

Remember that this approach might require additional handling, especially if you want to ensure that the window position works correctly across different screen resolutions and configurations.

Let me know if you need further assistance or clarification!

2      

Use the NSApp object to access the main application window and set its position. You can do this in the onAppear modifier of your main view:

Thanks for sharing a far less complicated way of accessing the window. My only concern is that it relies on the event order to remain the same for mainWindow to be the actual window you expect when .onAppear() fires. Do you know of a more concrete way to ensure you get the window you expect?

Apple do like to tinker with things like this, we had to do workarounds for 10.10 and 10.11 to prevent the window shadow or a solid black window showing before the window had finished opening.

1      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.