Deliver hover events to non-key windows on macOS

Flutter's macOS engine only sends mouse-moved events to the key window
by default. The borderless audience (beamer) window deliberately never
becomes key, so chart tooltips never appeared on the second screen, and
hover styling stuck around whenever a window lost key status before the
exit event arrived. Track the mouse whenever the app is active instead,
for both the main window and every secondary window.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Brenno de Winter 2026-06-10 11:29:42 +02:00
parent 382945e99b
commit 280934d331
2 changed files with 11 additions and 0 deletions

View file

@ -5,6 +5,11 @@ import desktop_multi_window
class MainFlutterWindow: NSWindow { class MainFlutterWindow: NSWindow {
override func awakeFromNib() { override func awakeFromNib() {
let flutterViewController = FlutterViewController() let flutterViewController = FlutterViewController()
// Keep hover events flowing while this window is not key (e.g. when a
// dialog or the beamer window is in front): otherwise an element that was
// hovered when the window lost key status keeps its hover styling because
// the matching exit event is never delivered.
flutterViewController.mouseTrackingMode = .inActiveApp
let windowFrame = self.frame let windowFrame = self.frame
self.contentViewController = flutterViewController self.contentViewController = flutterViewController
self.setFrame(windowFrame, display: true) self.setFrame(windowFrame, display: true)

View file

@ -107,6 +107,12 @@ class MultiWindowManager: NSObject {
let project = FlutterDartProject() let project = FlutterDartProject()
project.dartEntrypointArguments = ["multi_window", windowId, config.arguments] project.dartEntrypointArguments = ["multi_window", windowId, config.arguments]
let flutterViewController = FlutterViewController(project: project) let flutterViewController = FlutterViewController(project: project)
// By default Flutter only delivers hover (mouse-moved) events to the
// key window. The audience/beamer window is borderless and never
// becomes key (the keyboard must stay with the presenter), so without
// this it would never see hover at all and state set by a click
// (e.g. a chart highlight) would never be cleared again.
flutterViewController.mouseTrackingMode = .inActiveApp
window.contentViewController = flutterViewController window.contentViewController = flutterViewController
window.setFrame(NSRect(x: 0, y: 0, width: 800, height: 600), display: true) window.setFrame(NSRect(x: 0, y: 0, width: 800, height: 600), display: true)