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

Mac: windows always display as key if a child is key

On other platforms, user expectation is that a parent window will display
as inactive when a modal is showing. This isn't the case on Mac.

Additionally, the code that passes key commands up to the parent window
uses this status to determine whether to pass keys from child windows up.

This change (hopefully) shows a window as active iff a child is active.
It plays well with the current code that handles this for bubbles because
PaintAsActive is now reference counted.

Still outstanding: making a non-key child window key *does* cause the
browser frame to be drawn as key and *does* handle hotkeys correctly,
but does *not* fix the traffic lights until the browser window has been
interacted with.

Bug: 1046540
Change-Id: I1629e66457c42b268c2283a8dbeb6823c66b1111
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2033432
Commit-Queue: Leonard Grey <lgrey@chromium.org>
Reviewed-by: default avatarccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#739444}
parent ca1327a4
......@@ -544,7 +544,13 @@ TEST_F(BubbleDialogDelegateViewTest, VisibleAnchorChanges) {
Widget* bubble_widget =
BubbleDialogDelegateView::CreateBubble(bubble_delegate);
bubble_widget->Show();
#if defined(OS_MACOSX)
// All child widgets make the parent paint as active on Mac.
// See https://crbug.com/1046540
EXPECT_TRUE(anchor_widget->ShouldPaintAsActive());
#else
EXPECT_FALSE(anchor_widget->ShouldPaintAsActive());
#endif // defined(OS_MACOSX)
bubble_delegate->SetAnchorView(anchor_widget->GetContentsView());
EXPECT_TRUE(anchor_widget->ShouldPaintAsActive());
......
......@@ -268,6 +268,8 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate,
FocusManager* focus_manager_ = nullptr;
std::unique_ptr<ui::InputMethod> input_method_;
std::unique_ptr<ZoomFocusMonitor> zoom_focus_monitor_;
// Held while this widget is active if it's a child.
std::unique_ptr<Widget::PaintAsActiveLock> parent_key_lock_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMac);
};
......
......@@ -157,9 +157,15 @@ void NativeWidgetMac::OnWindowKeyStatusChanged(
if (is_key) {
widget->OnNativeFocus();
widget->GetFocusManager()->RestoreFocusedView();
if (NativeWidgetMacNSWindowHost* parent_host = ns_window_host_->parent()) {
parent_key_lock_ = parent_host->native_widget_mac()
->GetTopLevelWidget()
->LockPaintAsActive();
}
} else {
widget->OnNativeBlur();
widget->GetFocusManager()->StoreFocusedView(true);
parent_key_lock_.reset();
}
}
......@@ -792,6 +798,7 @@ void NativeWidgetMac::OnNativeViewHierarchyWillChange() {
// listeners.
if (!GetWidget()->is_top_level())
SetFocusManager(nullptr);
parent_key_lock_.reset();
}
void NativeWidgetMac::OnNativeViewHierarchyChanged() {
......
......@@ -199,15 +199,21 @@ TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
EXPECT_TRUE(button);
NSData* active_button_image = ViewAsTIFF(button);
EXPECT_TRUE(active_button_image);
// Pop open a bubble on the parent Widget. When the visibility of Bubbles with
// an anchor View changes, BubbleDialogDelegateView::HandleVisibilityChanged()
// updates Widget::ShouldPaintAsActive() accordingly.
ShowKeyWindow(BubbleDialogDelegateView::CreateBubble(
new TestBubbleView(parent_widget)));
EXPECT_TRUE(parent_widget->ShouldPaintAsActive());
// If a child widget is key, the parent should paint as active.
Widget* child_widget = new Widget;
Widget::InitParams params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.parent = parent_widget->GetNativeView();
child_widget->Init(std::move(params));
child_widget->SetContentsView(new View);
child_widget->Show();
NSWindow* child = child_widget->GetNativeWindow().GetNativeNSWindow();
// Ensure the button instance is still valid.
EXPECT_EQ(button, [parent standardWindowButton:NSWindowCloseButton]);
EXPECT_TRUE(parent_widget->ShouldPaintAsActive());
// Parent window should still be main, and have its traffic lights active.
EXPECT_TRUE([parent isMainWindow]);
......@@ -226,10 +232,18 @@ TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
ShowKeyWindow(other_widget);
EXPECT_FALSE([parent isMainWindow]);
EXPECT_FALSE([parent isKeyWindow]);
EXPECT_FALSE(parent_widget->ShouldPaintAsActive());
EXPECT_TRUE([button isEnabled]);
NSData* inactive_button_image = ViewAsTIFF(button);
EXPECT_FALSE([active_button_image isEqualToData:inactive_button_image]);
// Focus the child again and assert the parent once again paints as active.
[child makeKeyWindow];
EXPECT_TRUE(parent_widget->ShouldPaintAsActive());
EXPECT_TRUE([child isKeyWindow]);
EXPECT_FALSE([parent isKeyWindow]);
child_widget->CloseNow();
other_widget->CloseNow();
parent_widget->CloseNow();
}
......
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