onReceive(_:perform:) on Frontmost Window Only?

I have a simple document-based application for macOS.

struct ContentView: View {
    @Binding var document: TextDocument
    
    var body: some View {
		.onReceive(NotificationCenter.default.publisher(for: .notificationTextWillAppendSomeTextt), perform: { _ in
        
		})
		VStack {
			TextEditor(text: $document.text)
		}
	}
}

extension Notification.Name {
    static let notificationTextWillAppendSomeTextt = Notification.Name("TextWillAppendSomeText")
}

Suppose that my application currently has three tabs. If I call a menu command through

post(name:object:)

this menu command call will affect all three of them. This stackoverflow topic talks about it, too. So how could I tell which window should get a call and others don't? Thanks.

Accepted Answer

In reference to this article ( https://nilcoalescing.com/blog/ProvidingTheCurrentDocumentToMenuCommands/ ), you can do it with @FocusedBinding. I don't even know what this @FocusedBinding guy is. It's been around since macOS 11? Ugh...

import SwiftUI

@main
struct FocusedBindingCrazyMamaApp: App {
	var body: some Scene {
		DocumentGroup(newDocument: FocusedBindingCrazyMamaDocument()) { file in
			ContentView(document: file.$document)
				.focusedSceneValue(\.focusedDocument, file.$document)
		}
		.commands {
			CommandGroup(replacing: .saveItem) {
				UppercasedText()
				
				LowercasedText()
			}
		}
	}
}

extension FocusedValues {
	struct DocumentFocusedValues: FocusedValueKey {
		typealias Value = Binding<FocusedBindingCrazyMamaDocument>
	}

	var focusedDocument: Binding<FocusedBindingCrazyMamaDocument>? {
		get {
			self[DocumentFocusedValues.self]
		}
		set {
			self[DocumentFocusedValues.self] = newValue
		}
	}
}

struct UppercasedText: View {
	@FocusedBinding(\.focusedDocument) var focusedDocument
	
	var body: some View {
		Button {
			guard let text = focusedDocument?.text else {
				return
			}
			focusedDocument?.text = text.uppercased()
		} label: {
			Text("Uppercase Text")
		}
		.disabled(focusedDocument == nil)
		.keyboardShortcut("u", modifiers: [.command, .shift])
	}
}

struct LowercasedText: View {
	@FocusedBinding(\.focusedDocument) var focusedDocument
	
	var body: some View {
		Button {
			guard let text = focusedDocument?.text else {
				return
			}
			focusedDocument?.text = text.lowercased()
		} label: {
			Text("Lowercase Text")
		}
		.disabled(
			focusedDocument == nil
		)
		.keyboardShortcut("l", modifiers: [.command, .shift])
	}
}

// ContentView.swift //
import SwiftUI

struct ContentView: View {
	@Binding var document: FocusedBindingCrazyMamaDocument
	
	var body: some View {
		TextEditor(text: $document.text)
			.foregroundStyle(.white)
			.font(.system(size: 24))
			.scrollContentBackground(.hidden)
			.background(.black)
	}
}

#Preview {
	ContentView(document: .constant(FocusedBindingCrazyMamaDocument()))
}

don't even know what this @FocusedBinding guy is.

I find this is more and more a problem with SwiftUI.

At the beginning, it was made to be very simple (and it is for very simple apps).

But with the need to get more flexibility (closer to UIKit), it is now adding a lot of concepts such as @FocusedBinding, to "turn around" the limits of State based architecture.

Simplicity has gone.

In your case, can't you add a user info, with the ID of the window for instance ? And test in each window if the notification if for itself.

In your case, can't you add a user info, with the ID of the window for instance ? And test in each window if the notification if for itself.

Thanks for the tip. I don't know if that works. You wouldn't still be able to tell which tab is the one currently being selected, I suppose.

onReceive(_:perform:) on Frontmost Window Only?
 
 
Q