OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
6 | 6 |
7 #include <Cocoa/Cocoa.h> | 7 #include <Cocoa/Cocoa.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <tuple> | 10 #include <tuple> |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "content/public/test/test_browser_context.h" | 33 #include "content/public/test/test_browser_context.h" |
34 #include "content/public/test/test_utils.h" | 34 #include "content/public/test/test_utils.h" |
35 #include "content/test/test_render_view_host.h" | 35 #include "content/test/test_render_view_host.h" |
36 #include "gpu/ipc/common/gpu_messages.h" | 36 #include "gpu/ipc/common/gpu_messages.h" |
37 #include "gpu/ipc/service/image_transport_surface.h" | 37 #include "gpu/ipc/service/image_transport_surface.h" |
38 #include "testing/gmock/include/gmock/gmock.h" | 38 #include "testing/gmock/include/gmock/gmock.h" |
39 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
40 #include "testing/gtest_mac.h" | 40 #include "testing/gtest_mac.h" |
41 #import "third_party/ocmock/OCMock/OCMock.h" | 41 #import "third_party/ocmock/OCMock/OCMock.h" |
42 #import "third_party/ocmock/ocmock_extensions.h" | 42 #import "third_party/ocmock/ocmock_extensions.h" |
| 43 #import "ui/base/test/scoped_fake_nswindow_focus.h" |
43 #include "ui/events/base_event_utils.h" | 44 #include "ui/events/base_event_utils.h" |
44 #include "ui/events/blink/web_input_event_traits.h" | 45 #include "ui/events/blink/web_input_event_traits.h" |
45 #include "ui/events/test/cocoa_test_event_utils.h" | 46 #include "ui/events/test/cocoa_test_event_utils.h" |
46 #import "ui/gfx/test/ui_cocoa_test_helper.h" | 47 #import "ui/gfx/test/ui_cocoa_test_helper.h" |
47 #include "ui/latency/latency_info.h" | 48 #include "ui/latency/latency_info.h" |
48 | 49 |
49 // Helper class with methods used to mock -[NSEvent phase], used by | 50 // Helper class with methods used to mock -[NSEvent phase], used by |
50 // |MockScrollWheelEventWithPhase()|. | 51 // |MockScrollWheelEventWithPhase()|. |
51 @interface MockPhaseMethods : NSObject { | 52 @interface MockPhaseMethods : NSObject { |
52 } | 53 } |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 RenderWidgetHostImpl* rwh = | 459 RenderWidgetHostImpl* rwh = |
459 new RenderWidgetHostImpl(&delegate, process_host, routing_id, false); | 460 new RenderWidgetHostImpl(&delegate, process_host, routing_id, false); |
460 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false); | 461 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false); |
461 | 462 |
462 view->InitAsFullscreen(rwhv_mac_); | 463 view->InitAsFullscreen(rwhv_mac_); |
463 | 464 |
464 WindowedNotificationObserver observer( | 465 WindowedNotificationObserver observer( |
465 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, | 466 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, |
466 Source<RenderWidgetHost>(rwh)); | 467 Source<RenderWidgetHost>(rwh)); |
467 | 468 |
| 469 // Key equivalents are only sent to the renderer if the window is key. |
| 470 ui::test::ScopedFakeNSWindowFocus key_window_faker; |
| 471 [[view->cocoa_view() window] makeKeyWindow]; |
| 472 |
468 // Command-ESC will destroy the view, while the window is still in | 473 // Command-ESC will destroy the view, while the window is still in |
469 // |-performKeyEquivalent:|. There are other cases where this can | 474 // |-performKeyEquivalent:|. There are other cases where this can |
470 // happen, Command-ESC is the easiest to trigger. | 475 // happen, Command-ESC is the easiest to trigger. |
471 [[view->cocoa_view() window] performKeyEquivalent: | 476 [[view->cocoa_view() window] performKeyEquivalent: |
472 cocoa_test_event_utils::KeyEventWithKeyCode( | 477 cocoa_test_event_utils::KeyEventWithKeyCode( |
473 53, 27, NSKeyDown, NSCommandKeyMask)]; | 478 53, 27, NSKeyDown, NSCommandKeyMask)]; |
474 observer.Wait(); | 479 observer.Wait(); |
475 } | 480 } |
476 | 481 |
477 // Test that NSEvent of private use character won't generate keypress event | 482 // Test that NSEvent of private use character won't generate keypress event |
(...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 | 1793 |
1789 // Verify that this IPC is asking for no monitoring or immediate updates. | 1794 // Verify that this IPC is asking for no monitoring or immediate updates. |
1790 InputMsg_RequestCompositionUpdates::Read(composition_request_msg_for_child, | 1795 InputMsg_RequestCompositionUpdates::Read(composition_request_msg_for_child, |
1791 &child_msg_params); | 1796 &child_msg_params); |
1792 is_child_msg_for_immediate_request = std::get<0>(child_msg_params); | 1797 is_child_msg_for_immediate_request = std::get<0>(child_msg_params); |
1793 is_child_msg_for_monitor_request = std::get<1>(child_msg_params); | 1798 is_child_msg_for_monitor_request = std::get<1>(child_msg_params); |
1794 EXPECT_FALSE(is_child_msg_for_immediate_request); | 1799 EXPECT_FALSE(is_child_msg_for_immediate_request); |
1795 EXPECT_FALSE(is_child_msg_for_monitor_request); | 1800 EXPECT_FALSE(is_child_msg_for_monitor_request); |
1796 } | 1801 } |
1797 | 1802 |
| 1803 // Ensure RenderWidgetHostViewMac claims hotkeys when AppKit spams the UI with |
| 1804 // -performKeyEquivalent:, but only when the window is key. |
| 1805 TEST_F(RenderWidgetHostViewMacTest, ForwardKeyEquivalentsOnlyIfKey) { |
| 1806 // This test needs an NSWindow. |rwhv_cocoa_| isn't in one, but going |
| 1807 // fullscreen conveniently puts it in one. |
| 1808 EXPECT_FALSE([rwhv_cocoa_ window]); |
| 1809 rwhv_mac_->InitAsFullscreen(nullptr); |
| 1810 NSWindow* window = [rwhv_cocoa_ window]; |
| 1811 EXPECT_TRUE(window); |
| 1812 |
| 1813 MockRenderProcessHost* process_host = test_rvh()->GetProcess(); |
| 1814 process_host->sink().ClearMessages(); |
| 1815 |
| 1816 ui::test::ScopedFakeNSWindowFocus key_window_faker; |
| 1817 EXPECT_FALSE([window isKeyWindow]); |
| 1818 EXPECT_EQ(0U, process_host->sink().message_count()); |
| 1819 |
| 1820 // Cmd+x. |
| 1821 NSEvent* key_down = |
| 1822 cocoa_test_event_utils::KeyEventWithType(NSKeyDown, NSCommandKeyMask); |
| 1823 |
| 1824 // Sending while not key should forward along the responder chain (e.g. to the |
| 1825 // mainMenu). Note the event is being sent to the NSWindow, which may also ask |
| 1826 // other parts of the UI to handle it, but in the test they should all say |
| 1827 // "NO" as well. |
| 1828 EXPECT_FALSE([window performKeyEquivalent:key_down]); |
| 1829 EXPECT_EQ(0U, process_host->sink().message_count()); |
| 1830 |
| 1831 // Make key and send again. Event should be seen. |
| 1832 [window makeKeyWindow]; |
| 1833 EXPECT_TRUE([window isKeyWindow]); |
| 1834 process_host->sink().ClearMessages(); // Ignore the focus messages. |
| 1835 |
| 1836 // -performKeyEquivalent: now returns YES to prevent further propagation, and |
| 1837 // the event is sent to the renderer. |
| 1838 EXPECT_TRUE([window performKeyEquivalent:key_down]); |
| 1839 EXPECT_EQ(2U, process_host->sink().message_count()); |
| 1840 EXPECT_EQ("RawKeyDown Char", GetInputMessageTypes(process_host)); |
| 1841 |
| 1842 rwhv_mac_->release_pepper_fullscreen_window_for_testing(); |
| 1843 } |
| 1844 |
1798 } // namespace content | 1845 } // namespace content |
OLD | NEW |