switftUI's focusedValue is not being set on return of focus to an app's Windows

Originator:jonathan.hume
Number:rdar://FB9703748 Date Originated:14/11/2021
Status:Open Resolved:
Product:SwiftUI Framework Product Version:
Classification:Incorrect/Unexpected Behavior Reproducible:
 
On a  
1. MacBook Pro (15-inch, 2018) i7 room heater :-)
2. macOS Monterey 12.0 Beta 12 (21A5552a)
3. Xcode 3.0 beta 5 (13A5212g)


I’m finding that any previously set focusValues are not being restored when focus is moved away from, and then back to the original window (and focused field)

1. Compile and run attached example app and OtherView starts off correctly showing “No focusedScientist”
2. Highlight the contents of the  ContentView TextField and OtherView correctly shows the name of the scientist as focused, e.g. “Charpentier”
3. Click onto any other app, e.g. Finder, Xcode and OtherView correctly shows “No focusedScientist”
4. Finally click back onto example app and observe that the ContentView TextField showing the scientist’s name remains highlighted, but the OtherView TextField is now incorrectly showing “No focusedScientist” despite this.

Code 

import SwiftUI

@main
struct macosFocusedValueFun: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .commands {
            ScientistsCommands()
        }
    }
}

struct ScientistsCommands: Commands {
    @FocusedValue(\.scientist) var focusedScientist: String?

    var body: some Commands {
        print("\t Building the CommandMenu, focusedText = \(String(describing: focusedScientist))\n")

        return CommandMenu("Scientists") {
            if let fs = focusedScientist {
                Button("Action using selection = \"\(fs)\"") { /* Do something with the selection */ }
            } else {
                Button("Action with no selection") { /* Do something different if no selection */ }
            }
        }
    }
}

struct ContentView: View {
    @State var scientist: String = ""
    var body: some View {
        Form {
            OtherView()

            TextField("ContentView", text: $scientist, prompt: Text("Enter text here"))
                .focusedValue(\.scientist, scientist)

                .onAppear {
                    /// Add some data so that when there are multiple windows it's a bit easier to distiguish between them
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                        scientist = [
                            "Curie", "Bell Burnell", "Meitner", "Hodgkin", "Franklin", "Herschel",
                            "Charpentier", "Doudna",
                        ]
                        .randomElement() ?? ""
                    }
                }
        }
        .frame(width: 300, height: 200)
    }
}

struct OtherView: View {
    @FocusedValue(\.scientist) var focusedScientist: String?
    var body: some View {
        TextField("OtherView", text: .constant(focusedScientist ?? "No focusedScientist"), prompt: Text("Enter text in ContentView"))
    }
}

struct MyKey: FocusedValueKey {
    typealias Value = String
}

extension FocusedValues {
    var scientist: String? {
        get { self[MyKey.self] }
        set {
            guard self[MyKey.self] != newValue else {
                /// Never gets fired ...
                print("guard: not setting newValue = \(String(describing: newValue)) == existing")
                return
            }
            /// Even with only a single window this gets called at least twice each time a new focuseText value is set. Which, together with the guard never firing,
            /// implies that focusedText is being kept on a per Window instance basis, i.e. with just one window mainWindow and keyWindow
            print("=============================================================") /// Delimit blocks of action triggered by updates
            print("Setting newValue = \(String(describing: newValue))")
            self[MyKey.self] = newValue
        }
    }
}

Comments

May also be related ... https://openradar.appspot.com/FB9163579#ag9zfm9wZW5yYWRhci1ocmRyFAsSB0NvbW1lbnQYgICAqtOU9AgM

By jonathan.hume at Nov. 15, 2021, 4:27 p.m. (reply...)

Still present in macOS 12.01 and Xcode 13.1.

By jonathan.hume at Nov. 13, 2021, 12:52 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!