summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_browsertest.mm23
-rw-r--r--chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm5
-rw-r--r--chrome/browser/ui/test/scoped_fake_nswindow_main_status.h32
-rw-r--r--chrome/browser/ui/test/scoped_fake_nswindow_main_status.mm47
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--ui/base/BUILD.gn2
-rw-r--r--ui/base/test/scoped_fake_nswindow_focus.h39
-rw-r--r--ui/base/test/scoped_fake_nswindow_focus.mm100
-rw-r--r--ui/base/ui_base.gyp2
-rw-r--r--ui/views/accessible_pane_view_unittest.cc23
10 files changed, 176 insertions, 99 deletions
diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_browsertest.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_browsertest.mm
index 5959808..fb3302e 100644
--- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_browsertest.mm
+++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac_browsertest.mm
@@ -19,13 +19,13 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/browser_window.h"
-#import "chrome/browser/ui/test/scoped_fake_nswindow_main_status.h"
#include "chrome/common/chrome_switches.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/browser/app_window/native_app_window.h"
#include "extensions/browser/uninstall_reason.h"
#include "extensions/common/extension.h"
#include "extensions/test/extension_test_message_listener.h"
+#import "ui/base/test/scoped_fake_nswindow_focus.h"
namespace {
@@ -77,7 +77,7 @@ class AppShimMenuControllerBrowserTest
void CheckHasAppMenus(const extensions::Extension* app) const {
const int kExtraTopLevelItems = 4;
NSArray* item_array = [[NSApp mainMenu] itemArray];
- EXPECT_EQ(initial_menu_item_count_ + kExtraTopLevelItems,
+ ASSERT_EQ(initial_menu_item_count_ + kExtraTopLevelItems,
[item_array count]);
for (NSUInteger i = 0; i < initial_menu_item_count_; ++i)
EXPECT_TRUE([[item_array objectAtIndex:i] isHidden]);
@@ -186,11 +186,8 @@ IN_PROC_BROWSER_TEST_F(AppShimMenuControllerBrowserTest,
extensions::AppWindow* app_1_app_window = FirstWindowForApp(app_1_);
{
- ScopedFakeNSWindowMainStatus app_1_is_main(
- app_1_app_window->GetNativeWindow());
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSWindowDidBecomeMainNotification
- object:app_1_app_window->GetNativeWindow()];
+ ui::test::ScopedFakeNSWindowFocus fake_focus;
+ [app_1_app_window->GetNativeWindow() makeMainWindow];
CheckHasAppMenus(app_1_);
// Closing a background window without focusing it should not change menus.
@@ -200,10 +197,9 @@ IN_PROC_BROWSER_TEST_F(AppShimMenuControllerBrowserTest,
postNotificationName:NSWindowWillCloseNotification
object:chrome_window->GetNativeWindow()];
CheckHasAppMenus(app_1_);
+
+ // |fake_focus| going out of scope sends NSWindowWillResignMainNotification.
}
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSWindowDidResignMainNotification
- object:app_1_app_window->GetNativeWindow()];
app_1_app_window->GetBaseWindow()->Close();
CheckNoAppMenus();
}
@@ -250,10 +246,9 @@ IN_PROC_BROWSER_TEST_F(AppShimMenuControllerBrowserTest,
FirstWindowForApp(app_2_)->GetBaseWindow()->Close();
chrome::BrowserIterator()->window()->Close();
NSWindow* app_1_window = FirstWindowForApp(app_1_)->GetNativeWindow();
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSWindowDidBecomeMainNotification
- object:app_1_window];
- ScopedFakeNSWindowMainStatus app_1_is_main(app_1_window);
+
+ ui::test::ScopedFakeNSWindowFocus fake_focus;
+ [app_1_window makeMainWindow];
CheckHasAppMenus(app_1_);
ExtensionService::UninstallExtensionHelper(
diff --git a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm
index ce248ad..22f98a3 100644
--- a/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/apps/native_app_window_cocoa_browsertest.mm
@@ -18,7 +18,6 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/extensions/app_launch_params.h"
#include "chrome/browser/ui/extensions/application_launch.h"
-#import "chrome/browser/ui/test/scoped_fake_nswindow_main_status.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/test_utils.h"
@@ -28,6 +27,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#import "testing/gtest_mac.h"
#import "ui/base/test/nswindow_fullscreen_notification_waiter.h"
+#import "ui/base/test/scoped_fake_nswindow_focus.h"
#import "ui/base/test/scoped_fake_nswindow_fullscreen.h"
#import "ui/base/test/windowed_nsnotification_observer.h"
#import "ui/gfx/mac/nswindow_frame_controls.h"
@@ -699,7 +699,8 @@ IN_PROC_BROWSER_TEST_P(NativeAppWindowCocoaBrowserTest, FrameColor) {
EXPECT_NEAR(expected_components[1], color_components[1], 0.01);
EXPECT_NEAR(expected_components[2], color_components[2], 0.01);
- ScopedFakeNSWindowMainStatus fake_main(ns_window);
+ ui::test::ScopedFakeNSWindowFocus fake_focus;
+ [ns_window makeMainWindow];
bitmap = ScreenshotNSWindow(ns_window);
// The window is now active so it should be red (#FF0000).
diff --git a/chrome/browser/ui/test/scoped_fake_nswindow_main_status.h b/chrome/browser/ui/test/scoped_fake_nswindow_main_status.h
deleted file mode 100644
index 0d4df98..0000000
--- a/chrome/browser/ui/test/scoped_fake_nswindow_main_status.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_TEST_SCOPED_FAKE_NSWINDOW_MAIN_STATUS_H_
-#define CHROME_BROWSER_UI_TEST_SCOPED_FAKE_NSWINDOW_MAIN_STATUS_H_
-
-#include "base/memory/scoped_ptr.h"
-
-namespace base {
-namespace mac {
-class ScopedObjCClassSwizzler;
-}
-}
-
-@class NSWindow;
-
-// Simulates a particular NSWindow to report YES for [NSWindow isMainWindow].
-// This allows test coverage of code relying on window focus changes without
-// resorting to an interactive_ui_test.
-class ScopedFakeNSWindowMainStatus {
- public:
- explicit ScopedFakeNSWindowMainStatus(NSWindow* window);
- ~ScopedFakeNSWindowMainStatus();
-
- private:
- scoped_ptr<base::mac::ScopedObjCClassSwizzler> swizzler_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedFakeNSWindowMainStatus);
-};
-
-#endif // CHROME_BROWSER_UI_TEST_SCOPED_FAKE_NSWINDOW_MAIN_STATUS_H_
diff --git a/chrome/browser/ui/test/scoped_fake_nswindow_main_status.mm b/chrome/browser/ui/test/scoped_fake_nswindow_main_status.mm
deleted file mode 100644
index 0f2c27d..0000000
--- a/chrome/browser/ui/test/scoped_fake_nswindow_main_status.mm
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "chrome/browser/ui/test/scoped_fake_nswindow_main_status.h"
-
-#import <Cocoa/Cocoa.h>
-
-#import "base/mac/foundation_util.h"
-#import "base/mac/scoped_objc_class_swizzler.h"
-
-namespace {
-
-NSWindow* g_fake_main_window = nil;
-
-}
-
-// Donates a testing implementation of [NSWindow isMainWindow].
-@interface IsMainWindowDonorForWindow : NSObject
-@end
-
-@implementation IsMainWindowDonorForWindow
-- (BOOL)isMainWindow {
- NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
- return selfAsWindow == g_fake_main_window;
-}
-@end
-
-ScopedFakeNSWindowMainStatus::ScopedFakeNSWindowMainStatus(NSWindow* window)
- : swizzler_(new base::mac::ScopedObjCClassSwizzler(
- [NSWindow class],
- [IsMainWindowDonorForWindow class],
- @selector(isMainWindow))) {
- DCHECK(!g_fake_main_window);
- g_fake_main_window = window;
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSWindowDidBecomeMainNotification
- object:g_fake_main_window];
-}
-
-ScopedFakeNSWindowMainStatus::~ScopedFakeNSWindowMainStatus() {
- NSWindow* window = g_fake_main_window;
- g_fake_main_window = nil;
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSWindowDidResignMainNotification
- object:window];
-}
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 9262d92..041ef6c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -515,8 +515,6 @@
'browser/ui/sync/profile_signin_confirmation_helper_browsertest.cc',
'browser/ui/tab_modal_confirm_dialog_browsertest.cc',
'browser/ui/tab_modal_confirm_dialog_browsertest.h',
- 'browser/ui/test/scoped_fake_nswindow_main_status.h',
- 'browser/ui/test/scoped_fake_nswindow_main_status.mm',
'browser/ui/toolbar/browser_actions_bar_browsertest.cc',
'browser/ui/toolbar/browser_actions_bar_browsertest.h',
'browser/ui/toolbar/component_toolbar_actions_browsertest.cc',
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 573d72b..cc416e3 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -571,6 +571,8 @@ source_set("test_support") {
"test/material_design_controller_test_api.h",
"test/nswindow_fullscreen_notification_waiter.h",
"test/nswindow_fullscreen_notification_waiter.mm",
+ "test/scoped_fake_nswindow_focus.h",
+ "test/scoped_fake_nswindow_focus.mm",
"test/scoped_fake_nswindow_fullscreen.h",
"test/scoped_fake_nswindow_fullscreen.mm",
"test/test_clipboard.cc",
diff --git a/ui/base/test/scoped_fake_nswindow_focus.h b/ui/base/test/scoped_fake_nswindow_focus.h
new file mode 100644
index 0000000..aafd715
--- /dev/null
+++ b/ui/base/test/scoped_fake_nswindow_focus.h
@@ -0,0 +1,39 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_BASE_TEST_SCOPED_FAKE_NSWINDOW_FOCUS_H_
+#define UI_BASE_TEST_SCOPED_FAKE_NSWINDOW_FOCUS_H_
+
+#include "base/memory/scoped_ptr.h"
+
+namespace base {
+namespace mac {
+class ScopedObjCClassSwizzler;
+}
+}
+
+namespace ui {
+namespace test {
+
+// Simulates key and main status by listening for -makeKeyWindow and
+// -makeMainWindow. This allows test coverage of code relying on window focus
+// changes without resorting to an interactive_ui_test.
+class ScopedFakeNSWindowFocus {
+ public:
+ ScopedFakeNSWindowFocus();
+ ~ScopedFakeNSWindowFocus();
+
+ private:
+ scoped_ptr<base::mac::ScopedObjCClassSwizzler> is_main_swizzler_;
+ scoped_ptr<base::mac::ScopedObjCClassSwizzler> make_main_swizzler_;
+ scoped_ptr<base::mac::ScopedObjCClassSwizzler> is_key_swizzler_;
+ scoped_ptr<base::mac::ScopedObjCClassSwizzler> make_key_swizzler_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedFakeNSWindowFocus);
+};
+
+} // namespace test
+} // namespace ui
+
+#endif // UI_BASE_TEST_SCOPED_FAKE_NSWINDOW_FOCUS_H_
diff --git a/ui/base/test/scoped_fake_nswindow_focus.mm b/ui/base/test/scoped_fake_nswindow_focus.mm
new file mode 100644
index 0000000..b78680d
--- /dev/null
+++ b/ui/base/test/scoped_fake_nswindow_focus.mm
@@ -0,0 +1,100 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ui/base/test/scoped_fake_nswindow_focus.h"
+
+#import <Cocoa/Cocoa.h>
+
+#import "base/mac/foundation_util.h"
+#import "base/mac/scoped_objc_class_swizzler.h"
+
+using base::mac::ScopedObjCClassSwizzler;
+
+namespace {
+
+NSWindow* g_fake_focused_window = nil;
+
+void SetFocus(NSWindow* window) {
+ g_fake_focused_window = window;
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidBecomeMainNotification
+ object:g_fake_focused_window];
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidBecomeKeyNotification
+ object:g_fake_focused_window];
+}
+
+void ClearFocus() {
+ NSWindow* window = g_fake_focused_window;
+ g_fake_focused_window = nil;
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidResignKeyNotification
+ object:window];
+
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:NSWindowDidResignMainNotification
+ object:window];
+}
+
+} // namespace
+
+// Donates testing implementations of NSWindow methods.
+@interface FakeNSWindowFocusDonor : NSObject
+@end
+
+@implementation FakeNSWindowFocusDonor
+
+- (BOOL)isKeyWindow {
+ NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
+ return selfAsWindow == g_fake_focused_window;
+}
+
+- (BOOL)isMainWindow {
+ NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
+ return selfAsWindow == g_fake_focused_window;
+}
+
+- (void)makeKeyWindow {
+ NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
+ if (selfAsWindow == g_fake_focused_window ||
+ ![selfAsWindow canBecomeKeyWindow])
+ return;
+
+ ClearFocus();
+ SetFocus(selfAsWindow);
+}
+
+- (void)makeMainWindow {
+ [self makeKeyWindow];
+}
+
+@end
+
+namespace ui {
+namespace test {
+
+ScopedFakeNSWindowFocus::ScopedFakeNSWindowFocus()
+ : is_main_swizzler_(
+ new ScopedObjCClassSwizzler([NSWindow class],
+ [FakeNSWindowFocusDonor class],
+ @selector(isMainWindow))),
+ make_main_swizzler_(
+ new ScopedObjCClassSwizzler([NSWindow class],
+ [FakeNSWindowFocusDonor class],
+ @selector(makeMainWindow))),
+ is_key_swizzler_(
+ new ScopedObjCClassSwizzler([NSWindow class],
+ [FakeNSWindowFocusDonor class],
+ @selector(isKeyWindow))),
+ make_key_swizzler_(
+ new ScopedObjCClassSwizzler([NSWindow class],
+ [FakeNSWindowFocusDonor class],
+ @selector(makeKeyWindow))) {}
+
+ScopedFakeNSWindowFocus::~ScopedFakeNSWindowFocus() {
+ ClearFocus();
+}
+
+} // namespace test
+} // namespace ui
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp
index ed99bf0..3e8375c 100644
--- a/ui/base/ui_base.gyp
+++ b/ui/base/ui_base.gyp
@@ -684,6 +684,8 @@
'ime/dummy_text_input_client.h',
'test/nswindow_fullscreen_notification_waiter.h',
'test/nswindow_fullscreen_notification_waiter.mm',
+ 'test/scoped_fake_nswindow_focus.h',
+ 'test/scoped_fake_nswindow_focus.mm',
'test/scoped_fake_nswindow_fullscreen.h',
'test/scoped_fake_nswindow_fullscreen.mm',
'test/windowed_nsnotification_observer.h',
diff --git a/ui/views/accessible_pane_view_unittest.cc b/ui/views/accessible_pane_view_unittest.cc
index d53fb72..16c2a32 100644
--- a/ui/views/accessible_pane_view_unittest.cc
+++ b/ui/views/accessible_pane_view_unittest.cc
@@ -10,6 +10,10 @@
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
+#if defined(OS_MACOSX)
+#include "ui/base/test/scoped_fake_nswindow_focus.h"
+#endif
+
namespace views {
// TODO(alicet): bring pane rotation into views and add tests.
@@ -98,13 +102,20 @@ TEST_F(AccessiblePaneViewTest, SimpleSetPaneFocus) {
widget.reset();
}
-// This test will not work properly in Windows because it uses ::GetNextWindow
-// on deactivate which is rather unpredictable where the focus will land.
TEST_F(AccessiblePaneViewTest, SetPaneFocusAndRestore) {
+#if defined(OS_MACOSX)
+ // On Aura platforms, this test creates Ash windows and only interacts with
+ // the Ash window manager. On Mac, it creates native windows, but since unit
+ // tests cannot gain key status, fake it out here.
+ ui::test::ScopedFakeNSWindowFocus fake_focus;
+#endif
+
View* test_view_main = new View();
scoped_ptr<Widget> widget_main(new Widget());
Widget::InitParams params_main = CreateParams(Widget::InitParams::TYPE_POPUP);
params_main.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ // By default, TYPE_POPUP is not activatable.
+ params_main.activatable = Widget::InitParams::ACTIVATABLE_YES;
params_main.bounds = gfx::Rect(0, 0, 20, 20);
widget_main->Init(params_main);
View* root_main = widget_main->GetRootView();
@@ -118,6 +129,7 @@ TEST_F(AccessiblePaneViewTest, SetPaneFocusAndRestore) {
scoped_ptr<Widget> widget_bar(new Widget());
Widget::InitParams params_bar = CreateParams(Widget::InitParams::TYPE_POPUP);
params_bar.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params_bar.activatable = Widget::InitParams::ACTIVATABLE_YES;
params_bar.bounds = gfx::Rect(50, 50, 650, 650);
widget_bar->Init(params_bar);
View* root_bar = widget_bar->GetRootView();
@@ -133,9 +145,16 @@ TEST_F(AccessiblePaneViewTest, SetPaneFocusAndRestore) {
EXPECT_EQ(test_view_bar->child_button(),
test_view_bar->GetWidget()->GetFocusManager()->GetFocusedView());
+ // Deactivate() is only reliable on Ash. On Windows it uses ::GetNextWindow()
+ // to simply activate another window, and which one is not predictable. On
+ // Mac, Deactivate() is not implemented. Note that TestBarView calls
+ // set_allow_deactivate_on_esc(true), which is only otherwise used in Ash.
+#if !defined(OS_MACOSX) || defined(USE_ASH)
+ // Esc should deactivate the widget.
test_view_bar->AcceleratorPressed(test_view_bar->escape_key());
EXPECT_TRUE(widget_main->IsActive());
EXPECT_FALSE(widget_bar->IsActive());
+#endif
widget_bar->CloseNow();
widget_bar.reset();