Commit b4c5880d authored by Leonard Grey's avatar Leonard Grey Committed by Commit Bot

Mac: Implement accessibility zoom focus following for topchrome

For very mysterious reasons, this only kind of works; peeking at the
systemwide notification which is sent (UAZoomFocusDidChangeNotification),
something often tells the system to go focus a seemingly random part of the
screen instead.

I've been unable to make headway on this, so sending CL on the principle
that "something is better than nothing." We can revisit later if we can
figure out why this is happening.

Comfortingly (?) the same thing happens to Safari web content so I'm going
to assume something is wonky with this system on the OS side.

Bug: 957395
Change-Id: I8356cff86795f19648ab6746d1f23fd5ea1a7025
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1713390Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Commit-Queue: Leonard Grey <lgrey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682303}
parent 843f015a
......@@ -225,6 +225,9 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
friend class test::HitTestNativeWidgetMac;
friend class views::test::WidgetTest;
class ZoomFocusMonitor;
std::unique_ptr<ZoomFocusMonitor> zoom_focus_monitor_;
internal::NativeWidgetDelegate* delegate_;
std::unique_ptr<NativeWidgetMacNSWindowHost> ns_window_host_;
......
......@@ -4,7 +4,9 @@
#include "ui/views/widget/native_widget_mac.h"
#include <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
#include <utility>
......@@ -106,11 +108,29 @@ ui::ZOrderLevel ZOrderLevelForCGWindowLevel(CGWindowLevel level) {
} // namespace
// Implements zoom following focus for macOS accessibility zoom.
class NativeWidgetMac::ZoomFocusMonitor : public FocusChangeListener {
public:
ZoomFocusMonitor() = default;
~ZoomFocusMonitor() override {}
void OnWillChangeFocus(View* focused_before, View* focused_now) override {}
void OnDidChangeFocus(View* focused_before, View* focused_now) override {
if (!focused_now || !UAZoomEnabled())
return;
// Web content handles its own zooming.
if (strcmp("WebView", focused_now->GetClassName()) == 0)
return;
NSRect rect = NSRectFromCGRect(focused_now->GetBoundsInScreen().ToCGRect());
UAZoomChangeFocus(&rect, nullptr, kUAZoomFocusTypeOther);
}
};
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetMac, public:
NativeWidgetMac::NativeWidgetMac(internal::NativeWidgetDelegate* delegate)
: delegate_(delegate),
: zoom_focus_monitor_(std::make_unique<ZoomFocusMonitor>()),
delegate_(delegate),
ns_window_host_(new NativeWidgetMacNSWindowHost(this)),
ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {}
......@@ -122,6 +142,8 @@ NativeWidgetMac::~NativeWidgetMac() {
}
void NativeWidgetMac::WindowDestroying() {
if (auto* focus_manager = GetWidget()->GetFocusManager())
focus_manager->RemoveFocusChangeListener(zoom_focus_monitor_.get());
OnWindowDestroying(GetNativeWindow());
delegate_->OnNativeWidgetDestroying();
}
......@@ -208,6 +230,9 @@ void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) {
if (auto* focus_manager = GetWidget()->GetFocusManager()) {
GetNSWindowMojo()->MakeFirstResponder();
ns_window_host_->SetFocusManager(focus_manager);
// Non-top-level widgets use the the top level widget's focus manager.
if (GetWidget() == GetTopLevelWidget())
focus_manager->AddFocusChangeListener(zoom_focus_monitor_.get());
}
ns_window_host_->CreateCompositor(params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment