From 280934d331950e32504757ab59623e541d2520f9 Mon Sep 17 00:00:00 2001 From: Brenno de Winter Date: Wed, 10 Jun 2026 11:29:42 +0200 Subject: [PATCH] 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 --- macos/Runner/MainFlutterWindow.swift | 5 +++++ .../macos/Classes/FlutterMultiWindowPlugin.swift | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift index abe25af..086406b 100644 --- a/macos/Runner/MainFlutterWindow.swift +++ b/macos/Runner/MainFlutterWindow.swift @@ -5,6 +5,11 @@ import desktop_multi_window class MainFlutterWindow: NSWindow { override func awakeFromNib() { 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 self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) diff --git a/third_party/desktop_multi_window/macos/Classes/FlutterMultiWindowPlugin.swift b/third_party/desktop_multi_window/macos/Classes/FlutterMultiWindowPlugin.swift index 6236314..e22707c 100644 --- a/third_party/desktop_multi_window/macos/Classes/FlutterMultiWindowPlugin.swift +++ b/third_party/desktop_multi_window/macos/Classes/FlutterMultiWindowPlugin.swift @@ -107,6 +107,12 @@ class MultiWindowManager: NSObject { let project = FlutterDartProject() project.dartEntrypointArguments = ["multi_window", windowId, config.arguments] 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.setFrame(NSRect(x: 0, y: 0, width: 800, height: 600), display: true)