summaryrefslogtreecommitdiff
path: root/chromium/ui/views
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-07-14 17:41:05 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-08-04 12:37:36 +0000
commit399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (patch)
tree6b06b60ff365abef0e13b3503d593a0df48d20e8 /chromium/ui/views
parent7366110654eec46f21b6824f302356426f48cd74 (diff)
downloadqtwebengine-chromium-399c965b6064c440ddcf4015f5f8e9d131c7a0a6.tar.gz
BASELINE: Update Chromium to 52.0.2743.76 and Ninja to 1.7.1
Change-Id: I382f51b959689505a60f8b707255ecb344f7d8b4 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ui/views')
-rw-r--r--chromium/ui/views/BUILD.gn24
-rw-r--r--chromium/ui/views/accessibility/ax_aura_obj_cache_unittest.cc4
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_unittest.cc8
-rw-r--r--chromium/ui/views/accessible_pane_view.h5
-rw-r--r--chromium/ui/views/accessible_pane_view_unittest.cc18
-rw-r--r--chromium/ui/views/animation/bounds_animator.cc9
-rw-r--r--chromium/ui/views/animation/bounds_animator.h4
-rw-r--r--chromium/ui/views/animation/bounds_animator_unittest.cc11
-rw-r--r--chromium/ui/views/animation/button_ink_drop_delegate.cc23
-rw-r--r--chromium/ui/views/animation/button_ink_drop_delegate.h10
-rw-r--r--chromium/ui/views/animation/flood_fill_ink_drop_ripple.cc (renamed from chromium/ui/views/animation/flood_fill_ink_drop_animation.cc)45
-rw-r--r--chromium/ui/views/animation/flood_fill_ink_drop_ripple.h (renamed from chromium/ui/views/animation/flood_fill_ink_drop_animation.h)33
-rw-r--r--chromium/ui/views/animation/ink_drop.h (renamed from chromium/ui/views/animation/ink_drop_animation_controller.h)19
-rw-r--r--chromium/ui/views/animation/ink_drop_animation_controller_factory.cc74
-rw-r--r--chromium/ui/views/animation/ink_drop_animation_controller_factory.h36
-rw-r--r--chromium/ui/views/animation/ink_drop_animation_controller_factory_unittest.cc171
-rw-r--r--chromium/ui/views/animation/ink_drop_animation_controller_impl.cc259
-rw-r--r--chromium/ui/views/animation/ink_drop_animation_ended_reason.h10
-rw-r--r--chromium/ui/views/animation/ink_drop_animation_unittest.cc354
-rw-r--r--chromium/ui/views/animation/ink_drop_delegate.h3
-rw-r--r--chromium/ui/views/animation/ink_drop_factory.cc71
-rw-r--r--chromium/ui/views/animation/ink_drop_factory.h34
-rw-r--r--chromium/ui/views/animation/ink_drop_factory_unittest.cc158
-rw-r--r--chromium/ui/views/animation/ink_drop_host.h15
-rw-r--r--chromium/ui/views/animation/ink_drop_host_view.cc12
-rw-r--r--chromium/ui/views/animation/ink_drop_host_view.h11
-rw-r--r--chromium/ui/views/animation/ink_drop_hover.cc12
-rw-r--r--chromium/ui/views/animation/ink_drop_hover.h16
-rw-r--r--chromium/ui/views/animation/ink_drop_hover_unittest.cc6
-rw-r--r--chromium/ui/views/animation/ink_drop_impl.cc253
-rw-r--r--chromium/ui/views/animation/ink_drop_impl.h (renamed from chromium/ui/views/animation/ink_drop_animation_controller_impl.h)92
-rw-r--r--chromium/ui/views/animation/ink_drop_impl_unittest.cc (renamed from chromium/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc)122
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple.cc (renamed from chromium/ui/views/animation/ink_drop_animation.cc)34
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple.h (renamed from chromium/ui/views/animation/ink_drop_animation.h)32
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple_observer.h (renamed from chromium/ui/views/animation/ink_drop_animation_observer.h)16
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple_unittest.cc348
-rw-r--r--chromium/ui/views/animation/ink_drop_state.h8
-rw-r--r--chromium/ui/views/animation/scroll_animator.h5
-rw-r--r--chromium/ui/views/animation/square_ink_drop_ripple.cc (renamed from chromium/ui/views/animation/square_ink_drop_animation.cc)60
-rw-r--r--chromium/ui/views/animation/square_ink_drop_ripple.h (renamed from chromium/ui/views/animation/square_ink_drop_animation.h)46
-rw-r--r--chromium/ui/views/animation/square_ink_drop_ripple_unittest.cc (renamed from chromium/ui/views/animation/square_ink_drop_animation_unittest.cc)83
-rw-r--r--chromium/ui/views/border.cc64
-rw-r--r--chromium/ui/views/border.h42
-rw-r--r--chromium/ui/views/bubble/bubble_border.h5
-rw-r--r--chromium/ui/views/bubble/bubble_border_unittest.cc3
-rw-r--r--chromium/ui/views/bubble/bubble_delegate.cc335
-rw-r--r--chromium/ui/views/bubble/bubble_delegate.h220
-rw-r--r--chromium/ui/views/bubble/bubble_delegate_unittest.cc323
-rw-r--r--chromium/ui/views/bubble/bubble_dialog_delegate.cc10
-rw-r--r--chromium/ui/views/bubble/bubble_dialog_delegate.h6
-rw-r--r--chromium/ui/views/bubble/bubble_dialog_delegate_unittest.cc60
-rw-r--r--chromium/ui/views/bubble/bubble_frame_view.cc15
-rw-r--r--chromium/ui/views/bubble/bubble_frame_view.h4
-rw-r--r--chromium/ui/views/bubble/bubble_frame_view_unittest.cc12
-rw-r--r--chromium/ui/views/bubble/bubble_window_targeter.cc7
-rw-r--r--chromium/ui/views/bubble/bubble_window_targeter.h7
-rw-r--r--chromium/ui/views/bubble/bubble_window_targeter_unittest.cc22
-rw-r--r--chromium/ui/views/bubble/tray_bubble_view.cc12
-rw-r--r--chromium/ui/views/bubble/tray_bubble_view.h20
-rw-r--r--chromium/ui/views/button_drag_utils.cc2
-rw-r--r--chromium/ui/views/cocoa/bridged_content_view.h4
-rw-r--r--chromium/ui/views/cocoa/bridged_content_view.mm328
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget.h12
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget.mm13
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget_interactive_uitest.mm2
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget_unittest.mm570
-rw-r--r--chromium/ui/views/cocoa/cocoa_mouse_capture.h5
-rw-r--r--chromium/ui/views/cocoa/cocoa_mouse_capture_unittest.mm2
-rw-r--r--chromium/ui/views/cocoa/native_widget_mac_nswindow.mm28
-rw-r--r--chromium/ui/views/cocoa/widget_owner_nswindow_adapter.mm16
-rw-r--r--chromium/ui/views/color_chooser/color_chooser_view.cc5
-rw-r--r--chromium/ui/views/controls/button/blue_button.cc4
-rw-r--r--chromium/ui/views/controls/button/blue_button.h2
-rw-r--r--chromium/ui/views/controls/button/blue_button_unittest.cc13
-rw-r--r--chromium/ui/views/controls/button/button.cc11
-rw-r--r--chromium/ui/views/controls/button/button.h3
-rw-r--r--chromium/ui/views/controls/button/checkbox.cc5
-rw-r--r--chromium/ui/views/controls/button/custom_button.cc16
-rw-r--r--chromium/ui/views/controls/button/custom_button.h11
-rw-r--r--chromium/ui/views/controls/button/custom_button_unittest.cc39
-rw-r--r--chromium/ui/views/controls/button/image_button.cc2
-rw-r--r--chromium/ui/views/controls/button/image_button.h13
-rw-r--r--chromium/ui/views/controls/button/label_button.cc109
-rw-r--r--chromium/ui/views/controls/button/label_button.h31
-rw-r--r--chromium/ui/views/controls/button/label_button_border.h5
-rw-r--r--chromium/ui/views/controls/button/label_button_unittest.cc129
-rw-r--r--chromium/ui/views/controls/button/md_text_button.cc60
-rw-r--r--chromium/ui/views/controls/button/md_text_button.h10
-rw-r--r--chromium/ui/views/controls/button/menu_button.cc2
-rw-r--r--chromium/ui/views/controls/button/menu_button_unittest.cc45
-rw-r--r--chromium/ui/views/controls/combobox/combobox.cc134
-rw-r--r--chromium/ui/views/controls/combobox/combobox.h25
-rw-r--r--chromium/ui/views/controls/combobox/combobox_unittest.cc120
-rw-r--r--chromium/ui/views/controls/focusable_border.cc20
-rw-r--r--chromium/ui/views/controls/image_view.cc2
-rw-r--r--chromium/ui/views/controls/image_view.h4
-rw-r--r--chromium/ui/views/controls/label.cc26
-rw-r--r--chromium/ui/views/controls/label.h10
-rw-r--r--chromium/ui/views/controls/label_unittest.cc90
-rw-r--r--chromium/ui/views/controls/link.cc28
-rw-r--r--chromium/ui/views/controls/link.h4
-rw-r--r--chromium/ui/views/controls/menu/menu_controller.cc42
-rw-r--r--chromium/ui/views/controls/menu/menu_controller.h18
-rw-r--r--chromium/ui/views/controls/menu/menu_controller_unittest.cc106
-rw-r--r--chromium/ui/views/controls/menu/menu_host.h5
-rw-r--r--chromium/ui/views/controls/menu/menu_image_util.cc6
-rw-r--r--chromium/ui/views/controls/menu/menu_message_loop_aura.cc6
-rw-r--r--chromium/ui/views/controls/menu/menu_message_loop_aura.h3
-rw-r--r--chromium/ui/views/controls/menu/menu_model_adapter_unittest.cc4
-rw-r--r--chromium/ui/views/controls/menu/menu_runner.cc2
-rw-r--r--chromium/ui/views/controls/menu/menu_runner.h9
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_cocoa_unittest.mm17
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_impl.cc19
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_impl.h12
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_impl_adapter.h2
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_impl_cocoa.h3
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_impl_cocoa.mm8
-rw-r--r--chromium/ui/views/controls/menu/menu_runner_unittest.cc171
-rw-r--r--chromium/ui/views/controls/menu/menu_scroll_view_container.cc6
-rw-r--r--chromium/ui/views/controls/menu/menu_separator_win.cc4
-rw-r--r--chromium/ui/views/controls/menu/native_menu_win.cc2
-rw-r--r--chromium/ui/views/controls/menu/submenu_view.h2
-rw-r--r--chromium/ui/views/controls/native/native_view_host.h2
-rw-r--r--chromium/ui/views/controls/native/native_view_host_aura.h4
-rw-r--r--chromium/ui/views/controls/native/native_view_host_aura_unittest.cc5
-rw-r--r--chromium/ui/views/controls/native/native_view_host_mac.mm8
-rw-r--r--chromium/ui/views/controls/native/native_view_host_mac_unittest.mm3
-rw-r--r--chromium/ui/views/controls/native/native_view_host_test_base.h7
-rw-r--r--chromium/ui/views/controls/native/native_view_host_unittest.cc39
-rw-r--r--chromium/ui/views/controls/prefix_selector_unittest.cc2
-rw-r--r--chromium/ui/views/controls/scroll_view_unittest.cc3
-rw-r--r--chromium/ui/views/controls/scrollbar/base_scroll_bar.cc4
-rw-r--r--chromium/ui/views/controls/scrollbar/base_scroll_bar.h4
-rw-r--r--chromium/ui/views/controls/scrollbar/base_scroll_bar_button.cc5
-rw-r--r--chromium/ui/views/controls/scrollbar/base_scroll_bar_button.h4
-rw-r--r--chromium/ui/views/controls/scrollbar/native_scroll_bar_views.cc5
-rw-r--r--chromium/ui/views/controls/scrollbar/scrollbar_unittest.cc2
-rw-r--r--chromium/ui/views/controls/separator.cc1
-rw-r--r--chromium/ui/views/controls/slider.cc7
-rw-r--r--chromium/ui/views/controls/slider.h2
-rw-r--r--chromium/ui/views/controls/slider_unittest.cc4
-rw-r--r--chromium/ui/views/controls/styled_label.cc6
-rw-r--r--chromium/ui/views/controls/styled_label_unittest.cc7
-rw-r--r--chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc7
-rw-r--r--chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc10
-rw-r--r--chromium/ui/views/controls/table/table_header.h2
-rw-r--r--chromium/ui/views/controls/table/table_view.cc5
-rw-r--r--chromium/ui/views/controls/table/table_view.h6
-rw-r--r--chromium/ui/views/controls/table/table_view_unittest.cc6
-rw-r--r--chromium/ui/views/controls/textfield/textfield.cc66
-rw-r--r--chromium/ui/views/controls/textfield/textfield.h15
-rw-r--r--chromium/ui/views/controls/textfield/textfield_model.h4
-rw-r--r--chromium/ui/views/controls/textfield/textfield_model_unittest.cc5
-rw-r--r--chromium/ui/views/controls/textfield/textfield_unittest.cc265
-rw-r--r--chromium/ui/views/controls/tree/tree_view.cc3
-rw-r--r--chromium/ui/views/controls/tree/tree_view.h4
-rw-r--r--chromium/ui/views/controls/webview/web_dialog_view.cc2
-rw-r--r--chromium/ui/views/controls/webview/web_dialog_view.h2
-rw-r--r--chromium/ui/views/controls/webview/webview.cc13
-rw-r--r--chromium/ui/views/controls/webview/webview.h13
-rw-r--r--chromium/ui/views/controls/webview/webview_unittest.cc49
-rw-r--r--chromium/ui/views/corewm/cursor_height_provider_win.cc7
-rw-r--r--chromium/ui/views/corewm/desktop_capture_controller_unittest.cc14
-rw-r--r--chromium/ui/views/corewm/tooltip_aura.cc9
-rw-r--r--chromium/ui/views/corewm/tooltip_aura.h5
-rw-r--r--chromium/ui/views/corewm/tooltip_controller.cc10
-rw-r--r--chromium/ui/views/corewm/tooltip_controller.h6
-rw-r--r--chromium/ui/views/corewm/tooltip_controller_unittest.cc57
-rw-r--r--chromium/ui/views/corewm/tooltip_win.cc23
-rw-r--r--chromium/ui/views/debug_utils.cc41
-rw-r--r--chromium/ui/views/drag_utils.cc8
-rw-r--r--chromium/ui/views/event_monitor.h7
-rw-r--r--chromium/ui/views/event_monitor_aura.cc9
-rw-r--r--chromium/ui/views/event_monitor_mac.mm15
-rw-r--r--chromium/ui/views/event_monitor_unittest.cc8
-rw-r--r--chromium/ui/views/examples/BUILD.gn4
-rw-r--r--chromium/ui/views/examples/DEPS2
-rw-r--r--chromium/ui/views/examples/bubble_example.cc12
-rw-r--r--chromium/ui/views/examples/button_example.cc67
-rw-r--r--chromium/ui/views/examples/button_example.h12
-rw-r--r--chromium/ui/views/examples/combobox_example.cc3
-rw-r--r--chromium/ui/views/examples/examples.gyp2
-rw-r--r--chromium/ui/views/examples/examples_main.cc28
-rw-r--r--chromium/ui/views/examples/examples_window.cc4
-rw-r--r--chromium/ui/views/examples/examples_window.h5
-rw-r--r--chromium/ui/views/examples/examples_window_with_content.cc2
-rw-r--r--chromium/ui/views/examples/label_example.cc3
-rw-r--r--chromium/ui/views/examples/label_example.h2
-rw-r--r--chromium/ui/views/examples/menu_example.cc6
-rw-r--r--chromium/ui/views/examples/multiline_example.cc28
-rw-r--r--chromium/ui/views/examples/multiline_example.h3
-rw-r--r--chromium/ui/views/examples/tree_view_example.cc9
-rw-r--r--chromium/ui/views/examples/tree_view_example.h9
-rw-r--r--chromium/ui/views/examples/widget_example.cc3
-rw-r--r--chromium/ui/views/focus/focus_manager.cc44
-rw-r--r--chromium/ui/views/focus/focus_manager.h34
-rw-r--r--chromium/ui/views/focus/focus_manager_delegate.h6
-rw-r--r--chromium/ui/views/focus/focus_manager_unittest.cc168
-rw-r--r--chromium/ui/views/focus/focus_search.cc15
-rw-r--r--chromium/ui/views/focus/focus_search.h3
-rw-r--r--chromium/ui/views/focus/focus_traversal_unittest.cc199
-rw-r--r--chromium/ui/views/layout/box_layout_unittest.cc2
-rw-r--r--chromium/ui/views/linux_ui/linux_ui.h9
-rw-r--r--chromium/ui/views/mouse_watcher.cc2
-rw-r--r--chromium/ui/views/mouse_watcher.h7
-rw-r--r--chromium/ui/views/mouse_watcher_view_host.cc6
-rw-r--r--chromium/ui/views/mus/BUILD.gn137
-rw-r--r--chromium/ui/views/mus/DEPS10
-rw-r--r--chromium/ui/views/mus/aura_init.cc27
-rw-r--r--chromium/ui/views/mus/aura_init.h19
-rw-r--r--chromium/ui/views/mus/display_converter.cc6
-rw-r--r--chromium/ui/views/mus/display_converter.h6
-rw-r--r--chromium/ui/views/mus/display_list.cc109
-rw-r--r--chromium/ui/views/mus/display_list.h69
-rw-r--r--chromium/ui/views/mus/display_list_unittest.cc113
-rw-r--r--chromium/ui/views/mus/interactive_ui_tests_manifest.json10
-rw-r--r--chromium/ui/views/mus/interactive_ui_tests_mus.cc9
-rw-r--r--chromium/ui/views/mus/native_widget_mus.cc417
-rw-r--r--chromium/ui/views/mus/native_widget_mus.h74
-rw-r--r--chromium/ui/views/mus/native_widget_mus_unittest.cc258
-rw-r--r--chromium/ui/views/mus/platform_test_helper_mus.cc109
-rw-r--r--chromium/ui/views/mus/platform_window_mus.cc162
-rw-r--r--chromium/ui/views/mus/platform_window_mus.h48
-rw-r--r--chromium/ui/views/mus/run_all_unittests_mus.cc4
-rw-r--r--chromium/ui/views/mus/screen_mus.cc210
-rw-r--r--chromium/ui/views/mus/screen_mus.h48
-rw-r--r--chromium/ui/views/mus/screen_mus_delegate.h8
-rw-r--r--chromium/ui/views/mus/screen_mus_unittest.cc32
-rw-r--r--chromium/ui/views/mus/surface_binding.cc31
-rw-r--r--chromium/ui/views/mus/surface_binding.h15
-rw-r--r--chromium/ui/views/mus/surface_context_factory.cc23
-rw-r--r--chromium/ui/views/mus/surface_context_factory.h10
-rw-r--r--chromium/ui/views/mus/unittests_manifest.json10
-rw-r--r--chromium/ui/views/mus/views_mus_test_suite.cc160
-rw-r--r--chromium/ui/views/mus/views_mus_test_suite.h34
-rw-r--r--chromium/ui/views/mus/window_manager_connection.cc90
-rw-r--r--chromium/ui/views/mus/window_manager_connection.h37
-rw-r--r--chromium/ui/views/mus/window_manager_connection_unittest.cc118
-rw-r--r--chromium/ui/views/mus/window_tree_host_mus.cc12
-rw-r--r--chromium/ui/views/mus/window_tree_host_mus.h15
-rw-r--r--chromium/ui/views/painter.cc25
-rw-r--r--chromium/ui/views/painter.h12
-rw-r--r--chromium/ui/views/pointer_watcher.h42
-rw-r--r--chromium/ui/views/run_all_unittests.cc60
-rw-r--r--chromium/ui/views/run_all_unittests.h14
-rw-r--r--chromium/ui/views/run_all_unittests_main.cc4
-rw-r--r--chromium/ui/views/style/mac/combobox_background_mac.cc28
-rw-r--r--chromium/ui/views/style/mac/combobox_background_mac.h7
-rw-r--r--chromium/ui/views/style/mac/dialog_button_border_mac.cc151
-rw-r--r--chromium/ui/views/style/mac/dialog_button_border_mac.h5
-rw-r--r--chromium/ui/views/style/mac/dialog_button_border_mac_unittest.cc31
-rw-r--r--chromium/ui/views/style/platform_style.cc69
-rw-r--r--chromium/ui/views/style/platform_style.h47
-rw-r--r--chromium/ui/views/style/platform_style_linux.cc10
-rw-r--r--chromium/ui/views/style/platform_style_mac.mm49
-rw-r--r--chromium/ui/views/touchui/touch_selection_controller_impl.cc34
-rw-r--r--chromium/ui/views/touchui/touch_selection_controller_impl.h7
-rw-r--r--chromium/ui/views/touchui/touch_selection_controller_impl_unittest.cc88
-rw-r--r--chromium/ui/views/touchui/touch_selection_menu_runner_views.cc32
-rw-r--r--chromium/ui/views/touchui/touch_selection_menu_runner_views.h3
-rw-r--r--chromium/ui/views/view.cc57
-rw-r--r--chromium/ui/views/view.h67
-rw-r--r--chromium/ui/views/view_targeter_unittest.cc5
-rw-r--r--chromium/ui/views/view_unittest.cc86
-rw-r--r--chromium/ui/views/view_unittest_aura.cc7
-rw-r--r--chromium/ui/views/views.gyp79
-rw-r--r--chromium/ui/views/views_delegate.h4
-rw-r--r--chromium/ui/views/views_exports.cc10
-rw-r--r--chromium/ui/views/views_test_suite.cc62
-rw-r--r--chromium/ui/views/views_test_suite.h45
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h9
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc10
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurawin.cc3
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc21
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h17
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc23
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc16
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h7
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_factory_ozone.h7
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_focus_rules_unittest.cc8
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h10
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc22
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h41
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc11
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen.h4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_ozone.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc6
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_win.h3
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc100
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h52
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc156
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h8
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc51
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h12
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc74
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h11
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc17
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc20
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc18
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h11
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc1
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc25
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h4
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc6
-rw-r--r--chromium/ui/views/widget/native_widget_aura.cc45
-rw-r--r--chromium/ui/views/widget/native_widget_aura.h10
-rw-r--r--chromium/ui/views/widget/native_widget_aura_unittest.cc113
-rw-r--r--chromium/ui/views/widget/native_widget_delegate.h3
-rw-r--r--chromium/ui/views/widget/native_widget_mac.h7
-rw-r--r--chromium/ui/views/widget/native_widget_mac.mm18
-rw-r--r--chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm29
-rw-r--r--chromium/ui/views/widget/native_widget_mac_unittest.mm180
-rw-r--r--chromium/ui/views/widget/native_widget_private.h10
-rw-r--r--chromium/ui/views/widget/root_view.cc3
-rw-r--r--chromium/ui/views/widget/root_view.h4
-rw-r--r--chromium/ui/views/widget/root_view_unittest.cc7
-rw-r--r--chromium/ui/views/widget/tooltip_manager.h1
-rw-r--r--chromium/ui/views/widget/tooltip_manager_aura.cc4
-rw-r--r--chromium/ui/views/widget/widget.cc57
-rw-r--r--chromium/ui/views/widget/widget.h35
-rw-r--r--chromium/ui/views/widget/widget_delegate.cc5
-rw-r--r--chromium/ui/views/widget/widget_delegate.h2
-rw-r--r--chromium/ui/views/widget/widget_hwnd_utils.cc13
-rw-r--r--chromium/ui/views/widget/widget_interactive_uitest.cc129
-rw-r--r--chromium/ui/views/widget/widget_unittest.cc210
-rw-r--r--chromium/ui/views/widget/window_reorderer.h5
-rw-r--r--chromium/ui/views/widget/window_reorderer_unittest.cc26
-rw-r--r--chromium/ui/views/win/fullscreen_handler.cc13
-rw-r--r--chromium/ui/views/win/fullscreen_handler.h1
-rw-r--r--chromium/ui/views/win/hwnd_message_handler.cc136
-rw-r--r--chromium/ui/views/win/hwnd_message_handler.h36
-rw-r--r--chromium/ui/views/win/hwnd_message_handler_delegate.h2
-rw-r--r--chromium/ui/views/win/windows_session_change_observer.cc5
-rw-r--r--chromium/ui/views/window/custom_frame_view.h5
-rw-r--r--chromium/ui/views/window/dialog_client_view.cc33
-rw-r--r--chromium/ui/views/window/dialog_client_view_unittest.cc4
-rw-r--r--chromium/ui/views/window/dialog_delegate.cc16
-rw-r--r--chromium/ui/views/window/dialog_delegate.h11
-rw-r--r--chromium/ui/views/window/dialog_delegate_unittest.cc2
-rw-r--r--chromium/ui/views/window/non_client_view.cc14
-rw-r--r--chromium/ui/views/window/non_client_view.h7
346 files changed, 7989 insertions, 5237 deletions
diff --git a/chromium/ui/views/BUILD.gn b/chromium/ui/views/BUILD.gn
index 5b85b89b3cf..d02ed9bd420 100644
--- a/chromium/ui/views/BUILD.gn
+++ b/chromium/ui/views/BUILD.gn
@@ -34,6 +34,7 @@ component("views") {
"//skia",
"//third_party/icu",
"//ui/accessibility",
+ "//ui/display",
"//ui/native_theme",
"//ui/resources",
"//ui/strings",
@@ -104,6 +105,7 @@ component("views") {
]
deps += [
"//ui/events/devices",
+ "//ui/events/devices/x11",
"//ui/events/platform/x11",
"//ui/gfx/x",
]
@@ -138,8 +140,10 @@ component("views") {
"//ui/events:dom_keycode_converter",
]
libs = [
- # Required by bridged_native_widget.mm.
- "QuartzCore.framework",
+ "AppKit.framework",
+ "CoreGraphics.framework",
+ "Foundation.framework",
+ "QuartzCore.framework", # Required by bridged_native_widget.mm.
]
}
}
@@ -174,7 +178,10 @@ source_set("test_support_internal") {
"//ui/gfx/geometry",
]
- sources += [ "test/platform_test_helper.h" ]
+ sources += [
+ "test/platform_test_helper.cc",
+ "test/platform_test_helper.h",
+ ]
if (use_aura) {
sources += gypi_values.views_test_support_aura_sources
@@ -204,7 +211,6 @@ static_library("test_support") {
":test_support_internal",
]
sources = [
- "test/default_platform_test_helper.cc",
"test/native_widget_factory_desktop.cc",
]
}
@@ -240,10 +246,8 @@ test("views_unittests") {
"//url",
]
- # TODO(thakis): This should be a data_deps on //ui/resources:ui_test_pak, but
- # that has no effect. (See similar TODOs elsewhere ui_test.pak is listed)
- data = [
- "$root_out_dir/ui_test.pak",
+ data_deps = [
+ "//ui/resources:ui_test_pak_data",
]
if (is_win) {
@@ -306,7 +310,9 @@ if (is_mac) {
test("macviews_interactive_ui_tests") {
sources = [
"cocoa/bridged_native_widget_interactive_uitest.mm",
- "run_all_unittests.cc",
+ "run_all_unittests_main.cc",
+ "views_test_suite.cc",
+ "views_test_suite.h",
"widget/native_widget_mac_interactive_uitest.mm",
]
deps = [
diff --git a/chromium/ui/views/accessibility/ax_aura_obj_cache_unittest.cc b/chromium/ui/views/accessibility/ax_aura_obj_cache_unittest.cc
index 80122369c31..3e5184d777d 100644
--- a/chromium/ui/views/accessibility/ax_aura_obj_cache_unittest.cc
+++ b/chromium/ui/views/accessibility/ax_aura_obj_cache_unittest.cc
@@ -10,13 +10,13 @@ namespace test {
namespace {
-// This class can be used as a deleter for scoped_ptr<Widget>
+// This class can be used as a deleter for std::unique_ptr<Widget>
// to call function Widget::CloseNow automatically.
struct WidgetCloser {
inline void operator()(Widget* widget) const { widget->CloseNow(); }
};
-using WidgetAutoclosePtr = scoped_ptr<Widget, WidgetCloser>;
+using WidgetAutoclosePtr = std::unique_ptr<Widget, WidgetCloser>;
}
class AXAuraObjCacheTest : public WidgetTest {
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc b/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc
index 705f3efc77f..a60b1cb6b95 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc
+++ b/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc
@@ -48,9 +48,9 @@ class NativeViewAccessibilityTest : public ViewsTestBase {
}
protected:
- scoped_ptr<TestButton> button_;
+ std::unique_ptr<TestButton> button_;
NativeViewAccessibility* button_accessibility_;
- scoped_ptr<Label> label_;
+ std::unique_ptr<Label> label_;
NativeViewAccessibility* label_accessibility_;
};
@@ -90,13 +90,13 @@ class TestNativeViewAccessibility : public NativeViewAccessibility {
};
TEST_F(NativeViewAccessibilityTest, CrashOnWidgetDestroyed) {
- scoped_ptr<Widget> parent_widget(new Widget);
+ std::unique_ptr<Widget> parent_widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
parent_widget->Init(params);
- scoped_ptr<Widget> child_widget(new Widget);
+ std::unique_ptr<Widget> child_widget(new Widget);
child_widget->Init(params);
// Make sure that deleting the parent widget can't cause a crash
diff --git a/chromium/ui/views/accessible_pane_view.h b/chromium/ui/views/accessible_pane_view.h
index 36170a84c95..80d4e54bfcd 100644
--- a/chromium/ui/views/accessible_pane_view.h
+++ b/chromium/ui/views/accessible_pane_view.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_ACCESSIBLE_PANE_VIEW_H_
#define UI_VIEWS_ACCESSIBLE_PANE_VIEW_H_
+#include <memory>
+
#include "base/containers/hash_tables.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/views/focus/focus_manager.h"
@@ -106,7 +107,7 @@ class VIEWS_EXPORT AccessiblePaneView : public View,
// Our custom focus search implementation that traps focus in this
// pane and traverses all views that are focusable for accessibility,
// not just those that are normally focusable.
- scoped_ptr<FocusSearch> focus_search_;
+ std::unique_ptr<FocusSearch> focus_search_;
// Registered accelerators
ui::Accelerator home_key_;
diff --git a/chromium/ui/views/accessible_pane_view_unittest.cc b/chromium/ui/views/accessible_pane_view_unittest.cc
index 864481ff3ff..d3f5bd0d44b 100644
--- a/chromium/ui/views/accessible_pane_view_unittest.cc
+++ b/chromium/ui/views/accessible_pane_view_unittest.cc
@@ -38,10 +38,10 @@ class TestBarView : public AccessiblePaneView,
private:
void Init();
- scoped_ptr<LabelButton> child_button_;
- scoped_ptr<LabelButton> second_child_button_;
- scoped_ptr<LabelButton> third_child_button_;
- scoped_ptr<LabelButton> not_child_button_;
+ std::unique_ptr<LabelButton> child_button_;
+ std::unique_ptr<LabelButton> second_child_button_;
+ std::unique_ptr<LabelButton> third_child_button_;
+ std::unique_ptr<LabelButton> not_child_button_;
DISALLOW_COPY_AND_ASSIGN(TestBarView);
};
@@ -74,7 +74,7 @@ View* TestBarView::GetDefaultFocusableChild() {
TEST_F(AccessiblePaneViewTest, SimpleSetPaneFocus) {
TestBarView* test_view = new TestBarView();
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
@@ -102,7 +102,7 @@ TEST_F(AccessiblePaneViewTest, SimpleSetPaneFocus) {
TEST_F(AccessiblePaneViewTest, SetPaneFocusAndRestore) {
View* test_view_main = new View();
- scoped_ptr<Widget> widget_main(new Widget());
+ std::unique_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.
@@ -117,7 +117,7 @@ TEST_F(AccessiblePaneViewTest, SetPaneFocusAndRestore) {
EXPECT_TRUE(test_view_main->HasFocus());
TestBarView* test_view_bar = new TestBarView();
- scoped_ptr<Widget> widget_bar(new Widget());
+ std::unique_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;
@@ -157,7 +157,7 @@ TEST_F(AccessiblePaneViewTest, SetPaneFocusAndRestore) {
TEST_F(AccessiblePaneViewTest, TwoSetPaneFocus) {
TestBarView* test_view = new TestBarView();
TestBarView* test_view_2 = new TestBarView();
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
@@ -187,7 +187,7 @@ TEST_F(AccessiblePaneViewTest, TwoSetPaneFocus) {
TEST_F(AccessiblePaneViewTest, PaneFocusTraversal) {
TestBarView* test_view = new TestBarView();
TestBarView* original_test_view = new TestBarView();
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
diff --git a/chromium/ui/views/animation/bounds_animator.cc b/chromium/ui/views/animation/bounds_animator.cc
index ba9412722e0..3f0e65fd0f0 100644
--- a/chromium/ui/views/animation/bounds_animator.cc
+++ b/chromium/ui/views/animation/bounds_animator.cc
@@ -4,7 +4,8 @@
#include "ui/views/animation/bounds_animator.h"
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "ui/gfx/animation/animation_container.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/views/animation/bounds_animator_observer.h"
@@ -89,14 +90,14 @@ void BoundsAnimator::SetAnimationForView(View* view,
SlideAnimation* animation) {
DCHECK(animation);
- scoped_ptr<SlideAnimation> animation_wrapper(animation);
+ std::unique_ptr<SlideAnimation> animation_wrapper(animation);
if (!IsAnimating(view))
return;
// We delay deleting the animation until the end so that we don't prematurely
// send out notification that we're done.
- scoped_ptr<Animation> old_animation(ResetAnimationForView(view));
+ std::unique_ptr<Animation> old_animation(ResetAnimationForView(view));
data_[view].animation = animation_wrapper.release();
animation_to_view_[animation] = view;
@@ -112,7 +113,7 @@ const SlideAnimation* BoundsAnimator::GetAnimationForView(View* view) {
void BoundsAnimator::SetAnimationDelegate(
View* view,
- scoped_ptr<AnimationDelegate> delegate) {
+ std::unique_ptr<AnimationDelegate> delegate) {
DCHECK(IsAnimating(view));
data_[view].delegate = delegate.release();
diff --git a/chromium/ui/views/animation/bounds_animator.h b/chromium/ui/views/animation/bounds_animator.h
index 2840c3dcd73..7f4208985b2 100644
--- a/chromium/ui/views/animation/bounds_animator.h
+++ b/chromium/ui/views/animation/bounds_animator.h
@@ -6,11 +6,11 @@
#define UI_VIEWS_ANIMATION_BOUNDS_ANIMATOR_H_
#include <map>
+#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "ui/gfx/animation/animation_container_observer.h"
#include "ui/gfx/animation/animation_delegate.h"
@@ -71,7 +71,7 @@ class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
// Sets the delegate for the animation for the specified view.
void SetAnimationDelegate(View* view,
- scoped_ptr<gfx::AnimationDelegate> delegate);
+ std::unique_ptr<gfx::AnimationDelegate> delegate);
// Returns true if BoundsAnimator is animating the bounds of |view|.
bool IsAnimating(View* view) const;
diff --git a/chromium/ui/views/animation/bounds_animator_unittest.cc b/chromium/ui/views/animation/bounds_animator_unittest.cc
index 7e09deba510..f8421ae6af5 100644
--- a/chromium/ui/views/animation/bounds_animator_unittest.cc
+++ b/chromium/ui/views/animation/bounds_animator_unittest.cc
@@ -114,7 +114,8 @@ TEST_F(BoundsAnimatorTest, AnimateViewTo) {
gfx::Rect target_bounds(10, 10, 20, 20);
animator()->AnimateViewTo(child(), target_bounds);
animator()->SetAnimationDelegate(
- child(), scoped_ptr<gfx::AnimationDelegate>(new TestAnimationDelegate()));
+ child(),
+ std::unique_ptr<gfx::AnimationDelegate>(new TestAnimationDelegate()));
// The animator should be animating now.
EXPECT_TRUE(animator()->IsAnimating());
@@ -136,7 +137,7 @@ TEST_F(BoundsAnimatorTest, AnimateViewTo) {
TEST_F(BoundsAnimatorTest, DeleteDelegateOnCancel) {
animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
animator()->SetAnimationDelegate(
- child(), scoped_ptr<gfx::AnimationDelegate>(new OwnedDelegate()));
+ child(), std::unique_ptr<gfx::AnimationDelegate>(new OwnedDelegate()));
animator()->Cancel();
@@ -153,7 +154,7 @@ TEST_F(BoundsAnimatorTest, DeleteDelegateOnCancel) {
TEST_F(BoundsAnimatorTest, DeleteDelegateOnNewAnimate) {
animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
animator()->SetAnimationDelegate(
- child(), scoped_ptr<gfx::AnimationDelegate>(new OwnedDelegate()));
+ child(), std::unique_ptr<gfx::AnimationDelegate>(new OwnedDelegate()));
animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
@@ -164,11 +165,11 @@ TEST_F(BoundsAnimatorTest, DeleteDelegateOnNewAnimate) {
// Makes sure StopAnimating works.
TEST_F(BoundsAnimatorTest, StopAnimating) {
- scoped_ptr<OwnedDelegate> delegate(new OwnedDelegate());
+ std::unique_ptr<OwnedDelegate> delegate(new OwnedDelegate());
animator()->AnimateViewTo(child(), gfx::Rect(0, 0, 10, 10));
animator()->SetAnimationDelegate(
- child(), scoped_ptr<gfx::AnimationDelegate>(new OwnedDelegate()));
+ child(), std::unique_ptr<gfx::AnimationDelegate>(new OwnedDelegate()));
animator()->StopAnimatingView(child());
diff --git a/chromium/ui/views/animation/button_ink_drop_delegate.cc b/chromium/ui/views/animation/button_ink_drop_delegate.cc
index 73152d77bc5..3862e871b97 100644
--- a/chromium/ui/views/animation/button_ink_drop_delegate.cc
+++ b/chromium/ui/views/animation/button_ink_drop_delegate.cc
@@ -6,8 +6,8 @@
#include "ui/events/event.h"
#include "ui/events/scoped_target_handler.h"
-#include "ui/views/animation/ink_drop_animation_controller.h"
-#include "ui/views/animation/ink_drop_animation_controller_factory.h"
+#include "ui/views/animation/ink_drop.h"
+#include "ui/views/animation/ink_drop_factory.h"
#include "ui/views/animation/ink_drop_host.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/view.h"
@@ -18,23 +18,25 @@ ButtonInkDropDelegate::ButtonInkDropDelegate(InkDropHost* ink_drop_host,
View* view)
: target_handler_(new ui::ScopedTargetHandler(view, this)),
ink_drop_host_(ink_drop_host),
- ink_drop_animation_controller_(
- InkDropAnimationControllerFactory::CreateInkDropAnimationController(
- ink_drop_host_)) {}
+ ink_drop_(InkDropFactory::CreateInkDrop(ink_drop_host_)) {}
ButtonInkDropDelegate::~ButtonInkDropDelegate() {
}
void ButtonInkDropDelegate::OnAction(InkDropState state) {
- ink_drop_animation_controller_->AnimateToState(state);
+ ink_drop_->AnimateToState(state);
}
void ButtonInkDropDelegate::SnapToActivated() {
- ink_drop_animation_controller_->SnapToActivated();
+ ink_drop_->SnapToActivated();
}
void ButtonInkDropDelegate::SetHovered(bool is_hovered) {
- ink_drop_animation_controller_->SetHovered(is_hovered);
+ ink_drop_->SetHovered(is_hovered);
+}
+
+InkDropState ButtonInkDropDelegate::GetTargetInkDropState() const {
+ return ink_drop_->GetTargetInkDropState();
}
////////////////////////////////////////////////////////////////////////////////
@@ -54,8 +56,7 @@ void ButtonInkDropDelegate::OnMouseEvent(ui::MouseEvent* event) {
}
void ButtonInkDropDelegate::OnGestureEvent(ui::GestureEvent* event) {
- InkDropState current_ink_drop_state =
- ink_drop_animation_controller_->GetTargetInkDropState();
+ InkDropState current_ink_drop_state = ink_drop_->GetTargetInkDropState();
InkDropState ink_drop_state = InkDropState::HIDDEN;
switch (event->type()) {
@@ -93,7 +94,7 @@ void ButtonInkDropDelegate::OnGestureEvent(ui::GestureEvent* event) {
// would prematurely pre-empt these animations.
return;
}
- ink_drop_animation_controller_->AnimateToState(ink_drop_state);
+ ink_drop_->AnimateToState(ink_drop_state);
}
} // namespace views
diff --git a/chromium/ui/views/animation/button_ink_drop_delegate.h b/chromium/ui/views/animation/button_ink_drop_delegate.h
index f4c245ecdc1..aa9330d2948 100644
--- a/chromium/ui/views/animation/button_ink_drop_delegate.h
+++ b/chromium/ui/views/animation/button_ink_drop_delegate.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_ANIMATION_BUTTON_INK_DROP_DELEGATE_H_
#define UI_VIEWS_ANIMATION_BUTTON_INK_DROP_DELEGATE_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/geometry/point.h"
#include "ui/views/animation/ink_drop_delegate.h"
@@ -18,7 +19,7 @@ class ScopedTargetHandler;
namespace views {
-class InkDropAnimationController;
+class InkDrop;
class InkDropHost;
class View;
@@ -40,6 +41,7 @@ class VIEWS_EXPORT ButtonInkDropDelegate : public InkDropDelegate,
void OnAction(InkDropState state) override;
void SnapToActivated() override;
void SetHovered(bool is_hovered) override;
+ InkDropState GetTargetInkDropState() const override;
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override;
@@ -47,7 +49,7 @@ class VIEWS_EXPORT ButtonInkDropDelegate : public InkDropDelegate,
private:
// An instance of ScopedTargetHandler allowing |this| to handle events.
- scoped_ptr<ui::ScopedTargetHandler> target_handler_;
+ std::unique_ptr<ui::ScopedTargetHandler> target_handler_;
// Parent InkDropHost (typically a View) that hosts the ink ripple animations.
InkDropHost* ink_drop_host_;
@@ -57,7 +59,7 @@ class VIEWS_EXPORT ButtonInkDropDelegate : public InkDropDelegate,
gfx::Point last_ink_drop_location_;
// Animation controller for the ink drop ripple effect.
- scoped_ptr<InkDropAnimationController> ink_drop_animation_controller_;
+ std::unique_ptr<InkDrop> ink_drop_;
DISALLOW_COPY_AND_ASSIGN(ButtonInkDropDelegate);
};
diff --git a/chromium/ui/views/animation/flood_fill_ink_drop_animation.cc b/chromium/ui/views/animation/flood_fill_ink_drop_ripple.cc
index 6e177aaff37..f779066bf3a 100644
--- a/chromium/ui/views/animation/flood_fill_ink_drop_animation.cc
+++ b/chromium/ui/views/animation/flood_fill_ink_drop_ripple.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/animation/flood_fill_ink_drop_animation.h"
+#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include <algorithm>
@@ -96,9 +96,9 @@ int kAnimationDurationInMs[] = {
// Returns the InkDropState sub animation duration for the given |state|.
base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
return base::TimeDelta::FromMilliseconds(
- (views::InkDropAnimation::UseFastAnimations()
+ (views::InkDropRipple::UseFastAnimations()
? 1
- : views::InkDropAnimation::kSlowAnimationDurationFactor) *
+ : views::InkDropRipple::kSlowAnimationDurationFactor) *
kAnimationDurationInMs[state]);
}
@@ -106,10 +106,9 @@ base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
namespace views {
-FloodFillInkDropAnimation::FloodFillInkDropAnimation(
- const gfx::Rect& clip_bounds,
- const gfx::Point& center_point,
- SkColor color)
+FloodFillInkDropRipple::FloodFillInkDropRipple(const gfx::Rect& clip_bounds,
+ const gfx::Point& center_point,
+ SkColor color)
: clip_bounds_(clip_bounds),
center_point_(center_point),
root_layer_(ui::LAYER_NOT_DRAWN),
@@ -117,7 +116,7 @@ FloodFillInkDropAnimation::FloodFillInkDropAnimation(
color,
std::max(clip_bounds_.width(), clip_bounds_.height()) / 2.f),
ink_drop_state_(InkDropState::HIDDEN) {
- root_layer_.set_name("FloodFillInkDropAnimation:ROOT_LAYER");
+ root_layer_.set_name("FloodFillInkDropRipple:ROOT_LAYER");
root_layer_.SetMasksToBounds(true);
root_layer_.SetBounds(clip_bounds);
@@ -130,34 +129,34 @@ FloodFillInkDropAnimation::FloodFillInkDropAnimation(
painted_layer_.SetVisible(true);
painted_layer_.SetOpacity(1.0);
painted_layer_.SetMasksToBounds(false);
- painted_layer_.set_name("FloodFillInkDropAnimation:PAINTED_LAYER");
+ painted_layer_.set_name("FloodFillInkDropRipple:PAINTED_LAYER");
root_layer_.Add(&painted_layer_);
SetStateToHidden();
}
-FloodFillInkDropAnimation::~FloodFillInkDropAnimation() {
+FloodFillInkDropRipple::~FloodFillInkDropRipple() {
// Explicitly aborting all the animations ensures all callbacks are invoked
// while this instance still exists.
AbortAllAnimations();
}
-void FloodFillInkDropAnimation::SnapToActivated() {
- InkDropAnimation::SnapToActivated();
+void FloodFillInkDropRipple::SnapToActivated() {
+ InkDropRipple::SnapToActivated();
SetOpacity(kVisibleOpacity);
painted_layer_.SetTransform(GetMaxSizeTargetTransform());
}
-ui::Layer* FloodFillInkDropAnimation::GetRootLayer() {
+ui::Layer* FloodFillInkDropRipple::GetRootLayer() {
return &root_layer_;
}
-bool FloodFillInkDropAnimation::IsVisible() const {
+bool FloodFillInkDropRipple::IsVisible() const {
return root_layer_.visible();
}
-void FloodFillInkDropAnimation::AnimateStateChange(
+void FloodFillInkDropRipple::AnimateStateChange(
InkDropState old_ink_drop_state,
InkDropState new_ink_drop_state,
ui::LayerAnimationObserver* animation_observer) {
@@ -245,18 +244,18 @@ void FloodFillInkDropAnimation::AnimateStateChange(
}
}
-void FloodFillInkDropAnimation::SetStateToHidden() {
+void FloodFillInkDropRipple::SetStateToHidden() {
painted_layer_.SetTransform(CalculateTransform(kMinRadius));
- root_layer_.SetOpacity(InkDropAnimation::kHiddenOpacity);
+ root_layer_.SetOpacity(InkDropRipple::kHiddenOpacity);
root_layer_.SetVisible(false);
}
-void FloodFillInkDropAnimation::AbortAllAnimations() {
+void FloodFillInkDropRipple::AbortAllAnimations() {
root_layer_.GetAnimator()->AbortAllAnimations();
painted_layer_.GetAnimator()->AbortAllAnimations();
}
-void FloodFillInkDropAnimation::AnimateToTransform(
+void FloodFillInkDropRipple::AnimateToTransform(
const gfx::Transform& transform,
base::TimeDelta duration,
ui::LayerAnimator::PreemptionStrategy preemption_strategy,
@@ -277,11 +276,11 @@ void FloodFillInkDropAnimation::AnimateToTransform(
animator->StartAnimation(sequence);
}
-void FloodFillInkDropAnimation::SetOpacity(float opacity) {
+void FloodFillInkDropRipple::SetOpacity(float opacity) {
root_layer_.SetOpacity(opacity);
}
-void FloodFillInkDropAnimation::AnimateToOpacity(
+void FloodFillInkDropRipple::AnimateToOpacity(
float opacity,
base::TimeDelta duration,
ui::LayerAnimator::PreemptionStrategy preemption_strategy,
@@ -302,7 +301,7 @@ void FloodFillInkDropAnimation::AnimateToOpacity(
animator->StartAnimation(animation_sequence);
}
-gfx::Transform FloodFillInkDropAnimation::CalculateTransform(
+gfx::Transform FloodFillInkDropRipple::CalculateTransform(
float target_radius) const {
const float target_scale = target_radius / circle_layer_delegate_.radius();
const gfx::Point drawn_center_point =
@@ -317,7 +316,7 @@ gfx::Transform FloodFillInkDropAnimation::CalculateTransform(
return transform;
}
-gfx::Transform FloodFillInkDropAnimation::GetMaxSizeTargetTransform() const {
+gfx::Transform FloodFillInkDropRipple::GetMaxSizeTargetTransform() const {
// TODO(estade): get rid of this 2, but make the fade out start before the
// active/action transform is done.
return CalculateTransform(
diff --git a/chromium/ui/views/animation/flood_fill_ink_drop_animation.h b/chromium/ui/views/animation/flood_fill_ink_drop_ripple.h
index 2ddde9647af..795ffeb8ab1 100644
--- a/chromium/ui/views/animation/flood_fill_ink_drop_animation.h
+++ b/chromium/ui/views/animation/flood_fill_ink_drop_ripple.h
@@ -2,24 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_FLOOD_FILL_INK_DROP_ANIMATION_H_
-#define UI_VIEWS_ANIMATION_FLOOD_FILL_INK_DROP_ANIMATION_H_
+#ifndef UI_VIEWS_ANIMATION_FLOOD_FILL_INK_DROP_RIPPLE_H_
+#define UI_VIEWS_ANIMATION_FLOOD_FILL_INK_DROP_RIPPLE_H_
+#include <memory>
#include <string>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h"
-#include "ui/views/animation/ink_drop_animation.h"
#include "ui/views/animation/ink_drop_painted_layer_delegates.h"
+#include "ui/views/animation/ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/views_export.h"
@@ -31,10 +30,10 @@ namespace views {
class CircleLayerDelegate;
namespace test {
-class FloodFillInkDropAnimationTestApi;
+class FloodFillInkDropRippleTestApi;
} // namespace test
-// An ink drop animation that starts as a small circle and flood fills a
+// An ink drop ripple that starts as a small circle and flood fills a
// rectangle of the given size. The circle is clipped to the rectangles bounds.
//
// The valid InkDropState transitions are defined below:
@@ -47,22 +46,22 @@ class FloodFillInkDropAnimationTestApi;
// {All InkDropStates} => ACTIVATED
// {All InkDropStates} => DEACTIVATED
//
-class VIEWS_EXPORT FloodFillInkDropAnimation : public InkDropAnimation {
+class VIEWS_EXPORT FloodFillInkDropRipple : public InkDropRipple {
public:
- FloodFillInkDropAnimation(const gfx::Rect& clip_bounds,
- const gfx::Point& center_point,
- SkColor color);
- ~FloodFillInkDropAnimation() override;
+ FloodFillInkDropRipple(const gfx::Rect& clip_bounds,
+ const gfx::Point& center_point,
+ SkColor color);
+ ~FloodFillInkDropRipple() override;
- // InkDropAnimation:
+ // InkDropRipple:
void SnapToActivated() override;
ui::Layer* GetRootLayer() override;
bool IsVisible() const override;
private:
- friend class test::FloodFillInkDropAnimationTestApi;
+ friend class test::FloodFillInkDropRippleTestApi;
- // InkDropAnimation:
+ // InkDropRipple:
void AnimateStateChange(InkDropState old_ink_drop_state,
InkDropState new_ink_drop_state,
ui::LayerAnimationObserver* observer) override;
@@ -123,9 +122,9 @@ class VIEWS_EXPORT FloodFillInkDropAnimation : public InkDropAnimation {
// The current ink drop state.
InkDropState ink_drop_state_;
- DISALLOW_COPY_AND_ASSIGN(FloodFillInkDropAnimation);
+ DISALLOW_COPY_AND_ASSIGN(FloodFillInkDropRipple);
};
} // namespace views
-#endif // UI_VIEWS_ANIMATION_FLOOD_FILL_INK_DROP_ANIMATION_H_
+#endif // UI_VIEWS_ANIMATION_FLOOD_FILL_INK_DROP_RIPPLE_H_
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller.h b/chromium/ui/views/animation/ink_drop.h
index ec511e21986..c79828ac567 100644
--- a/chromium/ui/views/animation/ink_drop_animation_controller.h
+++ b/chromium/ui/views/animation/ink_drop.h
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_H_
+#ifndef UI_VIEWS_ANIMATION_INK_DROP_H_
+#define UI_VIEWS_ANIMATION_INK_DROP_H_
+
+#include <memory>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/events/event_handler.h"
@@ -22,10 +23,10 @@ class Layer;
namespace views {
// Pure virtual base class that manages the lifetime and state of an ink drop
-// animation as well as visual hover state feedback.
-class VIEWS_EXPORT InkDropAnimationController {
+// ripple as well as visual hover state feedback.
+class VIEWS_EXPORT InkDrop {
public:
- virtual ~InkDropAnimationController() {}
+ virtual ~InkDrop() {}
// Gets the target state of the ink drop.
virtual InkDropState GetTargetInkDropState() const = 0;
@@ -47,12 +48,12 @@ class VIEWS_EXPORT InkDropAnimationController {
virtual void SetHovered(bool is_hovered) = 0;
protected:
- InkDropAnimationController() {}
+ InkDrop() {}
private:
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationController);
+ DISALLOW_COPY_AND_ASSIGN(InkDrop);
};
} // namespace views
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_H_
+#endif // UI_VIEWS_ANIMATION_INK_DROP_H_
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller_factory.cc b/chromium/ui/views/animation/ink_drop_animation_controller_factory.cc
deleted file mode 100644
index 19bae013b57..00000000000
--- a/chromium/ui/views/animation/ink_drop_animation_controller_factory.cc
+++ /dev/null
@@ -1,74 +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.
-
-#include "ui/views/animation/ink_drop_animation_controller_factory.h"
-
-#include "base/macros.h"
-#include "ui/base/material_design/material_design_controller.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/views/animation/ink_drop_animation_controller.h"
-#include "ui/views/animation/ink_drop_animation_controller_impl.h"
-#include "ui/views/views_export.h"
-
-namespace views {
-
-namespace {
-
-// A stub implementation of an InkDropAnimationController that can be used when
-// material design is not enabled.
-class InkDropAnimationControllerStub
- : public InkDropAnimationController {
- public:
- explicit InkDropAnimationControllerStub();
- ~InkDropAnimationControllerStub() override;
-
- // InkDropAnimationController:
- InkDropState GetTargetInkDropState() const override;
- bool IsVisible() const override;
- void AnimateToState(InkDropState state) override;
- void SnapToActivated() override;
- void SetHovered(bool is_hovered) override;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerStub);
-};
-
-InkDropAnimationControllerStub::InkDropAnimationControllerStub() {}
-
-InkDropAnimationControllerStub::~InkDropAnimationControllerStub() {}
-
-InkDropState InkDropAnimationControllerStub::GetTargetInkDropState() const {
- return InkDropState::HIDDEN;
-}
-
-bool InkDropAnimationControllerStub::IsVisible() const {
- return false;
-}
-
-void InkDropAnimationControllerStub::AnimateToState(InkDropState state) {}
-
-void InkDropAnimationControllerStub::SnapToActivated() {}
-
-void InkDropAnimationControllerStub::SetHovered(bool is_hovered) {}
-
-} // namespace
-
-InkDropAnimationControllerFactory::InkDropAnimationControllerFactory() {}
-
-InkDropAnimationControllerFactory::~InkDropAnimationControllerFactory() {}
-
-scoped_ptr<InkDropAnimationController>
-InkDropAnimationControllerFactory::CreateInkDropAnimationController(
- InkDropHost* ink_drop_host) {
- if (ui::MaterialDesignController::IsModeMaterial()) {
- return scoped_ptr<InkDropAnimationController>(
- new InkDropAnimationControllerImpl(ink_drop_host));
- }
-
- return scoped_ptr<InkDropAnimationController>(
- new InkDropAnimationControllerStub());
-}
-
-} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller_factory.h b/chromium/ui/views/animation/ink_drop_animation_controller_factory.h
deleted file mode 100644
index 839631460f7..00000000000
--- a/chromium/ui/views/animation/ink_drop_animation_controller_factory.h
+++ /dev/null
@@ -1,36 +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 UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_FACTORY_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_FACTORY_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/views/views_export.h"
-
-namespace views {
-class InkDropAnimationController;
-class InkDropHost;
-
-// A factory to create InkDropAnimationController. A different
-// InkDropAnimationController type will be created based on whether or not
-// material design is enabled.
-class VIEWS_EXPORT InkDropAnimationControllerFactory {
- public:
- // Creates a new InkDropAnimationController that will add/remove an
- // InkDropAnimation's ui::Layer to/from the |ink_drop_host| when the animation
- // is active/inactive.
- static scoped_ptr<InkDropAnimationController>
- CreateInkDropAnimationController(InkDropHost* ink_drop_host);
-
- private:
- InkDropAnimationControllerFactory();
- ~InkDropAnimationControllerFactory();
-
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerFactory);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_FACTORY_H_
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller_factory_unittest.cc b/chromium/ui/views/animation/ink_drop_animation_controller_factory_unittest.cc
deleted file mode 100644
index c75b2c23d7b..00000000000
--- a/chromium/ui/views/animation/ink_drop_animation_controller_factory_unittest.cc
+++ /dev/null
@@ -1,171 +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.
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/test/test_mock_time_task_runner.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/timer/timer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/material_design/material_design_controller.h"
-#include "ui/base/test/material_design_controller_test_api.h"
-#include "ui/compositor/scoped_animation_duration_scale_mode.h"
-#include "ui/views/animation/ink_drop_animation_controller.h"
-#include "ui/views/animation/ink_drop_animation_controller_factory.h"
-#include "ui/views/animation/ink_drop_animation_controller_impl.h"
-#include "ui/views/animation/ink_drop_host.h"
-#include "ui/views/animation/ink_drop_state.h"
-#include "ui/views/animation/test/test_ink_drop_host.h"
-
-namespace views {
-
-class InkDropAnimationControllerFactoryTest
- : public testing::TestWithParam<
- testing::tuple<ui::MaterialDesignController::Mode>> {
- public:
- InkDropAnimationControllerFactoryTest();
- ~InkDropAnimationControllerFactoryTest();
-
- protected:
- // A dummy InkDropHost required to create an InkDropAnimationController.
- TestInkDropHost test_ink_drop_host_;
-
- // The InkDropAnimationController returned by the
- // InkDropAnimationControllerFactory test target.
- scoped_ptr<InkDropAnimationController> ink_drop_animation_controller_;
-
- private:
- // Extracts and returns the material design mode from the test parameters.
- ui::MaterialDesignController::Mode GetMaterialMode() const;
-
- scoped_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_;
-
- // Required by base::Timer's.
- scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerFactoryTest);
-};
-
-InkDropAnimationControllerFactoryTest::InkDropAnimationControllerFactoryTest()
- : ink_drop_animation_controller_(nullptr) {
- // Any call by a previous test to MaterialDesignController::GetMode() will
- // initialize and cache the mode. This ensures that these tests will run from
- // a non-initialized state.
- ui::test::MaterialDesignControllerTestAPI::UninitializeMode();
- ui::test::MaterialDesignControllerTestAPI::SetMode(GetMaterialMode());
- ink_drop_animation_controller_.reset(
- InkDropAnimationControllerFactory::CreateInkDropAnimationController(
- &test_ink_drop_host_)
- .release());
-
- zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
- ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
-
- switch (GetMaterialMode()) {
- case ui::MaterialDesignController::NON_MATERIAL:
- break;
- case ui::MaterialDesignController::MATERIAL_NORMAL:
- case ui::MaterialDesignController::MATERIAL_HYBRID:
- // The Timer's used by the InkDropAnimationControllerImpl class require a
- // base::ThreadTaskRunnerHandle instance.
- scoped_refptr<base::TestMockTimeTaskRunner> task_runner(
- new base::TestMockTimeTaskRunner);
- thread_task_runner_handle_.reset(
- new base::ThreadTaskRunnerHandle(task_runner));
- break;
- }
-}
-
-InkDropAnimationControllerFactoryTest::
- ~InkDropAnimationControllerFactoryTest() {
- ui::test::MaterialDesignControllerTestAPI::UninitializeMode();
-}
-
-ui::MaterialDesignController::Mode
-InkDropAnimationControllerFactoryTest::GetMaterialMode() const {
- return testing::get<0>(GetParam());
-}
-
-// Note: First argument is optional and intentionally left blank.
-// (it's a prefix for the generated test cases)
-INSTANTIATE_TEST_CASE_P(
- ,
- InkDropAnimationControllerFactoryTest,
- testing::Values(ui::MaterialDesignController::NON_MATERIAL,
- ui::MaterialDesignController::MATERIAL_NORMAL,
- ui::MaterialDesignController::MATERIAL_HYBRID));
-
-TEST_P(InkDropAnimationControllerFactoryTest,
- VerifyInkDropLayersRemovedAfterDestructionWhenRippleIsActive) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_.reset();
- EXPECT_EQ(0, test_ink_drop_host_.num_ink_drop_layers());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest,
- VerifyInkDropLayersRemovedAfterDestructionWhenHoverIsActive) {
- test_ink_drop_host_.set_should_show_hover(true);
- ink_drop_animation_controller_->SetHovered(true);
- ink_drop_animation_controller_.reset();
- EXPECT_EQ(0, test_ink_drop_host_.num_ink_drop_layers());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, StateIsHiddenInitially) {
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, TypicalQuickAction) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(
- InkDropState::ACTION_TRIGGERED);
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, CancelQuickAction) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(InkDropState::HIDDEN);
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, TypicalSlowAction) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(
- InkDropState::ALTERNATE_ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(
- InkDropState::ALTERNATE_ACTION_TRIGGERED);
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, CancelSlowAction) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(
- InkDropState::ALTERNATE_ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(InkDropState::HIDDEN);
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, TypicalQuickActivated) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTIVATED);
- ink_drop_animation_controller_->AnimateToState(InkDropState::DEACTIVATED);
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-TEST_P(InkDropAnimationControllerFactoryTest, TypicalSlowActivated) {
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(
- InkDropState::ALTERNATE_ACTION_PENDING);
- ink_drop_animation_controller_->AnimateToState(InkDropState::ACTIVATED);
- ink_drop_animation_controller_->AnimateToState(InkDropState::DEACTIVATED);
- EXPECT_EQ(InkDropState::HIDDEN,
- ink_drop_animation_controller_->GetTargetInkDropState());
-}
-
-} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller_impl.cc b/chromium/ui/views/animation/ink_drop_animation_controller_impl.cc
deleted file mode 100644
index 62e953ba606..00000000000
--- a/chromium/ui/views/animation/ink_drop_animation_controller_impl.cc
+++ /dev/null
@@ -1,259 +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.
-
-#include "ui/views/animation/ink_drop_animation_controller_impl.h"
-
-#include "base/auto_reset.h"
-#include "base/timer/timer.h"
-#include "ui/compositor/layer.h"
-#include "ui/views/animation/ink_drop_host.h"
-#include "ui/views/animation/ink_drop_hover.h"
-#include "ui/views/animation/square_ink_drop_animation.h"
-
-namespace views {
-
-namespace {
-
-// The duration, in milliseconds, of the hover state fade in animation when it
-// is triggered by user input.
-const int kHoverFadeInFromUserInputDurationInMs = 250;
-
-// The duration, in milliseconds, of the hover state fade out animation when it
-// is triggered by user input.
-const int kHoverFadeOutFromUserInputDurationInMs = 250;
-
-// The duration, in milliseconds, of the hover state fade in animation when it
-// is triggered by an ink drop ripple animation ending.
-const int kHoverFadeInAfterAnimationDurationInMs = 250;
-
-// The duration, in milliseconds, of the hover state fade out animation when it
-// is triggered by an ink drop ripple animation starting.
-const int kHoverFadeOutBeforeAnimationDurationInMs = 120;
-
-// The amount of time in milliseconds that |hover_| should delay after a ripple
-// animation before fading in.
-const int kHoverFadeInAfterAnimationDelayInMs = 1000;
-
-// Returns true if an ink drop with the given |ink_drop_state| should
-// automatically transition to the InkDropState::HIDDEN state.
-bool ShouldAnimateToHidden(InkDropState ink_drop_state) {
- switch (ink_drop_state) {
- case views::InkDropState::ACTION_TRIGGERED:
- case views::InkDropState::ALTERNATE_ACTION_TRIGGERED:
- case views::InkDropState::DEACTIVATED:
- return true;
- default:
- return false;
- }
-}
-
-} // namespace
-
-InkDropAnimationControllerImpl::InkDropAnimationControllerImpl(
- InkDropHost* ink_drop_host)
- : ink_drop_host_(ink_drop_host),
- root_layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)),
- root_layer_added_to_host_(false),
- is_hovered_(false),
- hover_after_animation_timer_(nullptr) {
- root_layer_->set_name("InkDropAnimationControllerImpl:RootLayer");
-}
-
-InkDropAnimationControllerImpl::~InkDropAnimationControllerImpl() {
- // Explicitly destroy the InkDropAnimation so that this still exists if
- // views::InkDropAnimationObserver methods are called on this.
- DestroyInkDropAnimation();
- DestroyInkDropHover();
-}
-
-InkDropState InkDropAnimationControllerImpl::GetTargetInkDropState() const {
- if (!ink_drop_animation_)
- return InkDropState::HIDDEN;
- return ink_drop_animation_->target_ink_drop_state();
-}
-
-bool InkDropAnimationControllerImpl::IsVisible() const {
- return ink_drop_animation_ && ink_drop_animation_->IsVisible();
-}
-
-void InkDropAnimationControllerImpl::AnimateToState(
- InkDropState ink_drop_state) {
- DestroyHiddenTargetedAnimations();
- if (!ink_drop_animation_)
- CreateInkDropAnimation();
-
- if (ink_drop_state != views::InkDropState::HIDDEN) {
- SetHoveredInternal(false, base::TimeDelta::FromMilliseconds(
- kHoverFadeOutBeforeAnimationDurationInMs),
- true);
- }
-
- ink_drop_animation_->AnimateToState(ink_drop_state);
-}
-
-void InkDropAnimationControllerImpl::SnapToActivated() {
- DestroyHiddenTargetedAnimations();
- if (!ink_drop_animation_)
- CreateInkDropAnimation();
-
- SetHoveredInternal(false, base::TimeDelta(), false);
-
- ink_drop_animation_->SnapToActivated();
-}
-
-void InkDropAnimationControllerImpl::SetHovered(bool is_hovered) {
- is_hovered_ = is_hovered;
- SetHoveredInternal(is_hovered,
- is_hovered ? base::TimeDelta::FromMilliseconds(
- kHoverFadeInFromUserInputDurationInMs)
- : base::TimeDelta::FromMilliseconds(
- kHoverFadeOutFromUserInputDurationInMs),
- false);
-}
-
-void InkDropAnimationControllerImpl::DestroyHiddenTargetedAnimations() {
- if (ink_drop_animation_ &&
- (ink_drop_animation_->target_ink_drop_state() == InkDropState::HIDDEN ||
- ShouldAnimateToHidden(ink_drop_animation_->target_ink_drop_state()))) {
- DestroyInkDropAnimation();
- }
-}
-
-void InkDropAnimationControllerImpl::CreateInkDropAnimation() {
- DestroyInkDropAnimation();
- ink_drop_animation_ = ink_drop_host_->CreateInkDropAnimation();
- ink_drop_animation_->set_observer(this);
- root_layer_->Add(ink_drop_animation_->GetRootLayer());
- AddRootLayerToHostIfNeeded();
-}
-
-void InkDropAnimationControllerImpl::DestroyInkDropAnimation() {
- if (!ink_drop_animation_)
- return;
- root_layer_->Remove(ink_drop_animation_->GetRootLayer());
- ink_drop_animation_.reset();
- RemoveRootLayerFromHostIfNeeded();
-}
-
-void InkDropAnimationControllerImpl::CreateInkDropHover() {
- DestroyInkDropHover();
-
- hover_ = ink_drop_host_->CreateInkDropHover();
- if (!hover_)
- return;
- hover_->set_observer(this);
- root_layer_->Add(hover_->layer());
- AddRootLayerToHostIfNeeded();
-}
-
-void InkDropAnimationControllerImpl::DestroyInkDropHover() {
- if (!hover_)
- return;
- root_layer_->Remove(hover_->layer());
- hover_->set_observer(nullptr);
- hover_.reset();
- RemoveRootLayerFromHostIfNeeded();
-}
-
-void InkDropAnimationControllerImpl::AddRootLayerToHostIfNeeded() {
- DCHECK(hover_ || ink_drop_animation_);
- if (!root_layer_added_to_host_) {
- root_layer_added_to_host_ = true;
- ink_drop_host_->AddInkDropLayer(root_layer_.get());
- }
-}
-
-void InkDropAnimationControllerImpl::RemoveRootLayerFromHostIfNeeded() {
- if (root_layer_added_to_host_ && !hover_ && !ink_drop_animation_) {
- root_layer_added_to_host_ = false;
- ink_drop_host_->RemoveInkDropLayer(root_layer_.get());
- }
-}
-
-bool InkDropAnimationControllerImpl::IsHoverFadingInOrVisible() const {
- return hover_ && hover_->IsFadingInOrVisible();
-}
-
-// -----------------------------------------------------------------------------
-// views::InkDropAnimationObserver:
-
-void InkDropAnimationControllerImpl::AnimationStarted(
- InkDropState ink_drop_state) {}
-
-void InkDropAnimationControllerImpl::AnimationEnded(
- InkDropState ink_drop_state,
- InkDropAnimationEndedReason reason) {
- if (reason != InkDropAnimationEndedReason::SUCCESS)
- return;
- if (ShouldAnimateToHidden(ink_drop_state)) {
- ink_drop_animation_->AnimateToState(views::InkDropState::HIDDEN);
- } else if (ink_drop_state == views::InkDropState::HIDDEN) {
- if (is_hovered_)
- StartHoverAfterAnimationTimer();
- // TODO(bruthig): Investigate whether creating and destroying
- // InkDropAnimations is expensive and consider creating an
- // InkDropAnimationPool. See www.crbug.com/522175.
- DestroyInkDropAnimation();
- }
-}
-
-// -----------------------------------------------------------------------------
-// views::InkDropHoverObserver:
-
-void InkDropAnimationControllerImpl::AnimationStarted(
- InkDropHover::AnimationType animation_type) {}
-
-void InkDropAnimationControllerImpl::AnimationEnded(
- InkDropHover::AnimationType animation_type,
- InkDropAnimationEndedReason reason) {
- if (animation_type == InkDropHover::FADE_OUT &&
- reason == InkDropAnimationEndedReason::SUCCESS) {
- DestroyInkDropHover();
- }
-}
-
-void InkDropAnimationControllerImpl::SetHoveredInternal(
- bool is_hovered,
- base::TimeDelta animation_duration,
- bool explode) {
- StopHoverAfterAnimationTimer();
-
- if (IsHoverFadingInOrVisible() == is_hovered)
- return;
-
- if (is_hovered) {
- CreateInkDropHover();
- if (hover_ && !IsVisible())
- hover_->FadeIn(animation_duration);
- } else {
- hover_->FadeOut(animation_duration, explode);
- }
-}
-
-void InkDropAnimationControllerImpl::StartHoverAfterAnimationTimer() {
- StopHoverAfterAnimationTimer();
-
- if (!hover_after_animation_timer_)
- hover_after_animation_timer_.reset(new base::OneShotTimer);
-
- hover_after_animation_timer_->Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kHoverFadeInAfterAnimationDelayInMs),
- base::Bind(&InkDropAnimationControllerImpl::HoverAfterAnimationTimerFired,
- base::Unretained(this)));
-}
-
-void InkDropAnimationControllerImpl::StopHoverAfterAnimationTimer() {
- if (hover_after_animation_timer_)
- hover_after_animation_timer_.reset();
-}
-
-void InkDropAnimationControllerImpl::HoverAfterAnimationTimerFired() {
- SetHoveredInternal(true, base::TimeDelta::FromMilliseconds(
- kHoverFadeInAfterAnimationDurationInMs),
- true);
- hover_after_animation_timer_.reset();
-}
-
-} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_animation_ended_reason.h b/chromium/ui/views/animation/ink_drop_animation_ended_reason.h
index fc2f359cef2..0761f102e04 100644
--- a/chromium/ui/views/animation/ink_drop_animation_ended_reason.h
+++ b/chromium/ui/views/animation/ink_drop_animation_ended_reason.h
@@ -5,8 +5,11 @@
#ifndef UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_ENDED_REASON_H_
#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_ENDED_REASON_H_
+#include <iosfwd>
#include <string>
+#include "ui/views/views_export.h"
+
namespace views {
// Enumeration of the different reasons why an ink drop animation has finished.
@@ -18,7 +21,12 @@ enum class InkDropAnimationEndedReason {
};
// Returns a human readable string for |reason|. Useful for logging.
-std::string ToString(InkDropAnimationEndedReason reason);
+VIEWS_EXPORT std::string ToString(InkDropAnimationEndedReason reason);
+
+// This is declared here for use in gtest-based unit tests but is defined in
+// the views_test_support target. Depend on that to use this in your unit test.
+// This should not be used in production code - call ToString() instead.
+void PrintTo(InkDropAnimationEndedReason reason, ::std::ostream* os);
} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_animation_unittest.cc b/chromium/ui/views/animation/ink_drop_animation_unittest.cc
deleted file mode 100644
index e1ff62c456c..00000000000
--- a/chromium/ui/views/animation/ink_drop_animation_unittest.cc
+++ /dev/null
@@ -1,354 +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 UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_UNITTEST_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_UNITTEST_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/views/animation/flood_fill_ink_drop_animation.h"
-#include "ui/views/animation/ink_drop_animation.h"
-#include "ui/views/animation/ink_drop_animation_observer.h"
-#include "ui/views/animation/ink_drop_state.h"
-#include "ui/views/animation/square_ink_drop_animation.h"
-#include "ui/views/animation/test/flood_fill_ink_drop_animation_test_api.h"
-#include "ui/views/animation/test/ink_drop_animation_test_api.h"
-#include "ui/views/animation/test/square_ink_drop_animation_test_api.h"
-#include "ui/views/animation/test/test_ink_drop_animation_observer.h"
-
-namespace views {
-namespace test {
-
-// Represents all the derivatives of the InkDropAnimation class. To be used with
-// the InkDropAnimationTest fixture to test all derviatives.
-enum InkDropAnimationTestTypes {
- SQUARE_INK_DROP_ANIMATION,
- FLOOD_FILL_INK_DROP_ANIMATION
-};
-
-// Test fixture for all InkDropAnimation class derivatives.
-//
-// To add a new derivative:
-// 1. Add a value to the InkDropAnimationTestTypes enum.
-// 2. Implement set up and tear down code for the new enum value in
-// InkDropAnimationTest() and
-// ~InkDropAnimationTest().
-// 3. Add the new enum value to the INSTANTIATE_TEST_CASE_P) Values list.
-class InkDropAnimationTest
- : public testing::TestWithParam<InkDropAnimationTestTypes> {
- public:
- InkDropAnimationTest();
- ~InkDropAnimationTest() override;
-
- protected:
- TestInkDropAnimationObserver observer_;
-
- scoped_ptr<InkDropAnimation> ink_drop_animation_;
-
- scoped_ptr<InkDropAnimationTestApi> test_api_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationTest);
-};
-
-InkDropAnimationTest::InkDropAnimationTest() {
- switch (GetParam()) {
- case SQUARE_INK_DROP_ANIMATION: {
- SquareInkDropAnimation* square_ink_drop_animation =
- new SquareInkDropAnimation(gfx::Size(10, 10), 2, gfx::Size(8, 8), 1,
- gfx::Point(), SK_ColorBLACK);
- ink_drop_animation_.reset(square_ink_drop_animation);
- test_api_.reset(
- new SquareInkDropAnimationTestApi(square_ink_drop_animation));
- break;
- }
- case FLOOD_FILL_INK_DROP_ANIMATION: {
- FloodFillInkDropAnimation* flood_fill_ink_drop_animation =
- new FloodFillInkDropAnimation(gfx::Rect(0, 0, 10, 10), gfx::Point(),
- SK_ColorBLACK);
- ink_drop_animation_.reset(flood_fill_ink_drop_animation);
- test_api_.reset(
- new FloodFillInkDropAnimationTestApi(flood_fill_ink_drop_animation));
- break;
- }
- }
- ink_drop_animation_->set_observer(&observer_);
- observer_.set_ink_drop_animation(ink_drop_animation_.get());
- test_api_->SetDisableAnimationTimers(true);
-}
-
-InkDropAnimationTest::~InkDropAnimationTest() {}
-
-// Note: First argument is optional and intentionally left blank.
-// (it's a prefix for the generated test cases)
-INSTANTIATE_TEST_CASE_P(,
- InkDropAnimationTest,
- testing::Values(SQUARE_INK_DROP_ANIMATION,
- FLOOD_FILL_INK_DROP_ANIMATION));
-
-TEST_P(InkDropAnimationTest, InitialStateAfterConstruction) {
- EXPECT_EQ(views::InkDropState::HIDDEN,
- ink_drop_animation_->target_ink_drop_state());
-}
-
-// Verify no animations are used when animating from HIDDEN to HIDDEN.
-TEST_P(InkDropAnimationTest, AnimateToHiddenFromInvisibleState) {
- EXPECT_EQ(InkDropState::HIDDEN, ink_drop_animation_->target_ink_drop_state());
-
- ink_drop_animation_->AnimateToState(InkDropState::HIDDEN);
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
- EXPECT_FALSE(ink_drop_animation_->IsVisible());
-}
-
-TEST_P(InkDropAnimationTest, AnimateToHiddenFromVisibleState) {
- ink_drop_animation_->AnimateToState(InkDropState::ACTION_PENDING);
- test_api_->CompleteAnimations();
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
-
- EXPECT_NE(InkDropState::HIDDEN, ink_drop_animation_->target_ink_drop_state());
-
- ink_drop_animation_->AnimateToState(InkDropState::HIDDEN);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(3, observer_.last_animation_started_ordinal());
- EXPECT_EQ(4, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
-}
-
-TEST_P(InkDropAnimationTest, ActionPendingOpacity) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(InkDropAnimation::kVisibleOpacity, test_api_->GetCurrentOpacity());
-}
-
-TEST_P(InkDropAnimationTest, QuickActionOpacity) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_TRIGGERED);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
-}
-
-TEST_P(InkDropAnimationTest, SlowActionPendingOpacity) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(
- views::InkDropState::ALTERNATE_ACTION_PENDING);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(InkDropAnimation::kVisibleOpacity, test_api_->GetCurrentOpacity());
-}
-
-TEST_P(InkDropAnimationTest, SlowActionOpacity) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(
- views::InkDropState::ALTERNATE_ACTION_PENDING);
- ink_drop_animation_->AnimateToState(
- views::InkDropState::ALTERNATE_ACTION_TRIGGERED);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
-}
-
-TEST_P(InkDropAnimationTest, ActivatedOpacity) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTIVATED);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(InkDropAnimation::kVisibleOpacity, test_api_->GetCurrentOpacity());
-}
-
-TEST_P(InkDropAnimationTest, DeactivatedOpacity) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTIVATED);
- ink_drop_animation_->AnimateToState(views::InkDropState::DEACTIVATED);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
-}
-
-// Verify animations are aborted during deletion and the
-// InkDropAnimationObservers are notified.
-TEST_P(InkDropAnimationTest, AnimationsAbortedDuringDeletion) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_.reset();
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(views::InkDropState::ACTION_PENDING,
- observer_.last_animation_ended_context());
- EXPECT_EQ(InkDropAnimationEndedReason::PRE_EMPTED,
- observer_.last_animation_ended_reason());
-}
-
-TEST_P(InkDropAnimationTest, VerifyObserversAreNotified) {
- ink_drop_animation_->AnimateToState(InkDropState::ACTION_PENDING);
-
- EXPECT_TRUE(test_api_->HasActiveAnimations());
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_TRUE(observer_.AnimationHasNotEnded());
- EXPECT_EQ(InkDropState::ACTION_PENDING,
- observer_.last_animation_started_context());
-
- test_api_->CompleteAnimations();
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropState::ACTION_PENDING,
- observer_.last_animation_ended_context());
-}
-
-TEST_P(InkDropAnimationTest, VerifyObserversAreNotifiedOfSuccessfulAnimations) {
- ink_drop_animation_->AnimateToState(InkDropState::ACTION_PENDING);
- test_api_->CompleteAnimations();
-
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropAnimationEndedReason::SUCCESS,
- observer_.last_animation_ended_reason());
-}
-
-TEST_P(InkDropAnimationTest, VerifyObserversAreNotifiedOfPreemptedAnimations) {
- ink_drop_animation_->AnimateToState(InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(InkDropState::ALTERNATE_ACTION_PENDING);
-
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropAnimationEndedReason::PRE_EMPTED,
- observer_.last_animation_ended_reason());
-}
-
-TEST_P(InkDropAnimationTest, InkDropStatesPersistWhenCallingAnimateToState) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTIVATED);
- EXPECT_EQ(views::InkDropState::ACTIVATED,
- ink_drop_animation_->target_ink_drop_state());
-}
-
-TEST_P(InkDropAnimationTest, HideImmediatelyWithoutActiveAnimations) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- test_api_->CompleteAnimations();
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_NE(InkDropState::HIDDEN, ink_drop_animation_->target_ink_drop_state());
-
- ink_drop_animation_->HideImmediately();
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_EQ(views::InkDropState::HIDDEN,
- ink_drop_animation_->target_ink_drop_state());
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
-
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
- EXPECT_FALSE(ink_drop_animation_->IsVisible());
-}
-
-// Verifies all active animations are aborted and the InkDropState is set to
-// HIDDEN after invoking HideImmediately().
-TEST_P(InkDropAnimationTest, HideImmediatelyWithActiveAnimations) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- EXPECT_TRUE(test_api_->HasActiveAnimations());
- EXPECT_NE(InkDropState::HIDDEN, ink_drop_animation_->target_ink_drop_state());
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
-
- ink_drop_animation_->HideImmediately();
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_EQ(views::InkDropState::HIDDEN,
- ink_drop_animation_->target_ink_drop_state());
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropState::ACTION_PENDING,
- observer_.last_animation_ended_context());
- EXPECT_EQ(InkDropAnimationEndedReason::PRE_EMPTED,
- observer_.last_animation_ended_reason());
-
- EXPECT_EQ(InkDropAnimation::kHiddenOpacity, test_api_->GetCurrentOpacity());
- EXPECT_FALSE(ink_drop_animation_->IsVisible());
-}
-
-TEST_P(InkDropAnimationTest, SnapToActivatedWithoutActiveAnimations) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- test_api_->CompleteAnimations();
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_NE(InkDropState::ACTIVATED,
- ink_drop_animation_->target_ink_drop_state());
-
- ink_drop_animation_->SnapToActivated();
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_EQ(views::InkDropState::ACTIVATED,
- ink_drop_animation_->target_ink_drop_state());
- EXPECT_EQ(3, observer_.last_animation_started_ordinal());
- EXPECT_EQ(4, observer_.last_animation_ended_ordinal());
-
- EXPECT_EQ(InkDropAnimation::kVisibleOpacity, test_api_->GetCurrentOpacity());
- EXPECT_TRUE(ink_drop_animation_->IsVisible());
-}
-
-// Verifies all active animations are aborted and the InkDropState is set to
-// ACTIVATED after invoking SnapToActivated().
-TEST_P(InkDropAnimationTest, SnapToActivatedWithActiveAnimations) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- EXPECT_TRUE(test_api_->HasActiveAnimations());
- EXPECT_NE(InkDropState::ACTIVATED,
- ink_drop_animation_->target_ink_drop_state());
- EXPECT_EQ(1, observer_.last_animation_started_ordinal());
-
- ink_drop_animation_->SnapToActivated();
-
- EXPECT_FALSE(test_api_->HasActiveAnimations());
- EXPECT_EQ(views::InkDropState::ACTIVATED,
- ink_drop_animation_->target_ink_drop_state());
- EXPECT_EQ(3, observer_.last_animation_started_ordinal());
- EXPECT_EQ(4, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(InkDropState::ACTIVATED, observer_.last_animation_ended_context());
- EXPECT_EQ(InkDropAnimationEndedReason::SUCCESS,
- observer_.last_animation_ended_reason());
-
- EXPECT_EQ(InkDropAnimation::kVisibleOpacity, test_api_->GetCurrentOpacity());
- EXPECT_TRUE(ink_drop_animation_->IsVisible());
-}
-
-TEST_P(InkDropAnimationTest, AnimateToVisibleFromHidden) {
- EXPECT_EQ(InkDropState::HIDDEN, ink_drop_animation_->target_ink_drop_state());
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- EXPECT_TRUE(ink_drop_animation_->IsVisible());
-}
-
-// Verifies that the value of InkDropAnimation::target_ink_drop_state() returns
-// the most recent value passed to AnimateToState() when notifying observers
-// that an animation has started within the AnimateToState() function call.
-TEST_P(InkDropAnimationTest, TargetInkDropStateOnAnimationStarted) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(views::InkDropState::HIDDEN);
-
- EXPECT_EQ(3, observer_.last_animation_started_ordinal());
- EXPECT_EQ(views::InkDropState::HIDDEN,
- observer_.target_state_at_last_animation_started());
-}
-
-// Verifies that the value of InkDropAnimation::target_ink_drop_state() returns
-// the most recent value passed to AnimateToState() when notifying observers
-// that an animation has ended within the AnimateToState() function call.
-TEST_P(InkDropAnimationTest, TargetInkDropStateOnAnimationEnded) {
- ink_drop_animation_->AnimateToState(views::InkDropState::ACTION_PENDING);
- ink_drop_animation_->AnimateToState(views::InkDropState::HIDDEN);
-
- EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
- EXPECT_EQ(views::InkDropState::HIDDEN,
- observer_.target_state_at_last_animation_ended());
-}
-
-} // namespace test
-} // namespace views
-
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_UNITTEST_H_
diff --git a/chromium/ui/views/animation/ink_drop_delegate.h b/chromium/ui/views/animation/ink_drop_delegate.h
index 61235241f92..545f5be0e3a 100644
--- a/chromium/ui/views/animation/ink_drop_delegate.h
+++ b/chromium/ui/views/animation/ink_drop_delegate.h
@@ -35,6 +35,9 @@ class VIEWS_EXPORT InkDropDelegate {
// Enables or disables the hover state.
virtual void SetHovered(bool is_hovered) = 0;
+ // Returns the current InkDropState
+ virtual InkDropState GetTargetInkDropState() const = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(InkDropDelegate);
};
diff --git a/chromium/ui/views/animation/ink_drop_factory.cc b/chromium/ui/views/animation/ink_drop_factory.cc
new file mode 100644
index 00000000000..f67f6b68cd1
--- /dev/null
+++ b/chromium/ui/views/animation/ink_drop_factory.cc
@@ -0,0 +1,71 @@
+// 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.
+
+#include "ui/views/animation/ink_drop_factory.h"
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "ui/base/material_design/material_design_controller.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/views/animation/ink_drop.h"
+#include "ui/views/animation/ink_drop_impl.h"
+#include "ui/views/views_export.h"
+
+namespace views {
+
+namespace {
+
+// A stub implementation of an InkDrop that can be used when material design is
+// not enabled.
+class InkDropStub : public InkDrop {
+ public:
+ explicit InkDropStub();
+ ~InkDropStub() override;
+
+ // InkDrop:
+ InkDropState GetTargetInkDropState() const override;
+ bool IsVisible() const override;
+ void AnimateToState(InkDropState state) override;
+ void SnapToActivated() override;
+ void SetHovered(bool is_hovered) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InkDropStub);
+};
+
+InkDropStub::InkDropStub() {}
+
+InkDropStub::~InkDropStub() {}
+
+InkDropState InkDropStub::GetTargetInkDropState() const {
+ return InkDropState::HIDDEN;
+}
+
+bool InkDropStub::IsVisible() const {
+ return false;
+}
+
+void InkDropStub::AnimateToState(InkDropState state) {}
+
+void InkDropStub::SnapToActivated() {}
+
+void InkDropStub::SetHovered(bool is_hovered) {}
+
+} // namespace
+
+InkDropFactory::InkDropFactory() {}
+
+InkDropFactory::~InkDropFactory() {}
+
+std::unique_ptr<InkDrop> InkDropFactory::CreateInkDrop(
+ InkDropHost* ink_drop_host) {
+ if (ui::MaterialDesignController::IsModeMaterial()) {
+ return base::WrapUnique(new InkDropImpl(ink_drop_host));
+ }
+
+ return base::WrapUnique(new InkDropStub());
+}
+
+} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_factory.h b/chromium/ui/views/animation/ink_drop_factory.h
new file mode 100644
index 00000000000..0fc57d82d54
--- /dev/null
+++ b/chromium/ui/views/animation/ink_drop_factory.h
@@ -0,0 +1,34 @@
+// 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_VIEWS_ANIMATION_INK_DROP_FACTORY_H_
+#define UI_VIEWS_ANIMATION_INK_DROP_FACTORY_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "ui/views/views_export.h"
+
+namespace views {
+class InkDrop;
+class InkDropHost;
+
+// A factory to create an InkDrop. A different InkDrop type will be created
+// based on whether or not material design is enabled.
+class VIEWS_EXPORT InkDropFactory {
+ public:
+ // Creates a new InkDrop that will add/remove an InkDropRipple's ui::Layer
+ // to/from the |ink_drop_host| when the animation is active/inactive.
+ static std::unique_ptr<InkDrop> CreateInkDrop(InkDropHost* ink_drop_host);
+
+ private:
+ InkDropFactory();
+ ~InkDropFactory();
+
+ DISALLOW_COPY_AND_ASSIGN(InkDropFactory);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_ANIMATION_INK_DROP_FACTORY_H_
diff --git a/chromium/ui/views/animation/ink_drop_factory_unittest.cc b/chromium/ui/views/animation/ink_drop_factory_unittest.cc
new file mode 100644
index 00000000000..3afc90393e7
--- /dev/null
+++ b/chromium/ui/views/animation/ink_drop_factory_unittest.cc
@@ -0,0 +1,158 @@
+// 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.
+
+#include "ui/views/animation/ink_drop_factory.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/timer/timer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/material_design/material_design_controller.h"
+#include "ui/base/test/material_design_controller_test_api.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/views/animation/ink_drop.h"
+#include "ui/views/animation/ink_drop_host.h"
+#include "ui/views/animation/ink_drop_impl.h"
+#include "ui/views/animation/ink_drop_state.h"
+#include "ui/views/animation/test/test_ink_drop_host.h"
+
+namespace views {
+
+class InkDropFactoryTest
+ : public testing::TestWithParam<
+ testing::tuple<ui::MaterialDesignController::Mode>> {
+ public:
+ InkDropFactoryTest();
+ ~InkDropFactoryTest();
+
+ protected:
+ // A dummy InkDropHost required to create an InkDrop.
+ TestInkDropHost test_ink_drop_host_;
+
+ // The InkDrop returned by the InkDropFactory test target.
+ std::unique_ptr<InkDrop> ink_drop_;
+
+ private:
+ // Extracts and returns the material design mode from the test parameters.
+ ui::MaterialDesignController::Mode GetMaterialMode() const;
+
+ std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_;
+
+ // Required by base::Timer's.
+ std::unique_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
+
+ std::unique_ptr<ui::test::MaterialDesignControllerTestAPI>
+ material_design_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(InkDropFactoryTest);
+};
+
+InkDropFactoryTest::InkDropFactoryTest() : ink_drop_(nullptr) {
+ // Any call by a previous test to MaterialDesignController::GetMode() will
+ // initialize and cache the mode. This ensures that these tests will run from
+ // a non-initialized state.
+ material_design_state_.reset(
+ new ui::test::MaterialDesignControllerTestAPI(GetMaterialMode()));
+ ink_drop_.reset(
+ InkDropFactory::CreateInkDrop(&test_ink_drop_host_).release());
+
+ zero_duration_mode_.reset(new ui::ScopedAnimationDurationScaleMode(
+ ui::ScopedAnimationDurationScaleMode::ZERO_DURATION));
+
+ switch (GetMaterialMode()) {
+ case ui::MaterialDesignController::NON_MATERIAL:
+ break;
+ case ui::MaterialDesignController::MATERIAL_NORMAL:
+ case ui::MaterialDesignController::MATERIAL_HYBRID:
+ // The Timer's used by the InkDropImpl class require a
+ // base::ThreadTaskRunnerHandle instance.
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner(
+ new base::TestMockTimeTaskRunner);
+ thread_task_runner_handle_.reset(
+ new base::ThreadTaskRunnerHandle(task_runner));
+ break;
+ }
+}
+
+InkDropFactoryTest::~InkDropFactoryTest() {
+ material_design_state_.reset();
+}
+
+ui::MaterialDesignController::Mode InkDropFactoryTest::GetMaterialMode() const {
+ return testing::get<0>(GetParam());
+}
+
+// Note: First argument is optional and intentionally left blank.
+// (it's a prefix for the generated test cases)
+INSTANTIATE_TEST_CASE_P(
+ ,
+ InkDropFactoryTest,
+ testing::Values(ui::MaterialDesignController::NON_MATERIAL,
+ ui::MaterialDesignController::MATERIAL_NORMAL,
+ ui::MaterialDesignController::MATERIAL_HYBRID));
+
+TEST_P(InkDropFactoryTest,
+ VerifyInkDropLayersRemovedAfterDestructionWhenRippleIsActive) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_.reset();
+ EXPECT_EQ(0, test_ink_drop_host_.num_ink_drop_layers());
+}
+
+TEST_P(InkDropFactoryTest,
+ VerifyInkDropLayersRemovedAfterDestructionWhenHoverIsActive) {
+ test_ink_drop_host_.set_should_show_hover(true);
+ ink_drop_->SetHovered(true);
+ ink_drop_.reset();
+ EXPECT_EQ(0, test_ink_drop_host_.num_ink_drop_layers());
+}
+
+TEST_P(InkDropFactoryTest, StateIsHiddenInitially) {
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+TEST_P(InkDropFactoryTest, TypicalQuickAction) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ACTION_TRIGGERED);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+TEST_P(InkDropFactoryTest, CancelQuickAction) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::HIDDEN);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+TEST_P(InkDropFactoryTest, TypicalSlowAction) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ALTERNATE_ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ALTERNATE_ACTION_TRIGGERED);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+TEST_P(InkDropFactoryTest, CancelSlowAction) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ALTERNATE_ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::HIDDEN);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+TEST_P(InkDropFactoryTest, TypicalQuickActivated) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ACTIVATED);
+ ink_drop_->AnimateToState(InkDropState::DEACTIVATED);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+TEST_P(InkDropFactoryTest, TypicalSlowActivated) {
+ ink_drop_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ALTERNATE_ACTION_PENDING);
+ ink_drop_->AnimateToState(InkDropState::ACTIVATED);
+ ink_drop_->AnimateToState(InkDropState::DEACTIVATED);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_->GetTargetInkDropState());
+}
+
+} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_host.h b/chromium/ui/views/animation/ink_drop_host.h
index 570f2710b49..aa13504e49a 100644
--- a/chromium/ui/views/animation/ink_drop_host.h
+++ b/chromium/ui/views/animation/ink_drop_host.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_ANIMATION_INK_DROP_HOST_H_
#define UI_VIEWS_ANIMATION_INK_DROP_HOST_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/point.h"
#include "ui/views/views_export.h"
@@ -16,12 +17,12 @@ class Layer;
namespace views {
-class InkDropAnimation;
+class InkDropRipple;
class InkDropHover;
-// Used by the InkDropAnimationController to add and remove the ink drop layers
-// from a host's layer tree. Typically the ink drop layer is added to a View's
-// layer but it can also be added to a View's ancestor layer.
+// Used by the InkDrop to add and remove the ink drop layers from a host's layer
+// tree. Typically the ink drop layer is added to a View's layer but it can also
+// be added to a View's ancestor layer.
//
// Note: Some Views do not own a Layer, but you can use
// View::SetLayer(new ui::Layer(ui::LAYER_NOT_DRAWN)) to force the View to have
@@ -38,10 +39,10 @@ class VIEWS_EXPORT InkDropHost {
virtual void RemoveInkDropLayer(ui::Layer* ink_drop_layer) = 0;
// Creates and returns the effect used for press.
- virtual scoped_ptr<InkDropAnimation> CreateInkDropAnimation() const = 0;
+ virtual std::unique_ptr<InkDropRipple> CreateInkDropRipple() const = 0;
// Creates and returns the effect used for hover.
- virtual scoped_ptr<InkDropHover> CreateInkDropHover() const = 0;
+ virtual std::unique_ptr<InkDropHover> CreateInkDropHover() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(InkDropHost);
diff --git a/chromium/ui/views/animation/ink_drop_host_view.cc b/chromium/ui/views/animation/ink_drop_host_view.cc
index 317645e6118..faf32b07d81 100644
--- a/chromium/ui/views/animation/ink_drop_host_view.cc
+++ b/chromium/ui/views/animation/ink_drop_host_view.cc
@@ -7,7 +7,7 @@
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/views/animation/ink_drop_hover.h"
-#include "ui/views/animation/square_ink_drop_animation.h"
+#include "ui/views/animation/square_ink_drop_ripple.h"
namespace views {
@@ -46,16 +46,16 @@ void InkDropHostView::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
SetPaintToLayer(false);
}
-scoped_ptr<InkDropAnimation> InkDropHostView::CreateInkDropAnimation() const {
- scoped_ptr<InkDropAnimation> animation(new SquareInkDropAnimation(
+std::unique_ptr<InkDropRipple> InkDropHostView::CreateInkDropRipple() const {
+ std::unique_ptr<InkDropRipple> ripple(new SquareInkDropRipple(
CalculateLargeInkDropSize(ink_drop_size_), kInkDropLargeCornerRadius,
ink_drop_size_, kInkDropSmallCornerRadius, GetInkDropCenter(),
GetInkDropBaseColor()));
- return animation;
+ return ripple;
}
-scoped_ptr<InkDropHover> InkDropHostView::CreateInkDropHover() const {
- scoped_ptr<InkDropHover> hover(
+std::unique_ptr<InkDropHover> InkDropHostView::CreateInkDropHover() const {
+ std::unique_ptr<InkDropHover> hover(
new InkDropHover(ink_drop_size_, kInkDropSmallCornerRadius,
GetInkDropCenter(), GetInkDropBaseColor()));
hover->set_explode_size(CalculateLargeInkDropSize(ink_drop_size_));
diff --git a/chromium/ui/views/animation/ink_drop_host_view.h b/chromium/ui/views/animation/ink_drop_host_view.h
index 3a3efa6b6ed..e4ebe6d3b6d 100644
--- a/chromium/ui/views/animation/ink_drop_host_view.h
+++ b/chromium/ui/views/animation/ink_drop_host_view.h
@@ -5,7 +5,8 @@
#ifndef UI_VIEWS_ANIMATION_INK_DROP_HOST_VIEW_H_
#define UI_VIEWS_ANIMATION_INK_DROP_HOST_VIEW_H_
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/animation/ink_drop_host.h"
@@ -13,7 +14,7 @@
namespace views {
-class InkDropAnimation;
+class InkDropRipple;
class InkDropHover;
// A view that provides InkDropHost functionality.
@@ -25,8 +26,8 @@ class VIEWS_EXPORT InkDropHostView : public views::View, public InkDropHost {
// Overridden from views::InkDropHost:
void AddInkDropLayer(ui::Layer* ink_drop_layer) override;
void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override;
- scoped_ptr<InkDropAnimation> CreateInkDropAnimation() const override;
- scoped_ptr<InkDropHover> CreateInkDropHover() const override;
+ std::unique_ptr<InkDropRipple> CreateInkDropRipple() const override;
+ std::unique_ptr<InkDropHover> CreateInkDropHover() const override;
void set_ink_drop_size(const gfx::Size& size) { ink_drop_size_ = size; }
@@ -43,6 +44,6 @@ class VIEWS_EXPORT InkDropHostView : public views::View, public InkDropHost {
DISALLOW_COPY_AND_ASSIGN(InkDropHostView);
};
-}
+} // namespace views
#endif // UI_VIEWS_ANIMATION_INK_DROP_HOST_VIEW_H_
diff --git a/chromium/ui/views/animation/ink_drop_hover.cc b/chromium/ui/views/animation/ink_drop_hover.cc
index af98e614f59..24ad3844eb1 100644
--- a/chromium/ui/views/animation/ink_drop_hover.cc
+++ b/chromium/ui/views/animation/ink_drop_hover.cc
@@ -24,6 +24,18 @@ const float kHiddenOpacity = 0.0f;
} // namespace
+std::string ToString(InkDropHover::AnimationType animation_type) {
+ switch (animation_type) {
+ case InkDropHover::FADE_IN:
+ return std::string("FADE_IN");
+ case InkDropHover::FADE_OUT:
+ return std::string("FADE_OUT");
+ }
+ NOTREACHED()
+ << "Should never be reached but is necessary for some compilers.";
+ return std::string("UNKNOWN");
+}
+
InkDropHover::InkDropHover(const gfx::Size& size,
int corner_radius,
const gfx::Point& center_point,
diff --git a/chromium/ui/views/animation/ink_drop_hover.h b/chromium/ui/views/animation/ink_drop_hover.h
index e1cd2d42e5e..4c18b1d1889 100644
--- a/chromium/ui/views/animation/ink_drop_hover.h
+++ b/chromium/ui/views/animation/ink_drop_hover.h
@@ -5,8 +5,10 @@
#ifndef UI_VIEWS_ANIMATION_INK_DROP_HOVER_H_
#define UI_VIEWS_ANIMATION_INK_DROP_HOVER_H_
+#include <iosfwd>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/point.h"
@@ -102,16 +104,24 @@ class VIEWS_EXPORT InkDropHover {
bool last_animation_initiated_was_fade_in_;
// The LayerDelegate that paints the hover |layer_|.
- scoped_ptr<RoundedRectangleLayerDelegate> layer_delegate_;
+ std::unique_ptr<RoundedRectangleLayerDelegate> layer_delegate_;
// The visual hover layer that is painted by |layer_delegate_|.
- scoped_ptr<ui::Layer> layer_;
+ std::unique_ptr<ui::Layer> layer_;
InkDropHoverObserver* observer_;
DISALLOW_COPY_AND_ASSIGN(InkDropHover);
};
+// Returns a human readable string for |animation_type|. Useful for logging.
+VIEWS_EXPORT std::string ToString(InkDropHover::AnimationType animation_type);
+
+// This is declared here for use in gtest-based unit tests but is defined in
+// the views_test_support target. Depend on that to use this in your unit test.
+// This should not be used in production code - call ToString() instead.
+void PrintTo(InkDropHover::AnimationType animation_type, ::std::ostream* os);
+
} // namespace views
#endif // UI_VIEWS_ANIMATION_INK_DROP_HOVER_H_
diff --git a/chromium/ui/views/animation/ink_drop_hover_unittest.cc b/chromium/ui/views/animation/ink_drop_hover_unittest.cc
index 5d02ab7f1ed..eefe5a639f0 100644
--- a/chromium/ui/views/animation/ink_drop_hover_unittest.cc
+++ b/chromium/ui/views/animation/ink_drop_hover_unittest.cc
@@ -4,8 +4,10 @@
#include "ui/views/animation/ink_drop_hover.h"
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -23,7 +25,7 @@ class InkDropHoverTest : public testing::Test {
protected:
// The test target.
- scoped_ptr<InkDropHover> ink_drop_hover_;
+ std::unique_ptr<InkDropHover> ink_drop_hover_;
// Allows privileged access to the the |ink_drop_hover_|.
InkDropHoverTestApi test_api_;
diff --git a/chromium/ui/views/animation/ink_drop_impl.cc b/chromium/ui/views/animation/ink_drop_impl.cc
new file mode 100644
index 00000000000..cce475b58b5
--- /dev/null
+++ b/chromium/ui/views/animation/ink_drop_impl.cc
@@ -0,0 +1,253 @@
+// 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.
+
+#include "ui/views/animation/ink_drop_impl.h"
+
+#include "base/auto_reset.h"
+#include "base/timer/timer.h"
+#include "ui/compositor/layer.h"
+#include "ui/views/animation/ink_drop_host.h"
+#include "ui/views/animation/ink_drop_hover.h"
+#include "ui/views/animation/square_ink_drop_ripple.h"
+
+namespace views {
+
+namespace {
+
+// The duration, in milliseconds, of the hover state fade in animation when it
+// is triggered by user input.
+const int kHoverFadeInFromUserInputDurationInMs = 250;
+
+// The duration, in milliseconds, of the hover state fade out animation when it
+// is triggered by user input.
+const int kHoverFadeOutFromUserInputDurationInMs = 250;
+
+// The duration, in milliseconds, of the hover state fade in animation when it
+// is triggered by an ink drop ripple animation ending.
+const int kHoverFadeInAfterRippleDurationInMs = 250;
+
+// The duration, in milliseconds, of the hover state fade out animation when it
+// is triggered by an ink drop ripple animation starting.
+const int kHoverFadeOutBeforeRippleDurationInMs = 120;
+
+// The amount of time in milliseconds that |hover_| should delay after a ripple
+// animation before fading in.
+const int kHoverFadeInAfterRippleDelayInMs = 1000;
+
+// Returns true if an ink drop with the given |ink_drop_state| should
+// automatically transition to the InkDropState::HIDDEN state.
+bool ShouldAnimateToHidden(InkDropState ink_drop_state) {
+ switch (ink_drop_state) {
+ case views::InkDropState::ACTION_TRIGGERED:
+ case views::InkDropState::ALTERNATE_ACTION_TRIGGERED:
+ case views::InkDropState::DEACTIVATED:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace
+
+InkDropImpl::InkDropImpl(InkDropHost* ink_drop_host)
+ : ink_drop_host_(ink_drop_host),
+ root_layer_(new ui::Layer(ui::LAYER_NOT_DRAWN)),
+ root_layer_added_to_host_(false),
+ is_hovered_(false),
+ hover_after_ripple_timer_(nullptr) {
+ root_layer_->set_name("InkDropImpl:RootLayer");
+}
+
+InkDropImpl::~InkDropImpl() {
+ // Explicitly destroy the InkDropRipple so that this still exists if
+ // views::InkDropRippleObserver methods are called on this.
+ DestroyInkDropRipple();
+ DestroyInkDropHover();
+}
+
+InkDropState InkDropImpl::GetTargetInkDropState() const {
+ if (!ink_drop_ripple_)
+ return InkDropState::HIDDEN;
+ return ink_drop_ripple_->target_ink_drop_state();
+}
+
+bool InkDropImpl::IsVisible() const {
+ return ink_drop_ripple_ && ink_drop_ripple_->IsVisible();
+}
+
+void InkDropImpl::AnimateToState(InkDropState ink_drop_state) {
+ DestroyHiddenTargetedAnimations();
+ if (!ink_drop_ripple_)
+ CreateInkDropRipple();
+
+ if (ink_drop_state != views::InkDropState::HIDDEN) {
+ SetHoveredInternal(false, base::TimeDelta::FromMilliseconds(
+ kHoverFadeOutBeforeRippleDurationInMs),
+ true);
+ }
+
+ ink_drop_ripple_->AnimateToState(ink_drop_state);
+}
+
+void InkDropImpl::SnapToActivated() {
+ DestroyHiddenTargetedAnimations();
+ if (!ink_drop_ripple_)
+ CreateInkDropRipple();
+
+ SetHoveredInternal(false, base::TimeDelta(), false);
+
+ ink_drop_ripple_->SnapToActivated();
+}
+
+void InkDropImpl::SetHovered(bool is_hovered) {
+ is_hovered_ = is_hovered;
+ SetHoveredInternal(is_hovered,
+ is_hovered ? base::TimeDelta::FromMilliseconds(
+ kHoverFadeInFromUserInputDurationInMs)
+ : base::TimeDelta::FromMilliseconds(
+ kHoverFadeOutFromUserInputDurationInMs),
+ false);
+}
+
+void InkDropImpl::DestroyHiddenTargetedAnimations() {
+ if (ink_drop_ripple_ &&
+ (ink_drop_ripple_->target_ink_drop_state() == InkDropState::HIDDEN ||
+ ShouldAnimateToHidden(ink_drop_ripple_->target_ink_drop_state()))) {
+ DestroyInkDropRipple();
+ }
+}
+
+void InkDropImpl::CreateInkDropRipple() {
+ DestroyInkDropRipple();
+ ink_drop_ripple_ = ink_drop_host_->CreateInkDropRipple();
+ ink_drop_ripple_->set_observer(this);
+ root_layer_->Add(ink_drop_ripple_->GetRootLayer());
+ AddRootLayerToHostIfNeeded();
+}
+
+void InkDropImpl::DestroyInkDropRipple() {
+ if (!ink_drop_ripple_)
+ return;
+ root_layer_->Remove(ink_drop_ripple_->GetRootLayer());
+ ink_drop_ripple_.reset();
+ RemoveRootLayerFromHostIfNeeded();
+}
+
+void InkDropImpl::CreateInkDropHover() {
+ DestroyInkDropHover();
+
+ hover_ = ink_drop_host_->CreateInkDropHover();
+ if (!hover_)
+ return;
+ hover_->set_observer(this);
+ root_layer_->Add(hover_->layer());
+ AddRootLayerToHostIfNeeded();
+}
+
+void InkDropImpl::DestroyInkDropHover() {
+ if (!hover_)
+ return;
+ root_layer_->Remove(hover_->layer());
+ hover_->set_observer(nullptr);
+ hover_.reset();
+ RemoveRootLayerFromHostIfNeeded();
+}
+
+void InkDropImpl::AddRootLayerToHostIfNeeded() {
+ DCHECK(hover_ || ink_drop_ripple_);
+ if (!root_layer_added_to_host_) {
+ root_layer_added_to_host_ = true;
+ ink_drop_host_->AddInkDropLayer(root_layer_.get());
+ }
+}
+
+void InkDropImpl::RemoveRootLayerFromHostIfNeeded() {
+ if (root_layer_added_to_host_ && !hover_ && !ink_drop_ripple_) {
+ root_layer_added_to_host_ = false;
+ ink_drop_host_->RemoveInkDropLayer(root_layer_.get());
+ }
+}
+
+bool InkDropImpl::IsHoverFadingInOrVisible() const {
+ return hover_ && hover_->IsFadingInOrVisible();
+}
+
+// -----------------------------------------------------------------------------
+// views::InkDropRippleObserver:
+
+void InkDropImpl::AnimationStarted(InkDropState ink_drop_state) {}
+
+void InkDropImpl::AnimationEnded(InkDropState ink_drop_state,
+ InkDropAnimationEndedReason reason) {
+ if (reason != InkDropAnimationEndedReason::SUCCESS)
+ return;
+ if (ShouldAnimateToHidden(ink_drop_state)) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::HIDDEN);
+ } else if (ink_drop_state == views::InkDropState::HIDDEN) {
+ if (is_hovered_)
+ StartHoverAfterRippleTimer();
+ // TODO(bruthig): Investigate whether creating and destroying
+ // InkDropRipples is expensive and consider creating an
+ // InkDropRipplePool. See www.crbug.com/522175.
+ DestroyInkDropRipple();
+ }
+}
+
+// -----------------------------------------------------------------------------
+// views::InkDropHoverObserver:
+
+void InkDropImpl::AnimationStarted(InkDropHover::AnimationType animation_type) {
+}
+
+void InkDropImpl::AnimationEnded(InkDropHover::AnimationType animation_type,
+ InkDropAnimationEndedReason reason) {
+ if (animation_type == InkDropHover::FADE_OUT &&
+ reason == InkDropAnimationEndedReason::SUCCESS) {
+ DestroyInkDropHover();
+ }
+}
+
+void InkDropImpl::SetHoveredInternal(bool is_hovered,
+ base::TimeDelta animation_duration,
+ bool explode) {
+ StopHoverAfterRippleTimer();
+
+ if (IsHoverFadingInOrVisible() == is_hovered)
+ return;
+
+ if (is_hovered) {
+ CreateInkDropHover();
+ if (hover_ && !IsVisible())
+ hover_->FadeIn(animation_duration);
+ } else {
+ hover_->FadeOut(animation_duration, explode);
+ }
+}
+
+void InkDropImpl::StartHoverAfterRippleTimer() {
+ StopHoverAfterRippleTimer();
+
+ if (!hover_after_ripple_timer_)
+ hover_after_ripple_timer_.reset(new base::OneShotTimer);
+
+ hover_after_ripple_timer_->Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kHoverFadeInAfterRippleDelayInMs),
+ base::Bind(&InkDropImpl::HoverAfterRippleTimerFired,
+ base::Unretained(this)));
+}
+
+void InkDropImpl::StopHoverAfterRippleTimer() {
+ if (hover_after_ripple_timer_)
+ hover_after_ripple_timer_.reset();
+}
+
+void InkDropImpl::HoverAfterRippleTimerFired() {
+ SetHoveredInternal(true, base::TimeDelta::FromMilliseconds(
+ kHoverFadeInAfterRippleDurationInMs),
+ true);
+ hover_after_ripple_timer_.reset();
+}
+
+} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller_impl.h b/chromium/ui/views/animation/ink_drop_impl.h
index f39e4b9dd8a..dec07a9a981 100644
--- a/chromium/ui/views/animation/ink_drop_animation_controller_impl.h
+++ b/chromium/ui/views/animation/ink_drop_impl.h
@@ -2,16 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_IMPL_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_IMPL_H_
+#ifndef UI_VIEWS_ANIMATION_INK_DROP_IMPL_H_
+#define UI_VIEWS_ANIMATION_INK_DROP_IMPL_H_
+
+#include <memory>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
-#include "ui/views/animation/ink_drop_animation_controller.h"
-#include "ui/views/animation/ink_drop_animation_observer.h"
+#include "ui/views/animation/ink_drop.h"
#include "ui/views/animation/ink_drop_hover_observer.h"
+#include "ui/views/animation/ink_drop_ripple_observer.h"
#include "ui/views/views_export.h"
namespace base {
@@ -20,26 +21,25 @@ class Timer;
namespace views {
namespace test {
-class InkDropAnimationControllerImplTestApi;
+class InkDropImplTestApi;
} // namespace test
-class InkDropAnimation;
+class InkDropRipple;
class InkDropHost;
class InkDropHover;
-class InkDropAnimationControllerFactoryTest;
+class InkDropFactoryTest;
-// A functional implementation of an InkDropAnimationController.
-class VIEWS_EXPORT InkDropAnimationControllerImpl
- : public InkDropAnimationController,
- public InkDropAnimationObserver,
- public InkDropHoverObserver {
+// A functional implementation of an InkDrop.
+class VIEWS_EXPORT InkDropImpl : public InkDrop,
+ public InkDropRippleObserver,
+ public InkDropHoverObserver {
public:
- // Constructs an ink drop controller that will attach the ink drop to the
- // given |ink_drop_host|.
- explicit InkDropAnimationControllerImpl(InkDropHost* ink_drop_host);
- ~InkDropAnimationControllerImpl() override;
+ // Constructs an ink drop that will attach the ink drop to the given
+ // |ink_drop_host|.
+ explicit InkDropImpl(InkDropHost* ink_drop_host);
+ ~InkDropImpl() override;
- // InkDropAnimationController:
+ // InkDrop:
InkDropState GetTargetInkDropState() const override;
bool IsVisible() const override;
void AnimateToState(InkDropState ink_drop_state) override;
@@ -47,18 +47,18 @@ class VIEWS_EXPORT InkDropAnimationControllerImpl
void SetHovered(bool is_hovered) override;
private:
- friend class test::InkDropAnimationControllerImplTestApi;
+ friend class test::InkDropImplTestApi;
- // Destroys |ink_drop_animation_| if it's targeted to the HIDDEN state.
+ // Destroys |ink_drop_ripple_| if it's targeted to the HIDDEN state.
void DestroyHiddenTargetedAnimations();
- // Creates a new InkDropAnimation and sets it to |ink_drop_animation_|. If
- // |ink_drop_animation_| wasn't null then it will be destroyed using
- // DestroyInkDropAnimation().
- void CreateInkDropAnimation();
+ // Creates a new InkDropRipple and sets it to |ink_drop_ripple_|. If
+ // |ink_drop_ripple_| wasn't null then it will be destroyed using
+ // DestroyInkDropRipple().
+ void CreateInkDropRipple();
- // Destroys the current |ink_drop_animation_|.
- void DestroyInkDropAnimation();
+ // Destroys the current |ink_drop_ripple_|.
+ void DestroyInkDropRipple();
// Creates a new InkDropHover and sets it to |hover_|. If |hover_| wasn't null
// then it will be destroyed using DestroyInkDropHover().
@@ -79,7 +79,7 @@ class VIEWS_EXPORT InkDropAnimationControllerImpl
// is visible.
bool IsHoverFadingInOrVisible() const;
- // views::InkDropAnimationObserver:
+ // views::InkDropRippleObserver:
void AnimationStarted(InkDropState ink_drop_state) override;
void AnimationEnded(InkDropState ink_drop_state,
InkDropAnimationEndedReason reason) override;
@@ -97,45 +97,45 @@ class VIEWS_EXPORT InkDropAnimationControllerImpl
base::TimeDelta animation_duration,
bool explode);
- // Starts the |hover_after_animation_timer_| timer. This will stop the current
- // |hover_after_animation_timer_| instance if it exists.
- void StartHoverAfterAnimationTimer();
+ // Starts the |hover_after_ripple_timer_| timer. This will stop the current
+ // |hover_after_ripple_timer_| instance if it exists.
+ void StartHoverAfterRippleTimer();
- // Stops and destroys the current |hover_after_animation_timer_| instance.
- void StopHoverAfterAnimationTimer();
+ // Stops and destroys the current |hover_after_ripple_timer_| instance.
+ void StopHoverAfterRippleTimer();
- // Callback for when the |hover_after_animation_timer_| fires.
- void HoverAfterAnimationTimerFired();
+ // Callback for when the |hover_after_ripple_timer_| fires.
+ void HoverAfterRippleTimerFired();
// The host of the ink drop. Used to poll for information such as whether the
// hover should be shown or not.
InkDropHost* ink_drop_host_;
- // The root Layer that parents the InkDropAnimation layers and the
- // InkDropHover layers. The |root_layer_| is the one that is added and removed
- // from the InkDropHost.
- scoped_ptr<ui::Layer> root_layer_;
+ // The root Layer that parents the InkDropRipple layers and the InkDropHover
+ // layers. The |root_layer_| is the one that is added and removed from the
+ // InkDropHost.
+ std::unique_ptr<ui::Layer> root_layer_;
// True when the |root_layer_| has been added to the |ink_drop_host_|.
bool root_layer_added_to_host_;
// The current InkDropHover. Lazily created using CreateInkDropHover();
- scoped_ptr<InkDropHover> hover_;
+ std::unique_ptr<InkDropHover> hover_;
// Tracks the logical hovered state of |this| as manipulated by the public
// SetHovered() function.
bool is_hovered_;
- // The current InkDropAnimation. Created on demand using
- // CreateInkDropAnimation().
- scoped_ptr<InkDropAnimation> ink_drop_animation_;
+ // The current InkDropRipple. Created on demand using CreateInkDropRipple().
+ std::unique_ptr<InkDropRipple> ink_drop_ripple_;
- // The timer used to delay the hover fade in after an ink drop animation.
- scoped_ptr<base::Timer> hover_after_animation_timer_;
+ // The timer used to delay the hover fade in after an ink drop ripple
+ // animation.
+ std::unique_ptr<base::Timer> hover_after_ripple_timer_;
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerImpl);
+ DISALLOW_COPY_AND_ASSIGN(InkDropImpl);
};
} // namespace views
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_CONTROLLER_IMPL_H_
+#endif // UI_VIEWS_ANIMATION_INK_DROP_IMPL_H_
diff --git a/chromium/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc b/chromium/ui/views/animation/ink_drop_impl_unittest.cc
index 75e1d4cea76..ef480e051c7 100644
--- a/chromium/ui/views/animation/ink_drop_animation_controller_impl_unittest.cc
+++ b/chromium/ui/views/animation/ink_drop_impl_unittest.cc
@@ -2,84 +2,80 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/animation/ink_drop_animation_controller_impl.h"
+#include "ui/views/animation/ink_drop_impl.h"
#include "base/macros.h"
#include "base/test/test_simple_task_runner.h"
-#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/views/animation/ink_drop_animation.h"
-#include "ui/views/animation/test/ink_drop_animation_controller_impl_test_api.h"
+#include "ui/views/animation/ink_drop_ripple.h"
+#include "ui/views/animation/test/ink_drop_impl_test_api.h"
#include "ui/views/animation/test/test_ink_drop_host.h"
namespace views {
-// NOTE: The InkDropAnimationControllerImpl class is also tested by the
-// InkDropAnimationControllerFactoryTest tests.
-class InkDropAnimationControllerImplTest : public testing::Test {
+// NOTE: The InkDropImpl class is also tested by the InkDropFactoryTest tests.
+class InkDropImplTest : public testing::Test {
public:
- InkDropAnimationControllerImplTest();
- ~InkDropAnimationControllerImplTest() override;
+ InkDropImplTest();
+ ~InkDropImplTest() override;
protected:
TestInkDropHost ink_drop_host_;
// The test target.
- InkDropAnimationControllerImpl ink_drop_animation_controller_;
+ InkDropImpl ink_drop_;
// Allows privileged access to the the |ink_drop_hover_|.
- test::InkDropAnimationControllerImplTestApi test_api_;
+ test::InkDropImplTestApi test_api_;
- // Used to control the tasks scheduled by the InkDropAnimationControllerImpl's
- // Timer.
+ // Used to control the tasks scheduled by the InkDropImpl's Timer.
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
// Required by base::Timer's.
- scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
+ std::unique_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
private:
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationControllerImplTest);
+ DISALLOW_COPY_AND_ASSIGN(InkDropImplTest);
};
-InkDropAnimationControllerImplTest::InkDropAnimationControllerImplTest()
- : ink_drop_animation_controller_(&ink_drop_host_),
- test_api_(&ink_drop_animation_controller_),
+InkDropImplTest::InkDropImplTest()
+ : ink_drop_(&ink_drop_host_),
+ test_api_(&ink_drop_),
task_runner_(new base::TestSimpleTaskRunner),
thread_task_runner_handle_(
new base::ThreadTaskRunnerHandle(task_runner_)) {
ink_drop_host_.set_disable_timers_for_test(true);
}
-InkDropAnimationControllerImplTest::~InkDropAnimationControllerImplTest() {}
+InkDropImplTest::~InkDropImplTest() {}
-TEST_F(InkDropAnimationControllerImplTest, SetHoveredIsFadingInOrVisible) {
+TEST_F(InkDropImplTest, SetHoveredIsFadingInOrVisible) {
ink_drop_host_.set_should_show_hover(true);
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible());
test_api_.CompleteAnimations();
- ink_drop_animation_controller_.SetHovered(false);
+ ink_drop_.SetHovered(false);
EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible());
}
-TEST_F(InkDropAnimationControllerImplTest,
- HoverDoesntFadeInAfterAnimationIfHoverNotSet) {
+TEST_F(InkDropImplTest, HoverDoesntFadeInAfterAnimationIfHoverNotSet) {
ink_drop_host_.set_should_show_hover(true);
- ink_drop_animation_controller_.SetHovered(false);
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED);
+ ink_drop_.SetHovered(false);
+ ink_drop_.AnimateToState(InkDropState::ACTION_TRIGGERED);
test_api_.CompleteAnimations();
EXPECT_FALSE(task_runner_->HasPendingTask());
EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible());
}
-TEST_F(InkDropAnimationControllerImplTest,
- HoverFadesInAfterAnimationWhenHostIsHovered) {
+TEST_F(InkDropImplTest, HoverFadesInAfterAnimationWhenHostIsHovered) {
ink_drop_host_.set_should_show_hover(true);
- ink_drop_animation_controller_.SetHovered(true);
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED);
+ ink_drop_.SetHovered(true);
+ ink_drop_.AnimateToState(InkDropState::ACTION_TRIGGERED);
test_api_.CompleteAnimations();
EXPECT_TRUE(task_runner_->HasPendingTask());
@@ -89,11 +85,10 @@ TEST_F(InkDropAnimationControllerImplTest,
EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible());
}
-TEST_F(InkDropAnimationControllerImplTest,
- HoverDoesntFadeInAfterAnimationWhenHostIsNotHovered) {
+TEST_F(InkDropImplTest, HoverDoesntFadeInAfterAnimationWhenHostIsNotHovered) {
ink_drop_host_.set_should_show_hover(false);
- ink_drop_animation_controller_.SetHovered(true);
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED);
+ ink_drop_.SetHovered(true);
+ ink_drop_.AnimateToState(InkDropState::ACTION_TRIGGERED);
test_api_.CompleteAnimations();
EXPECT_TRUE(task_runner_->HasPendingTask());
@@ -103,86 +98,83 @@ TEST_F(InkDropAnimationControllerImplTest,
EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible());
}
-TEST_F(InkDropAnimationControllerImplTest,
- HoveredStateNotVisibleOrFadingInAfterAnimateToState) {
+TEST_F(InkDropImplTest, HoveredStateNotVisibleOrFadingInAfterAnimateToState) {
ink_drop_host_.set_should_show_hover(true);
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
test_api_.CompleteAnimations();
EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible());
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_TRIGGERED);
+ ink_drop_.AnimateToState(InkDropState::ACTION_TRIGGERED);
EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible());
}
// Verifies that there is not a crash when setting hovered state and the host
// returns null for the hover.
-TEST_F(InkDropAnimationControllerImplTest,
- SetHoveredFalseWorksWhenNoInkDropHoverExists) {
+TEST_F(InkDropImplTest, SetHoveredFalseWorksWhenNoInkDropHoverExists) {
ink_drop_host_.set_should_show_hover(false);
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_FALSE(test_api_.hover());
- ink_drop_animation_controller_.SetHovered(false);
+ ink_drop_.SetHovered(false);
EXPECT_FALSE(test_api_.hover());
}
-TEST_F(InkDropAnimationControllerImplTest, HoverFadesOutOnSnapToActivated) {
+TEST_F(InkDropImplTest, HoverFadesOutOnSnapToActivated) {
ink_drop_host_.set_should_show_hover(true);
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
test_api_.CompleteAnimations();
EXPECT_TRUE(test_api_.IsHoverFadingInOrVisible());
- ink_drop_animation_controller_.SnapToActivated();
+ ink_drop_.SnapToActivated();
EXPECT_FALSE(test_api_.IsHoverFadingInOrVisible());
}
-TEST_F(InkDropAnimationControllerImplTest, LayersRemovedFromHostAfterHover) {
+TEST_F(InkDropImplTest, LayersRemovedFromHostAfterHover) {
ink_drop_host_.set_should_show_hover(true);
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
test_api_.CompleteAnimations();
- ink_drop_animation_controller_.SetHovered(false);
+ ink_drop_.SetHovered(false);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
test_api_.CompleteAnimations();
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
}
-TEST_F(InkDropAnimationControllerImplTest, LayersRemovedFromHostAfterInkDrop) {
+TEST_F(InkDropImplTest, LayersRemovedFromHostAfterInkDrop) {
ink_drop_host_.set_should_show_hover(true);
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_.AnimateToState(InkDropState::ACTION_PENDING);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.AnimateToState(InkDropState::HIDDEN);
+ ink_drop_.AnimateToState(InkDropState::HIDDEN);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
test_api_.CompleteAnimations();
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
}
-TEST_F(InkDropAnimationControllerImplTest,
- LayersAddedToHostWhenHoverOrInkDropVisible) {
+TEST_F(InkDropImplTest, LayersAddedToHostWhenHoverOrInkDropVisible) {
ink_drop_host_.set_should_show_hover(true);
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_.AnimateToState(InkDropState::ACTION_PENDING);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.AnimateToState(InkDropState::HIDDEN);
+ ink_drop_.AnimateToState(InkDropState::HIDDEN);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
test_api_.CompleteAnimations();
@@ -196,19 +188,18 @@ TEST_F(InkDropAnimationControllerImplTest,
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
}
-TEST_F(InkDropAnimationControllerImplTest,
- LayersNotAddedToHostWhenHoverTimeFires) {
+TEST_F(InkDropImplTest, LayersNotAddedToHostWhenHoverTimeFires) {
ink_drop_host_.set_should_show_hover(true);
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_.AnimateToState(InkDropState::ACTION_PENDING);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.AnimateToState(InkDropState::HIDDEN);
+ ink_drop_.AnimateToState(InkDropState::HIDDEN);
test_api_.CompleteAnimations();
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
@@ -220,21 +211,20 @@ TEST_F(InkDropAnimationControllerImplTest,
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
}
-TEST_F(InkDropAnimationControllerImplTest,
- LayersArentRemovedWhenPreemptingFadeOut) {
+TEST_F(InkDropImplTest, LayersArentRemovedWhenPreemptingFadeOut) {
ink_drop_host_.set_should_show_hover(true);
EXPECT_EQ(0, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
test_api_.CompleteAnimations();
- ink_drop_animation_controller_.SetHovered(false);
+ ink_drop_.SetHovered(false);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
- ink_drop_animation_controller_.SetHovered(true);
+ ink_drop_.SetHovered(true);
EXPECT_EQ(1, ink_drop_host_.num_ink_drop_layers());
}
diff --git a/chromium/ui/views/animation/ink_drop_animation.cc b/chromium/ui/views/animation/ink_drop_ripple.cc
index 214716da23a..006e2f81259 100644
--- a/chromium/ui/views/animation/ink_drop_animation.cc
+++ b/chromium/ui/views/animation/ink_drop_ripple.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/animation/ink_drop_animation.h"
+#include "ui/views/animation/ink_drop_ripple.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -13,9 +13,9 @@
namespace views {
-const double InkDropAnimation::kSlowAnimationDurationFactor = 3.0;
+const double InkDropRipple::kSlowAnimationDurationFactor = 3.0;
-bool InkDropAnimation::UseFastAnimations() {
+bool InkDropRipple::UseFastAnimations() {
static bool fast =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
(::switches::kMaterialDesignInkDropAnimationSpeed)) !=
@@ -23,15 +23,15 @@ bool InkDropAnimation::UseFastAnimations() {
return fast;
}
-const float InkDropAnimation::kHiddenOpacity = 0.f;
-const float InkDropAnimation::kVisibleOpacity = 0.175f;
+const float InkDropRipple::kHiddenOpacity = 0.f;
+const float InkDropRipple::kVisibleOpacity = 0.175f;
-InkDropAnimation::InkDropAnimation()
+InkDropRipple::InkDropRipple()
: target_ink_drop_state_(InkDropState::HIDDEN), observer_(nullptr) {}
-InkDropAnimation::~InkDropAnimation() {}
+InkDropRipple::~InkDropRipple() {}
-void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) {
+void InkDropRipple::AnimateToState(InkDropState ink_drop_state) {
// Does not return early if |target_ink_drop_state_| == |ink_drop_state| for
// two reasons.
// 1. The attached observers must be notified of all animations started and
@@ -45,9 +45,9 @@ void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) {
// |animation_observer|.
ui::CallbackLayerAnimationObserver* animation_observer =
new ui::CallbackLayerAnimationObserver(
- base::Bind(&InkDropAnimation::AnimationStartedCallback,
+ base::Bind(&InkDropRipple::AnimationStartedCallback,
base::Unretained(this), ink_drop_state),
- base::Bind(&InkDropAnimation::AnimationEndedCallback,
+ base::Bind(&InkDropRipple::AnimationEndedCallback,
base::Unretained(this), ink_drop_state));
InkDropState old_ink_drop_state = target_ink_drop_state_;
@@ -68,7 +68,7 @@ void InkDropAnimation::AnimateToState(InkDropState ink_drop_state) {
// AnimationEndedCallback which can delete |this|.
}
-void InkDropAnimation::SnapToActivated() {
+void InkDropRipple::SnapToActivated() {
AbortAllAnimations();
// |animation_observer| will be deleted when AnimationEndedCallback() returns
// true.
@@ -76,32 +76,32 @@ void InkDropAnimation::SnapToActivated() {
// |animation_observer|.
ui::CallbackLayerAnimationObserver* animation_observer =
new ui::CallbackLayerAnimationObserver(
- base::Bind(&InkDropAnimation::AnimationStartedCallback,
+ base::Bind(&InkDropRipple::AnimationStartedCallback,
base::Unretained(this), InkDropState::ACTIVATED),
- base::Bind(&InkDropAnimation::AnimationEndedCallback,
+ base::Bind(&InkDropRipple::AnimationEndedCallback,
base::Unretained(this), InkDropState::ACTIVATED));
GetRootLayer()->SetVisible(true);
target_ink_drop_state_ = InkDropState::ACTIVATED;
animation_observer->SetActive();
}
-void InkDropAnimation::HideImmediately() {
+void InkDropRipple::HideImmediately() {
AbortAllAnimations();
SetStateToHidden();
target_ink_drop_state_ = InkDropState::HIDDEN;
}
-test::InkDropAnimationTestApi* InkDropAnimation::GetTestApi() {
+test::InkDropRippleTestApi* InkDropRipple::GetTestApi() {
return nullptr;
}
-void InkDropAnimation::AnimationStartedCallback(
+void InkDropRipple::AnimationStartedCallback(
InkDropState ink_drop_state,
const ui::CallbackLayerAnimationObserver& observer) {
observer_->AnimationStarted(ink_drop_state);
}
-bool InkDropAnimation::AnimationEndedCallback(
+bool InkDropRipple::AnimationEndedCallback(
InkDropState ink_drop_state,
const ui::CallbackLayerAnimationObserver& observer) {
if (ink_drop_state == InkDropState::HIDDEN)
diff --git a/chromium/ui/views/animation/ink_drop_animation.h b/chromium/ui/views/animation/ink_drop_ripple.h
index b00be7db26f..738bb9ba252 100644
--- a/chromium/ui/views/animation/ink_drop_animation.h
+++ b/chromium/ui/views/animation/ink_drop_ripple.h
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_H_
+#ifndef UI_VIEWS_ANIMATION_INK_DROP_RIPPLE_H_
+#define UI_VIEWS_ANIMATION_INK_DROP_RIPPLE_H_
#include "base/macros.h"
#include "ui/gfx/geometry/point.h"
-#include "ui/views/animation/ink_drop_animation_observer.h"
+#include "ui/views/animation/ink_drop_ripple_observer.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/views_export.h"
@@ -20,15 +20,15 @@ class LayerAnimationObserver;
namespace views {
namespace test {
-class InkDropAnimationTestApi;
+class InkDropRippleTestApi;
} // namespace test
// Simple base class for animations that provide visual feedback for View state.
-// Manages the attached InkDropAnimationObservers.
+// Manages the attached InkDropRippleObservers.
//
// TODO(bruthig): Document the ink drop ripple on chromium.org and add a link to
// the doc here.
-class VIEWS_EXPORT InkDropAnimation {
+class VIEWS_EXPORT InkDropRipple {
public:
// TODO(bruthig): Remove UseFastAnimations() and kSlowAnimationDurationFactor.
// See http://crbug.com/584681
@@ -47,16 +47,14 @@ class VIEWS_EXPORT InkDropAnimation {
// The opacity of the ink drop when it is visible.
static const float kVisibleOpacity;
- InkDropAnimation();
- virtual ~InkDropAnimation();
+ InkDropRipple();
+ virtual ~InkDropRipple();
// In the event that an animation is in progress for ink drop state 's1' and
// an animation to a new state 's2' is triggered, then
// AnimationEnded(s1, PRE_EMPTED) will be called before
// AnimationStarted(s2).
- void set_observer(InkDropAnimationObserver* observer) {
- observer_ = observer;
- }
+ void set_observer(InkDropRippleObserver* observer) { observer_ = observer; }
// Animates from the current InkDropState to the new |ink_drop_state|.
//
@@ -68,8 +66,8 @@ class VIEWS_EXPORT InkDropAnimation {
// Immediately aborts all in-progress animations and hides the ink drop.
//
- // NOTE: This will NOT raise InkDropAnimation(Started|Ended) events for the
- // state transition to HIDDEN!
+ // NOTE: This will NOT raise Animation(Started|Ended) events for the state
+ // transition to HIDDEN!
void HideImmediately();
// Immediately snaps the ink drop to the ACTIVATED target state. All pending
@@ -88,7 +86,7 @@ class VIEWS_EXPORT InkDropAnimation {
// Returns a test api to access internals of this. Default implmentations
// should return nullptr and test specific subclasses can override to return
// an instance.
- virtual test::InkDropAnimationTestApi* GetTestApi();
+ virtual test::InkDropRippleTestApi* GetTestApi();
protected:
// Animates the ripple from the |old_ink_drop_state| to the
@@ -121,11 +119,11 @@ class VIEWS_EXPORT InkDropAnimation {
// The target InkDropState.
InkDropState target_ink_drop_state_;
- InkDropAnimationObserver* observer_;
+ InkDropRippleObserver* observer_;
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimation);
+ DISALLOW_COPY_AND_ASSIGN(InkDropRipple);
};
} // namespace views
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_H_
+#endif // UI_VIEWS_ANIMATION_INK_DROP_RIPPLE_H_
diff --git a/chromium/ui/views/animation/ink_drop_animation_observer.h b/chromium/ui/views/animation/ink_drop_ripple_observer.h
index 831a6be06b3..b294b3ae95c 100644
--- a/chromium/ui/views/animation/ink_drop_animation_observer.h
+++ b/chromium/ui/views/animation/ink_drop_ripple_observer.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_OBSERVER_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_OBSERVER_H_
+#ifndef UI_VIEWS_ANIMATION_INK_DROP_RIPPLE_OBSERVER_H_
+#define UI_VIEWS_ANIMATION_INK_DROP_RIPPLE_OBSERVER_H_
#include <string>
@@ -14,8 +14,8 @@
namespace views {
-// Observer to attach to an InkDropAnimation.
-class VIEWS_EXPORT InkDropAnimationObserver {
+// Observer to attach to an InkDropRipple.
+class VIEWS_EXPORT InkDropRippleObserver {
public:
// An animation for the given |ink_drop_state| has started.
virtual void AnimationStarted(InkDropState ink_drop_state) = 0;
@@ -29,13 +29,13 @@ class VIEWS_EXPORT InkDropAnimationObserver {
InkDropAnimationEndedReason reason) = 0;
protected:
- InkDropAnimationObserver() = default;
- virtual ~InkDropAnimationObserver() = default;
+ InkDropRippleObserver() = default;
+ virtual ~InkDropRippleObserver() = default;
private:
- DISALLOW_COPY_AND_ASSIGN(InkDropAnimationObserver);
+ DISALLOW_COPY_AND_ASSIGN(InkDropRippleObserver);
};
} // namespace views
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_OBSERVER_H_
+#endif // UI_VIEWS_ANIMATION_INK_DROP_RIPPLE_OBSERVER_H_
diff --git a/chromium/ui/views/animation/ink_drop_ripple_unittest.cc b/chromium/ui/views/animation/ink_drop_ripple_unittest.cc
new file mode 100644
index 00000000000..2925af02b56
--- /dev/null
+++ b/chromium/ui/views/animation/ink_drop_ripple_unittest.cc
@@ -0,0 +1,348 @@
+// 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.
+
+#include "ui/views/animation/ink_drop_ripple.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
+#include "ui/views/animation/ink_drop_ripple_observer.h"
+#include "ui/views/animation/ink_drop_state.h"
+#include "ui/views/animation/square_ink_drop_ripple.h"
+#include "ui/views/animation/test/flood_fill_ink_drop_ripple_test_api.h"
+#include "ui/views/animation/test/ink_drop_ripple_test_api.h"
+#include "ui/views/animation/test/square_ink_drop_ripple_test_api.h"
+#include "ui/views/animation/test/test_ink_drop_ripple_observer.h"
+
+namespace views {
+namespace test {
+
+// Represents all the derivatives of the InkDropRipple class. To be used with
+// the InkDropRippleTest fixture to test all derviatives.
+enum InkDropRippleTestTypes {
+ SQUARE_INK_DROP_RIPPLE,
+ FLOOD_FILL_INK_DROP_RIPPLE
+};
+
+// Test fixture for all InkDropRipple class derivatives.
+//
+// To add a new derivative:
+// 1. Add a value to the InkDropRippleTestTypes enum.
+// 2. Implement set up and tear down code for the new enum value in
+// InkDropRippleTest() and
+// ~InkDropRippleTest().
+// 3. Add the new enum value to the INSTANTIATE_TEST_CASE_P) Values list.
+class InkDropRippleTest
+ : public testing::TestWithParam<InkDropRippleTestTypes> {
+ public:
+ InkDropRippleTest();
+ ~InkDropRippleTest() override;
+
+ protected:
+ TestInkDropRippleObserver observer_;
+
+ std::unique_ptr<InkDropRipple> ink_drop_ripple_;
+
+ std::unique_ptr<InkDropRippleTestApi> test_api_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InkDropRippleTest);
+};
+
+InkDropRippleTest::InkDropRippleTest() {
+ switch (GetParam()) {
+ case SQUARE_INK_DROP_RIPPLE: {
+ SquareInkDropRipple* square_ink_drop_ripple =
+ new SquareInkDropRipple(gfx::Size(10, 10), 2, gfx::Size(8, 8), 1,
+ gfx::Point(), SK_ColorBLACK);
+ ink_drop_ripple_.reset(square_ink_drop_ripple);
+ test_api_.reset(new SquareInkDropRippleTestApi(square_ink_drop_ripple));
+ break;
+ }
+ case FLOOD_FILL_INK_DROP_RIPPLE: {
+ FloodFillInkDropRipple* flood_fill_ink_drop_ripple =
+ new FloodFillInkDropRipple(gfx::Rect(0, 0, 10, 10), gfx::Point(),
+ SK_ColorBLACK);
+ ink_drop_ripple_.reset(flood_fill_ink_drop_ripple);
+ test_api_.reset(
+ new FloodFillInkDropRippleTestApi(flood_fill_ink_drop_ripple));
+ break;
+ }
+ }
+ ink_drop_ripple_->set_observer(&observer_);
+ observer_.set_ink_drop_ripple(ink_drop_ripple_.get());
+ test_api_->SetDisableAnimationTimers(true);
+}
+
+InkDropRippleTest::~InkDropRippleTest() {}
+
+// Note: First argument is optional and intentionally left blank.
+// (it's a prefix for the generated test cases)
+INSTANTIATE_TEST_CASE_P(,
+ InkDropRippleTest,
+ testing::Values(SQUARE_INK_DROP_RIPPLE,
+ FLOOD_FILL_INK_DROP_RIPPLE));
+
+TEST_P(InkDropRippleTest, InitialStateAfterConstruction) {
+ EXPECT_EQ(views::InkDropState::HIDDEN,
+ ink_drop_ripple_->target_ink_drop_state());
+}
+
+// Verify no animations are used when animating from HIDDEN to HIDDEN.
+TEST_P(InkDropRippleTest, AnimateToHiddenFromInvisibleState) {
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
+
+ ink_drop_ripple_->AnimateToState(InkDropState::HIDDEN);
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+ EXPECT_FALSE(ink_drop_ripple_->IsVisible());
+}
+
+TEST_P(InkDropRippleTest, AnimateToHiddenFromVisibleState) {
+ ink_drop_ripple_->AnimateToState(InkDropState::ACTION_PENDING);
+ test_api_->CompleteAnimations();
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+
+ EXPECT_NE(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
+
+ ink_drop_ripple_->AnimateToState(InkDropState::HIDDEN);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(3, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(4, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+}
+
+TEST_P(InkDropRippleTest, ActionPendingOpacity) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(InkDropRipple::kVisibleOpacity, test_api_->GetCurrentOpacity());
+}
+
+TEST_P(InkDropRippleTest, QuickActionOpacity) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_TRIGGERED);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+}
+
+TEST_P(InkDropRippleTest, SlowActionPendingOpacity) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(
+ views::InkDropState::ALTERNATE_ACTION_PENDING);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(InkDropRipple::kVisibleOpacity, test_api_->GetCurrentOpacity());
+}
+
+TEST_P(InkDropRippleTest, SlowActionOpacity) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(
+ views::InkDropState::ALTERNATE_ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(
+ views::InkDropState::ALTERNATE_ACTION_TRIGGERED);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+}
+
+TEST_P(InkDropRippleTest, ActivatedOpacity) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTIVATED);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(InkDropRipple::kVisibleOpacity, test_api_->GetCurrentOpacity());
+}
+
+TEST_P(InkDropRippleTest, DeactivatedOpacity) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTIVATED);
+ ink_drop_ripple_->AnimateToState(views::InkDropState::DEACTIVATED);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+}
+
+// Verify animations are aborted during deletion and the
+// InkDropRippleObservers are notified.
+TEST_P(InkDropRippleTest, AnimationsAbortedDuringDeletion) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_.reset();
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(views::InkDropState::ACTION_PENDING,
+ observer_.last_animation_ended_context());
+ EXPECT_EQ(InkDropAnimationEndedReason::PRE_EMPTED,
+ observer_.last_animation_ended_reason());
+}
+
+TEST_P(InkDropRippleTest, VerifyObserversAreNotified) {
+ ink_drop_ripple_->AnimateToState(InkDropState::ACTION_PENDING);
+
+ EXPECT_TRUE(test_api_->HasActiveAnimations());
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_TRUE(observer_.AnimationHasNotEnded());
+ EXPECT_EQ(InkDropState::ACTION_PENDING,
+ observer_.last_animation_started_context());
+
+ test_api_->CompleteAnimations();
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropState::ACTION_PENDING,
+ observer_.last_animation_ended_context());
+}
+
+TEST_P(InkDropRippleTest, VerifyObserversAreNotifiedOfSuccessfulAnimations) {
+ ink_drop_ripple_->AnimateToState(InkDropState::ACTION_PENDING);
+ test_api_->CompleteAnimations();
+
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropAnimationEndedReason::SUCCESS,
+ observer_.last_animation_ended_reason());
+}
+
+TEST_P(InkDropRippleTest, VerifyObserversAreNotifiedOfPreemptedAnimations) {
+ ink_drop_ripple_->AnimateToState(InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(InkDropState::ALTERNATE_ACTION_PENDING);
+
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropAnimationEndedReason::PRE_EMPTED,
+ observer_.last_animation_ended_reason());
+}
+
+TEST_P(InkDropRippleTest, InkDropStatesPersistWhenCallingAnimateToState) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTIVATED);
+ EXPECT_EQ(views::InkDropState::ACTIVATED,
+ ink_drop_ripple_->target_ink_drop_state());
+}
+
+TEST_P(InkDropRippleTest, HideImmediatelyWithoutActiveAnimations) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ test_api_->CompleteAnimations();
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_NE(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
+
+ ink_drop_ripple_->HideImmediately();
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_EQ(views::InkDropState::HIDDEN,
+ ink_drop_ripple_->target_ink_drop_state());
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+ EXPECT_FALSE(ink_drop_ripple_->IsVisible());
+}
+
+// Verifies all active animations are aborted and the InkDropState is set to
+// HIDDEN after invoking HideImmediately().
+TEST_P(InkDropRippleTest, HideImmediatelyWithActiveAnimations) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ EXPECT_TRUE(test_api_->HasActiveAnimations());
+ EXPECT_NE(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+
+ ink_drop_ripple_->HideImmediately();
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_EQ(views::InkDropState::HIDDEN,
+ ink_drop_ripple_->target_ink_drop_state());
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropState::ACTION_PENDING,
+ observer_.last_animation_ended_context());
+ EXPECT_EQ(InkDropAnimationEndedReason::PRE_EMPTED,
+ observer_.last_animation_ended_reason());
+
+ EXPECT_EQ(InkDropRipple::kHiddenOpacity, test_api_->GetCurrentOpacity());
+ EXPECT_FALSE(ink_drop_ripple_->IsVisible());
+}
+
+TEST_P(InkDropRippleTest, SnapToActivatedWithoutActiveAnimations) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ test_api_->CompleteAnimations();
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_NE(InkDropState::ACTIVATED, ink_drop_ripple_->target_ink_drop_state());
+
+ ink_drop_ripple_->SnapToActivated();
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_EQ(views::InkDropState::ACTIVATED,
+ ink_drop_ripple_->target_ink_drop_state());
+ EXPECT_EQ(3, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(4, observer_.last_animation_ended_ordinal());
+
+ EXPECT_EQ(InkDropRipple::kVisibleOpacity, test_api_->GetCurrentOpacity());
+ EXPECT_TRUE(ink_drop_ripple_->IsVisible());
+}
+
+// Verifies all active animations are aborted and the InkDropState is set to
+// ACTIVATED after invoking SnapToActivated().
+TEST_P(InkDropRippleTest, SnapToActivatedWithActiveAnimations) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ EXPECT_TRUE(test_api_->HasActiveAnimations());
+ EXPECT_NE(InkDropState::ACTIVATED, ink_drop_ripple_->target_ink_drop_state());
+ EXPECT_EQ(1, observer_.last_animation_started_ordinal());
+
+ ink_drop_ripple_->SnapToActivated();
+
+ EXPECT_FALSE(test_api_->HasActiveAnimations());
+ EXPECT_EQ(views::InkDropState::ACTIVATED,
+ ink_drop_ripple_->target_ink_drop_state());
+ EXPECT_EQ(3, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(4, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(InkDropState::ACTIVATED, observer_.last_animation_ended_context());
+ EXPECT_EQ(InkDropAnimationEndedReason::SUCCESS,
+ observer_.last_animation_ended_reason());
+
+ EXPECT_EQ(InkDropRipple::kVisibleOpacity, test_api_->GetCurrentOpacity());
+ EXPECT_TRUE(ink_drop_ripple_->IsVisible());
+}
+
+TEST_P(InkDropRippleTest, AnimateToVisibleFromHidden) {
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ EXPECT_TRUE(ink_drop_ripple_->IsVisible());
+}
+
+// Verifies that the value of InkDropRipple::target_ink_drop_state() returns
+// the most recent value passed to AnimateToState() when notifying observers
+// that an animation has started within the AnimateToState() function call.
+TEST_P(InkDropRippleTest, TargetInkDropStateOnAnimationStarted) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(views::InkDropState::HIDDEN);
+
+ EXPECT_EQ(3, observer_.last_animation_started_ordinal());
+ EXPECT_EQ(views::InkDropState::HIDDEN,
+ observer_.target_state_at_last_animation_started());
+}
+
+// Verifies that the value of InkDropRipple::target_ink_drop_state() returns
+// the most recent value passed to AnimateToState() when notifying observers
+// that an animation has ended within the AnimateToState() function call.
+TEST_P(InkDropRippleTest, TargetInkDropStateOnAnimationEnded) {
+ ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
+ ink_drop_ripple_->AnimateToState(views::InkDropState::HIDDEN);
+
+ EXPECT_EQ(2, observer_.last_animation_ended_ordinal());
+ EXPECT_EQ(views::InkDropState::HIDDEN,
+ observer_.target_state_at_last_animation_ended());
+}
+
+} // namespace test
+} // namespace views
diff --git a/chromium/ui/views/animation/ink_drop_state.h b/chromium/ui/views/animation/ink_drop_state.h
index 2456455c5da..91214d39d9a 100644
--- a/chromium/ui/views/animation/ink_drop_state.h
+++ b/chromium/ui/views/animation/ink_drop_state.h
@@ -5,6 +5,7 @@
#ifndef UI_VIEWS_ANIMATION_INK_DROP_STATE_H_
#define UI_VIEWS_ANIMATION_INK_DROP_STATE_H_
+#include <iosfwd>
#include <string>
#include "ui/views/views_export.h"
@@ -36,7 +37,12 @@ enum class InkDropState {
};
// Returns a human readable string for |state|. Useful for logging.
-std::string ToString(InkDropState state);
+VIEWS_EXPORT std::string ToString(InkDropState state);
+
+// This is declared here for use in gtest-based unit tests but is defined in
+// the views_test_support target. Depend on that to use this in your unit test.
+// This should not be used in production code - call ToString() instead.
+void PrintTo(InkDropState ink_drop_state, ::std::ostream* os);
} // namespace views
diff --git a/chromium/ui/views/animation/scroll_animator.h b/chromium/ui/views/animation/scroll_animator.h
index 5473315f7f7..d9b64c99a41 100644
--- a/chromium/ui/views/animation/scroll_animator.h
+++ b/chromium/ui/views/animation/scroll_animator.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_ANIMATION_SCROLL_ANIMATOR_H_
#define UI_VIEWS_ANIMATION_SCROLL_ANIMATOR_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/views/views_export.h"
@@ -53,7 +54,7 @@ class VIEWS_EXPORT ScrollAnimator : public gfx::AnimationDelegate {
float duration_;
float acceleration_;
- scoped_ptr<gfx::SlideAnimation> animation_;
+ std::unique_ptr<gfx::SlideAnimation> animation_;
DISALLOW_COPY_AND_ASSIGN(ScrollAnimator);
};
diff --git a/chromium/ui/views/animation/square_ink_drop_animation.cc b/chromium/ui/views/animation/square_ink_drop_ripple.cc
index 58320aa8246..142a3a6ff77 100644
--- a/chromium/ui/views/animation/square_ink_drop_animation.cc
+++ b/chromium/ui/views/animation/square_ink_drop_ripple.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/animation/square_ink_drop_animation.h"
+#include "ui/views/animation/square_ink_drop_ripple.h"
#include <algorithm>
@@ -127,9 +127,9 @@ int kAnimationDurationInMs[] = {
// Returns the InkDropState sub animation duration for the given |state|.
base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
return base::TimeDelta::FromMilliseconds(
- (views::InkDropAnimation::UseFastAnimations()
+ (views::InkDropRipple::UseFastAnimations()
? 1
- : views::InkDropAnimation::kSlowAnimationDurationFactor) *
+ : views::InkDropRipple::kSlowAnimationDurationFactor) *
kAnimationDurationInMs[state]);
}
@@ -163,12 +163,12 @@ gfx::Transform CalculateRectTransform(const gfx::Point& drawn_center_point,
namespace views {
-SquareInkDropAnimation::SquareInkDropAnimation(const gfx::Size& large_size,
- int large_corner_radius,
- const gfx::Size& small_size,
- int small_corner_radius,
- const gfx::Point& center_point,
- SkColor color)
+SquareInkDropRipple::SquareInkDropRipple(const gfx::Size& large_size,
+ int large_corner_radius,
+ const gfx::Size& small_size,
+ int small_corner_radius,
+ const gfx::Point& center_point,
+ SkColor color)
: large_size_(large_size),
large_corner_radius_(large_corner_radius),
small_size_(small_size),
@@ -178,7 +178,7 @@ SquareInkDropAnimation::SquareInkDropAnimation(const gfx::Size& large_size,
std::min(large_size_.width(), large_size_.height()) / 2)),
rect_layer_delegate_(new RectangleLayerDelegate(color, large_size_)),
root_layer_(ui::LAYER_NOT_DRAWN) {
- root_layer_.set_name("SquareInkDropAnimation:ROOT_LAYER");
+ root_layer_.set_name("SquareInkDropRipple:ROOT_LAYER");
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
AddPaintLayer(static_cast<PaintedShape>(i));
@@ -193,33 +193,33 @@ SquareInkDropAnimation::SquareInkDropAnimation(const gfx::Size& large_size,
SetStateToHidden();
}
-SquareInkDropAnimation::~SquareInkDropAnimation() {
+SquareInkDropRipple::~SquareInkDropRipple() {
// Explicitly aborting all the animations ensures all callbacks are invoked
// while this instance still exists.
AbortAllAnimations();
}
-void SquareInkDropAnimation::SnapToActivated() {
- InkDropAnimation::SnapToActivated();
+void SquareInkDropRipple::SnapToActivated() {
+ InkDropRipple::SnapToActivated();
SetOpacity(kVisibleOpacity);
InkDropTransforms transforms;
GetActivatedTargetTransforms(&transforms);
SetTransforms(transforms);
}
-ui::Layer* SquareInkDropAnimation::GetRootLayer() {
+ui::Layer* SquareInkDropRipple::GetRootLayer() {
return &root_layer_;
}
-bool SquareInkDropAnimation::IsVisible() const {
+bool SquareInkDropRipple::IsVisible() const {
return root_layer_.visible();
}
-float SquareInkDropAnimation::GetCurrentOpacity() const {
+float SquareInkDropRipple::GetCurrentOpacity() const {
return root_layer_.opacity();
}
-std::string SquareInkDropAnimation::ToLayerName(PaintedShape painted_shape) {
+std::string SquareInkDropRipple::ToLayerName(PaintedShape painted_shape) {
switch (painted_shape) {
case TOP_LEFT_CIRCLE:
return "TOP_LEFT_CIRCLE";
@@ -240,7 +240,7 @@ std::string SquareInkDropAnimation::ToLayerName(PaintedShape painted_shape) {
return "UNKNOWN";
}
-void SquareInkDropAnimation::AnimateStateChange(
+void SquareInkDropRipple::AnimateStateChange(
InkDropState old_ink_drop_state,
InkDropState new_ink_drop_state,
ui::LayerAnimationObserver* animation_observer) {
@@ -379,22 +379,22 @@ void SquareInkDropAnimation::AnimateStateChange(
}
}
-void SquareInkDropAnimation::SetStateToHidden() {
+void SquareInkDropRipple::SetStateToHidden() {
InkDropTransforms transforms;
// Use non-zero size to avoid visual anomalies.
CalculateCircleTransforms(gfx::Size(1, 1), &transforms);
SetTransforms(transforms);
- root_layer_.SetOpacity(InkDropAnimation::kHiddenOpacity);
+ root_layer_.SetOpacity(InkDropRipple::kHiddenOpacity);
root_layer_.SetVisible(false);
}
-void SquareInkDropAnimation::AbortAllAnimations() {
+void SquareInkDropRipple::AbortAllAnimations() {
root_layer_.GetAnimator()->AbortAllAnimations();
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
painted_layers_[i]->GetAnimator()->AbortAllAnimations();
}
-void SquareInkDropAnimation::AnimateToTransforms(
+void SquareInkDropRipple::AnimateToTransforms(
const InkDropTransforms transforms,
base::TimeDelta duration,
ui::LayerAnimator::PreemptionStrategy preemption_strategy,
@@ -418,16 +418,16 @@ void SquareInkDropAnimation::AnimateToTransforms(
}
}
-void SquareInkDropAnimation::SetTransforms(const InkDropTransforms transforms) {
+void SquareInkDropRipple::SetTransforms(const InkDropTransforms transforms) {
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
painted_layers_[i]->SetTransform(transforms[i]);
}
-void SquareInkDropAnimation::SetOpacity(float opacity) {
+void SquareInkDropRipple::SetOpacity(float opacity) {
root_layer_.SetOpacity(opacity);
}
-void SquareInkDropAnimation::AnimateToOpacity(
+void SquareInkDropRipple::AnimateToOpacity(
float opacity,
base::TimeDelta duration,
ui::LayerAnimator::PreemptionStrategy preemption_strategy,
@@ -448,14 +448,14 @@ void SquareInkDropAnimation::AnimateToOpacity(
animator->StartAnimation(animation_sequence);
}
-void SquareInkDropAnimation::CalculateCircleTransforms(
+void SquareInkDropRipple::CalculateCircleTransforms(
const gfx::Size& size,
InkDropTransforms* transforms_out) const {
CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f,
transforms_out);
}
-void SquareInkDropAnimation::CalculateRectTransforms(
+void SquareInkDropRipple::CalculateRectTransforms(
const gfx::Size& size,
float corner_radius,
InkDropTransforms* transforms_out) const {
@@ -509,18 +509,18 @@ void SquareInkDropAnimation::CalculateRectTransforms(
std::max(kMinimumRectScale, size.height() / rect_delegate_height));
}
-void SquareInkDropAnimation::GetCurrentTransforms(
+void SquareInkDropRipple::GetCurrentTransforms(
InkDropTransforms* transforms_out) const {
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
(*transforms_out)[i] = painted_layers_[i]->transform();
}
-void SquareInkDropAnimation::GetActivatedTargetTransforms(
+void SquareInkDropRipple::GetActivatedTargetTransforms(
InkDropTransforms* transforms_out) const {
CalculateRectTransforms(small_size_, small_corner_radius_, transforms_out);
}
-void SquareInkDropAnimation::AddPaintLayer(PaintedShape painted_shape) {
+void SquareInkDropRipple::AddPaintLayer(PaintedShape painted_shape) {
ui::LayerDelegate* delegate = nullptr;
switch (painted_shape) {
case TOP_LEFT_CIRCLE:
diff --git a/chromium/ui/views/animation/square_ink_drop_animation.h b/chromium/ui/views/animation/square_ink_drop_ripple.h
index d704e7eb4af..dbc05ad6f33 100644
--- a/chromium/ui/views/animation/square_ink_drop_animation.h
+++ b/chromium/ui/views/animation/square_ink_drop_ripple.h
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_SQUARE_INK_DROP_ANIMATION_H_
-#define UI_VIEWS_ANIMATION_SQUARE_INK_DROP_ANIMATION_H_
+#ifndef UI_VIEWS_ANIMATION_SQUARE_INK_DROP_RIPPLE_H_
+#define UI_VIEWS_ANIMATION_SQUARE_INK_DROP_RIPPLE_H_
+#include <memory>
#include <string>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/layer.h"
@@ -17,7 +17,7 @@
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h"
-#include "ui/views/animation/ink_drop_animation.h"
+#include "ui/views/animation/ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/views_export.h"
@@ -30,10 +30,10 @@ class CircleLayerDelegate;
class RectangleLayerDelegate;
namespace test {
-class SquareInkDropAnimationTestApi;
+class SquareInkDropRippleTestApi;
} // namespace test
-// An ink drop animation that smoothly animates between a circle and a rounded
+// An ink drop ripple that smoothly animates between a circle and a rounded
// rectangle of different sizes for each of the different InkDropStates. The
// final frame for each InkDropState will be bounded by either a |large_size_|
// rectangle or a |small_size_| rectangle.
@@ -48,23 +48,23 @@ class SquareInkDropAnimationTestApi;
// {All InkDropStates} => ACTIVATED
// {All InkDropStates} => DEACTIVATED
//
-class VIEWS_EXPORT SquareInkDropAnimation : public InkDropAnimation {
+class VIEWS_EXPORT SquareInkDropRipple : public InkDropRipple {
public:
- SquareInkDropAnimation(const gfx::Size& large_size,
- int large_corner_radius,
- const gfx::Size& small_size,
- int small_corner_radius,
- const gfx::Point& center_point,
- SkColor color);
- ~SquareInkDropAnimation() override;
-
- // InkDropAnimation:
+ SquareInkDropRipple(const gfx::Size& large_size,
+ int large_corner_radius,
+ const gfx::Size& small_size,
+ int small_corner_radius,
+ const gfx::Point& center_point,
+ SkColor color);
+ ~SquareInkDropRipple() override;
+
+ // InkDropRipple:
void SnapToActivated() override;
ui::Layer* GetRootLayer() override;
bool IsVisible() const override;
private:
- friend class test::SquareInkDropAnimationTestApi;
+ friend class test::SquareInkDropRippleTestApi;
// Enumeration of the different shapes that compose the ink drop.
enum PaintedShape {
@@ -87,7 +87,7 @@ class VIEWS_EXPORT SquareInkDropAnimation : public InkDropAnimation {
float GetCurrentOpacity() const;
- // InkDropAnimation:
+ // InkDropRipple:
void AnimateStateChange(InkDropState old_ink_drop_state,
InkDropState new_ink_drop_state,
ui::LayerAnimationObserver* observer) override;
@@ -163,10 +163,10 @@ class VIEWS_EXPORT SquareInkDropAnimation : public InkDropAnimation {
int small_corner_radius_;
// ui::LayerDelegate to paint circles for all the circle layers.
- scoped_ptr<CircleLayerDelegate> circle_layer_delegate_;
+ std::unique_ptr<CircleLayerDelegate> circle_layer_delegate_;
// ui::LayerDelegate to paint rectangles for all the rectangle layers.
- scoped_ptr<RectangleLayerDelegate> rect_layer_delegate_;
+ std::unique_ptr<RectangleLayerDelegate> rect_layer_delegate_;
// The root layer that parents the animating layers. The root layer is used to
// manipulate opacity and location, and its children are used to manipulate
@@ -174,11 +174,11 @@ class VIEWS_EXPORT SquareInkDropAnimation : public InkDropAnimation {
ui::Layer root_layer_;
// ui::Layers for all of the painted shape layers that compose the ink drop.
- scoped_ptr<ui::Layer> painted_layers_[PAINTED_SHAPE_COUNT];
+ std::unique_ptr<ui::Layer> painted_layers_[PAINTED_SHAPE_COUNT];
- DISALLOW_COPY_AND_ASSIGN(SquareInkDropAnimation);
+ DISALLOW_COPY_AND_ASSIGN(SquareInkDropRipple);
};
} // namespace views
-#endif // UI_VIEWS_ANIMATION_SQUARE_INK_DROP_ANIMATION_H_
+#endif // UI_VIEWS_ANIMATION_SQUARE_INK_DROP_RIPPLE_H_
diff --git a/chromium/ui/views/animation/square_ink_drop_animation_unittest.cc b/chromium/ui/views/animation/square_ink_drop_ripple_unittest.cc
index 0b11630ca5e..44ec224aa0f 100644
--- a/chromium/ui/views/animation/square_ink_drop_animation_unittest.cc
+++ b/chromium/ui/views/animation/square_ink_drop_ripple_unittest.cc
@@ -2,28 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_UNITTEST_H_
-#define UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_UNITTEST_H_
+#include "ui/views/animation/square_ink_drop_ripple.h"
-#include "ui/views/animation/square_ink_drop_animation.h"
+#include <memory>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"
-#include "ui/views/animation/ink_drop_animation_observer.h"
+#include "ui/views/animation/ink_drop_ripple_observer.h"
#include "ui/views/animation/ink_drop_state.h"
-#include "ui/views/animation/test/square_ink_drop_animation_test_api.h"
-#include "ui/views/animation/test/test_ink_drop_animation_observer.h"
+#include "ui/views/animation/test/square_ink_drop_ripple_test_api.h"
+#include "ui/views/animation/test/test_ink_drop_ripple_observer.h"
namespace views {
namespace test {
namespace {
-using PaintedShape = views::test::SquareInkDropAnimationTestApi::PaintedShape;
+using PaintedShape = views::test::SquareInkDropRippleTestApi::PaintedShape;
// Transforms a copy of |point| with |transform| and returns it.
gfx::Point TransformPoint(const gfx::Transform& transform,
@@ -33,10 +31,10 @@ gfx::Point TransformPoint(const gfx::Transform& transform,
return transformed_point;
}
-class SquareInkDropAnimationCalculateTransformsTest : public testing::Test {
+class SquareInkDropRippleCalculateTransformsTest : public testing::Test {
public:
- SquareInkDropAnimationCalculateTransformsTest();
- ~SquareInkDropAnimationCalculateTransformsTest() override;
+ SquareInkDropRippleCalculateTransformsTest();
+ ~SquareInkDropRippleCalculateTransformsTest() override;
protected:
// Half the width/height of the drawn ink drop.
@@ -62,66 +60,63 @@ class SquareInkDropAnimationCalculateTransformsTest : public testing::Test {
static const gfx::Point kDrawnBottomMidPoint;
// The test target.
- SquareInkDropAnimation ink_drop_animation_;
+ SquareInkDropRipple ink_drop_ripple_;
// Provides internal access to the test target.
- SquareInkDropAnimationTestApi test_api_;
+ SquareInkDropRippleTestApi test_api_;
// The gfx::Transforms collection that is populated via the
// Calculate*Transforms() calls.
- SquareInkDropAnimationTestApi::InkDropTransforms transforms_;
+ SquareInkDropRippleTestApi::InkDropTransforms transforms_;
private:
- DISALLOW_COPY_AND_ASSIGN(SquareInkDropAnimationCalculateTransformsTest);
+ DISALLOW_COPY_AND_ASSIGN(SquareInkDropRippleCalculateTransformsTest);
};
-const int SquareInkDropAnimationCalculateTransformsTest::kHalfDrawnSize = 5;
-const int SquareInkDropAnimationCalculateTransformsTest::kDrawnSize =
+const int SquareInkDropRippleCalculateTransformsTest::kHalfDrawnSize = 5;
+const int SquareInkDropRippleCalculateTransformsTest::kDrawnSize =
2 * kHalfDrawnSize;
-const int SquareInkDropAnimationCalculateTransformsTest::kTransformedRadius =
- 10;
-const int SquareInkDropAnimationCalculateTransformsTest::kHalfTransformedSize =
+const int SquareInkDropRippleCalculateTransformsTest::kTransformedRadius = 10;
+const int SquareInkDropRippleCalculateTransformsTest::kHalfTransformedSize =
100;
-const int SquareInkDropAnimationCalculateTransformsTest::kTransformedSize =
+const int SquareInkDropRippleCalculateTransformsTest::kTransformedSize =
2 * kHalfTransformedSize;
-const gfx::Point
- SquareInkDropAnimationCalculateTransformsTest::kDrawnCenterPoint =
- gfx::Point(kHalfDrawnSize, kHalfDrawnSize);
+const gfx::Point SquareInkDropRippleCalculateTransformsTest::kDrawnCenterPoint =
+ gfx::Point(kHalfDrawnSize, kHalfDrawnSize);
const gfx::Point
- SquareInkDropAnimationCalculateTransformsTest::kDrawnMidLeftPoint =
+ SquareInkDropRippleCalculateTransformsTest::kDrawnMidLeftPoint =
gfx::Point(0, kHalfDrawnSize);
const gfx::Point
- SquareInkDropAnimationCalculateTransformsTest::kDrawnMidRightPoint =
+ SquareInkDropRippleCalculateTransformsTest::kDrawnMidRightPoint =
gfx::Point(kDrawnSize, kHalfDrawnSize);
-const gfx::Point
- SquareInkDropAnimationCalculateTransformsTest::kDrawnTopMidPoint =
- gfx::Point(kHalfDrawnSize, 0);
+const gfx::Point SquareInkDropRippleCalculateTransformsTest::kDrawnTopMidPoint =
+ gfx::Point(kHalfDrawnSize, 0);
const gfx::Point
- SquareInkDropAnimationCalculateTransformsTest::kDrawnBottomMidPoint =
+ SquareInkDropRippleCalculateTransformsTest::kDrawnBottomMidPoint =
gfx::Point(kHalfDrawnSize, kDrawnSize);
-SquareInkDropAnimationCalculateTransformsTest::
- SquareInkDropAnimationCalculateTransformsTest()
- : ink_drop_animation_(gfx::Size(kDrawnSize, kDrawnSize),
- 2,
- gfx::Size(kHalfDrawnSize, kHalfDrawnSize),
- 1,
- gfx::Point(),
- SK_ColorBLACK),
- test_api_(&ink_drop_animation_) {}
+SquareInkDropRippleCalculateTransformsTest::
+ SquareInkDropRippleCalculateTransformsTest()
+ : ink_drop_ripple_(gfx::Size(kDrawnSize, kDrawnSize),
+ 2,
+ gfx::Size(kHalfDrawnSize, kHalfDrawnSize),
+ 1,
+ gfx::Point(),
+ SK_ColorBLACK),
+ test_api_(&ink_drop_ripple_) {}
-SquareInkDropAnimationCalculateTransformsTest::
- ~SquareInkDropAnimationCalculateTransformsTest() {}
+SquareInkDropRippleCalculateTransformsTest::
+ ~SquareInkDropRippleCalculateTransformsTest() {}
} // namespace
-TEST_F(SquareInkDropAnimationCalculateTransformsTest,
+TEST_F(SquareInkDropRippleCalculateTransformsTest,
TransformedPointsUsingTransformsFromCalculateCircleTransforms) {
test_api_.CalculateCircleTransforms(
gfx::Size(kTransformedSize, kTransformedSize), &transforms_);
@@ -179,7 +174,7 @@ TEST_F(SquareInkDropAnimationCalculateTransformsTest,
}
}
-TEST_F(SquareInkDropAnimationCalculateTransformsTest,
+TEST_F(SquareInkDropRippleCalculateTransformsTest,
TransformedPointsUsingTransformsFromCalculateRectTransforms) {
test_api_.CalculateRectTransforms(
gfx::Size(kTransformedSize, kTransformedSize), kTransformedRadius,
@@ -244,5 +239,3 @@ TEST_F(SquareInkDropAnimationCalculateTransformsTest,
} // namespace test
} // namespace views
-
-#endif // UI_VIEWS_ANIMATION_INK_DROP_ANIMATION_UNITTEST_H_
diff --git a/chromium/ui/views/border.cc b/chromium/ui/views/border.cc
index a7a11440923..f2eb92ff111 100644
--- a/chromium/ui/views/border.cc
+++ b/chromium/ui/views/border.cc
@@ -4,9 +4,11 @@
#include "ui/views/border.h"
+#include <memory>
+
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -137,7 +139,7 @@ gfx::Size EmptyBorder::GetMinimumSize() const {
class BorderPainter : public Border {
public:
- BorderPainter(Painter* painter, const gfx::Insets& insets);
+ BorderPainter(std::unique_ptr<Painter> painter, const gfx::Insets& insets);
// Overridden from Border:
void Paint(const View& view, gfx::Canvas* canvas) override;
@@ -145,16 +147,16 @@ class BorderPainter : public Border {
gfx::Size GetMinimumSize() const override;
private:
- scoped_ptr<Painter> painter_;
+ std::unique_ptr<Painter> painter_;
const gfx::Insets insets_;
DISALLOW_COPY_AND_ASSIGN(BorderPainter);
};
-BorderPainter::BorderPainter(Painter* painter, const gfx::Insets& insets)
- : painter_(painter),
- insets_(insets) {
- DCHECK(painter);
+BorderPainter::BorderPainter(std::unique_ptr<Painter> painter,
+ const gfx::Insets& insets)
+ : painter_(std::move(painter)), insets_(insets) {
+ DCHECK(painter_);
}
void BorderPainter::Paint(const View& view, gfx::Canvas* canvas) {
@@ -178,50 +180,52 @@ Border::~Border() {
}
// static
-scoped_ptr<Border> Border::NullBorder() {
+std::unique_ptr<Border> Border::NullBorder() {
return nullptr;
}
// static
-scoped_ptr<Border> Border::CreateSolidBorder(int thickness, SkColor color) {
- return make_scoped_ptr(new SolidSidedBorder(gfx::Insets(thickness), color));
+std::unique_ptr<Border> Border::CreateSolidBorder(int thickness,
+ SkColor color) {
+ return base::WrapUnique(new SolidSidedBorder(gfx::Insets(thickness), color));
}
// static
-scoped_ptr<Border> Border::CreateEmptyBorder(const gfx::Insets& insets) {
- return make_scoped_ptr(new EmptyBorder(insets));
+std::unique_ptr<Border> Border::CreateEmptyBorder(const gfx::Insets& insets) {
+ return base::WrapUnique(new EmptyBorder(insets));
}
// static
-scoped_ptr<Border> Border::CreateRoundedRectBorder(int thickness,
- int corner_radius,
- SkColor color) {
- return make_scoped_ptr(
+std::unique_ptr<Border> Border::CreateRoundedRectBorder(int thickness,
+ int corner_radius,
+ SkColor color) {
+ return base::WrapUnique(
new RoundedRectBorder(thickness, corner_radius, color));
}
// static
-scoped_ptr<Border> Border::CreateEmptyBorder(int top,
- int left,
- int bottom,
- int right) {
+std::unique_ptr<Border> Border::CreateEmptyBorder(int top,
+ int left,
+ int bottom,
+ int right) {
return CreateEmptyBorder(gfx::Insets(top, left, bottom, right));
}
// static
-scoped_ptr<Border> Border::CreateSolidSidedBorder(int top,
- int left,
- int bottom,
- int right,
- SkColor color) {
- return make_scoped_ptr(new SolidSidedBorder(
- gfx::Insets(top, left, bottom, right), color));
+std::unique_ptr<Border> Border::CreateSolidSidedBorder(int top,
+ int left,
+ int bottom,
+ int right,
+ SkColor color) {
+ return base::WrapUnique(
+ new SolidSidedBorder(gfx::Insets(top, left, bottom, right), color));
}
// static
-scoped_ptr<Border> Border::CreateBorderPainter(Painter* painter,
- const gfx::Insets& insets) {
- return make_scoped_ptr(new BorderPainter(painter, insets));
+std::unique_ptr<Border> Border::CreateBorderPainter(
+ std::unique_ptr<Painter> painter,
+ const gfx::Insets& insets) {
+ return base::WrapUnique(new BorderPainter(std::move(painter), insets));
}
} // namespace views
diff --git a/chromium/ui/views/border.h b/chromium/ui/views/border.h
index e09dbeb09c8..d30cc7ca0b0 100644
--- a/chromium/ui/views/border.h
+++ b/chromium/ui/views/border.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_BORDER_H_
#define UI_VIEWS_BORDER_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/views_export.h"
@@ -43,39 +44,40 @@ class VIEWS_EXPORT Border {
virtual ~Border();
// Convenience for creating a scoped_ptr with no Border.
- static scoped_ptr<Border> NullBorder();
+ static std::unique_ptr<Border> NullBorder();
// Creates a border that is a simple line of the specified thickness and
// color.
- static scoped_ptr<Border> CreateSolidBorder(int thickness, SkColor color);
+ static std::unique_ptr<Border> CreateSolidBorder(int thickness,
+ SkColor color);
// Creates a border that is a rounded rectangle of the specified thickness and
// color.
- static scoped_ptr<Border> CreateRoundedRectBorder(int thickness,
- int corner_radius,
- SkColor color);
+ static std::unique_ptr<Border> CreateRoundedRectBorder(int thickness,
+ int corner_radius,
+ SkColor color);
// Creates a border for reserving space. The returned border does not
// paint anything.
- static scoped_ptr<Border> CreateEmptyBorder(const gfx::Insets& insets);
- static scoped_ptr<Border> CreateEmptyBorder(int top,
- int left,
- int bottom,
- int right);
+ static std::unique_ptr<Border> CreateEmptyBorder(const gfx::Insets& insets);
+ static std::unique_ptr<Border> CreateEmptyBorder(int top,
+ int left,
+ int bottom,
+ int right);
// Creates a border of the specified color, and specified thickness on each
// side.
- static scoped_ptr<Border> CreateSolidSidedBorder(int top,
- int left,
- int bottom,
- int right,
- SkColor color);
+ static std::unique_ptr<Border> CreateSolidSidedBorder(int top,
+ int left,
+ int bottom,
+ int right,
+ SkColor color);
- // Creates a Border from the specified Painter. The border owns the painter,
- // thus the painter is deleted when the Border is deleted.
+ // Creates a Border from the specified Painter.
// |insets| define size of an area allocated for a Border.
- static scoped_ptr<Border> CreateBorderPainter(Painter* painter,
- const gfx::Insets& insets);
+ static std::unique_ptr<Border> CreateBorderPainter(
+ std::unique_ptr<Painter> painter,
+ const gfx::Insets& insets);
// Renders the border for the specified view.
virtual void Paint(const View& view, gfx::Canvas* canvas) = 0;
diff --git a/chromium/ui/views/bubble/bubble_border.h b/chromium/ui/views/bubble/bubble_border.h
index 057459f2539..2ebdf9c6156 100644
--- a/chromium/ui/views/bubble/bubble_border.h
+++ b/chromium/ui/views/bubble/bubble_border.h
@@ -5,10 +5,11 @@
#ifndef UI_VIEWS_BUBBLE_BUBBLE_BORDER_H_
#define UI_VIEWS_BUBBLE_BUBBLE_BORDER_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
@@ -34,7 +35,7 @@ struct BorderImages {
int corner_radius);
virtual ~BorderImages();
- scoped_ptr<Painter> border_painter;
+ std::unique_ptr<Painter> border_painter;
gfx::ImageSkia left_arrow;
gfx::ImageSkia top_arrow;
gfx::ImageSkia right_arrow;
diff --git a/chromium/ui/views/bubble/bubble_border_unittest.cc b/chromium/ui/views/bubble/bubble_border_unittest.cc
index 31323822936..ffb0fbb0700 100644
--- a/chromium/ui/views/bubble/bubble_border_unittest.cc
+++ b/chromium/ui/views/bubble/bubble_border_unittest.cc
@@ -6,8 +6,9 @@
#include <stddef.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect.h"
diff --git a/chromium/ui/views/bubble/bubble_delegate.cc b/chromium/ui/views/bubble/bubble_delegate.cc
deleted file mode 100644
index 5850c3f827a..00000000000
--- a/chromium/ui/views/bubble/bubble_delegate.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "ui/views/bubble/bubble_delegate.h"
-
-#include "build/build_config.h"
-#include "ui/accessibility/ax_view_state.h"
-#include "ui/base/default_style.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/color_utils.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/native_theme/native_theme.h"
-#include "ui/views/bubble/bubble_frame_view.h"
-#include "ui/views/focus/view_storage.h"
-#include "ui/views/layout/layout_constants.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-
-#if defined(OS_WIN)
-#include "ui/base/win/shell.h"
-#endif
-
-namespace views {
-
-namespace {
-
-// Create a widget to host the bubble.
-Widget* CreateBubbleWidget(BubbleDelegateView* bubble) {
- Widget* bubble_widget = new Widget();
- Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
- bubble_params.delegate = bubble;
- bubble_params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
- bubble_params.accept_events = bubble->accept_events();
- if (bubble->parent_window())
- bubble_params.parent = bubble->parent_window();
- else if (bubble->anchor_widget())
- bubble_params.parent = bubble->anchor_widget()->GetNativeView();
- bubble_params.activatable = bubble->CanActivate() ?
- Widget::InitParams::ACTIVATABLE_YES : Widget::InitParams::ACTIVATABLE_NO;
- bubble->OnBeforeBubbleWidgetInit(&bubble_params, bubble_widget);
- bubble_widget->Init(bubble_params);
- if (bubble_params.parent)
- bubble_widget->StackAbove(bubble_params.parent);
- return bubble_widget;
-}
-
-} // namespace
-
-// static
-const char BubbleDelegateView::kViewClassName[] = "BubbleDelegateView";
-
-BubbleDelegateView::BubbleDelegateView()
- : BubbleDelegateView(nullptr, BubbleBorder::TOP_LEFT) {}
-
-BubbleDelegateView::BubbleDelegateView(View* anchor_view,
- BubbleBorder::Arrow arrow)
- : close_on_esc_(true),
- close_on_deactivate_(true),
- anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
- anchor_widget_(NULL),
- arrow_(arrow),
- shadow_(BubbleBorder::SMALL_SHADOW),
- color_explicitly_set_(false),
- margins_(kPanelVertMargin,
- kPanelHorizMargin,
- kPanelVertMargin,
- kPanelHorizMargin),
- accept_events_(true),
- border_accepts_events_(true),
- adjust_if_offscreen_(true),
- parent_window_(NULL),
- close_reason_(CloseReason::UNKNOWN) {
- if (anchor_view)
- SetAnchorView(anchor_view);
- AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
- UpdateColorsFromTheme(GetNativeTheme());
-}
-
-BubbleDelegateView::~BubbleDelegateView() {
- if (GetWidget())
- GetWidget()->RemoveObserver(this);
- SetLayoutManager(NULL);
- SetAnchorView(NULL);
-}
-
-// static
-Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
- bubble_delegate->Init();
- // Get the latest anchor widget from the anchor view at bubble creation time.
- bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView());
- Widget* bubble_widget = CreateBubbleWidget(bubble_delegate);
-
-#if defined(OS_WIN)
- // If glass is enabled, the bubble is allowed to extend outside the bounds of
- // the parent frame and let DWM handle compositing. If not, then we don't
- // want to allow the bubble to extend the frame because it will be clipped.
- bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled());
-#elif (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX)
- // Linux clips bubble windows that extend outside their parent window bounds.
- // Mac never adjusts.
- bubble_delegate->set_adjust_if_offscreen(false);
-#endif
-
- bubble_delegate->SizeToContents();
- bubble_widget->AddObserver(bubble_delegate);
- return bubble_widget;
-}
-
-BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() {
- return this;
-}
-
-bool BubbleDelegateView::ShouldShowCloseButton() const {
- return false;
-}
-
-View* BubbleDelegateView::GetContentsView() {
- return this;
-}
-
-NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView(
- Widget* widget) {
- BubbleFrameView* frame = new BubbleFrameView(
- gfx::Insets(kPanelVertMargin, kPanelHorizMargin, 0, kPanelHorizMargin),
- margins());
- // Note: In CreateBubble, the call to SizeToContents() will cause
- // the relayout that this call requires.
- frame->SetTitleFontList(GetTitleFontList());
- frame->SetFootnoteView(CreateFootnoteView());
-
- BubbleBorder::Arrow adjusted_arrow = arrow();
- if (base::i18n::IsRTL())
- adjusted_arrow = BubbleBorder::horizontal_mirror(adjusted_arrow);
- frame->SetBubbleBorder(scoped_ptr<BubbleBorder>(
- new BubbleBorder(adjusted_arrow, shadow(), color())));
- return frame;
-}
-
-void BubbleDelegateView::GetAccessibleState(ui::AXViewState* state) {
- state->role = ui::AX_ROLE_DIALOG;
-}
-
-const char* BubbleDelegateView::GetClassName() const {
- return kViewClassName;
-}
-
-void BubbleDelegateView::OnWidgetClosing(Widget* widget) {
- DCHECK(GetBubbleFrameView());
- if (widget == GetWidget() && close_reason_ == CloseReason::UNKNOWN &&
- GetBubbleFrameView()->close_button_clicked()) {
- close_reason_ = CloseReason::CLOSE_BUTTON;
- }
-}
-
-void BubbleDelegateView::OnWidgetDestroying(Widget* widget) {
- if (anchor_widget() == widget)
- SetAnchorView(NULL);
-}
-
-void BubbleDelegateView::OnWidgetVisibilityChanging(Widget* widget,
- bool visible) {
-#if defined(OS_WIN)
- // On Windows we need to handle this before the bubble is visible or hidden.
- // Please see the comment on the OnWidgetVisibilityChanging function. On
- // other platforms it is fine to handle it after the bubble is shown/hidden.
- HandleVisibilityChanged(widget, visible);
-#endif
-}
-
-void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget,
- bool visible) {
-#if !defined(OS_WIN)
- HandleVisibilityChanged(widget, visible);
-#endif
-}
-
-void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget,
- bool active) {
- if (close_on_deactivate() && widget == GetWidget() && !active) {
- if (close_reason_ == CloseReason::UNKNOWN)
- close_reason_ = CloseReason::DEACTIVATION;
- GetWidget()->Close();
- }
-}
-
-void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget,
- const gfx::Rect& new_bounds) {
- if (GetBubbleFrameView() && anchor_widget() == widget)
- SizeToContents();
-}
-
-View* BubbleDelegateView::GetAnchorView() const {
- return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_);
-}
-
-gfx::Rect BubbleDelegateView::GetAnchorRect() const {
- if (!GetAnchorView())
- return anchor_rect_;
-
- anchor_rect_ = GetAnchorView()->GetBoundsInScreen();
- anchor_rect_.Inset(anchor_view_insets_);
- return anchor_rect_;
-}
-
-void BubbleDelegateView::OnBeforeBubbleWidgetInit(Widget::InitParams* params,
- Widget* widget) const {
-}
-
-View* BubbleDelegateView::CreateFootnoteView() {
- return nullptr;
-}
-
-void BubbleDelegateView::UseCompactMargins() {
- const int kCompactMargin = 6;
- margins_.Set(kCompactMargin, kCompactMargin, kCompactMargin, kCompactMargin);
-}
-
-void BubbleDelegateView::SetAlignment(BubbleBorder::BubbleAlignment alignment) {
- GetBubbleFrameView()->bubble_border()->set_alignment(alignment);
- SizeToContents();
-}
-
-void BubbleDelegateView::SetArrowPaintType(
- BubbleBorder::ArrowPaintType paint_type) {
- GetBubbleFrameView()->bubble_border()->set_paint_arrow(paint_type);
- SizeToContents();
-}
-
-void BubbleDelegateView::OnAnchorBoundsChanged() {
- SizeToContents();
-}
-
-bool BubbleDelegateView::AcceleratorPressed(
- const ui::Accelerator& accelerator) {
- if (!close_on_esc() || accelerator.key_code() != ui::VKEY_ESCAPE)
- return false;
- close_reason_ = CloseReason::ESCAPE;
- GetWidget()->Close();
- return true;
-}
-
-void BubbleDelegateView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
- UpdateColorsFromTheme(theme);
-}
-
-void BubbleDelegateView::Init() {}
-
-void BubbleDelegateView::SetAnchorView(View* anchor_view) {
- // When the anchor view gets set the associated anchor widget might
- // change as well.
- if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) {
- if (anchor_widget()) {
- anchor_widget_->RemoveObserver(this);
- anchor_widget_ = NULL;
- }
- if (anchor_view) {
- anchor_widget_ = anchor_view->GetWidget();
- if (anchor_widget_)
- anchor_widget_->AddObserver(this);
- }
- }
-
- // Remove the old storage item and set the new (if there is one).
- ViewStorage* view_storage = ViewStorage::GetInstance();
- if (view_storage->RetrieveView(anchor_view_storage_id_))
- view_storage->RemoveView(anchor_view_storage_id_);
- if (anchor_view)
- view_storage->StoreView(anchor_view_storage_id_, anchor_view);
-
- // Do not update anchoring for NULL views; this could indicate that our
- // NativeWindow is being destroyed, so it would be dangerous for us to update
- // our anchor bounds at that point. (It's safe to skip this, since if we were
- // to update the bounds when |anchor_view| is NULL, the bubble won't move.)
- if (anchor_view && GetWidget())
- OnAnchorBoundsChanged();
-}
-
-void BubbleDelegateView::SetAnchorRect(const gfx::Rect& rect) {
- anchor_rect_ = rect;
- if (GetWidget())
- OnAnchorBoundsChanged();
-}
-
-void BubbleDelegateView::SizeToContents() {
- GetWidget()->SetBounds(GetBubbleBounds());
-}
-
-BubbleFrameView* BubbleDelegateView::GetBubbleFrameView() const {
- const NonClientView* view =
- GetWidget() ? GetWidget()->non_client_view() : NULL;
- return view ? static_cast<BubbleFrameView*>(view->frame_view()) : NULL;
-}
-
-gfx::Rect BubbleDelegateView::GetBubbleBounds() {
- // The argument rect has its origin at the bubble's arrow anchor point;
- // its size is the preferred size of the bubble's client view (this view).
- bool anchor_minimized = anchor_widget() && anchor_widget()->IsMinimized();
- return GetBubbleFrameView()->GetUpdatedWindowBounds(GetAnchorRect(),
- GetPreferredSize(), adjust_if_offscreen_ && !anchor_minimized);
-}
-
-const gfx::FontList& BubbleDelegateView::GetTitleFontList() const {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- return rb.GetFontListWithDelta(ui::kTitleFontSizeDelta);
-}
-
-void BubbleDelegateView::UpdateColorsFromTheme(const ui::NativeTheme* theme) {
- if (!color_explicitly_set_)
- color_ = theme->GetSystemColor(ui::NativeTheme::kColorId_BubbleBackground);
- set_background(Background::CreateSolidBackground(color()));
- BubbleFrameView* frame_view = GetBubbleFrameView();
- if (frame_view)
- frame_view->bubble_border()->set_background_color(color());
-}
-
-void BubbleDelegateView::HandleVisibilityChanged(Widget* widget, bool visible) {
- if (widget == GetWidget() && anchor_widget() &&
- anchor_widget()->GetTopLevelWidget()) {
- anchor_widget()->GetTopLevelWidget()->SetAlwaysRenderAsActive(visible);
- }
-
- // Fire AX_EVENT_ALERT for bubbles marked as AX_ROLE_ALERT_DIALOG; this
- // instructs accessibility tools to read the bubble in its entirety rather
- // than just its title and initially focused view. See
- // http://crbug.com/474622 for details.
- if (widget == GetWidget() && visible) {
- ui::AXViewState state;
- GetAccessibleState(&state);
- if (state.role == ui::AX_ROLE_ALERT_DIALOG)
- NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
- }
-}
-
-} // namespace views
diff --git a/chromium/ui/views/bubble/bubble_delegate.h b/chromium/ui/views/bubble/bubble_delegate.h
deleted file mode 100644
index 9392251e22d..00000000000
--- a/chromium/ui/views/bubble/bubble_delegate.h
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (c) 2012 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_VIEWS_BUBBLE_BUBBLE_DELEGATE_H_
-#define UI_VIEWS_BUBBLE_BUBBLE_DELEGATE_H_
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "ui/views/bubble/bubble_border.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_delegate.h"
-#include "ui/views/widget/widget_observer.h"
-
-namespace gfx {
-class FontList;
-class Rect;
-}
-
-namespace views {
-
-class BubbleFrameView;
-
-// BubbleDelegateView creates frame and client views for bubble Widgets.
-// BubbleDelegateView itself is the client's contents view.
-// TODO(estade): remove this in favor of BubbleDialogDelegateView.
-class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
- public WidgetObserver {
- public:
- // Internal class name.
- static const char kViewClassName[];
-
- enum class CloseReason {
- DEACTIVATION,
- ESCAPE,
- CLOSE_BUTTON,
- UNKNOWN,
- };
-
- BubbleDelegateView();
- BubbleDelegateView(View* anchor_view, BubbleBorder::Arrow arrow);
- ~BubbleDelegateView() override;
-
- // Create and initialize the bubble Widget(s) with proper bounds.
- static Widget* CreateBubble(BubbleDelegateView* bubble_delegate);
-
- // WidgetDelegateView overrides:
- BubbleDelegateView* AsBubbleDelegate() override;
- bool ShouldShowCloseButton() const override;
- View* GetContentsView() override;
- NonClientFrameView* CreateNonClientFrameView(Widget* widget) override;
- void GetAccessibleState(ui::AXViewState* state) override;
- const char* GetClassName() const override;
-
- // WidgetObserver overrides:
- void OnWidgetClosing(Widget* widget) override;
- void OnWidgetDestroying(Widget* widget) override;
- void OnWidgetVisibilityChanging(Widget* widget, bool visible) override;
- void OnWidgetVisibilityChanged(Widget* widget, bool visible) override;
- void OnWidgetActivationChanged(Widget* widget, bool active) override;
- void OnWidgetBoundsChanged(Widget* widget,
- const gfx::Rect& new_bounds) override;
-
- bool close_on_esc() const { return close_on_esc_; }
- void set_close_on_esc(bool close_on_esc) { close_on_esc_ = close_on_esc; }
-
- bool close_on_deactivate() const { return close_on_deactivate_; }
- void set_close_on_deactivate(bool close) { close_on_deactivate_ = close; }
-
- View* GetAnchorView() const;
- Widget* anchor_widget() const { return anchor_widget_; }
-
- // The anchor rect is used in the absence of an assigned anchor view.
- const gfx::Rect& anchor_rect() const { return anchor_rect_; }
-
- BubbleBorder::Arrow arrow() const { return arrow_; }
- void set_arrow(BubbleBorder::Arrow arrow) { arrow_ = arrow; }
-
- BubbleBorder::Shadow shadow() const { return shadow_; }
- void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; }
-
- SkColor color() const { return color_; }
- void set_color(SkColor color) {
- color_ = color;
- color_explicitly_set_ = true;
- }
-
- const gfx::Insets& margins() const { return margins_; }
- void set_margins(const gfx::Insets& margins) { margins_ = margins; }
-
- const gfx::Insets& anchor_view_insets() const { return anchor_view_insets_; }
- void set_anchor_view_insets(const gfx::Insets& i) { anchor_view_insets_ = i; }
-
- gfx::NativeView parent_window() const { return parent_window_; }
- void set_parent_window(gfx::NativeView window) { parent_window_ = window; }
-
- bool accept_events() const { return accept_events_; }
- void set_accept_events(bool accept_events) { accept_events_ = accept_events; }
-
- bool border_accepts_events() const { return border_accepts_events_; }
- void set_border_accepts_events(bool event) { border_accepts_events_ = event; }
-
- bool adjust_if_offscreen() const { return adjust_if_offscreen_; }
- void set_adjust_if_offscreen(bool adjust) { adjust_if_offscreen_ = adjust; }
-
- CloseReason close_reason() const { return close_reason_; }
-
- // Get the arrow's anchor rect in screen space.
- virtual gfx::Rect GetAnchorRect() const;
-
- // Allows delegates to provide custom parameters before widget initialization.
- virtual void OnBeforeBubbleWidgetInit(Widget::InitParams* params,
- Widget* widget) const;
-
- // Creates and returns a view to be displayed at the bottom of the bubble.
- virtual View* CreateFootnoteView();
-
- // Sets |margins_| to a default picked for smaller bubbles.
- void UseCompactMargins();
-
- // Sets the bubble alignment relative to the anchor. This may only be called
- // after calling CreateBubble.
- void SetAlignment(BubbleBorder::BubbleAlignment alignment);
-
- // Sets the bubble arrow paint type.
- void SetArrowPaintType(BubbleBorder::ArrowPaintType paint_type);
-
- // Call this method when the anchor bounds have changed to reposition the
- // bubble. The bubble is automatically repositioned when the anchor view
- // bounds change as a result of the widget's bounds changing.
- void OnAnchorBoundsChanged();
-
- protected:
- // Get bubble bounds from the anchor rect and client view's preferred size.
- virtual gfx::Rect GetBubbleBounds();
-
- // Return a FontList to use for the title of the bubble.
- // (The default is MediumFont).
- virtual const gfx::FontList& GetTitleFontList() const;
-
- // View overrides:
- bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
- void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
-
- // Perform view initialization on the contents for bubble sizing.
- virtual void Init();
-
- // Sets the anchor view or rect and repositions the bubble. Note that if a
- // valid view gets passed, the anchor rect will get ignored. If the view gets
- // deleted, but no new view gets set, the last known anchor postion will get
- // returned.
- void SetAnchorView(View* anchor_view);
- void SetAnchorRect(const gfx::Rect& rect);
-
- // Resize and potentially move the bubble to fit the content's preferred size.
- void SizeToContents();
-
- BubbleFrameView* GetBubbleFrameView() const;
-
- private:
- friend class BubbleBorderDelegate;
- friend class BubbleWindowTargeter;
-
- FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, CreateDelegate);
- FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, NonClientHitTest);
-
- // Update the bubble color from |theme|, unless it was explicitly set.
- void UpdateColorsFromTheme(const ui::NativeTheme* theme);
-
- // Handles widget visibility changes.
- void HandleVisibilityChanged(Widget* widget, bool visible);
-
- // Flags controlling bubble closure on the escape key and deactivation.
- bool close_on_esc_;
- bool close_on_deactivate_;
-
- // The view and widget to which this bubble is anchored. Since an anchor view
- // can be deleted without notice, we store it in the ViewStorage and retrieve
- // it from there. It will make sure that the view is still valid.
- const int anchor_view_storage_id_;
- Widget* anchor_widget_;
-
- // The anchor rect used in the absence of an anchor view.
- mutable gfx::Rect anchor_rect_;
-
- // The arrow's location on the bubble.
- BubbleBorder::Arrow arrow_;
-
- // Bubble border shadow to use.
- BubbleBorder::Shadow shadow_;
-
- // The background color of the bubble; and flag for when it's explicitly set.
- SkColor color_;
- bool color_explicitly_set_;
-
- // The margins between the content and the inside of the border.
- gfx::Insets margins_;
-
- // Insets applied to the |anchor_view_| bounds.
- gfx::Insets anchor_view_insets_;
-
- // Specifies whether the bubble (or its border) handles mouse events, etc.
- bool accept_events_;
- bool border_accepts_events_;
-
- // If true (defaults to true), the arrow may be mirrored and moved to fit the
- // bubble on screen better. It would be a no-op if the bubble has no arrow.
- bool adjust_if_offscreen_;
-
- // Parent native window of the bubble.
- gfx::NativeView parent_window_;
-
- CloseReason close_reason_;
-
- DISALLOW_COPY_AND_ASSIGN(BubbleDelegateView);
-};
-
-} // namespace views
-
-#endif // UI_VIEWS_BUBBLE_BUBBLE_DELEGATE_H_
diff --git a/chromium/ui/views/bubble/bubble_delegate_unittest.cc b/chromium/ui/views/bubble/bubble_delegate_unittest.cc
deleted file mode 100644
index f7656f06151..00000000000
--- a/chromium/ui/views/bubble/bubble_delegate_unittest.cc
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include <stddef.h>
-
-#include "base/macros.h"
-#include "ui/base/hit_test.h"
-#include "ui/events/event_utils.h"
-#include "ui/views/bubble/bubble_delegate.h"
-#include "ui/views/bubble/bubble_frame_view.h"
-#include "ui/views/controls/button/label_button.h"
-#include "ui/views/test/test_widget_observer.h"
-#include "ui/views/test/views_test_base.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/widget/widget_observer.h"
-
-namespace views {
-
-namespace {
-
-class TestBubbleDelegateView : public BubbleDelegateView {
- public:
- TestBubbleDelegateView(View* anchor_view)
- : BubbleDelegateView(anchor_view, BubbleBorder::TOP_LEFT),
- view_(new View()) {
- view_->SetFocusable(true);
- AddChildView(view_);
- }
- ~TestBubbleDelegateView() override {}
-
- void SetAnchorRectForTest(gfx::Rect rect) {
- SetAnchorRect(rect);
- }
-
- void SetAnchorViewForTest(View* view) {
- SetAnchorView(view);
- }
-
- // BubbleDelegateView overrides:
- View* GetInitiallyFocusedView() override { return view_; }
- gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); }
-
- BubbleFrameView* GetBubbleFrameViewForTest() const {
- return GetBubbleFrameView();
- }
-
- private:
- View* view_;
-
- DISALLOW_COPY_AND_ASSIGN(TestBubbleDelegateView);
-};
-
-class BubbleDelegateTest : public ViewsTestBase {
- public:
- BubbleDelegateTest() {}
- ~BubbleDelegateTest() override {}
-
- // Creates a test widget that owns its native widget.
- Widget* CreateTestWidget() {
- Widget* widget = new Widget();
- Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- widget->Init(params);
- return widget;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BubbleDelegateTest);
-};
-
-} // namespace
-
-TEST_F(BubbleDelegateTest, CreateDelegate) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- bubble_delegate->set_color(SK_ColorGREEN);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
- EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
- test::TestWidgetObserver bubble_observer(bubble_widget);
- bubble_widget->Show();
-
- BubbleBorder* border = bubble_delegate->GetBubbleFrameView()->bubble_border();
- EXPECT_EQ(bubble_delegate->arrow(), border->arrow());
- EXPECT_EQ(bubble_delegate->color(), border->background_color());
-
- EXPECT_FALSE(bubble_observer.widget_closed());
- bubble_widget->CloseNow();
- EXPECT_TRUE(bubble_observer.widget_closed());
-}
-
-TEST_F(BubbleDelegateTest, CloseAnchorWidget) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- // Preventing close on deactivate should not prevent closing with the anchor.
- bubble_delegate->set_close_on_deactivate(false);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
- EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
- EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
- test::TestWidgetObserver bubble_observer(bubble_widget);
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- bubble_widget->Show();
- EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- // TODO(msw): Remove activation hack to prevent bookkeeping errors in:
- // aura::test::TestActivationClient::OnWindowDestroyed().
- scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- // Ensure that closing the anchor widget also closes the bubble itself.
- anchor_widget->CloseNow();
- EXPECT_TRUE(bubble_observer.widget_closed());
-}
-
-// This test checks that the bubble delegate is capable to handle an early
-// destruction of the used anchor view. (Animations and delayed closure of the
-// bubble will call upon the anchor view to get its location).
-TEST_F(BubbleDelegateTest, CloseAnchorViewTest) {
- // Create an anchor widget and add a view to be used as an anchor view.
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- scoped_ptr<View> anchor_view(new View());
- anchor_widget->GetContentsView()->AddChildView(anchor_view.get());
- TestBubbleDelegateView* bubble_delegate = new TestBubbleDelegateView(
- anchor_view.get());
- // Prevent flakes by avoiding closing on activation changes.
- bubble_delegate->set_close_on_deactivate(false);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
-
- // Check that the anchor view is correct and set up an anchor view rect.
- // Make sure that this rect will get ignored (as long as the anchor view is
- // attached).
- EXPECT_EQ(anchor_view.get(), bubble_delegate->GetAnchorView());
- const gfx::Rect set_anchor_rect = gfx::Rect(10, 10, 100, 100);
- bubble_delegate->SetAnchorRectForTest(set_anchor_rect);
- const gfx::Rect view_rect = bubble_delegate->GetAnchorRect();
- EXPECT_NE(view_rect.ToString(), set_anchor_rect.ToString());
-
- // Create the bubble.
- bubble_widget->Show();
- EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
-
- // Remove now the anchor view and make sure that the original found rect
- // is still kept, so that the bubble does not jump when the view gets deleted.
- anchor_widget->GetContentsView()->RemoveChildView(anchor_view.get());
- anchor_view.reset();
- EXPECT_EQ(NULL, bubble_delegate->GetAnchorView());
- EXPECT_EQ(view_rect.ToString(), bubble_delegate->GetAnchorRect().ToString());
-}
-
-// Testing that a move of the anchor view will lead to new bubble locations.
-TEST_F(BubbleDelegateTest, TestAnchorRectMovesWithViewTest) {
- // Create an anchor widget and add a view to be used as anchor view.
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- TestBubbleDelegateView* bubble_delegate = new TestBubbleDelegateView(
- anchor_widget->GetContentsView());
- BubbleDelegateView::CreateBubble(bubble_delegate);
-
- anchor_widget->GetContentsView()->SetBounds(10, 10, 100, 100);
- const gfx::Rect view_rect = bubble_delegate->GetAnchorRect();
-
- anchor_widget->GetContentsView()->SetBounds(20, 10, 100, 100);
- const gfx::Rect view_rect_2 = bubble_delegate->GetAnchorRect();
- EXPECT_NE(view_rect.ToString(), view_rect_2.ToString());
-}
-
-TEST_F(BubbleDelegateTest, ResetAnchorWidget) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
-
- // Make sure the bubble widget is parented to a widget other than the anchor
- // widget so that closing the anchor widget does not close the bubble widget.
- scoped_ptr<Widget> parent_widget(CreateTestWidget());
- bubble_delegate->set_parent_window(parent_widget->GetNativeView());
- // Preventing close on deactivate should not prevent closing with the parent.
- bubble_delegate->set_close_on_deactivate(false);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
- EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
- EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
- test::TestWidgetObserver bubble_observer(bubble_widget);
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- // Showing and hiding the bubble widget should have no effect on its anchor.
- bubble_widget->Show();
- EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
- bubble_widget->Hide();
- EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
-
- // Ensure that closing the anchor widget clears the bubble's reference to that
- // anchor widget, but the bubble itself does not close.
- anchor_widget->CloseNow();
- EXPECT_NE(anchor_widget.get(), bubble_delegate->anchor_widget());
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- // TODO(msw): Remove activation hack to prevent bookkeeping errors in:
- // aura::test::TestActivationClient::OnWindowDestroyed().
- scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- // Ensure that closing the parent widget also closes the bubble itself.
- parent_widget->CloseNow();
- EXPECT_TRUE(bubble_observer.widget_closed());
-}
-
-TEST_F(BubbleDelegateTest, InitiallyFocusedView) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- EXPECT_EQ(bubble_delegate->GetInitiallyFocusedView(),
- bubble_widget->GetFocusManager()->GetFocusedView());
- bubble_widget->CloseNow();
-}
-
-TEST_F(BubbleDelegateTest, NonClientHitTest) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- TestBubbleDelegateView* bubble_delegate =
- new TestBubbleDelegateView(anchor_widget->GetContentsView());
- BubbleDelegateView::CreateBubble(bubble_delegate);
- BubbleFrameView* frame = bubble_delegate->GetBubbleFrameView();
- const int border = frame->bubble_border()->GetBorderThickness();
-
- struct {
- const int point;
- const int hit;
- } cases[] = {
- { border, HTNOWHERE },
- { border + 50, HTCLIENT },
- { 1000, HTNOWHERE },
- };
-
- for (size_t i = 0; i < arraysize(cases); ++i) {
- gfx::Point point(cases[i].point, cases[i].point);
- EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point))
- << " with border: " << border << ", at point " << cases[i].point;
- }
-}
-
-TEST_F(BubbleDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- test::TestWidgetObserver bubble_observer(bubble_widget);
- EXPECT_FALSE(bubble_observer.widget_closed());
-
- anchor_widget->Show();
- bubble_widget->Show();
- EXPECT_TRUE(bubble_widget->IsVisible());
- anchor_widget->SetBounds(gfx::Rect(10, 10, 100, 100));
- EXPECT_TRUE(bubble_widget->IsVisible());
-}
-
-// Test that setting WidgetDelegate::set_can_activate() to false makes the
-// widget created via BubbleDelegateView::CreateBubble() not activatable.
-TEST_F(BubbleDelegateTest, NotActivatable) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- bubble_delegate->set_can_activate(false);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- bubble_widget->Show();
- EXPECT_FALSE(bubble_widget->CanActivate());
-}
-
-TEST_F(BubbleDelegateTest, CloseReasons) {
- {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- bubble_delegate->set_close_on_deactivate(true);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- anchor_widget->Show();
- bubble_widget->Show();
- anchor_widget->Activate();
- EXPECT_TRUE(bubble_widget->IsClosed());
- EXPECT_EQ(BubbleDelegateView::CloseReason::DEACTIVATION,
- bubble_delegate->close_reason());
- }
-
- {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
- anchor_widget->GetContentsView(), BubbleBorder::NONE);
- bubble_delegate->set_close_on_esc(true);
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- bubble_widget->Show();
- // Cast as a test hack to access AcceleratorPressed() (which is protected
- // in BubbleDelegate).
- static_cast<View*>(bubble_delegate)
- ->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
- EXPECT_TRUE(bubble_widget->IsClosed());
- EXPECT_EQ(BubbleDelegateView::CloseReason::ESCAPE,
- bubble_delegate->close_reason());
- }
-
- {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- TestBubbleDelegateView* bubble_delegate =
- new TestBubbleDelegateView(anchor_widget->GetContentsView());
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
- bubble_widget->Show();
- BubbleFrameView* frame_view = bubble_delegate->GetBubbleFrameViewForTest();
- LabelButton* close_button = frame_view->close_;
- ASSERT_TRUE(close_button);
- frame_view->ButtonPressed(
- close_button,
- ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0),
- ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE));
- EXPECT_TRUE(bubble_widget->IsClosed());
- EXPECT_EQ(BubbleDelegateView::CloseReason::CLOSE_BUTTON,
- bubble_delegate->close_reason());
- }
-}
-
-} // namespace views
diff --git a/chromium/ui/views/bubble/bubble_dialog_delegate.cc b/chromium/ui/views/bubble/bubble_dialog_delegate.cc
index 9673891dc39..066626b81da 100644
--- a/chromium/ui/views/bubble/bubble_dialog_delegate.cc
+++ b/chromium/ui/views/bubble/bubble_dialog_delegate.cc
@@ -94,6 +94,7 @@ bool BubbleDialogDelegateView::ShouldShowCloseButton() const {
ClientView* BubbleDialogDelegateView::CreateClientView(Widget* widget) {
DialogClientView* client = new DialogClientView(widget, GetContentsView());
client->set_button_row_insets(gfx::Insets());
+ widget->non_client_view()->set_mirror_client_in_rtl(mirror_arrow_in_rtl_);
return client;
}
@@ -108,17 +109,13 @@ NonClientFrameView* BubbleDialogDelegateView::CreateNonClientFrameView(
frame->SetFootnoteView(CreateFootnoteView());
BubbleBorder::Arrow adjusted_arrow = arrow();
- if (base::i18n::IsRTL())
+ if (base::i18n::IsRTL() && mirror_arrow_in_rtl_)
adjusted_arrow = BubbleBorder::horizontal_mirror(adjusted_arrow);
- frame->SetBubbleBorder(scoped_ptr<BubbleBorder>(
+ frame->SetBubbleBorder(std::unique_ptr<BubbleBorder>(
new BubbleBorder(adjusted_arrow, shadow(), color())));
return frame;
}
-void BubbleDialogDelegateView::GetAccessibleState(ui::AXViewState* state) {
- state->role = ui::AX_ROLE_DIALOG;
-}
-
const char* BubbleDialogDelegateView::GetClassName() const {
return kViewClassName;
}
@@ -205,6 +202,7 @@ BubbleDialogDelegateView::BubbleDialogDelegateView(View* anchor_view,
anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()),
anchor_widget_(NULL),
arrow_(arrow),
+ mirror_arrow_in_rtl_(true),
shadow_(BubbleBorder::SMALL_SHADOW),
color_explicitly_set_(false),
margins_(kPanelVertMargin,
diff --git a/chromium/ui/views/bubble/bubble_dialog_delegate.h b/chromium/ui/views/bubble/bubble_dialog_delegate.h
index 13c576efd7e..7c8fbce4689 100644
--- a/chromium/ui/views/bubble/bubble_dialog_delegate.h
+++ b/chromium/ui/views/bubble/bubble_dialog_delegate.h
@@ -44,7 +44,6 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
bool ShouldShowCloseButton() const override;
ClientView* CreateClientView(Widget* widget) override;
NonClientFrameView* CreateNonClientFrameView(Widget* widget) override;
- void GetAccessibleState(ui::AXViewState* state) override;
const char* GetClassName() const override;
// WidgetObserver overrides:
@@ -67,6 +66,8 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
BubbleBorder::Arrow arrow() const { return arrow_; }
void set_arrow(BubbleBorder::Arrow arrow) { arrow_ = arrow; }
+ void set_mirror_arrow_in_rtl(bool mirror) { mirror_arrow_in_rtl_ = mirror; }
+
BubbleBorder::Shadow shadow() const { return shadow_; }
void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; }
@@ -173,6 +174,9 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
// The arrow's location on the bubble.
BubbleBorder::Arrow arrow_;
+ // Automatically mirror the arrow in RTL layout.
+ bool mirror_arrow_in_rtl_;
+
// Bubble border shadow to use.
BubbleBorder::Shadow shadow_;
diff --git a/chromium/ui/views/bubble/bubble_dialog_delegate_unittest.cc b/chromium/ui/views/bubble/bubble_dialog_delegate_unittest.cc
index 6c43388c944..ea787f8d094 100644
--- a/chromium/ui/views/bubble/bubble_dialog_delegate_unittest.cc
+++ b/chromium/ui/views/bubble/bubble_dialog_delegate_unittest.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
+#include "base/i18n/rtl.h"
#include "base/macros.h"
#include "ui/base/hit_test.h"
#include "ui/events/event_utils.h"
@@ -25,7 +26,7 @@ class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {
TestBubbleDialogDelegateView(View* anchor_view)
: BubbleDialogDelegateView(anchor_view, BubbleBorder::TOP_LEFT),
view_(new View()) {
- view_->SetFocusable(true);
+ view_->SetFocusBehavior(FocusBehavior::ALWAYS);
AddChildView(view_);
}
~TestBubbleDialogDelegateView() override {}
@@ -48,12 +49,13 @@ class BubbleDialogDelegateTest : public ViewsTestBase {
BubbleDialogDelegateTest() {}
~BubbleDialogDelegateTest() override {}
- // Creates a test widget that owns its native widget.
+ // Creates and shows a test widget that owns its native widget.
Widget* CreateTestWidget() {
Widget* widget = new Widget();
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(params);
+ widget->Show();
return widget;
}
@@ -64,7 +66,7 @@ class BubbleDialogDelegateTest : public ViewsTestBase {
} // namespace
TEST_F(BubbleDialogDelegateTest, CreateDelegate) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
TestBubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
bubble_delegate->set_color(SK_ColorGREEN);
@@ -76,7 +78,6 @@ TEST_F(BubbleDialogDelegateTest, CreateDelegate) {
bubble_widget->Show();
BubbleBorder* border = bubble_delegate->GetBubbleFrameView()->bubble_border();
- EXPECT_EQ(bubble_delegate->arrow(), border->arrow());
EXPECT_EQ(bubble_delegate->color(), border->background_color());
EXPECT_FALSE(bubble_observer.widget_closed());
@@ -84,8 +85,27 @@ TEST_F(BubbleDialogDelegateTest, CreateDelegate) {
EXPECT_TRUE(bubble_observer.widget_closed());
}
+TEST_F(BubbleDialogDelegateTest, MirrorArrowInRtl) {
+ std::string default_locale = base::i18n::GetConfiguredLocale();
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
+ for (bool rtl : {false, true}) {
+ base::i18n::SetICUDefaultLocale(rtl ? "he" : "en");
+ EXPECT_EQ(rtl, base::i18n::IsRTL());
+ for (bool mirror : {false, true}) {
+ TestBubbleDialogDelegateView* bubble =
+ new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
+ bubble->set_mirror_arrow_in_rtl(mirror);
+ BubbleDialogDelegateView::CreateBubble(bubble);
+ EXPECT_EQ(rtl && mirror ? BubbleBorder::horizontal_mirror(bubble->arrow())
+ : bubble->arrow(),
+ bubble->GetBubbleFrameView()->bubble_border()->arrow());
+ }
+ }
+ base::i18n::SetICUDefaultLocale(default_locale);
+}
+
TEST_F(BubbleDialogDelegateTest, CloseAnchorWidget) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
// Preventing close on deactivate should not prevent closing with the anchor.
@@ -104,7 +124,7 @@ TEST_F(BubbleDialogDelegateTest, CloseAnchorWidget) {
// TODO(msw): Remove activation hack to prevent bookkeeping errors in:
// aura::test::TestActivationClient::OnWindowDestroyed().
- scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
+ std::unique_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
EXPECT_FALSE(bubble_observer.widget_closed());
// Ensure that closing the anchor widget also closes the bubble itself.
@@ -117,8 +137,8 @@ TEST_F(BubbleDialogDelegateTest, CloseAnchorWidget) {
// bubble will call upon the anchor view to get its location).
TEST_F(BubbleDialogDelegateTest, CloseAnchorViewTest) {
// Create an anchor widget and add a view to be used as an anchor view.
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
- scoped_ptr<View> anchor_view(new View());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<View> anchor_view(new View());
anchor_widget->GetContentsView()->AddChildView(anchor_view.get());
TestBubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_view.get());
@@ -151,7 +171,7 @@ TEST_F(BubbleDialogDelegateTest, CloseAnchorViewTest) {
// Testing that a move of the anchor view will lead to new bubble locations.
TEST_F(BubbleDialogDelegateTest, TestAnchorRectMovesWithViewTest) {
// Create an anchor widget and add a view to be used as anchor view.
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
TestBubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
BubbleDialogDelegateView::CreateBubble(bubble_delegate);
@@ -165,13 +185,13 @@ TEST_F(BubbleDialogDelegateTest, TestAnchorRectMovesWithViewTest) {
}
TEST_F(BubbleDialogDelegateTest, ResetAnchorWidget) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
// Make sure the bubble widget is parented to a widget other than the anchor
// widget so that closing the anchor widget does not close the bubble widget.
- scoped_ptr<Widget> parent_widget(CreateTestWidget());
+ std::unique_ptr<Widget> parent_widget(CreateTestWidget());
bubble_delegate->set_parent_window(parent_widget->GetNativeView());
// Preventing close on deactivate should not prevent closing with the parent.
bubble_delegate->set_close_on_deactivate(false);
@@ -197,7 +217,7 @@ TEST_F(BubbleDialogDelegateTest, ResetAnchorWidget) {
// TODO(msw): Remove activation hack to prevent bookkeeping errors in:
// aura::test::TestActivationClient::OnWindowDestroyed().
- scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
+ std::unique_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
EXPECT_FALSE(bubble_observer.widget_closed());
// Ensure that closing the parent widget also closes the bubble itself.
@@ -206,7 +226,7 @@ TEST_F(BubbleDialogDelegateTest, ResetAnchorWidget) {
}
TEST_F(BubbleDialogDelegateTest, InitiallyFocusedView) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
Widget* bubble_widget =
@@ -218,7 +238,7 @@ TEST_F(BubbleDialogDelegateTest, InitiallyFocusedView) {
}
TEST_F(BubbleDialogDelegateTest, NonClientHitTest) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
TestBubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
BubbleDialogDelegateView::CreateBubble(bubble_delegate);
@@ -240,7 +260,7 @@ TEST_F(BubbleDialogDelegateTest, NonClientHitTest) {
}
TEST_F(BubbleDialogDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
Widget* bubble_widget =
@@ -248,7 +268,6 @@ TEST_F(BubbleDialogDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
test::TestWidgetObserver bubble_observer(bubble_widget);
EXPECT_FALSE(bubble_observer.widget_closed());
- anchor_widget->Show();
bubble_widget->Show();
EXPECT_TRUE(bubble_widget->IsVisible());
anchor_widget->SetBounds(gfx::Rect(10, 10, 100, 100));
@@ -258,7 +277,7 @@ TEST_F(BubbleDialogDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
// Test that setting WidgetDelegate::set_can_activate() to false makes the
// widget created via BubbleDialogDelegateView::CreateBubble() not activatable.
TEST_F(BubbleDialogDelegateTest, NotActivatable) {
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
bubble_delegate->set_can_activate(false);
@@ -270,20 +289,19 @@ TEST_F(BubbleDialogDelegateTest, NotActivatable) {
TEST_F(BubbleDialogDelegateTest, CloseMethods) {
{
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
bubble_delegate->set_close_on_deactivate(true);
Widget* bubble_widget =
BubbleDialogDelegateView::CreateBubble(bubble_delegate);
- anchor_widget->Show();
bubble_widget->Show();
anchor_widget->Activate();
EXPECT_TRUE(bubble_widget->IsClosed());
}
{
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
BubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
Widget* bubble_widget =
@@ -296,7 +314,7 @@ TEST_F(BubbleDialogDelegateTest, CloseMethods) {
}
{
- scoped_ptr<Widget> anchor_widget(CreateTestWidget());
+ std::unique_ptr<Widget> anchor_widget(CreateTestWidget());
TestBubbleDialogDelegateView* bubble_delegate =
new TestBubbleDialogDelegateView(anchor_widget->GetContentsView());
Widget* bubble_widget =
diff --git a/chromium/ui/views/bubble/bubble_frame_view.cc b/chromium/ui/views/bubble/bubble_frame_view.cc
index 3f8411b22d8..43bac842f05 100644
--- a/chromium/ui/views/bubble/bubble_frame_view.cc
+++ b/chromium/ui/views/bubble/bubble_frame_view.cc
@@ -14,9 +14,10 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/paint_context.h"
#include "ui/compositor/paint_recorder.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/path.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
#include "ui/native_theme/native_theme.h"
#include "ui/resources/grit/ui_resources.h"
@@ -220,7 +221,6 @@ void BubbleFrameView::UpdateWindowIcon() {
title_icon_->SetImage(&image);
}
-
void BubbleFrameView::UpdateWindowTitle() {
title_->SetText(GetWidget()->widget_delegate()->GetWindowTitle());
title_->SetVisible(GetWidget()->widget_delegate()->ShouldShowWindowTitle());
@@ -303,6 +303,7 @@ void BubbleFrameView::Layout() {
gfx::Size title_icon_pref_size(title_icon_->GetPreferredSize());
int padding = 0;
+ int title_height = title_icon_pref_size.height();
if (title_->visible() && !title_->text().empty()) {
if (title_icon_pref_size.width() > 0)
@@ -311,11 +312,11 @@ void BubbleFrameView::Layout() {
const int title_label_x =
bounds.x() + title_icon_pref_size.width() + padding;
title_->SizeToFit(std::max(1, close_->x() - title_label_x));
- title_->SetPosition(gfx::Point(title_label_x, bounds.y()));
+ title_height = std::max(title_height, title_->height());
+ title_->SetPosition(gfx::Point(
+ title_label_x, bounds.y() + (title_height - title_->height()) / 2));
}
- const int title_height =
- std::max(title_icon_pref_size.height(), title_->height());
title_icon_->SetBounds(bounds.x(), bounds.y(), title_icon_pref_size.width(),
title_height);
bounds.set_width(title_->bounds().right() - bounds.x());
@@ -364,7 +365,7 @@ void BubbleFrameView::ButtonPressed(Button* sender, const ui::Event& event) {
}
}
-void BubbleFrameView::SetBubbleBorder(scoped_ptr<BubbleBorder> border) {
+void BubbleFrameView::SetBubbleBorder(std::unique_ptr<BubbleBorder> border) {
bubble_border_ = border.get();
SetBorder(std::move(border));
@@ -414,7 +415,7 @@ gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect,
gfx::Rect BubbleFrameView::GetAvailableScreenBounds(
const gfx::Rect& rect) const {
// The bubble attempts to fit within the current screen bounds.
- return gfx::Screen::GetScreen()
+ return display::Screen::GetScreen()
->GetDisplayNearestPoint(rect.CenterPoint())
.work_area();
}
diff --git a/chromium/ui/views/bubble/bubble_frame_view.h b/chromium/ui/views/bubble/bubble_frame_view.h
index 812c3e77f35..90f1030c7d9 100644
--- a/chromium/ui/views/bubble/bubble_frame_view.h
+++ b/chromium/ui/views/bubble/bubble_frame_view.h
@@ -70,7 +70,7 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
// Use bubble_border() and SetBubbleBorder(), not border() and SetBorder().
BubbleBorder* bubble_border() const { return bubble_border_; }
- void SetBubbleBorder(scoped_ptr<BubbleBorder> border);
+ void SetBubbleBorder(std::unique_ptr<BubbleBorder> border);
gfx::Insets content_margins() const { return content_margins_; }
@@ -85,6 +85,8 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
bool close_button_clicked() const { return close_button_clicked_; }
+ LabelButton* GetCloseButtonForTest() { return close_; }
+
protected:
// Returns the available screen bounds if the frame were to show in |rect|.
virtual gfx::Rect GetAvailableScreenBounds(const gfx::Rect& rect) const;
diff --git a/chromium/ui/views/bubble/bubble_frame_view_unittest.cc b/chromium/ui/views/bubble/bubble_frame_view_unittest.cc
index d71137f5eb2..9f489f525d2 100644
--- a/chromium/ui/views/bubble/bubble_frame_view_unittest.cc
+++ b/chromium/ui/views/bubble/bubble_frame_view_unittest.cc
@@ -2,14 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/bubble/bubble_frame_view.h"
+
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/bubble/bubble_border.h"
-#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
@@ -70,7 +72,7 @@ class TestBubbleFrameView : public BubbleFrameView {
: BubbleFrameView(gfx::Insets(), gfx::Insets(kMargin)),
test_base_(test_base),
available_bounds_(gfx::Rect(0, 0, 1000, 1000)) {
- SetBubbleBorder(scoped_ptr<BubbleBorder>(
+ SetBubbleBorder(std::unique_ptr<BubbleBorder>(
new BubbleBorder(kArrow, BubbleBorder::NO_SHADOW, kColor)));
}
~TestBubbleFrameView() override {}
@@ -102,8 +104,8 @@ class TestBubbleFrameView : public BubbleFrameView {
gfx::Rect available_bounds_;
// Widget returned by GetWidget(). Only created if GetWidget() is called.
- mutable scoped_ptr<TestBubbleFrameViewWidgetDelegate> widget_delegate_;
- mutable scoped_ptr<Widget> widget_;
+ mutable std::unique_ptr<TestBubbleFrameViewWidgetDelegate> widget_delegate_;
+ mutable std::unique_ptr<Widget> widget_;
DISALLOW_COPY_AND_ASSIGN(TestBubbleFrameView);
};
diff --git a/chromium/ui/views/bubble/bubble_window_targeter.cc b/chromium/ui/views/bubble/bubble_window_targeter.cc
index 19e0c85f91a..8fa0da81c94 100644
--- a/chromium/ui/views/bubble/bubble_window_targeter.cc
+++ b/chromium/ui/views/bubble/bubble_window_targeter.cc
@@ -7,15 +7,14 @@
#include "ui/aura/window.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/bubble/bubble_frame_view.h"
namespace views {
-BubbleWindowTargeter::BubbleWindowTargeter(BubbleDelegateView* bubble)
+BubbleWindowTargeter::BubbleWindowTargeter(BubbleDialogDelegateView* bubble)
: wm::MaskedWindowTargeter(bubble->GetWidget()->GetNativeView()),
- bubble_(bubble) {
-}
+ bubble_(bubble) {}
BubbleWindowTargeter::~BubbleWindowTargeter() {
}
diff --git a/chromium/ui/views/bubble/bubble_window_targeter.h b/chromium/ui/views/bubble/bubble_window_targeter.h
index fd9550fcd6e..7b7f87b5f76 100644
--- a/chromium/ui/views/bubble/bubble_window_targeter.h
+++ b/chromium/ui/views/bubble/bubble_window_targeter.h
@@ -11,21 +11,22 @@ class Window;
}
namespace views {
-class BubbleDelegateView;
+
+class BubbleDialogDelegateView;
// A convenient window-targeter that uses a mask based on the content-bounds of
// the bubble-frame.
class VIEWS_EXPORT BubbleWindowTargeter
: public NON_EXPORTED_BASE(wm::MaskedWindowTargeter) {
public:
- explicit BubbleWindowTargeter(BubbleDelegateView* bubble);
+ explicit BubbleWindowTargeter(BubbleDialogDelegateView* bubble);
~BubbleWindowTargeter() override;
private:
// wm::MaskedWindowTargeter:
bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const override;
- views::BubbleDelegateView* bubble_;
+ views::BubbleDialogDelegateView* bubble_;
DISALLOW_COPY_AND_ASSIGN(BubbleWindowTargeter);
};
diff --git a/chromium/ui/views/bubble/bubble_window_targeter_unittest.cc b/chromium/ui/views/bubble/bubble_window_targeter_unittest.cc
index f40aa326977..3533ad2fb38 100644
--- a/chromium/ui/views/bubble/bubble_window_targeter_unittest.cc
+++ b/chromium/ui/views/bubble/bubble_window_targeter_unittest.cc
@@ -9,7 +9,7 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event_utils.h"
#include "ui/views/bubble/bubble_border.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
@@ -17,16 +17,15 @@ namespace views {
namespace {
-class WidgetOwnsNativeBubble : public BubbleDelegateView {
+class WidgetOwnsNativeBubble : public BubbleDialogDelegateView {
public:
WidgetOwnsNativeBubble(View* content, BubbleBorder::Arrow arrow)
- : BubbleDelegateView(content, arrow) {
- }
+ : BubbleDialogDelegateView(content, arrow) {}
~WidgetOwnsNativeBubble() override {}
private:
- // BubbleDelegateView:
+ // BubbleDialogDelegateView:
void OnBeforeBubbleWidgetInit(Widget::InitParams* params,
Widget* widget) const override {
params->ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -62,7 +61,7 @@ class BubbleWindowTargeterTest : public ViewsTestBase {
Widget* anchor_widget() { return anchor_.get(); }
Widget* bubble_widget() { return bubble_widget_.get(); }
- BubbleDelegateView* bubble_delegate() { return bubble_delegate_; }
+ BubbleDialogDelegateView* bubble_delegate() { return bubble_delegate_; }
private:
void CreateAnchorWidget() {
@@ -76,12 +75,13 @@ class BubbleWindowTargeterTest : public ViewsTestBase {
bubble_delegate_ = new WidgetOwnsNativeBubble(
anchor_->GetContentsView(), BubbleBorder::NONE);
bubble_delegate_->set_color(SK_ColorGREEN);
- bubble_widget_.reset(BubbleDelegateView::CreateBubble(bubble_delegate_));
+ bubble_widget_.reset(
+ BubbleDialogDelegateView::CreateBubble(bubble_delegate_));
}
- scoped_ptr<Widget> anchor_;
- scoped_ptr<Widget> bubble_widget_;
- BubbleDelegateView* bubble_delegate_;
+ std::unique_ptr<Widget> anchor_;
+ std::unique_ptr<Widget> bubble_widget_;
+ BubbleDialogDelegateView* bubble_delegate_;
DISALLOW_COPY_AND_ASSIGN(BubbleWindowTargeterTest);
};
@@ -107,7 +107,7 @@ TEST_F(BubbleWindowTargeterTest, HitTest) {
EXPECT_EQ(bubble_window, targeter->FindTargetForEvent(root, &move1));
}
- bubble_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
+ bubble_window->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
new BubbleWindowTargeter(bubble_delegate())));
{
bubble_delegate()->set_margins(gfx::Insets(20));
diff --git a/chromium/ui/views/bubble/tray_bubble_view.cc b/chromium/ui/views/bubble/tray_bubble_view.cc
index ad3267fe659..0303ea5c1f8 100644
--- a/chromium/ui/views/bubble/tray_bubble_view.cc
+++ b/chromium/ui/views/bubble/tray_bubble_view.cc
@@ -320,7 +320,7 @@ TrayBubbleView::TrayBubbleView(gfx::NativeView parent_window,
View* anchor,
Delegate* delegate,
const InitParams& init_params)
- : BubbleDelegateView(anchor, init_params.arrow),
+ : BubbleDialogDelegateView(anchor, init_params.arrow),
params_(init_params),
delegate_(delegate),
preferred_width_(init_params.min_width),
@@ -346,7 +346,7 @@ TrayBubbleView::~TrayBubbleView() {
}
void TrayBubbleView::InitializeAndShowBubble() {
- // Must occur after call to BubbleDelegateView::CreateBubble().
+ // Must occur after call to BubbleDialogDelegateView::CreateBubble().
SetAlignment(params_.arrow_alignment);
bubble_border_->UpdateArrowOffset();
@@ -354,7 +354,7 @@ void TrayBubbleView::InitializeAndShowBubble() {
GetWidget()->Show();
GetWidget()->GetNativeWindow()->SetEventTargeter(
- scoped_ptr<ui::EventTargeter>(new BubbleWindowTargeter(this)));
+ std::unique_ptr<ui::EventTargeter>(new BubbleWindowTargeter(this)));
UpdateBubble();
}
@@ -391,6 +391,10 @@ gfx::Insets TrayBubbleView::GetBorderInsets() const {
return bubble_border_->GetInsets();
}
+int TrayBubbleView::GetDialogButtons() const {
+ return ui::DIALOG_BUTTON_NONE;
+}
+
void TrayBubbleView::Init() {
BoxLayout* layout = new BottomAlignedBoxLayout(this);
layout->SetDefaultFlex(1);
@@ -411,7 +415,7 @@ bool TrayBubbleView::CanActivate() const {
NonClientFrameView* TrayBubbleView::CreateNonClientFrameView(Widget* widget) {
BubbleFrameView* frame = static_cast<BubbleFrameView*>(
- BubbleDelegateView::CreateNonClientFrameView(widget));
+ BubbleDialogDelegateView::CreateNonClientFrameView(widget));
frame->SetBubbleBorder(std::move(owned_bubble_border_));
return frame;
}
diff --git a/chromium/ui/views/bubble/tray_bubble_view.h b/chromium/ui/views/bubble/tray_bubble_view.h
index c0c0c7c2872..b24a2e90eef 100644
--- a/chromium/ui/views/bubble/tray_bubble_view.h
+++ b/chromium/ui/views/bubble/tray_bubble_view.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_
#define UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/mouse_watcher.h"
#include "ui/views/views_export.h"
@@ -31,7 +32,7 @@ class TrayBubbleContentMask;
// Ash status area). Mostly this handles custom anchor location and arrow and
// border rendering. This also has its own delegate for handling mouse events
// and other implementation specific details.
-class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
+class VIEWS_EXPORT TrayBubbleView : public views::BubbleDialogDelegateView,
public views::MouseWatcherListener {
public:
// AnchorType differentiates between bubbles that are anchored on a tray
@@ -73,7 +74,7 @@ class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
// accessible name for the bubble.
virtual base::string16 GetAccessibleNameForBubble() = 0;
- // Passes responsibility for BubbleDelegateView::GetAnchorRect to the
+ // Passes responsibility for BubbleDialogDelegateView::GetAnchorRect to the
// delegate.
virtual gfx::Rect GetAnchorRect(
views::Widget* anchor_widget,
@@ -154,7 +155,7 @@ class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
bool WidgetHasHitTestMask() const override;
void GetWidgetHitTestMask(gfx::Path* mask) const override;
- // Overridden from views::BubbleDelegateView.
+ // Overridden from views::BubbleDialogDelegateView.
gfx::Rect GetAnchorRect() const override;
// Overridden from views::View.
@@ -174,7 +175,8 @@ class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
Delegate* delegate,
const InitParams& init_params);
- // Overridden from views::BubbleDelegateView.
+ // Overridden from views::BubbleDialogDelegateView.
+ int GetDialogButtons() const override;
void Init() override;
// Overridden from views::View.
@@ -189,8 +191,8 @@ class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
// |bubble_border_| and |owned_bubble_border_| point to the same thing, but
// the latter ensures we don't leak it before passing off ownership.
internal::TrayBubbleBorder* bubble_border_;
- scoped_ptr<views::BubbleBorder> owned_bubble_border_;
- scoped_ptr<internal::TrayBubbleContentMask> bubble_content_mask_;
+ std::unique_ptr<views::BubbleBorder> owned_bubble_border_;
+ std::unique_ptr<internal::TrayBubbleContentMask> bubble_content_mask_;
bool is_gesture_dragging_;
// True once the mouse cursor was actively moved by the user over the bubble.
@@ -198,7 +200,7 @@ class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
bool mouse_actively_entered_;
// Used to find any mouse movements.
- scoped_ptr<MouseWatcher> mouse_watcher_;
+ std::unique_ptr<MouseWatcher> mouse_watcher_;
DISALLOW_COPY_AND_ASSIGN(TrayBubbleView);
};
diff --git a/chromium/ui/views/button_drag_utils.cc b/chromium/ui/views/button_drag_utils.cc
index 60bd6e5abca..70ecf3a3891 100644
--- a/chromium/ui/views/button_drag_utils.cc
+++ b/chromium/ui/views/button_drag_utils.cc
@@ -81,7 +81,7 @@ void SetDragImage(const GURL& url,
press_point = gfx::Vector2d(prefsize.width() / 2, prefsize.height() / 2);
// Render the image.
- scoped_ptr<gfx::Canvas> canvas(
+ std::unique_ptr<gfx::Canvas> canvas(
views::GetCanvasForDragImage(widget, prefsize));
button.Paint(ui::CanvasPainter(canvas.get(), 1.f).context());
drag_utils::SetDragImageOnDataObject(*canvas, press_point, data);
diff --git a/chromium/ui/views/cocoa/bridged_content_view.h b/chromium/ui/views/cocoa/bridged_content_view.h
index f4b6a867cd7..20111a8bf6b 100644
--- a/chromium/ui/views/cocoa/bridged_content_view.h
+++ b/chromium/ui/views/cocoa/bridged_content_view.h
@@ -79,6 +79,10 @@ class View;
// Update windowMask_ depending on the current view bounds.
- (void)updateWindowMask;
+// Notifies the associated FocusManager whether full keyboard access is enabled
+// or not.
+- (void)updateFullKeyboardAccess;
+
@end
#endif // UI_VIEWS_COCOA_BRIDGED_CONTENT_VIEW_H_
diff --git a/chromium/ui/views/cocoa/bridged_content_view.mm b/chromium/ui/views/cocoa/bridged_content_view.mm
index 6d72fef5cf7..a59d4f07884 100644
--- a/chromium/ui/views/cocoa/bridged_content_view.mm
+++ b/chromium/ui/views/cocoa/bridged_content_view.mm
@@ -32,6 +32,9 @@ using views::MenuController;
namespace {
+NSString* const kFullKeyboardAccessChangedNotification =
+ @"com.apple.KeyboardUIModeDidChange";
+
// Returns true if all four corners of |rect| are contained inside |path|.
bool IsRectInsidePath(NSRect rect, NSBezierPath* path) {
return [path containsPoint:rect.origin] &&
@@ -160,6 +163,40 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
return union_rect;
}
+// Returns the string corresponding to |requested_range| for the given |client|.
+// If a gfx::Range::InvalidRange() is passed, the full string stored by |client|
+// is returned. Sets |actual_range| corresponding to the returned string.
+base::string16 AttributedSubstringForRangeHelper(
+ const ui::TextInputClient* client,
+ const gfx::Range& requested_range,
+ gfx::Range* actual_range) {
+ // NSRange doesn't support reversed ranges.
+ DCHECK(!requested_range.is_reversed());
+ DCHECK(actual_range);
+
+ base::string16 substring;
+ gfx::Range text_range;
+ *actual_range = gfx::Range::InvalidRange();
+ if (!client || !client->GetTextRange(&text_range))
+ return substring;
+
+ // gfx::Range::Intersect() behaves a bit weirdly. If B is an empty range
+ // contained inside a non-empty range A, B intersection A returns
+ // gfx::Range::InvalidRange(), instead of returning B.
+ *actual_range = text_range.Contains(requested_range)
+ ? requested_range
+ : text_range.Intersect(requested_range);
+
+ // This is a special case for which the complete string should should be
+ // returned. NSTextView also follows this, though the same is not mentioned in
+ // NSTextInputClient documentation.
+ if (!requested_range.IsValid())
+ *actual_range = text_range;
+
+ client->GetTextFromRange(*actual_range, &substring);
+ return substring;
+}
+
} // namespace
@interface BridgedContentView ()
@@ -185,6 +222,9 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
domCode:(ui::DomCode)domCode
eventFlags:(int)eventFlags;
+// Notification handler invoked when the Full Keyboard Access mode is changed.
+- (void)onFullKeyboardAccessModeChanged:(NSNotification*)notification;
+
// Menu action handlers.
- (void)undo:(id)sender;
- (void)redo:(id)sender;
@@ -221,6 +261,17 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
owner:self
userInfo:nil]);
[self addTrackingArea:cursorTrackingArea_.get()];
+
+ // Get notified whenever Full Keyboard Access mode is changed.
+ [[NSDistributedNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(onFullKeyboardAccessModeChanged:)
+ name:kFullKeyboardAccessChangedNotification
+ object:nil];
+
+ // Initialize the focus manager with the correct keyboard accessibility
+ // setting.
+ [self updateFullKeyboardAccess];
}
return self;
}
@@ -228,6 +279,7 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
- (void)clearView {
textInputClient_ = nullptr;
hostedView_ = nullptr;
+ [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
[cursorTrackingArea_.get() clearOwner];
[self removeTrackingArea:cursorTrackingArea_.get()];
}
@@ -293,6 +345,16 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
[windowMask_ transformUsingAffineTransform:flipTransform];
}
+- (void)updateFullKeyboardAccess {
+ if (!hostedView_)
+ return;
+
+ views::FocusManager* focusManager =
+ hostedView_->GetWidget()->GetFocusManager();
+ if (focusManager)
+ focusManager->SetKeyboardAccessible([NSApp isFullKeyboardAccessEnabled]);
+}
+
// BridgedContentView private implementation.
- (void)handleKeyEvent:(NSEvent*)theEvent {
@@ -328,6 +390,12 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(&event);
}
+- (void)onFullKeyboardAccessModeChanged:(NSNotification*)notification {
+ DCHECK([[notification name]
+ isEqualToString:kFullKeyboardAccessChangedNotification]);
+ [self updateFullKeyboardAccess];
+}
+
- (void)undo:(id)sender {
// This DCHECK is more strict than a similar check in handleAction:. It can be
// done here because the actors sending these actions should be calling
@@ -567,6 +635,9 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
// TODO(tapted): Make this list complete, except for insert* methods which are
// dispatched as regular key events in doCommandBySelector:.
+// views::Textfields are single-line only, map Paragraph and Document commands
+// to Line. Also, Up/Down commands correspond to beginning/end of line.
+
// The insertText action message forwards to the TextInputClient unless a menu
// is active. Note that NSResponder's interpretKeyEvents: implementation doesn't
// direct insertText: through doCommandBySelector:, so this is still needed to
@@ -578,6 +649,11 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
// Selection movement and scrolling.
+- (void)moveForward:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveLeft:sender]
+ : [self moveRight:sender];
+}
+
- (void)moveRight:(id)sender {
[self handleAction:IDS_MOVE_RIGHT
keyCode:ui::VKEY_RIGHT
@@ -585,6 +661,11 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
eventFlags:0];
}
+- (void)moveBackward:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveRight:sender]
+ : [self moveLeft:sender];
+}
+
- (void)moveLeft:(id)sender {
[self handleAction:IDS_MOVE_LEFT
keyCode:ui::VKEY_LEFT
@@ -593,19 +674,177 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
}
- (void)moveUp:(id)sender {
- [self handleAction:0
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE
keyCode:ui::VKEY_UP
domCode:ui::DomCode::ARROW_UP
eventFlags:0];
}
- (void)moveDown:(id)sender {
- [self handleAction:0
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE
keyCode:ui::VKEY_DOWN
domCode:ui::DomCode::ARROW_DOWN
eventFlags:0];
}
+- (void)moveWordForward:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveWordLeft:sender]
+ : [self moveWordRight:sender];
+}
+
+- (void)moveWordBackward:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveWordRight:sender]
+ : [self moveWordLeft:sender];
+}
+
+- (void)moveToBeginningOfLine:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE
+ keyCode:ui::VKEY_HOME
+ domCode:ui::DomCode::HOME
+ eventFlags:0];
+}
+
+- (void)moveToEndOfLine:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE
+ keyCode:ui::VKEY_END
+ domCode:ui::DomCode::END
+ eventFlags:0];
+}
+
+- (void)moveToBeginningOfParagraph:(id)sender {
+ [self moveToBeginningOfLine:sender];
+}
+
+- (void)moveToEndOfParagraph:(id)sender {
+ [self moveToEndOfLine:sender];
+}
+
+- (void)moveToEndOfDocument:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE
+ keyCode:ui::VKEY_END
+ domCode:ui::DomCode::END
+ eventFlags:ui::EF_CONTROL_DOWN];
+}
+
+- (void)moveToBeginningOfDocument:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE
+ keyCode:ui::VKEY_HOME
+ domCode:ui::DomCode::HOME
+ eventFlags:ui::EF_CONTROL_DOWN];
+}
+
+- (void)pageDown:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE
+ keyCode:ui::VKEY_NEXT
+ domCode:ui::DomCode::PAGE_DOWN
+ eventFlags:0];
+}
+
+- (void)pageUp:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE
+ keyCode:ui::VKEY_PRIOR
+ domCode:ui::DomCode::PAGE_UP
+ eventFlags:0];
+}
+
+- (void)moveBackwardAndModifySelection:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveRightAndModifySelection:sender]
+ : [self moveLeftAndModifySelection:sender];
+}
+
+- (void)moveForwardAndModifySelection:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveLeftAndModifySelection:sender]
+ : [self moveRightAndModifySelection:sender];
+}
+
+- (void)moveWordForwardAndModifySelection:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveWordLeftAndModifySelection:sender]
+ : [self moveWordRightAndModifySelection:sender];
+}
+
+- (void)moveWordBackwardAndModifySelection:(id)sender {
+ IsTextRTL(textInputClient_) ? [self moveWordRightAndModifySelection:sender]
+ : [self moveWordLeftAndModifySelection:sender];
+}
+
+- (void)moveUpAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_UP
+ domCode:ui::DomCode::ARROW_UP
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveDownAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_DOWN
+ domCode:ui::DomCode::ARROW_DOWN
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveToBeginningOfLineAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_HOME
+ domCode:ui::DomCode::HOME
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveToEndOfLineAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_END
+ domCode:ui::DomCode::END
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveToBeginningOfParagraphAndModifySelection:(id)sender {
+ [self moveToBeginningOfLineAndModifySelection:sender];
+}
+
+- (void)moveToEndOfParagraphAndModifySelection:(id)sender {
+ [self moveToEndOfLineAndModifySelection:sender];
+}
+
+- (void)moveToEndOfDocumentAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_END
+ domCode:ui::DomCode::END
+ eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveToBeginningOfDocumentAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_HOME
+ domCode:ui::DomCode::HOME
+ eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
+}
+
+- (void)pageDownAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_NEXT
+ domCode:ui::DomCode::PAGE_DOWN
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
+- (void)pageUpAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_PRIOR
+ domCode:ui::DomCode::PAGE_UP
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveParagraphForwardAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_DOWN
+ domCode:ui::DomCode::ARROW_DOWN
+ eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
+}
+
+- (void)moveParagraphBackwardAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_UP
+ domCode:ui::DomCode::ARROW_UP
+ eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
+}
+
- (void)moveWordRight:(id)sender {
[self handleAction:IDS_MOVE_WORD_RIGHT
keyCode:ui::VKEY_RIGHT
@@ -620,13 +859,6 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
eventFlags:ui::EF_CONTROL_DOWN];
}
-- (void)moveLeftAndModifySelection:(id)sender {
- [self handleAction:IDS_MOVE_LEFT_AND_MODIFY_SELECTION
- keyCode:ui::VKEY_LEFT
- domCode:ui::DomCode::ARROW_LEFT
- eventFlags:ui::EF_SHIFT_DOWN];
-}
-
- (void)moveRightAndModifySelection:(id)sender {
[self handleAction:IDS_MOVE_RIGHT_AND_MODIFY_SELECTION
keyCode:ui::VKEY_RIGHT
@@ -634,6 +866,13 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
eventFlags:ui::EF_SHIFT_DOWN];
}
+- (void)moveLeftAndModifySelection:(id)sender {
+ [self handleAction:IDS_MOVE_LEFT_AND_MODIFY_SELECTION
+ keyCode:ui::VKEY_LEFT
+ domCode:ui::DomCode::ARROW_LEFT
+ eventFlags:ui::EF_SHIFT_DOWN];
+}
+
- (void)moveWordRightAndModifySelection:(id)sender {
[self handleAction:IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION
keyCode:ui::VKEY_RIGHT
@@ -649,31 +888,25 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
}
- (void)moveToLeftEndOfLine:(id)sender {
- [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE
- keyCode:ui::VKEY_HOME
- domCode:ui::DomCode::HOME
- eventFlags:0];
+ IsTextRTL(textInputClient_) ? [self moveToEndOfLine:sender]
+ : [self moveToBeginningOfLine:sender];
}
- (void)moveToRightEndOfLine:(id)sender {
- [self handleAction:IDS_MOVE_TO_END_OF_LINE
- keyCode:ui::VKEY_END
- domCode:ui::DomCode::END
- eventFlags:0];
+ IsTextRTL(textInputClient_) ? [self moveToBeginningOfLine:sender]
+ : [self moveToEndOfLine:sender];
}
- (void)moveToLeftEndOfLineAndModifySelection:(id)sender {
- [self handleAction:IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
- keyCode:ui::VKEY_HOME
- domCode:ui::DomCode::HOME
- eventFlags:ui::EF_SHIFT_DOWN];
+ IsTextRTL(textInputClient_)
+ ? [self moveToEndOfLineAndModifySelection:sender]
+ : [self moveToBeginningOfLineAndModifySelection:sender];
}
- (void)moveToRightEndOfLineAndModifySelection:(id)sender {
- [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
- keyCode:ui::VKEY_END
- domCode:ui::DomCode::END
- eventFlags:ui::EF_SHIFT_DOWN];
+ IsTextRTL(textInputClient_)
+ ? [self moveToBeginningOfLineAndModifySelection:sender]
+ : [self moveToEndOfLineAndModifySelection:sender];
}
// Deletions.
@@ -706,6 +939,28 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
eventFlags:ui::EF_CONTROL_DOWN];
}
+- (void)deleteToBeginningOfLine:(id)sender {
+ [self handleAction:IDS_DELETE_TO_BEGINNING_OF_LINE
+ keyCode:ui::VKEY_BACK
+ domCode:ui::DomCode::BACKSPACE
+ eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
+}
+
+- (void)deleteToEndOfLine:(id)sender {
+ [self handleAction:IDS_DELETE_TO_END_OF_LINE
+ keyCode:ui::VKEY_DELETE
+ domCode:ui::DomCode::DEL
+ eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN];
+}
+
+- (void)deleteToBeginningOfParagraph:(id)sender {
+ [self deleteToBeginningOfLine:sender];
+}
+
+- (void)deleteToEndOfParagraph:(id)sender {
+ [self deleteToEndOfLine:sender];
+}
+
// Cancellation.
- (void)cancelOperation:(id)sender {
@@ -759,17 +1014,20 @@ gfx::Rect GetFirstRectForRangeHelper(const ui::TextInputClient* client,
- (NSAttributedString*)
attributedSubstringForProposedRange:(NSRange)range
actualRange:(NSRangePointer)actualRange {
- base::string16 substring;
- if (textInputClient_) {
- gfx::Range textRange;
- textInputClient_->GetTextRange(&textRange);
- gfx::Range subrange = textRange.Intersect(gfx::Range(range));
- textInputClient_->GetTextFromRange(subrange, &substring);
- if (actualRange)
- *actualRange = subrange.ToNSRange();
+ gfx::Range actual_range;
+ base::string16 substring = AttributedSubstringForRangeHelper(
+ textInputClient_, gfx::Range(range), &actual_range);
+ if (actualRange) {
+ // To maintain consistency with NSTextView, return range {0,0} for an out of
+ // bounds requested range.
+ *actualRange =
+ actual_range.IsValid() ? actual_range.ToNSRange() : NSMakeRange(0, 0);
}
- return [[[NSAttributedString alloc]
- initWithString:base::SysUTF16ToNSString(substring)] autorelease];
+ return substring.empty()
+ ? nil
+ : [[[NSAttributedString alloc]
+ initWithString:base::SysUTF16ToNSString(substring)]
+ autorelease];
}
- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
diff --git a/chromium/ui/views/cocoa/bridged_native_widget.h b/chromium/ui/views/cocoa/bridged_native_widget.h
index fc521597ee7..e4df8e78faa 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget.h
+++ b/chromium/ui/views/cocoa/bridged_native_widget.h
@@ -7,11 +7,11 @@
#import <Cocoa/Cocoa.h>
+#include <memory>
#include <vector>
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#import "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/base/ime/input_method_delegate.h"
#include "ui/compositor/layer_owner.h"
@@ -260,9 +260,9 @@ class VIEWS_EXPORT BridgedNativeWidget
base::scoped_nsobject<NSWindow> window_;
base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_;
base::scoped_nsobject<BridgedContentView> bridged_view_;
- scoped_ptr<ui::InputMethod> input_method_;
- scoped_ptr<CocoaMouseCapture> mouse_capture_;
- scoped_ptr<TooltipManager> tooltip_manager_;
+ std::unique_ptr<ui::InputMethod> input_method_;
+ std::unique_ptr<CocoaMouseCapture> mouse_capture_;
+ std::unique_ptr<TooltipManager> tooltip_manager_;
FocusManager* focus_manager_; // Weak. Owned by our Widget.
Widget::InitParams::Type widget_type_;
@@ -270,8 +270,8 @@ class VIEWS_EXPORT BridgedNativeWidget
std::vector<BridgedNativeWidget*> child_windows_;
base::scoped_nsobject<NSView> compositor_superview_;
- scoped_ptr<ui::AcceleratedWidgetMac> compositor_widget_;
- scoped_ptr<ui::Compositor> compositor_;
+ std::unique_ptr<ui::AcceleratedWidgetMac> compositor_widget_;
+ std::unique_ptr<ui::Compositor> compositor_;
// Tracks the bounds when the window last started entering fullscreen. Used to
// provide an answer for GetRestoredBounds(), but not ever sent to Cocoa (it
diff --git a/chromium/ui/views/cocoa/bridged_native_widget.mm b/chromium/ui/views/cocoa/bridged_native_widget.mm
index 0ccff9d15a0..1c9560f2e88 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget.mm
+++ b/chromium/ui/views/cocoa/bridged_native_widget.mm
@@ -12,17 +12,17 @@
#import "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#import "base/mac/sdk_forward_declarations.h"
-#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
#import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/input_method_factory.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/gfx/geometry/dip_util.h"
#import "ui/gfx/mac/coordinate_conversion.h"
#import "ui/gfx/mac/nswindow_frame_controls.h"
-#include "ui/gfx/screen.h"
#import "ui/views/cocoa/bridged_content_view.h"
#import "ui/views/cocoa/cocoa_mouse_capture.h"
#include "ui/views/cocoa/tooltip_manager_mac.h"
@@ -107,8 +107,8 @@ const int kResizeAreaCornerSize = 12;
int kWindowPropertiesKey;
float GetDeviceScaleFactorFromView(NSView* view) {
- gfx::Display display =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(view);
+ display::Display display =
+ display::Screen::GetScreen()->GetDisplayNearestWindow(view);
DCHECK(display.is_valid());
return display.device_scale_factor();
}
@@ -799,6 +799,9 @@ void BridgedNativeWidget::OnWindowKeyStatusChangedTo(bool is_key) {
if ([window_ contentView] == [window_ firstResponder]) {
if (is_key) {
widget->OnNativeFocus();
+ // Explicitly set the keyboard accessibility state on regaining key
+ // window status.
+ [bridged_view_ updateFullKeyboardAccess];
widget->GetFocusManager()->RestoreFocusedView();
} else {
widget->OnNativeBlur();
diff --git a/chromium/ui/views/cocoa/bridged_native_widget_interactive_uitest.mm b/chromium/ui/views/cocoa/bridged_native_widget_interactive_uitest.mm
index 79fdac10510..9dc032a2ffe 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget_interactive_uitest.mm
+++ b/chromium/ui/views/cocoa/bridged_native_widget_interactive_uitest.mm
@@ -70,7 +70,7 @@ class BridgedNativeWidgetUITest : public test::WidgetTest {
}
protected:
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
};
// Tests for correct fullscreen tracking, regardless of whether it is initiated
diff --git a/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm b/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm
index 3b3eb082631..1faee145fec 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm
+++ b/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -6,19 +6,21 @@
#import <Cocoa/Cocoa.h>
+#include <memory>
+
#import "base/mac/foundation_util.h"
#import "base/mac/mac_util.h"
#import "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "testing/gtest_mac.h"
#import "ui/base/cocoa/window_size_constants.h"
#include "ui/base/ime/input_method.h"
-#import "ui/gfx/test/ui_cocoa_test_helper.h"
#import "ui/gfx/mac/coordinate_conversion.h"
+#import "ui/gfx/test/ui_cocoa_test_helper.h"
#import "ui/views/cocoa/bridged_content_view.h"
#import "ui/views/cocoa/native_widget_mac_nswindow.h"
#import "ui/views/cocoa/views_nswindow_delegate.h"
@@ -38,6 +40,21 @@ using base::SysUTF8ToNSString;
EXPECT_EQ(a.location, b.location); \
EXPECT_EQ(a.length, b.length);
+// Helpers to verify an expectation against both the actual toolkit-views
+// behaviour and the Cocoa behaviour.
+
+#define EXPECT_NSEQ_3(expected_literal, expected_cocoa, actual_views) \
+ EXPECT_NSEQ(expected_literal, actual_views); \
+ EXPECT_NSEQ(expected_cocoa, actual_views);
+
+#define EXPECT_EQ_RANGE_3(expected_literal, expected_cocoa, actual_views) \
+ EXPECT_EQ_RANGE(expected_literal, actual_views); \
+ EXPECT_EQ_RANGE(expected_cocoa, actual_views);
+
+#define EXPECT_EQ_3(expected_literal, expected_cocoa, actual_views) \
+ EXPECT_EQ(expected_literal, actual_views); \
+ EXPECT_EQ(expected_cocoa, actual_views);
+
namespace {
// Empty range shortcut for readibility.
@@ -125,9 +142,7 @@ class MockNativeWidgetMac : public NativeWidgetMac {
MockNativeWidgetMac(Widget* delegate) : NativeWidgetMac(delegate) {}
// Expose a reference, so that it can be reset() independently.
- scoped_ptr<BridgedNativeWidget>& bridge() {
- return bridge_;
- }
+ std::unique_ptr<BridgedNativeWidget>& bridge() { return bridge_; }
// internal::NativeWidgetPrivate:
void InitNativeWidget(const Widget::InitParams& params) override {
@@ -157,7 +172,7 @@ class BridgedNativeWidgetTestBase : public ui::CocoaTest {
native_widget_mac_(new MockNativeWidgetMac(widget_.get())) {
}
- scoped_ptr<BridgedNativeWidget>& bridge() {
+ std::unique_ptr<BridgedNativeWidget>& bridge() {
return native_widget_mac_->bridge();
}
@@ -184,7 +199,7 @@ class BridgedNativeWidgetTestBase : public ui::CocoaTest {
}
protected:
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
MockNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|.
// Make the InitParams available to tests to cover initialization codepaths.
@@ -197,24 +212,69 @@ class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase {
~BridgedNativeWidgetTest() override;
// Install a textfield with input type |text_input_type| in the view hierarchy
- // and make it the text input client.
- void InstallTextField(const std::string& text,
+ // and make it the text input client. Also initializes |dummy_text_view_|.
+ void InstallTextField(const base::string16& text,
ui::TextInputType text_input_type);
// Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view
- // hierarchy and make it the text input client.
+ // hierarchy and make it the text input client. Also initializes
+ // |dummy_text_view_|.
+ void InstallTextField(const base::string16& text);
+
void InstallTextField(const std::string& text);
- // Returns the current text as std::string.
- std::string GetText();
+ // Returns the actual current text for |ns_view_|.
+ NSString* GetActualText();
+
+ // Returns the expected current text from |dummy_text_view_|.
+ NSString* GetExpectedText();
+
+ // Returns the actual selection range for |ns_view_|.
+ NSRange GetActualSelectionRange();
+
+ // Returns the expected selection range from |dummy_text_view_|.
+ NSRange GetExpectedSelectionRange();
+
+ // Set the selection range for the installed textfield and |dummy_text_view_|.
+ void SetSelectionRange(NSRange range);
+
+ // Perform command |sel| on |ns_view_| and |dummy_text_view_|.
+ void PerformCommand(SEL sel);
+
+ // Make selection from |start| to |end| on installed views::Textfield and
+ // |dummy_text_view_|. If |start| > |end|, extend selection to left from
+ // |start|.
+ void MakeSelection(int start, int end);
// testing::Test:
void SetUp() override;
void TearDown() override;
protected:
- scoped_ptr<views::View> view_;
- BridgedContentView* ns_view_; // Weak. Owned by bridge().
+ // Test delete to beginning of line or paragraph based on |sel|. |sel| can be
+ // either deleteToBeginningOfLine: or deleteToBeginningOfParagraph:.
+ void TestDeleteBeginning(SEL sel);
+
+ // Test delete to end of line or paragraph based on |sel|. |sel| can be
+ // either deleteToEndOfLine: or deleteToEndOfParagraph:.
+ void TestDeleteEnd(SEL sel);
+
+ // Test editing commands in |selectors| against the expectations set by
+ // |dummy_text_view_|. This is done by selecting every substring within a set
+ // of test strings (both RTL and non-RTL) and performing every selector on
+ // both the NSTextView and the BridgedContentView hosting a focused
+ // views::TextField to ensure the resulting text and selection ranges match.
+ // |selectors| is an NSArray of NSStrings.
+ void TestEditingCommands(NSArray* selectors);
+
+ std::unique_ptr<views::View> view_;
+
+ // Weak. Owned by bridge().
+ BridgedContentView* ns_view_;
+
+ // An NSTextView which helps set the expectations for our tests.
+ base::scoped_nsobject<NSTextView> dummy_text_view_;
+
base::MessageLoopForUI message_loop_;
private:
@@ -228,10 +288,10 @@ BridgedNativeWidgetTest::~BridgedNativeWidgetTest() {
}
void BridgedNativeWidgetTest::InstallTextField(
- const std::string& text,
+ const base::string16& text,
ui::TextInputType text_input_type) {
Textfield* textfield = new Textfield();
- textfield->SetText(ASCIIToUTF16(text));
+ textfield->SetText(text);
textfield->SetTextInputType(text_input_type);
view_->RemoveAllChildViews(true);
view_->AddChildView(textfield);
@@ -243,17 +303,67 @@ void BridgedNativeWidgetTest::InstallTextField(
textfield->RequestFocus();
[ns_view_ setTextInputClient:textfield];
+
+ // Initialize the dummy text view.
+ dummy_text_view_.reset([[NSTextView alloc] initWithFrame:NSZeroRect]);
+ [dummy_text_view_ setString:SysUTF16ToNSString(text)];
}
-void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
+void BridgedNativeWidgetTest::InstallTextField(const base::string16& text) {
InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT);
}
-std::string BridgedNativeWidgetTest::GetText() {
+void BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
+ InstallTextField(base::ASCIIToUTF16(text), ui::TEXT_INPUT_TYPE_TEXT);
+}
+
+NSString* BridgedNativeWidgetTest::GetActualText() {
NSRange range = NSMakeRange(0, NSUIntegerMax);
- NSAttributedString* text =
- [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL];
- return SysNSStringToUTF8([text string]);
+ return [[ns_view_ attributedSubstringForProposedRange:range
+ actualRange:nullptr] string];
+}
+
+NSString* BridgedNativeWidgetTest::GetExpectedText() {
+ NSRange range = NSMakeRange(0, NSUIntegerMax);
+ return
+ [[dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:nullptr] string];
+}
+
+NSRange BridgedNativeWidgetTest::GetActualSelectionRange() {
+ return [ns_view_ selectedRange];
+}
+
+NSRange BridgedNativeWidgetTest::GetExpectedSelectionRange() {
+ return [dummy_text_view_ selectedRange];
+}
+
+void BridgedNativeWidgetTest::SetSelectionRange(NSRange range) {
+ ui::TextInputClient* client = [ns_view_ textInputClient];
+ client->SetSelectionRange(gfx::Range(range));
+
+ [dummy_text_view_ setSelectedRange:range];
+}
+
+void BridgedNativeWidgetTest::PerformCommand(SEL sel) {
+ [ns_view_ doCommandBySelector:sel];
+ [dummy_text_view_ doCommandBySelector:sel];
+}
+
+void BridgedNativeWidgetTest::MakeSelection(int start, int end) {
+ ui::TextInputClient* client = [ns_view_ textInputClient];
+ client->SetSelectionRange(gfx::Range(start, end));
+
+ // Though NSTextView has a selectionAffinity property, it does not seem to
+ // correspond to the selection direction. Hence we extend the selection from
+ //|start| to |end|.
+ [dummy_text_view_ setSelectedRange:NSMakeRange(start, 0)];
+ SEL sel = start > end ? @selector(moveBackwardAndModifySelection:)
+ : @selector(moveForwardAndModifySelection:);
+ size_t delta = std::abs(end - start);
+
+ for (size_t i = 0; i < delta; i++)
+ [dummy_text_view_ doCommandBySelector:sel];
}
void BridgedNativeWidgetTest::SetUp() {
@@ -285,6 +395,97 @@ void BridgedNativeWidgetTest::TearDown() {
BridgedNativeWidgetTestBase::TearDown();
}
+void BridgedNativeWidgetTest::TestDeleteBeginning(SEL sel) {
+ InstallTextField("foo bar baz");
+ EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Move the caret to the beginning of the line.
+ SetSelectionRange(NSMakeRange(0, 0));
+ // Verify no deletion takes place.
+ PerformCommand(sel);
+ EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Move the caret as- "foo| bar baz".
+ SetSelectionRange(NSMakeRange(3, 0));
+ PerformCommand(sel);
+ // Verify state is "| bar baz".
+ EXPECT_NSEQ_3(@" bar baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Make a selection as- " bar |baz|".
+ SetSelectionRange(NSMakeRange(5, 3));
+ PerformCommand(sel);
+ // Verify only the selection is deleted so that the state is " bar |".
+ EXPECT_NSEQ_3(@" bar ", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(5, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+}
+
+void BridgedNativeWidgetTest::TestDeleteEnd(SEL sel) {
+ InstallTextField("foo bar baz");
+ EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Caret is at the end of the line. Verify no deletion takes place.
+ PerformCommand(sel);
+ EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Move the caret as- "foo bar| baz".
+ SetSelectionRange(NSMakeRange(7, 0));
+ PerformCommand(sel);
+ // Verify state is "foo bar|".
+ EXPECT_NSEQ_3(@"foo bar", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(7, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Make a selection as- "|foo |bar".
+ SetSelectionRange(NSMakeRange(0, 4));
+ PerformCommand(sel);
+ // Verify only the selection is deleted so that the state is "|bar".
+ EXPECT_NSEQ_3(@"bar", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+}
+
+void BridgedNativeWidgetTest::TestEditingCommands(NSArray* selectors) {
+ const base::string16 test_strings[] = {
+ base::WideToUTF16(L"ab c"),
+ base::WideToUTF16(L"\x0634\x0632 \x064A") // RTL string.
+ };
+
+ for (const base::string16& test_string : test_strings) {
+ for (NSString* selector_string in selectors) {
+ SEL sel = NSSelectorFromString(selector_string);
+ const int len = test_string.length();
+ for (int i = 0; i <= len; i++) {
+ for (int j = 0; j <= len; j++) {
+ SCOPED_TRACE(base::StringPrintf(
+ "Testing range [%d-%d] for case %s and selector %s\n", i, j,
+ base::UTF16ToUTF8(test_string).c_str(),
+ base::SysNSStringToUTF8(selector_string).c_str()));
+
+ InstallTextField(test_string);
+ MakeSelection(i, j);
+ EXPECT_EQ_RANGE_3(NSMakeRange(std::min(i, j), std::abs(i - j)),
+ GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ PerformCommand(sel);
+ EXPECT_NSEQ(GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE(GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+ }
+ }
+ }
+ }
+}
+
// The TEST_VIEW macro expects the view it's testing to have a superview. In
// these tests, the NSView bridge is a contentView, at the root. These mimic
// what TEST_VIEW usually does.
@@ -418,7 +619,7 @@ TEST_F(BridgedNativeWidgetInitTest, ShadowType) {
// Ensure a nil NSTextInputContext is returned when the ui::TextInputClient is
// not editable, a password field, or unset.
TEST_F(BridgedNativeWidgetTest, InputContext) {
- const std::string test_string = "test_str";
+ const base::string16 test_string = base::ASCIIToUTF16("test_str");
InstallTextField(test_string, ui::TEXT_INPUT_TYPE_PASSWORD);
EXPECT_FALSE([ns_view_ inputContext]);
InstallTextField(test_string, ui::TEXT_INPUT_TYPE_TEXT);
@@ -436,11 +637,18 @@ TEST_F(BridgedNativeWidgetTest, TextInput_GetCompleteString) {
NSRange range = NSMakeRange(0, test_string.size());
NSRange actual_range;
- NSAttributedString* text =
+
+ NSAttributedString* actual_text =
[ns_view_ attributedSubstringForProposedRange:range
actualRange:&actual_range];
- EXPECT_EQ(test_string, SysNSStringToUTF8([text string]));
- EXPECT_EQ_RANGE(range, actual_range);
+
+ NSRange expected_range;
+ NSAttributedString* expected_text =
+ [dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:&expected_range];
+
+ EXPECT_NSEQ_3(@"foo bar baz", [expected_text string], [actual_text string]);
+ EXPECT_EQ_RANGE_3(range, expected_range, actual_range);
}
// Test getting middle substring using text input protocol.
@@ -450,11 +658,17 @@ TEST_F(BridgedNativeWidgetTest, TextInput_GetMiddleSubstring) {
NSRange range = NSMakeRange(4, 3);
NSRange actual_range;
- NSAttributedString* text =
+ NSAttributedString* actual_text =
[ns_view_ attributedSubstringForProposedRange:range
actualRange:&actual_range];
- EXPECT_EQ("bar", SysNSStringToUTF8([text string]));
- EXPECT_EQ_RANGE(range, actual_range);
+
+ NSRange expected_range;
+ NSAttributedString* expected_text =
+ [dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:&expected_range];
+
+ EXPECT_NSEQ_3(@"bar", [expected_text string], [actual_text string]);
+ EXPECT_EQ_RANGE_3(range, expected_range, actual_range);
}
// Test getting ending substring using text input protocol.
@@ -464,12 +678,16 @@ TEST_F(BridgedNativeWidgetTest, TextInput_GetEndingSubstring) {
NSRange range = NSMakeRange(8, 100);
NSRange actual_range;
- NSAttributedString* text =
+ NSAttributedString* actual_text =
[ns_view_ attributedSubstringForProposedRange:range
actualRange:&actual_range];
- EXPECT_EQ("baz", SysNSStringToUTF8([text string]));
- EXPECT_EQ(range.location, actual_range.location);
- EXPECT_EQ(3U, actual_range.length);
+ NSRange expected_range;
+ NSAttributedString* expected_text =
+ [dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:&expected_range];
+
+ EXPECT_NSEQ_3(@"baz", [expected_text string], [actual_text string]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(8, 3), expected_range, actual_range);
}
// Test getting empty substring using text input protocol.
@@ -477,13 +695,45 @@ TEST_F(BridgedNativeWidgetTest, TextInput_GetEmptySubstring) {
const std::string test_string = "foo bar baz";
InstallTextField(test_string);
+ // Try with EmptyRange(). This behaves specially and should return the
+ // complete string and the corresponding text range.
NSRange range = EmptyRange();
- NSRange actual_range;
- NSAttributedString* text =
+ NSRange actual_range = EmptyRange();
+ NSRange expected_range = EmptyRange();
+ NSAttributedString* actual_text =
[ns_view_ attributedSubstringForProposedRange:range
actualRange:&actual_range];
- EXPECT_EQ("", SysNSStringToUTF8([text string]));
- EXPECT_EQ_RANGE(range, actual_range);
+ NSAttributedString* expected_text =
+ [dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:&expected_range];
+ EXPECT_NSEQ_3(@"foo bar baz", [expected_text string], [actual_text string]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, test_string.length()), expected_range,
+ actual_range);
+
+ // Try with a valid empty range.
+ range = NSMakeRange(2, 0);
+ actual_range = EmptyRange();
+ expected_range = EmptyRange();
+ actual_text = [ns_view_ attributedSubstringForProposedRange:range
+ actualRange:&actual_range];
+ expected_text =
+ [dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:&expected_range];
+ EXPECT_NSEQ_3(nil, [expected_text string], [actual_text string]);
+ EXPECT_EQ_RANGE_3(range, expected_range, actual_range);
+
+ // Try with an out of bounds empty range.
+ range = NSMakeRange(20, 0);
+ actual_range = EmptyRange();
+ expected_range = EmptyRange();
+ actual_text = [ns_view_ attributedSubstringForProposedRange:range
+ actualRange:&actual_range];
+ expected_text =
+ [dummy_text_view_ attributedSubstringForProposedRange:range
+ actualRange:&expected_range];
+
+ EXPECT_NSEQ_3(nil, [expected_text string], [actual_text string]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), expected_range, actual_range);
}
// Test inserting text using text input protocol.
@@ -493,10 +743,10 @@ TEST_F(BridgedNativeWidgetTest, TextInput_InsertText) {
[ns_view_ insertText:SysUTF8ToNSString(test_string)
replacementRange:EmptyRange()];
- gfx::Range range(0, test_string.size());
- base::string16 text;
- EXPECT_TRUE([ns_view_ textInputClient]->GetTextFromRange(range, &text));
- EXPECT_EQ(ASCIIToUTF16(test_string), text);
+ [dummy_text_view_ insertText:SysUTF8ToNSString(test_string)
+ replacementRange:EmptyRange()];
+
+ EXPECT_NSEQ_3(@"foofoo", GetExpectedText(), GetActualText());
}
// Test replacing text using text input protocol.
@@ -505,7 +755,9 @@ TEST_F(BridgedNativeWidgetTest, TextInput_ReplaceText) {
InstallTextField(test_string);
[ns_view_ insertText:@"baz" replacementRange:NSMakeRange(4, 3)];
- EXPECT_EQ("foo baz", GetText());
+ [dummy_text_view_ insertText:@"baz" replacementRange:NSMakeRange(4, 3)];
+
+ EXPECT_NSEQ_3(@"foo baz", GetExpectedText(), GetActualText());
}
// Test IME composition using text input protocol.
@@ -513,7 +765,14 @@ TEST_F(BridgedNativeWidgetTest, TextInput_Compose) {
const std::string test_string = "foo ";
InstallTextField(test_string);
- EXPECT_FALSE([ns_view_ hasMarkedText]);
+ EXPECT_EQ_3(NO, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
+
+ // As per NSTextInputClient documentation, markedRange should return
+ // {NSNotFound, 0} iff hasMarked returns false. However, NSTextView returns
+ // {text_length, text_length} for this case. We maintain consistency with the
+ // documentation, hence the EXPECT_FALSE check.
+ EXPECT_FALSE(
+ NSEqualRanges([dummy_text_view_ markedRange], [ns_view_ markedRange]));
EXPECT_EQ_RANGE(EmptyRange(), [ns_view_ markedRange]);
// Start composition.
@@ -522,68 +781,234 @@ TEST_F(BridgedNativeWidgetTest, TextInput_Compose) {
[ns_view_ setMarkedText:compositionText
selectedRange:NSMakeRange(0, 2)
replacementRange:EmptyRange()];
- EXPECT_TRUE([ns_view_ hasMarkedText]);
- EXPECT_EQ_RANGE(NSMakeRange(test_string.size(), compositionLength),
- [ns_view_ markedRange]);
- EXPECT_EQ_RANGE(NSMakeRange(test_string.size(), 2), [ns_view_ selectedRange]);
+ [dummy_text_view_ setMarkedText:compositionText
+ selectedRange:NSMakeRange(0, 2)
+ replacementRange:EmptyRange()];
+ EXPECT_EQ_3(YES, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(test_string.size(), compositionLength),
+ [dummy_text_view_ markedRange], [ns_view_ markedRange]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(test_string.size(), 2),
+ GetExpectedSelectionRange(), GetActualSelectionRange());
// Confirm composition.
[ns_view_ unmarkText];
- EXPECT_FALSE([ns_view_ hasMarkedText]);
+ [dummy_text_view_ unmarkText];
+
+ EXPECT_EQ_3(NO, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
+ EXPECT_FALSE(
+ NSEqualRanges([dummy_text_view_ markedRange], [ns_view_ markedRange]));
EXPECT_EQ_RANGE(EmptyRange(), [ns_view_ markedRange]);
- EXPECT_EQ("foo bar", GetText());
- EXPECT_EQ_RANGE(NSMakeRange(GetText().size(), 0), [ns_view_ selectedRange]);
+ EXPECT_NSEQ_3(@"foo bar", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange([GetActualText() length], 0),
+ GetExpectedSelectionRange(), GetActualSelectionRange());
}
// Test moving the caret left and right using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_MoveLeftRight) {
InstallTextField("foo");
- EXPECT_EQ_RANGE(NSMakeRange(3, 0), [ns_view_ selectedRange]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(3, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// Move right not allowed, out of range.
- [ns_view_ doCommandBySelector:@selector(moveRight:)];
- EXPECT_EQ_RANGE(NSMakeRange(3, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(moveRight:));
+ EXPECT_EQ_RANGE_3(NSMakeRange(3, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// Move left.
- [ns_view_ doCommandBySelector:@selector(moveLeft:)];
- EXPECT_EQ_RANGE(NSMakeRange(2, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(moveLeft:));
+ EXPECT_EQ_RANGE_3(NSMakeRange(2, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// Move right.
- [ns_view_ doCommandBySelector:@selector(moveRight:)];
- EXPECT_EQ_RANGE(NSMakeRange(3, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(moveRight:));
+ EXPECT_EQ_RANGE_3(NSMakeRange(3, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
}
// Test backward delete using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteBackward) {
InstallTextField("a");
- EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// Delete one character.
- [ns_view_ doCommandBySelector:@selector(deleteBackward:)];
- EXPECT_EQ("", GetText());
- EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(deleteBackward:));
+ EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// Try to delete again on an empty string.
- [ns_view_ doCommandBySelector:@selector(deleteBackward:)];
- EXPECT_EQ("", GetText());
- EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(deleteBackward:));
+ EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
}
// Test forward delete using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteForward) {
InstallTextField("a");
- EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
+ EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// At the end of the string, can't delete forward.
- [ns_view_ doCommandBySelector:@selector(deleteForward:)];
- EXPECT_EQ("a", GetText());
- EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(deleteForward:));
+ EXPECT_NSEQ_3(@"a", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
// Should succeed after moving left first.
- [ns_view_ doCommandBySelector:@selector(moveLeft:)];
- [ns_view_ doCommandBySelector:@selector(deleteForward:)];
- EXPECT_EQ("", GetText());
- EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]);
+ PerformCommand(@selector(moveLeft:));
+ PerformCommand(@selector(deleteForward:));
+ EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+}
+
+// Test forward word deletion using text input protocol.
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordForward) {
+ InstallTextField("foo bar baz");
+ EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Caret is at the end of the line. Verify no deletion takes place.
+ PerformCommand(@selector(deleteWordForward:));
+ EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Move the caret as- "foo b|ar baz".
+ SetSelectionRange(NSMakeRange(5, 0));
+ PerformCommand(@selector(deleteWordForward:));
+ // Verify state is "foo b| baz"
+ EXPECT_NSEQ_3(@"foo b baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(5, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Make a selection as- "|fo|o b baz".
+ SetSelectionRange(NSMakeRange(0, 2));
+ PerformCommand(@selector(deleteWordForward:));
+ // Verify only the selection is deleted and state is "|o b baz".
+ EXPECT_NSEQ_3(@"o b baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+}
+
+// Test backward word deletion using text input protocol.
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordBackward) {
+ InstallTextField("foo bar baz");
+ EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Move the caret to the beginning of the line.
+ SetSelectionRange(NSMakeRange(0, 0));
+ // Verify no deletion takes place.
+ PerformCommand(@selector(deleteWordBackward:));
+ EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Move the caret as- "foo ba|r baz".
+ SetSelectionRange(NSMakeRange(6, 0));
+ PerformCommand(@selector(deleteWordBackward:));
+ // Verify state is "foo |r baz".
+ EXPECT_NSEQ_3(@"foo r baz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(4, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+
+ // Make a selection as- "f|oo r b|az".
+ SetSelectionRange(NSMakeRange(1, 6));
+ PerformCommand(@selector(deleteWordBackward:));
+ // Verify only the selection is deleted and state is "f|az"
+ EXPECT_NSEQ_3(@"faz", GetExpectedText(), GetActualText());
+ EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
+ GetActualSelectionRange());
+}
+
+// Test deleting to beginning/end of line/paragraph using text input protocol.
+
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfLine) {
+ TestDeleteBeginning(@selector(deleteToBeginningOfLine:));
+}
+
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfLine) {
+ TestDeleteEnd(@selector(deleteToEndOfLine:));
+}
+
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfParagraph) {
+ TestDeleteBeginning(@selector(deleteToBeginningOfParagraph:));
+}
+
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) {
+ TestDeleteEnd(@selector(deleteToEndOfParagraph:));
+}
+
+// Test move commands against expectations set by |dummy_text_view_|.
+TEST_F(BridgedNativeWidgetTest, TextInput_MoveEditingCommands) {
+ NSArray* selectors = @[
+ @"moveForward:",
+ @"moveRight:",
+ @"moveBackward:",
+ @"moveLeft:",
+ @"moveUp:",
+ @"moveDown:",
+ @"moveWordForward:",
+ @"moveWordBackward:",
+ @"moveToBeginningOfLine:",
+ @"moveToEndOfLine:",
+ @"moveToBeginningOfParagraph:",
+ @"moveToEndOfParagraph:",
+ @"moveToEndOfDocument:",
+ @"moveToBeginningOfDocument:",
+ @"pageDown:",
+ @"pageUp:",
+ @"moveWordRight:",
+ @"moveWordLeft:",
+ @"moveToLeftEndOfLine:",
+ @"moveToRightEndOfLine:"
+ ];
+ TestEditingCommands(selectors);
+}
+
+// Todo(karandeepb): Enable this test once the behavior of all move and select
+// commands are fixed.
+// Test move and select commands against expectations set by |dummy_text_view_|.
+TEST_F(BridgedNativeWidgetTest,
+ TextInput_MoveAndSelectEditingCommands_DISABLED) {
+ NSArray* selectors = @[
+ @"moveBackwardAndModifySelection:",
+ @"moveForwardAndModifySelection:",
+ @"moveWordForwardAndModifySelection:",
+ @"moveWordBackwardAndModifySelection:",
+ @"moveUpAndModifySelection:",
+ @"moveDownAndModifySelection:",
+ @"moveToBeginningOfLineAndModifySelection:",
+ @"moveToEndOfLineAndModifySelection:",
+ @"moveToBeginningOfParagraphAndModifySelection:",
+ @"moveToEndOfParagraphAndModifySelection:",
+ @"moveToEndOfDocumentAndModifySelection:",
+ @"moveToBeginningOfDocumentAndModifySelection:",
+ @"pageDownAndModifySelection:",
+ @"pageUpAndModifySelection:",
+ @"moveParagraphForwardAndModifySelection:",
+ @"moveParagraphBackwardAndModifySelection:",
+ @"moveRightAndModifySelection:",
+ @"moveLeftAndModifySelection:",
+ @"moveWordRightAndModifySelection:",
+ @"moveWordLeftAndModifySelection:",
+ @"moveToLeftEndOfLineAndModifySelection:",
+ @"moveToRightEndOfLineAndModifySelection:"
+ ];
+ TestEditingCommands(selectors);
+}
+
+// Test delete commands against expectations set by |dummy_text_view_|.
+TEST_F(BridgedNativeWidgetTest, TextInput_DeleteCommands) {
+ NSArray* selectors = @[
+ @"deleteForward:", @"deleteBackward:", @"deleteWordForward:",
+ @"deleteWordBackward:", @"deleteToBeginningOfLine:", @"deleteToEndOfLine:",
+ @"deleteToBeginningOfParagraph:", @"deleteToEndOfParagraph:"
+ ];
+ TestEditingCommands(selectors);
}
// Test firstRectForCharacterRange:actualRange for cases where query range is
@@ -717,8 +1142,7 @@ TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
EXPECT_FALSE(bridge()->target_fullscreen_state());
// Cocoa follows up with a failure message sent to the NSWindowDelegate (there
- // is no equivalent notification for failure). Called via id so that this
- // compiles on 10.6.
+ // is no equivalent notification for failure).
ViewsNSWindowDelegate* window_delegate =
base::mac::ObjCCast<ViewsNSWindowDelegate>([window delegate]);
[window_delegate windowDidFailToEnterFullScreen:window];
diff --git a/chromium/ui/views/cocoa/cocoa_mouse_capture.h b/chromium/ui/views/cocoa/cocoa_mouse_capture.h
index 55f87ede81c..247caa4e82c 100644
--- a/chromium/ui/views/cocoa/cocoa_mouse_capture.h
+++ b/chromium/ui/views/cocoa/cocoa_mouse_capture.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_COCOA_COCOA_MOUSE_CAPTURE_H_
#define UI_VIEWS_COCOA_COCOA_MOUSE_CAPTURE_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/views/views_export.h"
namespace views {
@@ -36,7 +37,7 @@ class VIEWS_EXPORT CocoaMouseCapture {
// The active event tap for this capture. Owned by this, but can be cleared
// out early if another instance of CocoaMouseCapture is created.
- scoped_ptr<ActiveEventTap> active_handle_;
+ std::unique_ptr<ActiveEventTap> active_handle_;
DISALLOW_COPY_AND_ASSIGN(CocoaMouseCapture);
};
diff --git a/chromium/ui/views/cocoa/cocoa_mouse_capture_unittest.mm b/chromium/ui/views/cocoa/cocoa_mouse_capture_unittest.mm
index 371a3fc6350..5b4e2bdf995 100644
--- a/chromium/ui/views/cocoa/cocoa_mouse_capture_unittest.mm
+++ b/chromium/ui/views/cocoa/cocoa_mouse_capture_unittest.mm
@@ -50,7 +50,7 @@ class TestCaptureDelegate : public CocoaMouseCaptureDelegate {
void OnMouseCaptureLost() override { ++capture_lost_count_; }
private:
- scoped_ptr<CocoaMouseCapture> mouse_capture_;
+ std::unique_ptr<CocoaMouseCapture> mouse_capture_;
int event_count_;
int capture_lost_count_;
diff --git a/chromium/ui/views/cocoa/native_widget_mac_nswindow.mm b/chromium/ui/views/cocoa/native_widget_mac_nswindow.mm
index 4acbd946877..8c12aaa696b 100644
--- a/chromium/ui/views/cocoa/native_widget_mac_nswindow.mm
+++ b/chromium/ui/views/cocoa/native_widget_mac_nswindow.mm
@@ -12,6 +12,10 @@
#include "ui/views/widget/native_widget_mac.h"
#include "ui/views/widget/widget_delegate.h"
+@interface NSWindow (Private)
+- (BOOL)hasKeyAppearance;
+@end
+
@interface NativeWidgetMacNSWindow ()
- (ViewsNSWindowDelegate*)viewsNSWindowDelegate;
- (views::Widget*)viewsWidget;
@@ -41,6 +45,12 @@
return self;
}
+// This override doesn't do anything, but keeping it helps diagnose lifetime
+// issues in crash stacktraces by inserting a symbol on NativeWidgetMacNSWindow.
+- (void)dealloc {
+ [super dealloc];
+}
+
// Public methods.
- (void)setCommandDispatcherDelegate:(id<CommandDispatcherDelegate>)delegate {
@@ -91,10 +101,10 @@
}
// Lets the traffic light buttons on the parent window keep their active state.
-- (BOOL)_sharesParentKeyState {
- // Follow -canBecomeMainWindow unless the window provides its own buttons.
- return ([self styleMask] & NSClosableWindowMask) == 0 &&
- ![self canBecomeMainWindow];
+- (BOOL)hasKeyAppearance {
+ if ([self delegate] && [self viewsWidget]->IsAlwaysRenderAsActive())
+ return YES;
+ return [super hasKeyAppearance];
}
// Override sendEvent to allow key events to be forwarded to a toolkit-views
@@ -199,9 +209,13 @@
// command handler, defer to AppController.
if ([item action] == @selector(commandDispatch:) ||
[item action] == @selector(commandDispatchUsingKeyModifiers:)) {
- return commandHandler_
- ? [commandHandler_ validateUserInterfaceItem:item window:self]
- : [[NSApp delegate] validateUserInterfaceItem:item];
+ if (commandHandler_)
+ return [commandHandler_ validateUserInterfaceItem:item window:self];
+
+ id appController = [NSApp delegate];
+ DCHECK([appController
+ conformsToProtocol:@protocol(NSUserInterfaceValidations)]);
+ return [appController validateUserInterfaceItem:item];
}
return [super validateUserInterfaceItem:item];
diff --git a/chromium/ui/views/cocoa/widget_owner_nswindow_adapter.mm b/chromium/ui/views/cocoa/widget_owner_nswindow_adapter.mm
index d85184ef5a4..63cc4468d95 100644
--- a/chromium/ui/views/cocoa/widget_owner_nswindow_adapter.mm
+++ b/chromium/ui/views/cocoa/widget_owner_nswindow_adapter.mm
@@ -62,8 +62,22 @@ WidgetOwnerNSWindowAdapter::WidgetOwnerNSWindowAdapter(
}
void WidgetOwnerNSWindowAdapter::OnWindowWillClose() {
- [child_->ns_window() close];
+ // Retain the child window before closing it. If the last reference to the
+ // NSWindow goes away inside -[NSWindow close], then bad stuff can happen.
+ // See e.g. http://crbug.com/616701.
+ base::scoped_nsobject<NSWindow> child_window(child_->ns_window(),
+ base::scoped_policy::RETAIN);
+
+ // AppKit child window relationships break when the windows are not visible,
+ // so if the child is not visible, it won't currently be a child.
+ DCHECK(![child_window isVisible] || [child_window parentWindow]);
+ DCHECK([child_window delegate]);
+
+ [child_window close];
// Note: |this| will be deleted here.
+
+ DCHECK(![child_window parentWindow]);
+ DCHECK(![child_window delegate]);
}
NSWindow* WidgetOwnerNSWindowAdapter::GetNSWindow() {
diff --git a/chromium/ui/views/color_chooser/color_chooser_view.cc b/chromium/ui/views/color_chooser/color_chooser_view.cc
index e0aea825e9e..ca3f2034061 100644
--- a/chromium/ui/views/color_chooser/color_chooser_view.cc
+++ b/chromium/ui/views/color_chooser/color_chooser_view.cc
@@ -11,7 +11,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
@@ -141,7 +140,6 @@ class ColorChooserView::HueView : public LocatedEventHandlerView {
ColorChooserView::HueView::HueView(ColorChooserView* chooser_view)
: chooser_view_(chooser_view),
level_(0) {
- SetFocusable(false);
}
void ColorChooserView::HueView::OnHueChanged(SkScalar hue) {
@@ -251,7 +249,6 @@ ColorChooserView::SaturationValueView::SaturationValueView(
ColorChooserView* chooser_view)
: chooser_view_(chooser_view),
hue_(0) {
- SetFocusable(false);
SetBorder(Border::CreateSolidBorder(kBorderWidth, SK_ColorGRAY));
}
@@ -344,7 +341,6 @@ class ColorChooserView::SelectedColorPatchView : public views::View {
};
ColorChooserView::SelectedColorPatchView::SelectedColorPatchView() {
- SetFocusable(false);
SetVisible(true);
SetBorder(Border::CreateSolidBorder(kBorderWidth, SK_ColorGRAY));
}
@@ -366,7 +362,6 @@ ColorChooserView::ColorChooserView(ColorChooserListener* listener,
: listener_(listener) {
DCHECK(listener_);
- SetFocusable(false);
set_background(Background::CreateSolidBackground(SK_ColorLTGRAY));
SetLayoutManager(new BoxLayout(BoxLayout::kVertical, kMarginWidth,
kMarginWidth, kMarginWidth));
diff --git a/chromium/ui/views/controls/button/blue_button.cc b/chromium/ui/views/controls/button/blue_button.cc
index 12ea638c160..c0e8b9902d0 100644
--- a/chromium/ui/views/controls/button/blue_button.cc
+++ b/chromium/ui/views/controls/button/blue_button.cc
@@ -51,10 +51,10 @@ const char* BlueButton::GetClassName() const {
return BlueButton::kViewClassName;
}
-scoped_ptr<LabelButtonBorder> BlueButton::CreateDefaultBorder() const {
+std::unique_ptr<LabelButtonBorder> BlueButton::CreateDefaultBorder() const {
// Insets for splitting the images.
const gfx::Insets insets(5);
- scoped_ptr<LabelButtonAssetBorder> button_border(
+ std::unique_ptr<LabelButtonAssetBorder> button_border(
new LabelButtonAssetBorder(style()));
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
button_border->SetPainter(false, STATE_NORMAL, Painter::CreateImagePainter(
diff --git a/chromium/ui/views/controls/button/blue_button.h b/chromium/ui/views/controls/button/blue_button.h
index 2599a88f4b6..ec414de1790 100644
--- a/chromium/ui/views/controls/button/blue_button.h
+++ b/chromium/ui/views/controls/button/blue_button.h
@@ -23,7 +23,7 @@ class VIEWS_EXPORT BlueButton : public LabelButton {
// Overridden from LabelButton:
void ResetColorsFromNativeTheme() override;
const char* GetClassName() const override;
- scoped_ptr<LabelButtonBorder> CreateDefaultBorder() const override;
+ std::unique_ptr<LabelButtonBorder> CreateDefaultBorder() const override;
DISALLOW_COPY_AND_ASSIGN(BlueButton);
};
diff --git a/chromium/ui/views/controls/button/blue_button_unittest.cc b/chromium/ui/views/controls/button/blue_button_unittest.cc
index 8fc77280e9f..68712179085 100644
--- a/chromium/ui/views/controls/button/blue_button_unittest.cc
+++ b/chromium/ui/views/controls/button/blue_button_unittest.cc
@@ -44,12 +44,15 @@ TEST_F(BlueButtonTest, Border) {
widget->GetContentsView()->AddChildView(blue_button);
blue_button->SizeToPreferredSize();
#if defined(OS_MACOSX)
- // On Mac, the default styled border has a large minimum width. To ensure that
- // the bitmaps are comparable, the size needs to match (checked below).
- // Increase the minimum size of the blue button to pass the size check.
+ // On Mac, themed STYLE_BUTTON buttons provide blue theming for dialog-default
+ // buttons. This makes it unlikely that they will appear together with a
+ // BlueButton on the same dialog. So the sizes don't really need to be
+ // consistent. However, for the purposes of this test (e.g. to ensure we don't
+ // accidentally make BlueButtons look like themed buttons on Mac), force the
+ // sizes to match (ignoring the minimum size) so that the bitmaps can be
+ // compared.
EXPECT_NE(button->size(), blue_button->size()); // Verify this is needed.
- blue_button->SetMinSize(button->border()->GetMinimumSize());
- blue_button->SizeToPreferredSize();
+ blue_button->SetSize(button->size());
#endif
gfx::Canvas canvas(blue_button->size(), 1.0, true);
diff --git a/chromium/ui/views/controls/button/button.cc b/chromium/ui/views/controls/button/button.cc
index 92603dd1459..37f8aa3f6b4 100644
--- a/chromium/ui/views/controls/button/button.cc
+++ b/chromium/ui/views/controls/button/button.cc
@@ -30,6 +30,15 @@ Button::ButtonState Button::GetButtonStateFrom(ui::NativeTheme::State state) {
Button::~Button() {
}
+void Button::SetFocusForPlatform() {
+#if defined(OS_MACOSX)
+ // On Mac, buttons are focusable only in full keyboard access mode.
+ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+#else
+ SetFocusBehavior(FocusBehavior::ALWAYS);
+#endif
+}
+
void Button::SetTooltipText(const base::string16& tooltip_text) {
tooltip_text_ = tooltip_text;
if (accessible_name_.empty())
@@ -64,7 +73,7 @@ void Button::GetAccessibleState(ui::AXViewState* state) {
Button::Button(ButtonListener* listener)
: listener_(listener),
tag_(-1) {
- SetAccessibilityFocusable(true);
+ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
}
void Button::NotifyClick(const ui::Event& event) {
diff --git a/chromium/ui/views/controls/button/button.h b/chromium/ui/views/controls/button/button.h
index dab4870ad53..e7acdc91ef0 100644
--- a/chromium/ui/views/controls/button/button.h
+++ b/chromium/ui/views/controls/button/button.h
@@ -49,6 +49,9 @@ class VIEWS_EXPORT Button : public InkDropHostView {
static ButtonState GetButtonStateFrom(ui::NativeTheme::State state);
+ // Make the button focusable as per the platform.
+ void SetFocusForPlatform();
+
void SetTooltipText(const base::string16& tooltip_text);
int tag() const { return tag_; }
diff --git a/chromium/ui/views/controls/button/checkbox.cc b/chromium/ui/views/controls/button/checkbox.cc
index 2ab281f1943..8ee9dc18baa 100644
--- a/chromium/ui/views/controls/button/checkbox.cc
+++ b/chromium/ui/views/controls/button/checkbox.cc
@@ -24,11 +24,12 @@ Checkbox::Checkbox(const base::string16& label)
: LabelButton(NULL, label),
checked_(false) {
SetHorizontalAlignment(gfx::ALIGN_LEFT);
- scoped_ptr<LabelButtonBorder> button_border(new LabelButtonBorder());
+ std::unique_ptr<LabelButtonBorder> button_border(new LabelButtonBorder());
// Inset the trailing side by a couple pixels for the focus border.
button_border->set_insets(gfx::Insets(0, 0, 0, 2));
SetBorder(std::move(button_border));
- SetFocusable(true);
+ SetFocusForPlatform();
+ set_request_focus_on_press(true);
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
diff --git a/chromium/ui/views/controls/button/custom_button.cc b/chromium/ui/views/controls/button/custom_button.cc
index 6e80eb12d9f..133f73f0657 100644
--- a/chromium/ui/views/controls/button/custom_button.cc
+++ b/chromium/ui/views/controls/button/custom_button.cc
@@ -12,7 +12,6 @@
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
-#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/animation/ink_drop_delegate.h"
#include "ui/views/animation/ink_drop_hover.h"
@@ -48,12 +47,13 @@ class MdFocusRing : public views::View {
MdFocusRing() {
SetPaintToLayer(true);
layer()->SetFillsBoundsOpaquely(false);
-
- // Don't accept input events.
- SetEnabled(false);
}
~MdFocusRing() override {}
+ bool CanProcessEventsWithinSubtree() const override {
+ return false;
+ }
+
void OnPaint(gfx::Canvas* canvas) override {
CustomButton::PaintMdFocusRing(canvas, this);
}
@@ -268,6 +268,10 @@ bool CustomButton::OnKeyPressed(const ui::KeyEvent& event) {
// KeyRelease and Enter clicks the button on KeyPressed.
if (event.key_code() == ui::VKEY_SPACE) {
SetState(STATE_PRESSED);
+ if (ink_drop_delegate_ &&
+ ink_drop_delegate_->GetTargetInkDropState() !=
+ views::InkDropState::ACTION_PENDING)
+ ink_drop_delegate_->OnAction(views::InkDropState::ACTION_PENDING);
} else if (event.key_code() == ui::VKEY_RETURN) {
SetState(STATE_NORMAL);
NotifyClick(event);
@@ -382,7 +386,7 @@ void CustomButton::VisibilityChanged(View* starting_from, bool visible) {
SetState(visible && ShouldEnterHoveredState() ? STATE_HOVERED : STATE_NORMAL);
}
-scoped_ptr<InkDropHover> CustomButton::CreateInkDropHover() const {
+std::unique_ptr<InkDropHover> CustomButton::CreateInkDropHover() const {
return ShouldShowInkDropHover() ? Button::CreateInkDropHover() : nullptr;
}
@@ -438,7 +442,7 @@ CustomButton::CustomButton(ButtonListener* listener)
animate_on_state_change_(true),
is_throbbing_(false),
triggerable_event_flags_(ui::EF_LEFT_MOUSE_BUTTON),
- request_focus_on_press_(true),
+ request_focus_on_press_(false),
ink_drop_delegate_(nullptr),
notify_action_(NOTIFY_ON_RELEASE),
has_ink_drop_action_on_click_(false),
diff --git a/chromium/ui/views/controls/button/custom_button.h b/chromium/ui/views/controls/button/custom_button.h
index cd94e3c3095..e03b5a520d7 100644
--- a/chromium/ui/views/controls/button/custom_button.h
+++ b/chromium/ui/views/controls/button/custom_button.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_CONTROLS_BUTTON_CUSTOM_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_CUSTOM_BUTTON_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/throb_animation.h"
@@ -19,8 +20,8 @@ class InkDropDelegate;
// A button with custom rendering. The base of ImageButton and LabelButton.
// Note that this type of button is not focusable by default and will not be
-// part of the focus chain. Call SetFocusable(true) to make it part of the
-// focus chain.
+// part of the focus chain, unless in accessibility mode. Call
+// SetFocusForPlatform() to make it part of the focus chain.
class VIEWS_EXPORT CustomButton : public Button, public gfx::AnimationDelegate {
public:
// An enum describing the events on which a button should notify its listener.
@@ -59,7 +60,7 @@ class VIEWS_EXPORT CustomButton : public Button, public gfx::AnimationDelegate {
int triggerable_event_flags() const { return triggerable_event_flags_; }
// Sets whether |RequestFocus| should be invoked on a mouse press. The default
- // is true.
+ // is false.
void set_request_focus_on_press(bool value) {
request_focus_on_press_ = value;
}
@@ -106,7 +107,7 @@ class VIEWS_EXPORT CustomButton : public Button, public gfx::AnimationDelegate {
void OnDragDone() override;
void GetAccessibleState(ui::AXViewState* state) override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
- scoped_ptr<InkDropHover> CreateInkDropHover() const override;
+ std::unique_ptr<InkDropHover> CreateInkDropHover() const override;
SkColor GetInkDropBaseColor() const override;
// Overridden from gfx::AnimationDelegate:
diff --git a/chromium/ui/views/controls/button/custom_button_unittest.cc b/chromium/ui/views/controls/button/custom_button_unittest.cc
index bd34cb036c4..4b9ca78c755 100644
--- a/chromium/ui/views/controls/button/custom_button_unittest.cc
+++ b/chromium/ui/views/controls/button/custom_button_unittest.cc
@@ -5,13 +5,14 @@
#include "ui/views/controls/button/custom_button.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/layout.h"
#include "ui/base/material_design/material_design_controller.h"
+#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
-#include "ui/gfx/screen.h"
#include "ui/views/animation/ink_drop_delegate.h"
#include "ui/views/animation/ink_drop_host.h"
#include "ui/views/animation/test/test_ink_drop_delegate.h"
@@ -85,7 +86,7 @@ class TestCustomButton : public CustomButton, public ButtonListener {
};
// An InkDropDelegate that keeps track of ink drop visibility.
-class TestInkDropDelegateThatTracksVisibilty : public InkDropDelegate {
+class TestInkDropDelegateThatTracksVisibilty : public TestInkDropDelegate {
public:
TestInkDropDelegateThatTracksVisibilty(bool* ink_shown, bool* ink_hidden)
: ink_shown_(ink_shown), ink_hidden_(ink_hidden) {}
@@ -93,7 +94,8 @@ class TestInkDropDelegateThatTracksVisibilty : public InkDropDelegate {
// InkDropDelegate:
void OnAction(InkDropState state) override {
- switch (state) {
+ TestInkDropDelegate::OnAction(state);
+ switch (GetTargetInkDropState()) {
case InkDropState::ACTION_PENDING:
case InkDropState::ALTERNATE_ACTION_PENDING:
case InkDropState::ACTIVATED:
@@ -123,14 +125,14 @@ class TestInkDropDelegateThatTracksVisibilty : public InkDropDelegate {
// A test Button class that owns a TestInkDropDelegate.
class TestButtonWithInkDrop : public TestCustomButton {
public:
- TestButtonWithInkDrop(scoped_ptr<InkDropDelegate> ink_drop_delegate)
+ TestButtonWithInkDrop(std::unique_ptr<InkDropDelegate> ink_drop_delegate)
: TestCustomButton(), ink_drop_delegate_(std::move(ink_drop_delegate)) {
set_ink_drop_delegate(ink_drop_delegate_.get());
}
~TestButtonWithInkDrop() override {}
private:
- scoped_ptr<views::InkDropDelegate> ink_drop_delegate_;
+ std::unique_ptr<views::InkDropDelegate> ink_drop_delegate_;
DISALLOW_COPY_AND_ASSIGN(TestButtonWithInkDrop);
};
@@ -163,7 +165,8 @@ class CustomButtonTest : public ViewsTestBase {
ViewsTestBase::TearDown();
}
- void CreateButtonWithInkDrop(scoped_ptr<InkDropDelegate> ink_drop_delegate) {
+ void CreateButtonWithInkDrop(
+ std::unique_ptr<InkDropDelegate> ink_drop_delegate) {
delete button_;
button_ = new TestButtonWithInkDrop(std::move(ink_drop_delegate));
widget_->SetContentsView(button_);
@@ -177,7 +180,7 @@ class CustomButtonTest : public ViewsTestBase {
}
private:
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
TestCustomButton* button_;
DISALLOW_COPY_AND_ASSIGN(CustomButtonTest);
@@ -390,10 +393,10 @@ TEST_F(CustomButtonTest, AsCustomButton) {
// Note: Ink drop is not hidden upon release because CustomButton descendants
// may enter a different ink drop state.
TEST_F(CustomButtonTest, ButtonClickTogglesInkDrop) {
- gfx::Point old_cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+ gfx::Point old_cursor = display::Screen::GetScreen()->GetCursorScreenPoint();
bool ink_shown = false;
bool ink_hidden = false;
- CreateButtonWithInkDrop(make_scoped_ptr(
+ CreateButtonWithInkDrop(base::WrapUnique(
new TestInkDropDelegateThatTracksVisibilty(&ink_shown, &ink_hidden)));
ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
@@ -409,10 +412,10 @@ TEST_F(CustomButtonTest, ButtonClickTogglesInkDrop) {
// Tests that pressing a button shows and releasing capture hides ink drop.
// Releasing capture should also reset PRESSED button state to NORMAL.
TEST_F(CustomButtonTest, CaptureLossHidesInkDrop) {
- gfx::Point old_cursor = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+ gfx::Point old_cursor = display::Screen::GetScreen()->GetCursorScreenPoint();
bool ink_shown = false;
bool ink_hidden = false;
- CreateButtonWithInkDrop(make_scoped_ptr(
+ CreateButtonWithInkDrop(base::WrapUnique(
new TestInkDropDelegateThatTracksVisibilty(&ink_shown, &ink_hidden)));
ui::test::EventGenerator generator(GetContext(), widget()->GetNativeWindow());
@@ -435,7 +438,7 @@ TEST_F(CustomButtonTest, CaptureLossHidesInkDrop) {
TEST_F(CustomButtonTest, HideInkDropWhenShowingContextMenu) {
TestInkDropDelegate* ink_drop_delegate = new TestInkDropDelegate();
- CreateButtonWithInkDrop(make_scoped_ptr(ink_drop_delegate));
+ CreateButtonWithInkDrop(base::WrapUnique(ink_drop_delegate));
TestContextMenuController context_menu_controller;
button()->set_context_menu_controller(&context_menu_controller);
button()->set_hide_ink_drop_when_showing_context_menu(true);
@@ -446,12 +449,12 @@ TEST_F(CustomButtonTest, HideInkDropWhenShowingContextMenu) {
button()->ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE);
EXPECT_FALSE(ink_drop_delegate->is_hovered());
- EXPECT_EQ(InkDropState::HIDDEN, ink_drop_delegate->state());
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_delegate->GetTargetInkDropState());
}
TEST_F(CustomButtonTest, DontHideInkDropWhenShowingContextMenu) {
TestInkDropDelegate* ink_drop_delegate = new TestInkDropDelegate();
- CreateButtonWithInkDrop(make_scoped_ptr(ink_drop_delegate));
+ CreateButtonWithInkDrop(base::WrapUnique(ink_drop_delegate));
TestContextMenuController context_menu_controller;
button()->set_context_menu_controller(&context_menu_controller);
button()->set_hide_ink_drop_when_showing_context_menu(false);
@@ -462,12 +465,13 @@ TEST_F(CustomButtonTest, DontHideInkDropWhenShowingContextMenu) {
button()->ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE);
EXPECT_TRUE(ink_drop_delegate->is_hovered());
- EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop_delegate->state());
+ EXPECT_EQ(InkDropState::ACTION_PENDING,
+ ink_drop_delegate->GetTargetInkDropState());
}
TEST_F(CustomButtonTest, InkDropAfterTryingToShowContextMenu) {
TestInkDropDelegate* ink_drop_delegate = new TestInkDropDelegate();
- CreateButtonWithInkDrop(make_scoped_ptr(ink_drop_delegate));
+ CreateButtonWithInkDrop(base::WrapUnique(ink_drop_delegate));
button()->set_context_menu_controller(nullptr);
ink_drop_delegate->SetHovered(true);
@@ -476,7 +480,8 @@ TEST_F(CustomButtonTest, InkDropAfterTryingToShowContextMenu) {
button()->ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE);
EXPECT_TRUE(ink_drop_delegate->is_hovered());
- EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop_delegate->state());
+ EXPECT_EQ(InkDropState::ACTION_PENDING,
+ ink_drop_delegate->GetTargetInkDropState());
}
} // namespace views
diff --git a/chromium/ui/views/controls/button/image_button.cc b/chromium/ui/views/controls/button/image_button.cc
index a79341914de..a9fda37f5b4 100644
--- a/chromium/ui/views/controls/button/image_button.cc
+++ b/chromium/ui/views/controls/button/image_button.cc
@@ -73,7 +73,7 @@ void ImageButton::SetImageAlignment(HorizontalAlignment h_align,
SchedulePaint();
}
-void ImageButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
+void ImageButton::SetFocusPainter(std::unique_ptr<Painter> focus_painter) {
focus_painter_ = std::move(focus_painter);
}
diff --git a/chromium/ui/views/controls/button/image_button.h b/chromium/ui/views/controls/button/image_button.h
index 71311fe08f4..3732c690705 100644
--- a/chromium/ui/views/controls/button/image_button.h
+++ b/chromium/ui/views/controls/button/image_button.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
+#include <memory>
+
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/base/layout.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/custom_button.h"
@@ -17,11 +18,9 @@ namespace views {
class Painter;
// An image button.
-
// Note that this type of button is not focusable by default and will not be
-// part of the focus chain. Call SetFocusable(true) to make it part of the
-// focus chain.
-
+// part of the focus chain, unless in accessibility mode. Call
+// SetFocusForPlatform() to make it part of the focus chain.
class VIEWS_EXPORT ImageButton : public CustomButton {
public:
static const char kViewClassName[];
@@ -56,7 +55,7 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
void SetImageAlignment(HorizontalAlignment h_align,
VerticalAlignment v_align);
- void SetFocusPainter(scoped_ptr<Painter> focus_painter);
+ void SetFocusPainter(std::unique_ptr<Painter> focus_painter);
// The minimum size of the contents (not including the border). The contents
// will be at least this size, but may be larger if the image itself is
@@ -113,7 +112,7 @@ class VIEWS_EXPORT ImageButton : public CustomButton {
// resources.
bool draw_image_mirrored_;
- scoped_ptr<Painter> focus_painter_;
+ std::unique_ptr<Painter> focus_painter_;
DISALLOW_COPY_AND_ASSIGN(ImageButton);
};
diff --git a/chromium/ui/views/controls/button/label_button.cc b/chromium/ui/views/controls/button/label_button.cc
index 6687b6e03c6..98b6e0da97a 100644
--- a/chromium/ui/views/controls/button/label_button.cc
+++ b/chromium/ui/views/controls/button/label_button.cc
@@ -10,7 +10,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
@@ -18,7 +18,7 @@
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/native_theme/native_theme.h"
-#include "ui/views/animation/flood_fill_ink_drop_animation.h"
+#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_hover.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button_border.h"
@@ -31,12 +31,6 @@ namespace {
// The default spacing between the icon and text.
const int kSpacing = 5;
-#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
-// Default text and shadow colors for STYLE_BUTTON.
-const SkColor kStyleButtonTextColor = SK_ColorBLACK;
-const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
-#endif
-
const gfx::FontList& GetDefaultNormalFontList() {
static base::LazyInstance<gfx::FontList>::Leaky font_list =
LAZY_INSTANCE_INITIALIZER;
@@ -44,6 +38,9 @@ const gfx::FontList& GetDefaultNormalFontList() {
}
const gfx::FontList& GetDefaultBoldFontList() {
+ if (!views::PlatformStyle::kDefaultLabelButtonHasBoldFont)
+ return GetDefaultNormalFontList();
+
static base::LazyInstance<gfx::FontList>::Leaky font_list =
LAZY_INSTANCE_INITIALIZER;
if ((font_list.Get().GetFontStyle() & gfx::Font::BOLD) == 0) {
@@ -164,10 +161,15 @@ const gfx::FontList& LabelButton::GetFontList() const {
void LabelButton::SetFontList(const gfx::FontList& font_list) {
cached_normal_font_list_ = font_list;
- cached_bold_font_list_ = font_list.DeriveWithStyle(
- font_list.GetFontStyle() | gfx::Font::BOLD);
- label_->SetFontList(is_default_ ?
- cached_bold_font_list_ : cached_normal_font_list_);
+ if (PlatformStyle::kDefaultLabelButtonHasBoldFont) {
+ cached_bold_font_list_ =
+ font_list.DeriveWithStyle(font_list.GetFontStyle() | gfx::Font::BOLD);
+ if (is_default_) {
+ label_->SetFontList(cached_bold_font_list_);
+ return;
+ }
+ }
+ label_->SetFontList(cached_normal_font_list_);
}
void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
@@ -199,9 +201,7 @@ void LabelButton::SetIsDefault(bool is_default) {
ui::Accelerator accel(ui::VKEY_RETURN, ui::EF_NONE);
is_default_ ? AddAccelerator(accel) : RemoveAccelerator(accel);
- label_->SetFontList(
- is_default ? cached_bold_font_list_ : cached_normal_font_list_);
- InvalidateLayout();
+ UpdateStyleToIndicateDefaultStatus();
}
void LabelButton::SetStyle(ButtonStyle style) {
@@ -215,8 +215,10 @@ void LabelButton::SetStyle(ButtonStyle style) {
SetFocusPainter(nullptr);
SetHorizontalAlignment(gfx::ALIGN_CENTER);
- SetFocusable(true);
- SetMinSize(gfx::Size(70, 33));
+ SetFocusForPlatform();
+ set_request_focus_on_press(true);
+ SetMinSize(gfx::Size(PlatformStyle::kMinLabelButtonWidth,
+ PlatformStyle::kMinLabelButtonHeight));
// Themed borders will be set once the button is added to a Widget, since that
// provides the value of GetNativeTheme().
@@ -230,7 +232,7 @@ void LabelButton::SetImageLabelSpacing(int spacing) {
InvalidateLayout();
}
-void LabelButton::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
+void LabelButton::SetFocusPainter(std::unique_ptr<Painter> focus_painter) {
focus_painter_ = std::move(focus_painter);
}
@@ -242,7 +244,7 @@ gfx::Size LabelButton::GetPreferredSize() const {
Label label(GetText(), cached_normal_font_list_);
label.SetShadows(label_->shadows());
- if (style() == STYLE_BUTTON) {
+ if (style_ == STYLE_BUTTON && PlatformStyle::kDefaultLabelButtonHasBoldFont) {
// Some text appears wider when rendered normally than when rendered bold.
// Accommodate the widest, as buttons may show bold and shouldn't resize.
const int current_width = label.GetPreferredSize().width();
@@ -363,11 +365,11 @@ void LabelButton::EnableCanvasFlippingForRTLUI(bool flip) {
image_->EnableCanvasFlippingForRTLUI(flip);
}
-scoped_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const {
+std::unique_ptr<LabelButtonBorder> LabelButton::CreateDefaultBorder() const {
return PlatformStyle::CreateLabelButtonBorder(style());
}
-void LabelButton::SetBorder(scoped_ptr<Border> border) {
+void LabelButton::SetBorder(std::unique_ptr<Border> border) {
border_is_themed_border_ = false;
View::SetBorder(std::move(border));
ResetCachedPreferredSize();
@@ -397,6 +399,7 @@ void LabelButton::OnBlur() {
void LabelButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
ResetColorsFromNativeTheme();
UpdateThemedBorder();
+ ResetLabelEnabledColor();
// Invalidate the layout to pickup the new insets from the border.
InvalidateLayout();
}
@@ -414,20 +417,18 @@ void LabelButton::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
ink_drop_container_->SetVisible(false);
}
-scoped_ptr<views::InkDropAnimation> LabelButton::CreateInkDropAnimation()
- const {
- return GetText().empty()
- ? CustomButton::CreateInkDropAnimation()
- : make_scoped_ptr(new views::FloodFillInkDropAnimation(
- GetLocalBounds(), GetInkDropCenter(),
- GetInkDropBaseColor()));
+std::unique_ptr<views::InkDropRipple> LabelButton::CreateInkDropRipple() const {
+ return GetText().empty() ? CustomButton::CreateInkDropRipple()
+ : base::WrapUnique(new views::FloodFillInkDropRipple(
+ GetLocalBounds(), GetInkDropCenter(),
+ GetInkDropBaseColor()));
}
-scoped_ptr<views::InkDropHover> LabelButton::CreateInkDropHover() const {
+std::unique_ptr<views::InkDropHover> LabelButton::CreateInkDropHover() const {
if (!ShouldShowInkDropHover())
return nullptr;
return GetText().empty() ? CustomButton::CreateInkDropHover()
- : make_scoped_ptr(new views::InkDropHover(
+ : base::WrapUnique(new views::InkDropHover(
size(), kInkDropSmallCornerRadius,
GetInkDropCenter(), GetInkDropBaseColor()));
}
@@ -442,9 +443,7 @@ gfx::Point LabelButton::GetInkDropCenter() const {
void LabelButton::StateChanged() {
const gfx::Size previous_image_size(image_->GetPreferredSize());
UpdateImage();
- const SkColor color = button_state_colors_[state()];
- if (state() != STATE_DISABLED && label_->enabled_color() != color)
- label_->SetEnabledColor(color);
+ ResetLabelEnabledColor();
label_->SetEnabled(state() != STATE_DISABLED);
if (image_->GetPreferredSize() != previous_image_size)
Layout();
@@ -469,38 +468,21 @@ void LabelButton::ResetColorsFromNativeTheme() {
theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonDisabledColor),
};
- // Certain styles do not change text color when hovered or pressed.
- bool constant_text_color = false;
// Use hardcoded colors for inverted color scheme support and STYLE_BUTTON.
if (color_utils::IsInvertedColorScheme()) {
- constant_text_color = true;
- colors[STATE_NORMAL] = SK_ColorWHITE;
+ colors[STATE_NORMAL] = colors[STATE_HOVERED] = colors[STATE_PRESSED] =
+ SK_ColorWHITE;
label_->SetBackgroundColor(SK_ColorBLACK);
label_->set_background(Background::CreateSolidBackground(SK_ColorBLACK));
label_->SetAutoColorReadabilityEnabled(true);
label_->SetShadows(gfx::ShadowValues());
} else if (style() == STYLE_BUTTON) {
- // TODO(erg): This is disabled on desktop linux because of the binary asset
- // confusion. These details should either be pushed into ui::NativeThemeWin
- // or should be obsoleted by rendering buttons with paint calls instead of
- // with static assets. http://crbug.com/350498
-#if !(defined(OS_LINUX) && !defined(OS_CHROMEOS))
- constant_text_color = true;
- colors[STATE_NORMAL] = kStyleButtonTextColor;
- label_->SetBackgroundColor(theme->GetSystemColor(
- ui::NativeTheme::kColorId_ButtonBackgroundColor));
- label_->SetAutoColorReadabilityEnabled(false);
- label_->SetShadows(gfx::ShadowValues(
- 1, gfx::ShadowValue(gfx::Vector2d(0, 1), 0, kStyleButtonShadowColor)));
-#endif
- label_->set_background(NULL);
+ PlatformStyle::ApplyLabelButtonTextStyle(label_, &colors);
+ label_->set_background(nullptr);
} else {
- label_->set_background(NULL);
+ label_->set_background(nullptr);
}
- if (constant_text_color)
- colors[STATE_HOVERED] = colors[STATE_PRESSED] = colors[STATE_NORMAL];
-
for (size_t state = STATE_NORMAL; state < STATE_COUNT; ++state) {
if (!explicitly_set_colors_[state]) {
SetTextColor(static_cast<ButtonState>(state), colors[state]);
@@ -509,6 +491,14 @@ void LabelButton::ResetColorsFromNativeTheme() {
}
}
+void LabelButton::UpdateStyleToIndicateDefaultStatus() {
+ const bool bold =
+ PlatformStyle::kDefaultLabelButtonHasBoldFont && is_default_;
+ label_->SetFontList(bold ? cached_bold_font_list_ : cached_normal_font_list_);
+ InvalidateLayout();
+ ResetLabelEnabledColor();
+}
+
void LabelButton::UpdateImage() {
image_->SetImage(GetImage(state()));
ResetCachedPreferredSize();
@@ -575,4 +565,13 @@ void LabelButton::ResetCachedPreferredSize() {
cached_preferred_size_ = gfx::Size();
}
+void LabelButton::ResetLabelEnabledColor() {
+ const SkColor color =
+ explicitly_set_colors_[state()]
+ ? button_state_colors_[state()]
+ : PlatformStyle::TextColorForButton(button_state_colors_, *this);
+ if (state() != STATE_DISABLED && label_->enabled_color() != color)
+ label_->SetEnabledColor(color);
+}
+
} // namespace views
diff --git a/chromium/ui/views/controls/button/label_button.h b/chromium/ui/views/controls/button/label_button.h
index a8f419c96fa..ceed96d9579 100644
--- a/chromium/ui/views/controls/button/label_button.h
+++ b/chromium/ui/views/controls/button/label_button.h
@@ -5,10 +5,11 @@
#ifndef UI_VIEWS_CONTROLS_BUTTON_LABEL_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_LABEL_BUTTON_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/custom_button.h"
@@ -18,7 +19,7 @@
namespace views {
-class InkDropAnimation;
+class InkDropRipple;
class InkDropHover;
class LabelButtonBorder;
class Painter;
@@ -87,15 +88,15 @@ class VIEWS_EXPORT LabelButton : public CustomButton,
// Call SetMinSize(gfx::Size()) to clear the size if needed.
void SetImageLabelSpacing(int spacing);
- void SetFocusPainter(scoped_ptr<Painter> focus_painter);
+ void SetFocusPainter(std::unique_ptr<Painter> focus_painter);
Painter* focus_painter() { return focus_painter_.get(); }
// Creates the default border for this button. This can be overridden by
// subclasses.
- virtual scoped_ptr<LabelButtonBorder> CreateDefaultBorder() const;
+ virtual std::unique_ptr<LabelButtonBorder> CreateDefaultBorder() const;
// View:
- void SetBorder(scoped_ptr<Border> border) override;
+ void SetBorder(std::unique_ptr<Border> border) override;
gfx::Size GetPreferredSize() const override;
int GetHeightForWidth(int w) const override;
void Layout() override;
@@ -103,14 +104,18 @@ class VIEWS_EXPORT LabelButton : public CustomButton,
void EnableCanvasFlippingForRTLUI(bool flip) override;
void AddInkDropLayer(ui::Layer* ink_drop_layer) override;
void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override;
- scoped_ptr<InkDropAnimation> CreateInkDropAnimation() const override;
- scoped_ptr<InkDropHover> CreateInkDropHover() const override;
+ std::unique_ptr<InkDropRipple> CreateInkDropRipple() const override;
+ std::unique_ptr<InkDropHover> CreateInkDropHover() const override;
gfx::Point GetInkDropCenter() const override;
protected:
ImageView* image() const { return image_; }
Label* label() const { return label_; }
+ bool explicitly_set_normal_color() const {
+ return explicitly_set_colors_[STATE_NORMAL];
+ }
+
// Returns the available area for the label and image. Subclasses can change
// these bounds if they need room to do manual painting.
virtual gfx::Rect GetChildAreaBounds();
@@ -130,6 +135,10 @@ class VIEWS_EXPORT LabelButton : public CustomButton,
// Resets colors from the NativeTheme, explicitly set colors are unchanged.
virtual void ResetColorsFromNativeTheme();
+ // Changes the visual styling of this button to reflect the state of
+ // |is_default()|.
+ virtual void UpdateStyleToIndicateDefaultStatus();
+
// Updates the image view to contain the appropriate button state image.
void UpdateImage();
@@ -146,7 +155,6 @@ class VIEWS_EXPORT LabelButton : public CustomButton,
FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, Image);
FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, LabelAndImage);
FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, FontList);
- FRIEND_TEST_ALL_PREFIXES(LabelButtonTest, ButtonStyleIsDefaultSize);
void SetTextInternal(const base::string16& text);
@@ -167,6 +175,11 @@ class VIEWS_EXPORT LabelButton : public CustomButton,
// as false.
void ResetCachedPreferredSize();
+ // Updates additional state related to focus or default status, rather than
+ // merely the CustomButton::state(). E.g. ensures the label text color is
+ // correct for the current background.
+ void ResetLabelEnabledColor();
+
// The image and label shown in the button.
ImageView* image_;
Label* label_;
@@ -216,7 +229,7 @@ class VIEWS_EXPORT LabelButton : public CustomButton,
// UI direction).
gfx::HorizontalAlignment horizontal_alignment_;
- scoped_ptr<Painter> focus_painter_;
+ std::unique_ptr<Painter> focus_painter_;
DISALLOW_COPY_AND_ASSIGN(LabelButton);
};
diff --git a/chromium/ui/views/controls/button/label_button_border.h b/chromium/ui/views/controls/button/label_button_border.h
index 48b33524a92..fabbde5e60e 100644
--- a/chromium/ui/views/controls/button/label_button_border.h
+++ b/chromium/ui/views/controls/button/label_button_border.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_CONTROLS_BUTTON_LABEL_BUTTON_BORDER_H_
#define UI_VIEWS_CONTROLS_BUTTON_LABEL_BUTTON_BORDER_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/button.h"
@@ -61,7 +62,7 @@ class VIEWS_EXPORT LabelButtonAssetBorder : public LabelButtonBorder {
private:
// The painters used for each unfocused or focused button state.
- scoped_ptr<Painter> painters_[2][Button::STATE_COUNT];
+ std::unique_ptr<Painter> painters_[2][Button::STATE_COUNT];
DISALLOW_COPY_AND_ASSIGN(LabelButtonAssetBorder);
};
diff --git a/chromium/ui/views/controls/button/label_button_unittest.cc b/chromium/ui/views/controls/button/label_button_unittest.cc
index d5b60451e9f..f8c0da76cd6 100644
--- a/chromium/ui/views/controls/button/label_button_unittest.cc
+++ b/chromium/ui/views/controls/button/label_button_unittest.cc
@@ -4,19 +4,23 @@
#include "ui/views/controls/button/label_button.h"
+#include "base/command_line.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/test/material_design_controller_test_api.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/text_utils.h"
+#include "ui/native_theme/native_theme.h"
#include "ui/views/animation/button_ink_drop_delegate.h"
+#include "ui/views/style/platform_style.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/widget_test.h"
@@ -34,10 +38,34 @@ gfx::ImageSkia CreateTestImage(int width, int height) {
namespace views {
+// Testing button that exposes protected methods.
+class TestLabelButton : public LabelButton {
+ public:
+ TestLabelButton() : LabelButton(nullptr, base::string16()) {}
+
+ using LabelButton::label;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestLabelButton);
+};
+
class LabelButtonTest : public test::WidgetTest {
public:
LabelButtonTest() {}
+ // Adds a LabelButton to the test Widget with the STYLE_BUTTON platform style.
+ TestLabelButton* AddStyledButton(const char* label, bool is_default) {
+ TestLabelButton* button = new TestLabelButton;
+ button->SetText(ASCIIToUTF16(label));
+ button->SetStyle(CustomButton::STYLE_BUTTON);
+ if (is_default)
+ button->SetIsDefault(true);
+ button_->GetWidget()->GetContentsView()->AddChildView(button);
+ button->SizeToPreferredSize();
+ button->Layout();
+ return button;
+ }
+
// testing::Test:
void SetUp() override {
WidgetTest::SetUp();
@@ -45,8 +73,26 @@ class LabelButtonTest : public test::WidgetTest {
// used (which could be derived from the Widget's NativeTheme).
test_widget_ = CreateTopLevelPlatformWidget();
- button_ = new LabelButton(nullptr, base::string16());
+ button_ = new TestLabelButton;
test_widget_->GetContentsView()->AddChildView(button_);
+
+ // Establish the expected text colors for testing changes due to state.
+ themed_normal_text_color_ = button_->GetNativeTheme()->GetSystemColor(
+ ui::NativeTheme::kColorId_ButtonEnabledColor);
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ // The Linux theme provides a non-black highlight text color, but it's not
+ // used for styled buttons.
+ styled_highlight_text_color_ = themed_normal_text_color_;
+ styled_normal_text_color_ = themed_normal_text_color_;
+#else
+ styled_highlight_text_color_ = button_->GetNativeTheme()->GetSystemColor(
+ ui::NativeTheme::kColorId_ButtonHighlightColor);
+
+ // For styled buttons only, platforms other than Desktop Linux either ignore
+ // NativeTheme and use a hardcoded black or (on Mac) have a NativeTheme that
+ // reliably returns black.
+ styled_normal_text_color_ = SK_ColorBLACK;
+#endif
}
void TearDown() override {
@@ -55,7 +101,11 @@ class LabelButtonTest : public test::WidgetTest {
}
protected:
- LabelButton* button_ = nullptr;
+ TestLabelButton* button_ = nullptr;
+
+ SkColor themed_normal_text_color_ = 0;
+ SkColor styled_normal_text_color_ = 0;
+ SkColor styled_highlight_text_color_ = 0;
private:
Widget* test_widget_ = nullptr;
@@ -290,21 +340,65 @@ TEST_F(LabelButtonTest, ChangeLabelImageSpacing) {
EXPECT_EQ(original_width, button_->GetPreferredSize().width());
}
-// Make sure the label gets the width it asks for and bolding it (via
-// SetDefault) causes the size to update. Regression test for crbug.com/578722
-TEST_F(LabelButtonTest, ButtonStyleIsDefaultSize) {
- LabelButton* button = new LabelButton(nullptr, base::ASCIIToUTF16("Save"));
- button->SetStyle(CustomButton::STYLE_BUTTON);
- button_->GetWidget()->GetContentsView()->AddChildView(button);
- button->SizeToPreferredSize();
- button->Layout();
- gfx::Size non_default_size = button->label_->size();
- EXPECT_EQ(button->label_->GetPreferredSize().width(),
+// Ensure the label gets the correct style for default buttons (e.g. bolding)
+// and button size updates correctly. Regression test for crbug.com/578722.
+TEST_F(LabelButtonTest, ButtonStyleIsDefaultStyle) {
+ TestLabelButton* button = AddStyledButton("Save", false);
+ gfx::Size non_default_size = button->label()->size();
+ EXPECT_EQ(button->label()->GetPreferredSize().width(),
non_default_size.width());
+ EXPECT_FALSE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD);
+ EXPECT_EQ(styled_normal_text_color_, button->label()->enabled_color());
button->SetIsDefault(true);
button->SizeToPreferredSize();
button->Layout();
- EXPECT_NE(non_default_size, button->label_->size());
+ EXPECT_EQ(styled_highlight_text_color_, button->label()->enabled_color());
+ if (PlatformStyle::kDefaultLabelButtonHasBoldFont) {
+ EXPECT_NE(non_default_size, button->label()->size());
+ EXPECT_TRUE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD);
+ } else {
+ EXPECT_EQ(non_default_size, button->label()->size());
+ EXPECT_FALSE(button->label()->font_list().GetFontStyle() & gfx::Font::BOLD);
+ }
+}
+
+// Ensure the label gets the correct style when pressed or becoming default.
+TEST_F(LabelButtonTest, HighlightedButtonStyle) {
+#if defined(OS_MACOSX)
+ // On Mac, ensure the normal and highlight colors are different, to ensure the
+ // tests are actually testing something. This might be the case on other
+ // platforms.
+ EXPECT_NE(styled_normal_text_color_, styled_highlight_text_color_);
+#endif
+
+ // For STYLE_TEXTBUTTON, the NativeTheme might not provide SK_ColorBLACK, but
+ // it should be the same for normal and pressed states.
+ EXPECT_EQ(themed_normal_text_color_, button_->label()->enabled_color());
+ button_->SetState(Button::STATE_PRESSED);
+ EXPECT_EQ(themed_normal_text_color_, button_->label()->enabled_color());
+
+ // Add a non-default button.
+ TestLabelButton* styled_button = AddStyledButton("OK", false);
+ EXPECT_EQ(styled_normal_text_color_, styled_button->label()->enabled_color());
+ styled_button->SetState(Button::STATE_PRESSED);
+ EXPECT_EQ(styled_highlight_text_color_,
+ styled_button->label()->enabled_color());
+
+ // If there's an explicit color set for STATE_PRESSED, that should be used.
+ styled_button->SetEnabledTextColors(SK_ColorRED);
+ EXPECT_EQ(SK_ColorRED, styled_button->label()->enabled_color());
+
+ // Test becoming default after adding to the Widget.
+ TestLabelButton* default_after = AddStyledButton("OK", false);
+ EXPECT_EQ(styled_normal_text_color_, default_after->label()->enabled_color());
+ default_after->SetIsDefault(true);
+ EXPECT_EQ(styled_highlight_text_color_,
+ default_after->label()->enabled_color());
+
+ // Test becoming default before adding to the Widget.
+ TestLabelButton* default_before = AddStyledButton("OK", true);
+ EXPECT_EQ(styled_highlight_text_color_,
+ default_before->label()->enabled_color());
}
// A ButtonInkDropDelegate that tracks the last hover state requested.
@@ -358,9 +452,8 @@ class InkDropLabelButtonTest : public ViewsTestBase {
// ViewsTestBase:
void SetUp() override {
- ui::test::MaterialDesignControllerTestAPI::SetMode(
- ui::MaterialDesignController::MATERIAL_NORMAL);
-
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kTopChromeMD, switches::kTopChromeMDMaterial);
ViewsTestBase::SetUp();
// Create a widget so that the CustomButton can query the hover state
@@ -379,12 +472,12 @@ class InkDropLabelButtonTest : public ViewsTestBase {
void TearDown() override {
widget_.reset();
ViewsTestBase::TearDown();
- ui::test::MaterialDesignControllerTestAPI::UninitializeMode();
+ ui::test::MaterialDesignControllerTestAPI::Uninitialize();
}
protected:
// Required to host the test target.
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
// The test target.
InkDropLabelButton* button_ = nullptr;
diff --git a/chromium/ui/views/controls/button/md_text_button.cc b/chromium/ui/views/controls/button/md_text_button.cc
index bf0c9bd03dd..ceaf7c6d739 100644
--- a/chromium/ui/views/controls/button/md_text_button.cc
+++ b/chromium/ui/views/controls/button/md_text_button.cc
@@ -10,6 +10,7 @@
#include "ui/native_theme/native_theme.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
+#include "ui/views/controls/button/blue_button.h"
#include "ui/views/painter.h"
namespace views {
@@ -23,19 +24,47 @@ const int kVerticalPadding = 6;
// Minimum size to reserve for the button contents.
const int kMinWidth = 48;
+LabelButton* CreateButton(ButtonListener* listener,
+ const base::string16& text,
+ bool md) {
+ if (md)
+ return MdTextButton::CreateMdButton(listener, text);
+
+ LabelButton* button = new LabelButton(listener, text);
+ button->SetStyle(CustomButton::STYLE_BUTTON);
+ return button;
+}
+
} // namespace
// static
LabelButton* MdTextButton::CreateStandardButton(ButtonListener* listener,
const base::string16& text) {
- if (ui::MaterialDesignController::IsModeMaterial())
- return CreateMdButton(listener, text);
+ return CreateButton(listener, text,
+ ui::MaterialDesignController::IsModeMaterial());
+}
- LabelButton* button = new LabelButton(listener, text);
- button->SetStyle(STYLE_BUTTON);
- return button;
+// static
+LabelButton* MdTextButton::CreateSecondaryUiButton(ButtonListener* listener,
+ const base::string16& text) {
+ return CreateButton(listener, text,
+ ui::MaterialDesignController::IsSecondaryUiMaterial());
}
+// static
+LabelButton* MdTextButton::CreateSecondaryUiBlueButton(
+ ButtonListener* listener,
+ const base::string16& text) {
+ if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
+ MdTextButton* md_button = MdTextButton::CreateMdButton(listener, text);
+ md_button->SetCallToAction(MdTextButton::STRONG_CALL_TO_ACTION);
+ return md_button;
+ }
+
+ return new BlueButton(listener, text);
+}
+
+// static
MdTextButton* MdTextButton::CreateMdButton(ButtonListener* listener,
const base::string16& text) {
MdTextButton* button = new MdTextButton(listener);
@@ -45,6 +74,7 @@ MdTextButton* MdTextButton::CreateMdButton(ButtonListener* listener,
button->SetBorder(
Border::CreateEmptyBorder(kVerticalPadding, kHorizontalPadding,
kVerticalPadding, kHorizontalPadding));
+ button->SetFocusForPlatform();
return button;
}
@@ -69,6 +99,15 @@ void MdTextButton::SetText(const base::string16& text) {
LabelButton::SetText(base::i18n::ToUpper(text));
}
+void MdTextButton::UpdateStyleToIndicateDefaultStatus() {
+ // Update the call to action state to reflect defaultness. Don't change strong
+ // call to action to weak.
+ if (!is_default())
+ SetCallToAction(NO_CALL_TO_ACTION);
+ else if (cta_ == NO_CALL_TO_ACTION)
+ SetCallToAction(WEAK_CALL_TO_ACTION);
+}
+
MdTextButton::MdTextButton(ButtonListener* listener)
: LabelButton(listener, base::string16()),
ink_drop_delegate_(this, this),
@@ -76,7 +115,7 @@ MdTextButton::MdTextButton(ButtonListener* listener)
set_ink_drop_delegate(&ink_drop_delegate_);
set_has_ink_drop_action_on_click(true);
SetHorizontalAlignment(gfx::ALIGN_CENTER);
- SetFocusable(true);
+ SetFocusForPlatform();
SetMinSize(gfx::Size(kMinWidth, 0));
SetFocusPainter(nullptr);
UseMdFocusRing();
@@ -89,7 +128,11 @@ void MdTextButton::UpdateColorsFromNativeTheme() {
ui::NativeTheme::ColorId fg_color_id = ui::NativeTheme::kColorId_NumColors;
switch (cta_) {
case NO_CALL_TO_ACTION:
- fg_color_id = ui::NativeTheme::kColorId_ButtonEnabledColor;
+ // When there's no call to action, respect a color override if one has
+ // been set. For other call to action states, don't let individual buttons
+ // specify a color.
+ if (!explicitly_set_normal_color())
+ fg_color_id = ui::NativeTheme::kColorId_ButtonEnabledColor;
break;
case WEAK_CALL_TO_ACTION:
fg_color_id = ui::NativeTheme::kColorId_CallToActionColor;
@@ -99,7 +142,8 @@ void MdTextButton::UpdateColorsFromNativeTheme() {
break;
}
ui::NativeTheme* theme = GetNativeTheme();
- SetEnabledTextColors(theme->GetSystemColor(fg_color_id));
+ if (fg_color_id != ui::NativeTheme::kColorId_NumColors)
+ SetEnabledTextColors(theme->GetSystemColor(fg_color_id));
set_background(
cta_ == STRONG_CALL_TO_ACTION
diff --git a/chromium/ui/views/controls/button/md_text_button.h b/chromium/ui/views/controls/button/md_text_button.h
index 8350dac7c68..cc85b261336 100644
--- a/chromium/ui/views/controls/button/md_text_button.h
+++ b/chromium/ui/views/controls/button/md_text_button.h
@@ -5,7 +5,8 @@
#ifndef UI_VIEWS_CONTROLS_BUTTON_MD_TEXT_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_MD_TEXT_BUTTON_H_
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "ui/views/animation/button_ink_drop_delegate.h"
#include "ui/views/controls/button/label_button.h"
@@ -26,6 +27,12 @@ class VIEWS_EXPORT MdTextButton : public LabelButton {
// in MD mode.
static LabelButton* CreateStandardButton(ButtonListener* listener,
const base::string16& text);
+ // As above, but only creates an MdTextButton if MD is enabled in the
+ // secondary UI (as opposed to just "top chrome"/"primary" UI).
+ static LabelButton* CreateSecondaryUiButton(ButtonListener* listener,
+ const base::string16& text);
+ static LabelButton* CreateSecondaryUiBlueButton(ButtonListener* listener,
+ const base::string16& text);
static MdTextButton* CreateMdButton(ButtonListener* listener,
const base::string16& text);
@@ -35,6 +42,7 @@ class VIEWS_EXPORT MdTextButton : public LabelButton {
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
SkColor GetInkDropBaseColor() const override;
void SetText(const base::string16& text) override;
+ void UpdateStyleToIndicateDefaultStatus() override;
private:
MdTextButton(ButtonListener* listener);
diff --git a/chromium/ui/views/controls/button/menu_button.cc b/chromium/ui/views/controls/button/menu_button.cc
index 4d1a1b97281..3602b45bc9c 100644
--- a/chromium/ui/views/controls/button/menu_button.cc
+++ b/chromium/ui/views/controls/button/menu_button.cc
@@ -10,11 +10,11 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches_util.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/text_constants.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/strings/grit/ui_strings.h"
diff --git a/chromium/ui/views/controls/button/menu_button_unittest.cc b/chromium/ui/views/controls/button/menu_button_unittest.cc
index fdfc4d0a9b4..e34315ec014 100644
--- a/chromium/ui/views/controls/button/menu_button_unittest.cc
+++ b/chromium/ui/views/controls/button/menu_button_unittest.cc
@@ -4,8 +4,9 @@
#include "ui/views/controls/button/menu_button.h"
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "ui/base/dragdrop/drag_drop_types.h"
@@ -104,7 +105,7 @@ class MenuButtonTest : public ViewsTestBase {
Widget* widget_;
TestMenuButton* button_;
- scoped_ptr<ui::test::EventGenerator> generator_;
+ std::unique_ptr<ui::test::EventGenerator> generator_;
DISALLOW_COPY_AND_ASSIGN(MenuButtonTest);
};
@@ -184,7 +185,7 @@ class PressStateMenuButtonListener : public MenuButtonListener {
private:
MenuButton* menu_button_;
- scoped_ptr<MenuButton::PressedLock> pressed_lock_;
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock_;
// The |pressed_lock_| will be released when true.
bool release_lock_;
@@ -349,7 +350,7 @@ TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) {
EXPECT_EQ(Button::STATE_HOVERED, button()->state());
// Introduce a PressedLock, which should make the button pressed.
- scoped_ptr<MenuButton::PressedLock> pressed_lock1(
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock1(
new MenuButton::PressedLock(button()));
EXPECT_EQ(Button::STATE_PRESSED, button()->state());
@@ -358,7 +359,7 @@ TEST_F(MenuButtonTest, ButtonStateForMenuButtonsWithPressedLocks) {
EXPECT_EQ(Button::STATE_PRESSED, button()->state());
// Creating a new lock should obviously keep the button pressed.
- scoped_ptr<MenuButton::PressedLock> pressed_lock2(
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock2(
new MenuButton::PressedLock(button()));
EXPECT_EQ(Button::STATE_PRESSED, button()->state());
@@ -436,7 +437,7 @@ TEST_F(MenuButtonTest, InkDropStateForMenuButtonActivationsWithoutListener) {
button()->set_ink_drop_delegate(&ink_drop_delegate);
button()->Activate(nullptr);
- EXPECT_EQ(InkDropState::HIDDEN, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop_delegate.GetTargetInkDropState());
}
TEST_F(MenuButtonTest,
@@ -447,7 +448,8 @@ TEST_F(MenuButtonTest,
button()->set_ink_drop_delegate(&ink_drop_delegate);
button()->Activate(nullptr);
- EXPECT_EQ(InkDropState::ACTION_TRIGGERED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTION_TRIGGERED,
+ ink_drop_delegate.GetTargetInkDropState());
}
TEST_F(
@@ -460,7 +462,7 @@ TEST_F(
button()->set_ink_drop_delegate(&ink_drop_delegate);
button()->Activate(nullptr);
- EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.GetTargetInkDropState());
// Prevent the button from accessing invalid memory during clean up.
button()->set_ink_drop_delegate(nullptr);
@@ -475,7 +477,8 @@ TEST_F(MenuButtonTest,
button()->set_ink_drop_delegate(&ink_drop_delegate);
button()->Activate(nullptr);
- EXPECT_EQ(InkDropState::DEACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::DEACTIVATED,
+ ink_drop_delegate.GetTargetInkDropState());
}
TEST_F(MenuButtonTest, InkDropStateForMenuButtonsWithPressedLocks) {
@@ -483,21 +486,22 @@ TEST_F(MenuButtonTest, InkDropStateForMenuButtonsWithPressedLocks) {
TestInkDropDelegate ink_drop_delegate;
button()->set_ink_drop_delegate(&ink_drop_delegate);
- scoped_ptr<MenuButton::PressedLock> pressed_lock1(
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock1(
new MenuButton::PressedLock(button()));
- EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.GetTargetInkDropState());
- scoped_ptr<MenuButton::PressedLock> pressed_lock2(
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock2(
new MenuButton::PressedLock(button()));
- EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.GetTargetInkDropState());
pressed_lock1.reset();
- EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.GetTargetInkDropState());
pressed_lock2.reset();
- EXPECT_EQ(InkDropState::DEACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::DEACTIVATED,
+ ink_drop_delegate.GetTargetInkDropState());
}
// Verifies only one ink drop animation is triggered when multiple PressedLocks
@@ -507,16 +511,17 @@ TEST_F(MenuButtonTest, OneInkDropAnimationForReentrantPressedLocks) {
TestInkDropDelegate ink_drop_delegate;
button()->set_ink_drop_delegate(&ink_drop_delegate);
- scoped_ptr<MenuButton::PressedLock> pressed_lock1(
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock1(
new MenuButton::PressedLock(button()));
- EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.GetTargetInkDropState());
ink_drop_delegate.OnAction(InkDropState::ACTION_PENDING);
- scoped_ptr<MenuButton::PressedLock> pressed_lock2(
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock2(
new MenuButton::PressedLock(button()));
- EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTION_PENDING,
+ ink_drop_delegate.GetTargetInkDropState());
}
// Verifies the InkDropState is left as ACTIVATED if a PressedLock is active
@@ -531,7 +536,7 @@ TEST_F(MenuButtonTest,
button()->Activate(nullptr);
- EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.state());
+ EXPECT_EQ(InkDropState::ACTIVATED, ink_drop_delegate.GetTargetInkDropState());
}
#if defined(USE_AURA)
diff --git a/chromium/ui/views/controls/combobox/combobox.cc b/chromium/ui/views/controls/combobox/combobox.cc
index 3de636fbdc1..dc7797936b7 100644
--- a/chromium/ui/views/controls/combobox/combobox.cc
+++ b/chromium/ui/views/controls/combobox/combobox.cc
@@ -46,6 +46,10 @@ namespace views {
namespace {
+// Action style arrow container padding widths
+const int kActionLeftPadding = 12;
+const int kActionRightPadding = 11;
+
// Menu border widths
const int kMenuBorderWidthLeft = 1;
const int kMenuBorderWidthTop = 1;
@@ -54,12 +58,6 @@ const int kMenuBorderWidthRight = 1;
// Limit how small a combobox can be.
const int kMinComboboxWidth = 25;
-// Size of the combobox arrow margins
-const int kDisclosureArrowLeftPadding = 7;
-const int kDisclosureArrowRightPadding = 7;
-const int kDisclosureArrowButtonLeftPadding = 11;
-const int kDisclosureArrowButtonRightPadding = 12;
-
// Define the id of the first item in the menu (since it needs to be > 0)
const int kFirstMenuItemId = 1000;
@@ -89,12 +87,29 @@ const int kFocusedPressedMenuButtonImages[] =
#undef MENU_IMAGE_GRID
+gfx::Rect PositionArrowWithinContainer(const gfx::Rect& container_bounds,
+ const gfx::Size& arrow_size,
+ Combobox::Style style) {
+ gfx::Rect bounds(container_bounds);
+ if (style == Combobox::STYLE_ACTION) {
+ // This positions the arrow horizontally. The later call to
+ // ClampToCenteredSize will position it vertically without touching the
+ // horizontal position.
+ bounds.Inset(kActionLeftPadding, 0, kActionRightPadding, 0);
+ DCHECK_EQ(bounds.width(), arrow_size.width());
+ }
+
+ bounds.ClampToCenteredSize(arrow_size);
+ return bounds;
+}
+
// The transparent button which holds a button state but is not rendered.
class TransparentButton : public CustomButton {
public:
TransparentButton(ButtonListener* listener)
: CustomButton(listener) {
SetAnimationDuration(LabelButton::kHoverAnimationDurationMs);
+ SetFocusBehavior(FocusBehavior::NEVER);
}
~TransparentButton() override {}
@@ -342,21 +357,28 @@ class Combobox::ComboboxMenuModelAdapter : public ui::MenuModel,
////////////////////////////////////////////////////////////////////////////////
// Combobox, public:
-Combobox::Combobox(ui::ComboboxModel* model)
+Combobox::Combobox(ui::ComboboxModel* model, Style style)
: model_(model),
- style_(STYLE_NORMAL),
+ style_(style),
listener_(NULL),
- selected_index_(model_->GetDefaultIndex()),
+ selected_index_(style == STYLE_ACTION ? 0 : model_->GetDefaultIndex()),
invalid_(false),
menu_model_adapter_(new ComboboxMenuModelAdapter(this, model)),
text_button_(new TransparentButton(this)),
arrow_button_(new TransparentButton(this)),
weak_ptr_factory_(this) {
ModelChanged();
- SetFocusable(true);
+#if defined(OS_MACOSX)
+ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+#else
+ SetFocusBehavior(FocusBehavior::ALWAYS);
+#endif
+
UpdateBorder();
+ arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style);
// set_background() takes ownership but takes a raw pointer.
- scoped_ptr<Background> b = PlatformStyle::CreateComboboxBackground();
+ std::unique_ptr<Background> b =
+ PlatformStyle::CreateComboboxBackground(GetArrowContainerWidth());
set_background(b.release());
// Initialize the button images.
@@ -381,8 +403,6 @@ Combobox::Combobox(ui::ComboboxModel* model)
text_button_->SetVisible(true);
arrow_button_->SetVisible(true);
- text_button_->SetFocusable(false);
- arrow_button_->SetFocusable(false);
AddChildView(text_button_);
AddChildView(arrow_button_);
}
@@ -400,19 +420,6 @@ const gfx::FontList& Combobox::GetFontList() {
return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta);
}
-void Combobox::SetStyle(Style style) {
- if (style_ == style)
- return;
-
- style_ = style;
- if (style_ == STYLE_ACTION)
- selected_index_ = 0;
-
- UpdateBorder();
- content_size_ = GetContentSize();
- PreferredSizeChanged();
-}
-
void Combobox::ModelChanged() {
// If the selection is no longer valid (or the model is empty), restore the
// default index.
@@ -461,12 +468,6 @@ void Combobox::SetInvalid(bool invalid) {
SchedulePaint();
}
-int Combobox::GetArrowButtonWidth() const {
- return GetDisclosureArrowLeftPadding() +
- ArrowSize().width() +
- GetDisclosureArrowRightPadding();
-}
-
void Combobox::Layout() {
PrefixDelegate::Layout();
@@ -480,9 +481,7 @@ void Combobox::Layout() {
break;
}
case STYLE_ACTION: {
- arrow_button_width = GetDisclosureArrowLeftPadding() +
- ArrowSize().width() +
- GetDisclosureArrowRightPadding();
+ arrow_button_width = GetArrowContainerWidth();
text_button_width = width() - arrow_button_width;
break;
}
@@ -493,6 +492,11 @@ void Combobox::Layout() {
arrow_button_->SetBounds(arrow_button_x, 0, arrow_button_width, height());
}
+void Combobox::OnEnabledChanged() {
+ PrefixDelegate::OnEnabledChanged();
+ arrow_image_ = PlatformStyle::CreateComboboxArrow(enabled(), style_);
+}
+
int Combobox::GetRowCount() {
return model()->GetItemCount();
}
@@ -525,8 +529,7 @@ gfx::Size Combobox::GetPreferredSize() const {
Textfield::kTextPadding,
Textfield::kTextPadding);
int total_width = std::max(kMinComboboxWidth, content_size_.width()) +
- insets.width() + GetDisclosureArrowLeftPadding() +
- ArrowSize().width() + GetDisclosureArrowRightPadding();
+ insets.width() + GetArrowContainerWidth();
return gfx::Size(total_width, content_size_.height() + insets.height());
}
@@ -700,7 +703,8 @@ void Combobox::ButtonPressed(Button* sender, const ui::Event& event) {
}
void Combobox::UpdateBorder() {
- scoped_ptr<FocusableBorder> border(PlatformStyle::CreateComboboxBorder());
+ std::unique_ptr<FocusableBorder> border(
+ PlatformStyle::CreateComboboxBorder());
if (style_ == STYLE_ACTION)
border->SetInsets(5, 10, 5, 10);
if (invalid_)
@@ -733,8 +737,7 @@ void Combobox::PaintText(gfx::Canvas* canvas) {
base::string16 text = model()->GetItemAt(selected_index_);
gfx::Size arrow_size = ArrowSize();
- int disclosure_arrow_offset = width() - arrow_size.width() -
- GetDisclosureArrowLeftPadding() - GetDisclosureArrowRightPadding();
+ int disclosure_arrow_offset = width() - GetArrowContainerWidth();
const gfx::FontList& font_list = Combobox::GetFontList();
int text_width = gfx::GetStringWidth(text, font_list);
@@ -745,26 +748,19 @@ void Combobox::PaintText(gfx::Canvas* canvas) {
AdjustBoundsForRTLUI(&text_bounds);
canvas->DrawStringRect(text, font_list, text_color, text_bounds);
- int arrow_x = disclosure_arrow_offset + GetDisclosureArrowLeftPadding();
- gfx::Rect arrow_bounds(arrow_x,
- height() / 2 - arrow_size.height() / 2,
- arrow_size.width(),
- arrow_size.height());
+ gfx::Rect arrow_bounds(disclosure_arrow_offset, 0, GetArrowContainerWidth(),
+ height());
+ arrow_bounds =
+ PositionArrowWithinContainer(arrow_bounds, ArrowSize(), style_);
AdjustBoundsForRTLUI(&arrow_bounds);
- gfx::ImageSkia arrow_image = PlatformStyle::CreateComboboxArrow(
- enabled(), style_);
- canvas->DrawImageInt(arrow_image, arrow_bounds.x(), arrow_bounds.y());
+ canvas->DrawImageInt(arrow_image_, arrow_bounds.x(), arrow_bounds.y());
}
void Combobox::PaintButtons(gfx::Canvas* canvas) {
DCHECK(style_ == STYLE_ACTION);
- gfx::ScopedCanvas scoped_canvas(canvas);
- if (base::i18n::IsRTL()) {
- canvas->Translate(gfx::Vector2d(width(), 0));
- canvas->Scale(-1, 1);
- }
+ gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, bounds());
bool focused = HasFocus();
const std::vector<const gfx::ImageSkia*>& arrow_button_images =
@@ -872,30 +868,8 @@ void Combobox::OnPerformAction() {
selected_index_ = 0;
}
-int Combobox::GetDisclosureArrowLeftPadding() const {
- switch (style_) {
- case STYLE_NORMAL:
- return kDisclosureArrowLeftPadding;
- case STYLE_ACTION:
- return kDisclosureArrowButtonLeftPadding;
- }
- NOTREACHED();
- return 0;
-}
-
-int Combobox::GetDisclosureArrowRightPadding() const {
- switch (style_) {
- case STYLE_NORMAL:
- return kDisclosureArrowRightPadding;
- case STYLE_ACTION:
- return kDisclosureArrowButtonRightPadding;
- }
- NOTREACHED();
- return 0;
-}
-
gfx::Size Combobox::ArrowSize() const {
- return PlatformStyle::CreateComboboxArrow(enabled(), style_).size();
+ return arrow_image_.size();
}
gfx::Size Combobox::GetContentSize() const {
@@ -921,4 +895,12 @@ PrefixSelector* Combobox::GetPrefixSelector() {
return selector_.get();
}
+int Combobox::GetArrowContainerWidth() const {
+ const int kNormalPadding = 7;
+ int padding = style_ == STYLE_NORMAL
+ ? kNormalPadding * 2
+ : kActionLeftPadding + kActionRightPadding;
+ return ArrowSize().width() + padding;
+}
+
} // namespace views
diff --git a/chromium/ui/views/controls/combobox/combobox.h b/chromium/ui/views/controls/combobox/combobox.h
index 64e4baa9be1..a3112c7eb9c 100644
--- a/chromium/ui/views/controls/combobox/combobox.h
+++ b/chromium/ui/views/controls/combobox/combobox.h
@@ -53,7 +53,7 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
static const char kViewClassName[];
// |model| is not owned by the combobox.
- explicit Combobox(ui::ComboboxModel* model);
+ explicit Combobox(ui::ComboboxModel* model, Style style = STYLE_NORMAL);
~Combobox() override;
static const gfx::FontList& GetFontList();
@@ -61,8 +61,6 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
// Sets the listener which will be called when a selection has been made.
void set_listener(ComboboxListener* listener) { listener_ = listener; }
- void SetStyle(Style style);
-
// Informs the combobox that its model changed.
void ModelChanged();
@@ -85,10 +83,6 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
void SetInvalid(bool invalid);
bool invalid() const { return invalid_; }
- // Returns the width of the arrow button component of the combobox: the arrow
- // button itself, and the padding on either side of it.
- int GetArrowButtonWidth() const;
-
// Overridden from View:
gfx::Size GetPreferredSize() const override;
const char* GetClassName() const override;
@@ -100,6 +94,7 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
void OnBlur() override;
void GetAccessibleState(ui::AXViewState* state) override;
void Layout() override;
+ void OnEnabledChanged() override;
// Overridden from PrefixDelegate:
int GetRowCount() override;
@@ -148,11 +143,14 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
PrefixSelector* GetPrefixSelector();
+ // Returns the width of the combobox's arrow container.
+ int GetArrowContainerWidth() const;
+
// Our model. Not owned.
ui::ComboboxModel* model_;
// The visual style of this combobox.
- Style style_;
+ const Style style_;
// Our listener. Not owned. Notified when the selected index change.
ComboboxListener* listener_;
@@ -167,10 +165,10 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
base::string16 accessible_name_;
// A helper used to select entries by keyboard input.
- scoped_ptr<PrefixSelector> selector_;
+ std::unique_ptr<PrefixSelector> selector_;
// Adapts a ComboboxModel for use by a views MenuRunner.
- scoped_ptr<ui::MenuModel> menu_model_adapter_;
+ std::unique_ptr<ui::MenuModel> menu_model_adapter_;
// Like MenuButton, we use a time object in order to keep track of when the
// combobox was closed. The time is used for simulating menu behavior; that
@@ -186,7 +184,7 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
// The painters or images that are used when |style_| is STYLE_BUTTONS. The
// first index means the state of unfocused or focused.
// The images are owned by ResourceBundle.
- scoped_ptr<Painter> body_button_painters_[2][Button::STATE_COUNT];
+ std::unique_ptr<Painter> body_button_painters_[2][Button::STATE_COUNT];
std::vector<const gfx::ImageSkia*>
menu_button_images_[2][Button::STATE_COUNT];
@@ -201,7 +199,10 @@ class VIEWS_EXPORT Combobox : public PrefixDelegate, public ButtonListener {
// Set while the dropdown is showing. Ensures the menu is closed if |this| is
// destroyed.
- scoped_ptr<views::MenuRunner> menu_runner_;
+ std::unique_ptr<views::MenuRunner> menu_runner_;
+
+ // The image to be drawn for this combobox's arrow.
+ gfx::ImageSkia arrow_image_;
// Used for making calbacks.
base::WeakPtrFactory<Combobox> weak_ptr_factory_;
diff --git a/chromium/ui/views/controls/combobox/combobox_unittest.cc b/chromium/ui/views/controls/combobox/combobox_unittest.cc
index 65659c97b7d..8d585c63a94 100644
--- a/chromium/ui/views/controls/combobox/combobox_unittest.cc
+++ b/chromium/ui/views/controls/combobox/combobox_unittest.cc
@@ -35,10 +35,8 @@ namespace {
// OnKeyReleased() methods.
class TestCombobox : public Combobox {
public:
- explicit TestCombobox(ui::ComboboxModel* model)
- : Combobox(model),
- key_handled_(false),
- key_received_(false) {}
+ TestCombobox(ui::ComboboxModel* model, Combobox::Style style)
+ : Combobox(model, style), key_handled_(false), key_received_(false) {}
bool OnKeyPressed(const ui::KeyEvent& e) override {
key_received_ = true;
@@ -195,14 +193,14 @@ class ComboboxTest : public ViewsTestBase {
ViewsTestBase::TearDown();
}
- void InitCombobox(const std::set<int>* separators) {
+ void InitCombobox(const std::set<int>* separators, Combobox::Style style) {
model_.reset(new TestComboboxModel());
if (separators)
model_->SetSeparators(*separators);
ASSERT_FALSE(combobox_);
- combobox_ = new TestCombobox(model_.get());
+ combobox_ = new TestCombobox(model_.get(), style);
test_api_.reset(new ComboboxTestApi(combobox_));
combobox_->set_id(1);
@@ -251,17 +249,17 @@ class ComboboxTest : public ViewsTestBase {
// |combobox_| will be allocated InitCombobox() and then owned by |widget_|.
TestCombobox* combobox_;
- scoped_ptr<ComboboxTestApi> test_api_;
+ std::unique_ptr<ComboboxTestApi> test_api_;
// Combobox does not take ownership of the model, hence it needs to be scoped.
- scoped_ptr<TestComboboxModel> model_;
+ std::unique_ptr<TestComboboxModel> model_;
private:
DISALLOW_COPY_AND_ASSIGN(ComboboxTest);
};
TEST_F(ComboboxTest, KeyTest) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
SendKeyEvent(ui::VKEY_END);
EXPECT_EQ(combobox_->selected_index() + 1, model_->GetItemCount());
SendKeyEvent(ui::VKEY_HOME);
@@ -287,7 +285,7 @@ TEST_F(ComboboxTest, DisabilityTest) {
model_.reset(new TestComboboxModel());
ASSERT_FALSE(combobox_);
- combobox_ = new TestCombobox(model_.get());
+ combobox_ = new TestCombobox(model_.get(), Combobox::STYLE_NORMAL);
combobox_->SetEnabled(false);
widget_ = new Widget;
@@ -305,7 +303,7 @@ TEST_F(ComboboxTest, DisabilityTest) {
TEST_F(ComboboxTest, SkipSeparatorSimple) {
std::set<int> separators;
separators.insert(2);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
EXPECT_EQ(0, combobox_->selected_index());
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_EQ(1, combobox_->selected_index());
@@ -326,7 +324,7 @@ TEST_F(ComboboxTest, SkipSeparatorSimple) {
TEST_F(ComboboxTest, SkipSeparatorBeginning) {
std::set<int> separators;
separators.insert(0);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
EXPECT_EQ(1, combobox_->selected_index());
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_EQ(2, combobox_->selected_index());
@@ -347,7 +345,7 @@ TEST_F(ComboboxTest, SkipSeparatorBeginning) {
TEST_F(ComboboxTest, SkipSeparatorEnd) {
std::set<int> separators;
separators.insert(TestComboboxModel::kItemCount - 1);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
combobox_->SetSelectedIndex(8);
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_EQ(8, combobox_->selected_index());
@@ -365,7 +363,7 @@ TEST_F(ComboboxTest, SkipMultipleSeparatorsAtBeginning) {
separators.insert(0);
separators.insert(1);
separators.insert(2);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
EXPECT_EQ(3, combobox_->selected_index());
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_EQ(4, combobox_->selected_index());
@@ -389,7 +387,7 @@ TEST_F(ComboboxTest, SkipMultipleAdjacentSeparatorsAtMiddle) {
separators.insert(4);
separators.insert(5);
separators.insert(6);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
combobox_->SetSelectedIndex(3);
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_EQ(7, combobox_->selected_index());
@@ -405,7 +403,7 @@ TEST_F(ComboboxTest, SkipMultipleSeparatorsAtEnd) {
separators.insert(7);
separators.insert(8);
separators.insert(9);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
combobox_->SetSelectedIndex(6);
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_EQ(6, combobox_->selected_index());
@@ -426,7 +424,7 @@ TEST_F(ComboboxTest, GetTextForRowTest) {
separators.insert(0);
separators.insert(1);
separators.insert(9);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
for (int i = 0; i < combobox_->GetRowCount(); ++i) {
if (separators.count(i) != 0) {
EXPECT_TRUE(combobox_->GetTextForRow(i).empty()) << i;
@@ -439,7 +437,7 @@ TEST_F(ComboboxTest, GetTextForRowTest) {
// Verifies selecting the first matching value (and returning whether found).
TEST_F(ComboboxTest, SelectValue) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
ASSERT_EQ(model_->GetDefaultIndex(), combobox_->selected_index());
EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER")));
EXPECT_EQ(0, combobox_->selected_index());
@@ -447,9 +445,11 @@ TEST_F(ComboboxTest, SelectValue) {
EXPECT_EQ(1, combobox_->selected_index());
EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("BANANAS")));
EXPECT_EQ(1, combobox_->selected_index());
+}
+TEST_F(ComboboxTest, SelectValueActionStyle) {
// With the action style, the selected index is always 0.
- combobox_->SetStyle(Combobox::STYLE_ACTION);
+ InitCombobox(nullptr, Combobox::STYLE_ACTION);
EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER")));
EXPECT_EQ(0, combobox_->selected_index());
EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("JELLY")));
@@ -459,10 +459,9 @@ TEST_F(ComboboxTest, SelectValue) {
}
TEST_F(ComboboxTest, SelectIndexActionStyle) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_ACTION);
// With the action style, the selected index is always 0.
- combobox_->SetStyle(Combobox::STYLE_ACTION);
combobox_->SetSelectedIndex(1);
EXPECT_EQ(0, combobox_->selected_index());
combobox_->SetSelectedIndex(2);
@@ -475,24 +474,23 @@ TEST_F(ComboboxTest, ListenerHandlesDelete) {
TestComboboxModel model;
// |combobox| will be deleted on change.
- TestCombobox* combobox = new TestCombobox(&model);
- scoped_ptr<EvilListener> evil_listener(new EvilListener());
+ TestCombobox* combobox = new TestCombobox(&model, Combobox::STYLE_NORMAL);
+ std::unique_ptr<EvilListener> evil_listener(new EvilListener());
combobox->set_listener(evil_listener.get());
ASSERT_NO_FATAL_FAILURE(ComboboxTestApi(combobox).PerformActionAt(2));
EXPECT_TRUE(evil_listener->deleted());
// With STYLE_ACTION
// |combobox| will be deleted on change.
- combobox = new TestCombobox(&model);
+ combobox = new TestCombobox(&model, Combobox::STYLE_ACTION);
evil_listener.reset(new EvilListener());
combobox->set_listener(evil_listener.get());
- combobox->SetStyle(Combobox::STYLE_ACTION);
ASSERT_NO_FATAL_FAILURE(ComboboxTestApi(combobox).PerformActionAt(2));
EXPECT_TRUE(evil_listener->deleted());
}
TEST_F(ComboboxTest, Click) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
TestComboboxListener listener;
combobox_->set_listener(&listener);
@@ -510,7 +508,7 @@ TEST_F(ComboboxTest, Click) {
}
TEST_F(ComboboxTest, ClickButDisabled) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
TestComboboxListener listener;
combobox_->set_listener(&listener);
@@ -528,7 +526,7 @@ TEST_F(ComboboxTest, ClickButDisabled) {
}
TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
TestComboboxListener listener;
combobox_->set_listener(&listener);
@@ -536,16 +534,22 @@ TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) {
// With STYLE_NORMAL, the click event is ignored.
SendKeyEvent(ui::VKEY_RETURN);
EXPECT_FALSE(listener.on_perform_action_called());
+}
+
+TEST_F(ComboboxTest, NotifyOnClickWithReturnKeyActionStyle) {
+ InitCombobox(nullptr, Combobox::STYLE_ACTION);
+
+ TestComboboxListener listener;
+ combobox_->set_listener(&listener);
// With STYLE_ACTION, the click event is notified.
- combobox_->SetStyle(Combobox::STYLE_ACTION);
SendKeyEvent(ui::VKEY_RETURN);
EXPECT_TRUE(listener.on_perform_action_called());
EXPECT_EQ(0, listener.perform_action_index());
}
TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
TestComboboxListener listener;
combobox_->set_listener(&listener);
@@ -555,9 +559,15 @@ TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) {
EXPECT_FALSE(listener.on_perform_action_called());
SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED);
EXPECT_FALSE(listener.on_perform_action_called());
+}
+
+TEST_F(ComboboxTest, NotifyOnClickWithSpaceKeyActionStyle) {
+ InitCombobox(nullptr, Combobox::STYLE_ACTION);
+
+ TestComboboxListener listener;
+ combobox_->set_listener(&listener);
// With STYLE_ACTION, the click event is notified after releasing.
- combobox_->SetStyle(Combobox::STYLE_ACTION);
SendKeyEvent(ui::VKEY_SPACE);
EXPECT_FALSE(listener.on_perform_action_called());
SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED);
@@ -566,12 +576,11 @@ TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) {
}
TEST_F(ComboboxTest, NotifyOnClickWithMouse) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_ACTION);
TestComboboxListener listener;
combobox_->set_listener(&listener);
- combobox_->SetStyle(Combobox::STYLE_ACTION);
combobox_->Layout();
// Click the right side (arrow button). The menu is shown.
@@ -593,16 +602,18 @@ TEST_F(ComboboxTest, NotifyOnClickWithMouse) {
}
TEST_F(ComboboxTest, ConsumingPressKeyEvents) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
EXPECT_FALSE(combobox_->OnKeyPressed(
ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE)));
EXPECT_FALSE(combobox_->OnKeyPressed(
ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE)));
+}
+TEST_F(ComboboxTest, ConsumingKeyPressEventsActionStyle) {
// When the combobox's style is STYLE_ACTION, pressing events of a space key
// or an enter key will be consumed.
- combobox_->SetStyle(Combobox::STYLE_ACTION);
+ InitCombobox(nullptr, Combobox::STYLE_ACTION);
EXPECT_TRUE(combobox_->OnKeyPressed(
ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE)));
EXPECT_TRUE(combobox_->OnKeyPressed(
@@ -612,8 +623,10 @@ TEST_F(ComboboxTest, ConsumingPressKeyEvents) {
TEST_F(ComboboxTest, ContentWidth) {
std::vector<std::string> values;
VectorComboboxModel model(&values);
- TestCombobox combobox(&model);
+ TestCombobox combobox(&model, Combobox::STYLE_NORMAL);
+ TestCombobox action_combobox(&model, Combobox::STYLE_ACTION);
ComboboxTestApi test_api(&combobox);
+ ComboboxTestApi action_test_api(&action_combobox);
std::string long_item = "this is the long item";
std::string short_item = "s";
@@ -621,11 +634,13 @@ TEST_F(ComboboxTest, ContentWidth) {
values.resize(1);
values[0] = long_item;
combobox.ModelChanged();
+ action_combobox.ModelChanged();
const int long_item_width = test_api.content_size().width();
values[0] = short_item;
combobox.ModelChanged();
+ action_combobox.ModelChanged();
const int short_item_width = test_api.content_size().width();
@@ -633,21 +648,20 @@ TEST_F(ComboboxTest, ContentWidth) {
values[0] = short_item;
values[1] = long_item;
combobox.ModelChanged();
+ action_combobox.ModelChanged();
// When the style is STYLE_NORMAL, the width will fit with the longest item.
- combobox.SetStyle(Combobox::STYLE_NORMAL);
EXPECT_EQ(long_item_width, test_api.content_size().width());
// When the style is STYLE_ACTION, the width will fit with the selected item's
// width.
- combobox.SetStyle(Combobox::STYLE_ACTION);
- EXPECT_EQ(short_item_width, test_api.content_size().width());
+ EXPECT_EQ(short_item_width, action_test_api.content_size().width());
}
// Test that model updates preserve the selected index, so long as it is in
// range.
TEST_F(ComboboxTest, ModelChanged) {
- InitCombobox(nullptr);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
EXPECT_EQ(0, combobox_->GetSelectedRow());
EXPECT_EQ(10, combobox_->GetRowCount());
@@ -689,7 +703,7 @@ TEST_F(ComboboxTest, ModelChanged) {
}
TEST_F(ComboboxTest, TypingPrefixNotifiesListener) {
- InitCombobox(NULL);
+ InitCombobox(nullptr, Combobox::STYLE_NORMAL);
TestComboboxListener listener;
combobox_->set_listener(&listener);
@@ -732,7 +746,7 @@ TEST_F(ComboboxTest, MenuModel) {
const int kSeparatorIndex = 3;
std::set<int> separators;
separators.insert(kSeparatorIndex);
- InitCombobox(&separators);
+ InitCombobox(&separators, Combobox::STYLE_NORMAL);
ui::MenuModel* menu_model = test_api_->menu_model();
@@ -758,9 +772,27 @@ TEST_F(ComboboxTest, MenuModel) {
EXPECT_EQ(ASCIIToUTF16("PEANUT BUTTER"), menu_model->GetLabelAt(0));
EXPECT_EQ(ASCIIToUTF16("JELLY"), menu_model->GetLabelAt(1));
- // Check that with STYLE_ACTION, the first item (only) is not shown.
EXPECT_TRUE(menu_model->IsVisibleAt(0));
- combobox_->SetStyle(Combobox::STYLE_ACTION);
+}
+
+// Check that with STYLE_ACTION, the first item (only) is not shown.
+TEST_F(ComboboxTest, MenuModelActionStyleMac) {
+ const int kSeparatorIndex = 3;
+ std::set<int> separators;
+ separators.insert(kSeparatorIndex);
+ InitCombobox(&separators, Combobox::STYLE_ACTION);
+
+ ui::MenuModel* menu_model = test_api_->menu_model();
+
+ EXPECT_EQ(TestComboboxModel::kItemCount, menu_model->GetItemCount());
+ EXPECT_EQ(ui::MenuModel::TYPE_SEPARATOR,
+ menu_model->GetTypeAt(kSeparatorIndex));
+
+ EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu_model->GetTypeAt(0));
+ EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu_model->GetTypeAt(1));
+
+ EXPECT_EQ(ASCIIToUTF16("PEANUT BUTTER"), menu_model->GetLabelAt(0));
+ EXPECT_EQ(ASCIIToUTF16("JELLY"), menu_model->GetLabelAt(1));
EXPECT_FALSE(menu_model->IsVisibleAt(0));
EXPECT_TRUE(menu_model->IsVisibleAt(1));
}
diff --git a/chromium/ui/views/controls/focusable_border.cc b/chromium/ui/views/controls/focusable_border.cc
index b3ddd149272..a4e76ff1ba2 100644
--- a/chromium/ui/views/controls/focusable_border.cc
+++ b/chromium/ui/views/controls/focusable_border.cc
@@ -6,10 +6,13 @@
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
+#include "ui/base/material_design/material_design_controller.h"
#include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/skia_util.h"
#include "ui/native_theme/native_theme.h"
+#include "ui/views/controls/textfield/textfield.h"
namespace {
@@ -21,7 +24,7 @@ namespace views {
FocusableBorder::FocusableBorder()
: insets_(kInsetSize, kInsetSize, kInsetSize, kInsetSize),
- override_color_(SK_ColorWHITE),
+ override_color_(gfx::kPlaceholderColor),
use_default_color_(true) {
}
@@ -38,14 +41,21 @@ void FocusableBorder::UseDefaultColor() {
}
void FocusableBorder::Paint(const View& view, gfx::Canvas* canvas) {
- SkPath path;
- path.addRect(gfx::RectToSkRect(view.GetLocalBounds()), SkPath::kCW_Direction);
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
-
paint.setColor(GetCurrentColor(view));
- paint.setStrokeWidth(SkIntToScalar(2));
+ SkPath path;
+ if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
+ path.moveTo(Textfield::kTextPadding, view.height() - 1);
+ path.rLineTo(view.width() - Textfield::kTextPadding * 2, 0);
+ path.offset(0.5f, 0.5f);
+ paint.setStrokeWidth(SkIntToScalar(1));
+ } else {
+ path.addRect(gfx::RectToSkRect(view.GetLocalBounds()),
+ SkPath::kCW_Direction);
+ paint.setStrokeWidth(SkIntToScalar(2));
+ }
canvas->DrawPath(path, paint);
}
diff --git a/chromium/ui/views/controls/image_view.cc b/chromium/ui/views/controls/image_view.cc
index 7127ca4f070..8b5952fa1c2 100644
--- a/chromium/ui/views/controls/image_view.cc
+++ b/chromium/ui/views/controls/image_view.cc
@@ -84,7 +84,7 @@ void ImageView::ResetImageSize() {
image_size_set_ = false;
}
-void ImageView::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
+void ImageView::SetFocusPainter(std::unique_ptr<Painter> focus_painter) {
focus_painter_ = std::move(focus_painter);
}
diff --git a/chromium/ui/views/controls/image_view.h b/chromium/ui/views/controls/image_view.h
index b3b762bcd43..eb3f727ead7 100644
--- a/chromium/ui/views/controls/image_view.h
+++ b/chromium/ui/views/controls/image_view.h
@@ -77,7 +77,7 @@ class VIEWS_EXPORT ImageView : public View {
void set_interactive(bool interactive) { interactive_ = interactive; }
- void SetFocusPainter(scoped_ptr<Painter> focus_painter);
+ void SetFocusPainter(std::unique_ptr<Painter> focus_painter);
// Overriden from View:
gfx::Size GetPreferredSize() const override;
@@ -133,7 +133,7 @@ class VIEWS_EXPORT ImageView : public View {
// safe to cache.
void* last_painted_bitmap_pixels_;
- scoped_ptr<views::Painter> focus_painter_;
+ std::unique_ptr<views::Painter> focus_painter_;
DISALLOW_COPY_AND_ASSIGN(ImageView);
};
diff --git a/chromium/ui/views/controls/label.cc b/chromium/ui/views/controls/label.cc
index d1a6cafa9c1..0f927f308d7 100644
--- a/chromium/ui/views/controls/label.cc
+++ b/chromium/ui/views/controls/label.cc
@@ -213,7 +213,7 @@ base::string16 Label::GetDisplayTextForTesting() {
gfx::Insets Label::GetInsets() const {
gfx::Insets insets = View::GetInsets();
- if (focusable()) {
+ if (focus_behavior() != FocusBehavior::NEVER) {
insets += gfx::Insets(kFocusBorderPadding, kFocusBorderPadding,
kFocusBorderPadding, kFocusBorderPadding);
}
@@ -332,15 +332,16 @@ bool Label::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
}
void Label::OnEnabledChanged() {
- RecalculateColors();
+ ApplyTextColors();
+ View::OnEnabledChanged();
}
-scoped_ptr<gfx::RenderText> Label::CreateRenderText(
+std::unique_ptr<gfx::RenderText> Label::CreateRenderText(
const base::string16& text,
gfx::HorizontalAlignment alignment,
gfx::DirectionalityMode directionality,
gfx::ElideBehavior elide_behavior) {
- scoped_ptr<gfx::RenderText> render_text(
+ std::unique_ptr<gfx::RenderText> render_text(
render_text_->CreateInstanceOfSameType());
render_text->SetHorizontalAlignment(alignment);
render_text->SetDirectionalityMode(directionality);
@@ -435,7 +436,7 @@ void Label::MaybeBuildRenderTextLines() {
return;
gfx::Rect rect = GetContentsBounds();
- if (focusable())
+ if (focus_behavior() != FocusBehavior::NEVER)
rect.Inset(kFocusBorderPadding, kFocusBorderPadding);
if (rect.IsEmpty())
return;
@@ -458,7 +459,7 @@ void Label::MaybeBuildRenderTextLines() {
gfx::ElideBehavior elide_behavior =
multi_line() ? gfx::NO_ELIDE : elide_behavior_;
if (!multi_line() || render_text_->MultilineSupported()) {
- scoped_ptr<gfx::RenderText> render_text =
+ std::unique_ptr<gfx::RenderText> render_text =
CreateRenderText(text(), alignment, directionality, elide_behavior);
render_text->SetDisplayRect(rect);
render_text->SetMultiline(multi_line());
@@ -471,7 +472,7 @@ void Label::MaybeBuildRenderTextLines() {
const int bottom = GetContentsBounds().bottom();
for (size_t i = 0; i < lines.size() && rect.y() <= bottom; ++i) {
- scoped_ptr<gfx::RenderText> line =
+ std::unique_ptr<gfx::RenderText> line =
CreateRenderText(lines[i], alignment, directionality, elide_behavior);
line->SetDisplayRect(rect);
lines_.push_back(std::move(line));
@@ -481,7 +482,7 @@ void Label::MaybeBuildRenderTextLines() {
for (size_t i = lines_.size(); i < lines.size(); ++i)
lines_.back()->SetText(lines_.back()->text() + lines[i]);
}
- RecalculateColors();
+ ApplyTextColors();
}
gfx::Rect Label::GetFocusBounds() {
@@ -535,7 +536,8 @@ gfx::Size Label::GetTextSize() const {
} else {
// Get the natural text size, unelided and only wrapped on newlines.
std::vector<base::string16> lines = GetLinesForWidth(width());
- scoped_ptr<gfx::RenderText> render_text(gfx::RenderText::CreateInstance());
+ std::unique_ptr<gfx::RenderText> render_text(
+ gfx::RenderText::CreateInstance());
render_text->SetFontList(font_list());
for (size_t i = 0; i < lines.size(); ++i) {
render_text->SetText(lines[i]);
@@ -559,6 +561,11 @@ void Label::RecalculateColors() {
background_color_) :
requested_disabled_color_;
+ ApplyTextColors();
+ SchedulePaint();
+}
+
+void Label::ApplyTextColors() {
SkColor color = enabled() ? actual_enabled_color_ : actual_disabled_color_;
bool subpixel_rendering_suppressed =
SkColorGetA(background_color_) != 0xFF || !subpixel_rendering_enabled_;
@@ -566,7 +573,6 @@ void Label::RecalculateColors() {
lines_[i]->SetColor(color);
lines_[i]->set_subpixel_rendering_suppressed(subpixel_rendering_suppressed);
}
- SchedulePaint();
}
void Label::UpdateColorsFromTheme(const ui::NativeTheme* theme) {
diff --git a/chromium/ui/views/controls/label.h b/chromium/ui/views/controls/label.h
index b2520e3d876..8ede4c04b88 100644
--- a/chromium/ui/views/controls/label.h
+++ b/chromium/ui/views/controls/label.h
@@ -137,7 +137,7 @@ class VIEWS_EXPORT Label : public View {
protected:
// Create a single RenderText instance to actually be painted.
- virtual scoped_ptr<gfx::RenderText> CreateRenderText(
+ virtual std::unique_ptr<gfx::RenderText> CreateRenderText(
const base::string16& text,
gfx::HorizontalAlignment alignment,
gfx::DirectionalityMode directionality,
@@ -176,18 +176,22 @@ class VIEWS_EXPORT Label : public View {
// Get the text size for the current layout.
gfx::Size GetTextSize() const;
+ // Updates |actual_{enabled,disabled}_color_| from requested colors.
void RecalculateColors();
+ // Applies |actual_{enabled,disabled}_color_| to |lines_|.
+ void ApplyTextColors();
+
// Updates any colors that have not been explicitly set from the theme.
void UpdateColorsFromTheme(const ui::NativeTheme* theme);
bool ShouldShowDefaultTooltip() const;
// An un-elided and single-line RenderText object used for preferred sizing.
- scoped_ptr<gfx::RenderText> render_text_;
+ std::unique_ptr<gfx::RenderText> render_text_;
// The RenderText instances used to display elided and multi-line text.
- std::vector<scoped_ptr<gfx::RenderText>> lines_;
+ std::vector<std::unique_ptr<gfx::RenderText>> lines_;
SkColor requested_enabled_color_;
SkColor actual_enabled_color_;
diff --git a/chromium/ui/views/controls/label_unittest.cc b/chromium/ui/views/controls/label_unittest.cc
index 63a12a85c7f..e2ab5080acc 100644
--- a/chromium/ui/views/controls/label_unittest.cc
+++ b/chromium/ui/views/controls/label_unittest.cc
@@ -22,8 +22,12 @@
using base::ASCIIToUTF16;
namespace views {
+namespace {
-typedef ViewsTestBase LabelTest;
+// All text sizing measurements (width and height) should be greater than this.
+const int kMinTextDimension = 4;
+
+using LabelTest = ViewsTestBase;
class LabelFocusTest : public FocusManagerTest {
public:
@@ -31,7 +35,7 @@ class LabelFocusTest : public FocusManagerTest {
~LabelFocusTest() override {}
protected:
- views::Label* label() { return label_; }
+ Label* label() { return label_; }
private:
// FocusManagerTest:
@@ -40,11 +44,31 @@ class LabelFocusTest : public FocusManagerTest {
GetContentsView()->AddChildView(label_);
}
- views::Label* label_;
+ Label* label_;
};
-// All text sizing measurements (width and height) should be greater than this.
-const int kMinTextDimension = 4;
+class TestLabel : public Label {
+ public:
+ TestLabel() : Label(ASCIIToUTF16("TestLabel")) { SizeToPreferredSize(); }
+
+ int schedule_paint_count() const { return schedule_paint_count_; }
+
+ void SimulatePaint() {
+ gfx::Canvas canvas(bounds().size(), 1.0, false /* is_opaque */);
+ Paint(ui::CanvasPainter(&canvas, 1.f).context());
+ }
+
+ // View:
+ void SchedulePaintInRect(const gfx::Rect& r) override {
+ ++schedule_paint_count_;
+ Label::SchedulePaintInRect(r);
+ }
+
+ private:
+ int schedule_paint_count_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(TestLabel);
+};
// A test utility function to set the application default text direction.
void SetRTL(bool rtl) {
@@ -53,7 +77,22 @@ void SetRTL(bool rtl) {
EXPECT_EQ(rtl, base::i18n::IsRTL());
}
-TEST_F(LabelTest, FontPropertySymbol) {
+// Returns true if |current| is bigger than |last|. Sets |last| to |current|.
+bool Increased(int current, int* last) {
+ bool increased = current > *last;
+ *last = current;
+ return increased;
+}
+
+} // namespace
+
+// Crashes on Linux only. http://crbug.com/612406
+#if defined(OS_LINUX)
+#define MAYBE_FontPropertySymbol DISABLED_FontPropertySymbol
+#else
+#define MAYBE_FontPropertySymbol FontPropertySymbol
+#endif
+TEST_F(LabelTest, MAYBE_FontPropertySymbol) {
Label label;
std::string font_name("symbol");
gfx::Font font(font_name, 26);
@@ -376,7 +415,6 @@ TEST_F(LabelTest, PreferredSizeForAllowCharacterBreak) {
TEST_F(LabelTest, MultiLineSizing) {
Label label;
- label.SetFocusable(false);
label.SetText(
ASCIIToUTF16("A random string\nwith multiple lines\nand returns!"));
label.SetMultiLine(true);
@@ -461,7 +499,6 @@ TEST_F(LabelTest, MultiLineSizingWithElide) {
const base::string16 text =
ASCIIToUTF16("A random string\nwith multiple lines\nand returns!");
Label label;
- label.SetFocusable(false);
label.SetText(text);
label.SetMultiLine(true);
@@ -591,7 +628,8 @@ TEST_F(LabelTest, ResetRenderTextData) {
#if !defined(OS_MACOSX)
TEST_F(LabelTest, MultilineSupportedRenderText) {
- scoped_ptr<gfx::RenderText> render_text(gfx::RenderText::CreateInstance());
+ std::unique_ptr<gfx::RenderText> render_text(
+ gfx::RenderText::CreateInstance());
ASSERT_TRUE(render_text->MultilineSupported());
Label label;
@@ -607,11 +645,41 @@ TEST_F(LabelTest, MultilineSupportedRenderText) {
}
#endif
+// Ensures SchedulePaint() calls are not made in OnPaint().
+TEST_F(LabelTest, NoSchedulePaintInOnPaint) {
+ TestLabel label;
+
+ // Initialization should schedule at least one paint, but the precise number
+ // doesn't really matter.
+ int count = label.schedule_paint_count();
+ EXPECT_LT(0, count);
+
+ // Painting should never schedule another paint.
+ label.SimulatePaint();
+ EXPECT_EQ(count, label.schedule_paint_count());
+
+ // Test a few things that should schedule paints. Multiple times is OK.
+ label.SetEnabled(false);
+ EXPECT_TRUE(Increased(label.schedule_paint_count(), &count));
+
+ label.SetText(label.text() + ASCIIToUTF16("Changed"));
+ EXPECT_TRUE(Increased(label.schedule_paint_count(), &count));
+
+ label.SizeToPreferredSize();
+ EXPECT_TRUE(Increased(label.schedule_paint_count(), &count));
+
+ label.SetEnabledColor(SK_ColorBLUE);
+ EXPECT_TRUE(Increased(label.schedule_paint_count(), &count));
+
+ label.SimulatePaint();
+ EXPECT_EQ(count, label.schedule_paint_count()); // Unchanged.
+}
+
TEST_F(LabelFocusTest, FocusBounds) {
label()->SetText(ASCIIToUTF16("Example"));
gfx::Size normal_size = label()->GetPreferredSize();
- label()->SetFocusable(true);
+ label()->SetFocusBehavior(View::FocusBehavior::ALWAYS);
label()->RequestFocus();
gfx::Size focusable_size = label()->GetPreferredSize();
// Focusable label requires larger size to paint the focus rectangle.
@@ -648,7 +716,7 @@ TEST_F(LabelFocusTest, FocusBounds) {
}
TEST_F(LabelFocusTest, EmptyLabel) {
- label()->SetFocusable(true);
+ label()->SetFocusBehavior(View::FocusBehavior::ALWAYS);
label()->RequestFocus();
label()->SizeToPreferredSize();
diff --git a/chromium/ui/views/controls/link.cc b/chromium/ui/views/controls/link.cc
index ec955b38597..df1177f452e 100644
--- a/chromium/ui/views/controls/link.cc
+++ b/chromium/ui/views/controls/link.cc
@@ -159,10 +159,7 @@ void Link::SetFontList(const gfx::FontList& font_list) {
void Link::SetText(const base::string16& text) {
Label::SetText(text);
- // Disable focusability for empty links. Otherwise Label::GetInsets() will
- // give them an unconditional 1-px. inset on every side to allow for a focus
- // border, when in this case we probably wanted zero width.
- SetFocusable(!text.empty());
+ ConfigureFocus();
}
void Link::OnNativeThemeChanged(const ui::NativeTheme* theme) {
@@ -193,14 +190,14 @@ void Link::SetUnderline(bool underline) {
void Link::Init() {
listener_ = NULL;
pressed_ = false;
- underline_ = true;
+ underline_ = !ui::MaterialDesignController::IsSecondaryUiMaterial();
RecalculateFont();
// Label::Init() calls SetText(), but if that's being called from Label(), our
// SetText() override will not be reached (because the constructed class is
- // only a Label at the moment, not yet a Link). So so the set_focusable()
- // call explicitly here.
- SetFocusable(!text().empty());
+ // only a Label at the moment, not yet a Link). So explicitly configure focus
+ // here.
+ ConfigureFocus();
}
void Link::SetPressed(bool pressed) {
@@ -221,6 +218,21 @@ void Link::RecalculateFont() {
Label::SetFontList(font_list().DeriveWithStyle(intended_style));
}
+void Link::ConfigureFocus() {
+ // Disable focusability for empty links. Otherwise Label::GetInsets() will
+ // give them an unconditional 1-px. inset on every side to allow for a focus
+ // border, when in this case we probably wanted zero width.
+ if (text().empty()) {
+ SetFocusBehavior(FocusBehavior::NEVER);
+ } else {
+#if defined(OS_MACOSX)
+ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+#else
+ SetFocusBehavior(FocusBehavior::ALWAYS);
+#endif
+ }
+}
+
SkColor Link::GetEnabledColor() {
// In material mode, there is no pressed effect, so always use the unpressed
// color.
diff --git a/chromium/ui/views/controls/link.h b/chromium/ui/views/controls/link.h
index 01da62ee97f..58cdc08b92a 100644
--- a/chromium/ui/views/controls/link.h
+++ b/chromium/ui/views/controls/link.h
@@ -53,6 +53,8 @@ class VIEWS_EXPORT Link : public Label {
void SetEnabledColor(SkColor color) override;
void SetPressedColor(SkColor color);
+ // TODO(estade): almost all the places that call this pass false. With MD,
+ // false is already the default so those callsites can be removed.
void SetUnderline(bool underline);
static const char kViewClassName[];
@@ -64,6 +66,8 @@ class VIEWS_EXPORT Link : public Label {
void RecalculateFont();
+ void ConfigureFocus();
+
SkColor GetEnabledColor();
SkColor GetPressedColor();
diff --git a/chromium/ui/views/controls/menu/menu_controller.cc b/chromium/ui/views/controls/menu/menu_controller.cc
index fcc41e8168a..030600f84cc 100644
--- a/chromium/ui/views/controls/menu/menu_controller.cc
+++ b/chromium/ui/views/controls/menu/menu_controller.cc
@@ -12,13 +12,13 @@
#include "build/build_config.h"
#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/menu/menu_config.h"
@@ -41,7 +41,7 @@
#if defined(OS_WIN)
#include "ui/aura/window_tree_host.h"
#include "ui/base/win/internal_constants.h"
-#include "ui/gfx/win/dpi.h"
+#include "ui/display/win/screen_win.h"
#include "ui/views/win/hwnd_util.h"
#endif
@@ -176,7 +176,8 @@ static void RepostEventImpl(const ui::LocatedEvent* event,
return;
#if defined(OS_WIN)
- gfx::Point screen_loc_pixels = gfx::win::DIPToScreenPoint(screen_loc);
+ gfx::Point screen_loc_pixels =
+ display::win::ScreenWin::DIPToScreenPoint(screen_loc);
HWND target_window = ::WindowFromPoint(screen_loc_pixels.ToPOINT());
// If we don't find a native window for the HWND at the current location,
// then attempt to find a native window from its parent if one exists.
@@ -491,6 +492,11 @@ MenuItemView* MenuController::Run(Widget* parent,
if (result_event_flags)
*result_event_flags = accept_event_flags_;
+ // The nested message loop could have been killed externally. Check to see if
+ // there are nested asynchronous menus to shutdown.
+ if (async_run_ && delegate_stack_.size() > 1)
+ ExitAsyncRun();
+
return ExitMenuRun();
}
@@ -1030,14 +1036,17 @@ ui::PostDispatchAction MenuController::OnWillDispatchKeyEvent(
else
OnKeyDown(key_code);
- TerminateNestedMessageLoopIfNecessary();
+ // MenuController may have been deleted, so check for an active instance
+ // before accessing member variables.
+ if (GetActiveInstance())
+ TerminateNestedMessageLoopIfNecessary();
return ui::POST_DISPATCH_NONE;
}
void MenuController::UpdateSubmenuSelection(SubmenuView* submenu) {
if (submenu->IsShowing()) {
- gfx::Point point = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+ gfx::Point point = display::Screen::GetScreen()->GetCursorScreenPoint();
const SubmenuView* root_submenu =
submenu->GetMenuItem()->GetRootMenuItem()->GetSubmenu();
View::ConvertPointFromScreen(
@@ -1182,7 +1191,7 @@ void MenuController::StartDrag(SubmenuView* source,
View::ConvertPointFromScreen(item, &press_loc);
gfx::Point widget_loc(press_loc);
View::ConvertPointToWidget(item, &widget_loc);
- scoped_ptr<gfx::Canvas> canvas(GetCanvasForDragImage(
+ std::unique_ptr<gfx::Canvas> canvas(GetCanvasForDragImage(
source->GetWidget(), gfx::Size(item->width(), item->height())));
item->PaintButton(canvas.get(), MenuItemView::PB_FOR_DRAG);
@@ -1392,14 +1401,14 @@ void MenuController::UpdateInitialLocation(const gfx::Rect& bounds,
// Calculate the bounds of the monitor we'll show menus on. Do this once to
// avoid repeated system queries for the info.
- pending_state_.monitor_bounds = gfx::Screen::GetScreen()
+ pending_state_.monitor_bounds = display::Screen::GetScreen()
->GetDisplayNearestPoint(bounds.origin())
.work_area();
if (!pending_state_.monitor_bounds.Contains(bounds)) {
// Use the monitor area if the work area doesn't contain the bounds. This
// handles showing a menu from the launcher.
- gfx::Rect monitor_area = gfx::Screen::GetScreen()
+ gfx::Rect monitor_area = display::Screen::GetScreen()
->GetDisplayNearestPoint(bounds.origin())
.bounds();
if (monitor_area.Contains(bounds))
@@ -1434,11 +1443,12 @@ bool MenuController::ShowSiblingMenu(SubmenuView* source,
return false;
}
- gfx::NativeWindow window_under_mouse =
- gfx::Screen::GetScreen()->GetWindowUnderCursor();
// TODO(oshima): Replace with views only API.
- if (!owner_ || window_under_mouse != owner_->GetNativeWindow())
+ if (!owner_ ||
+ !display::Screen::GetScreen()->IsWindowUnderCursor(
+ owner_->GetNativeWindow())) {
return false;
+ }
// The user moved the mouse outside the menu and over the owning window. See
// if there is a sibling menu we should show.
@@ -2321,7 +2331,7 @@ void MenuController::RepostEventAndCancel(SubmenuView* source,
gfx::NativeView native_view = source->GetWidget()->GetNativeView();
gfx::NativeWindow window = nullptr;
if (native_view) {
- gfx::Screen* screen = gfx::Screen::GetScreen();
+ display::Screen* screen = display::Screen::GetScreen();
window = screen->GetWindowAtScreenPoint(screen_loc);
}
#endif
@@ -2659,15 +2669,19 @@ void MenuController::SetInitialHotTrackedView(
void MenuController::SetHotTrackedButton(CustomButton* hot_button) {
if (hot_button == hot_button_) {
// Hot-tracked state may change outside of the MenuController. Correct it.
- if (hot_button && !hot_button->IsHotTracked())
+ if (hot_button && !hot_button->IsHotTracked()) {
hot_button->SetHotTracked(true);
+ hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
+ }
return;
}
if (hot_button_)
hot_button_->SetHotTracked(false);
hot_button_ = hot_button;
- if (hot_button)
+ if (hot_button) {
hot_button->SetHotTracked(true);
+ hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
+ }
}
} // namespace views
diff --git a/chromium/ui/views/controls/menu/menu_controller.h b/chromium/ui/views/controls/menu/menu_controller.h
index dc21826d6d4..20c1bee5d2f 100644
--- a/chromium/ui/views/controls/menu/menu_controller.h
+++ b/chromium/ui/views/controls/menu/menu_controller.h
@@ -5,19 +5,18 @@
#ifndef UI_VIEWS_CONTROLS_MENU_MENU_CONTROLLER_H_
#define UI_VIEWS_CONTROLS_MENU_MENU_CONTROLLER_H_
-#include "build/build_config.h"
-
#include <stddef.h>
#include <list>
+#include <memory>
#include <set>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
+#include "build/build_config.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/platform/platform_event_dispatcher.h"
@@ -26,9 +25,6 @@
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/widget/widget_observer.h"
-namespace gfx {
-class Screen;
-}
namespace ui {
class OSExchangeData;
class ScopedEventDispatcher;
@@ -54,6 +50,7 @@ class MenuRunnerImpl;
namespace test {
class MenuControllerTest;
+class MenuControllerTestApi;
}
// MenuController -------------------------------------------------------------
@@ -200,6 +197,7 @@ class VIEWS_EXPORT MenuController : public WidgetObserver {
private:
friend class internal::MenuRunnerImpl;
friend class test::MenuControllerTest;
+ friend class test::MenuControllerTestApi;
friend class MenuKeyEventHandler;
friend class MenuHostRootView;
friend class MenuItemView;
@@ -654,10 +652,10 @@ class VIEWS_EXPORT MenuController : public WidgetObserver {
// Task for scrolling the menu. If non-null indicates a scroll is currently
// underway.
- scoped_ptr<MenuScrollTask> scroll_task_;
+ std::unique_ptr<MenuScrollTask> scroll_task_;
// The lock to keep the menu button pressed while a menu is visible.
- scoped_ptr<MenuButton::PressedLock> pressed_lock_;
+ std::unique_ptr<MenuButton::PressedLock> pressed_lock_;
// ViewStorage id used to store the view mouse drag events are forwarded to.
// See UpdateActiveMouseView() for details.
@@ -702,10 +700,10 @@ class VIEWS_EXPORT MenuController : public WidgetObserver {
// A mask of the EventFlags for the mouse buttons currently pressed.
int current_mouse_pressed_state_;
- scoped_ptr<MenuMessageLoop> message_loop_;
+ std::unique_ptr<MenuMessageLoop> message_loop_;
#if defined(USE_AURA)
- scoped_ptr<MenuKeyEventHandler> key_event_handler_;
+ std::unique_ptr<MenuKeyEventHandler> key_event_handler_;
#endif
DISALLOW_COPY_AND_ASSIGN(MenuController);
diff --git a/chromium/ui/views/controls/menu/menu_controller_unittest.cc b/chromium/ui/views/controls/menu/menu_controller_unittest.cc
index ee26fb24200..2dd80af066e 100644
--- a/chromium/ui/views/controls/menu/menu_controller_unittest.cc
+++ b/chromium/ui/views/controls/menu/menu_controller_unittest.cc
@@ -24,6 +24,7 @@
#include "ui/views/controls/menu/menu_message_loop.h"
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "ui/views/controls/menu/submenu_view.h"
+#include "ui/views/test/menu_test_utils.h"
#include "ui/views/test/views_test_base.h"
#if defined(USE_AURA)
@@ -44,34 +45,6 @@ namespace test {
namespace {
-// Test implementation of MenuDelegate that only reports calls of OnPerformDrop.
-class TestMenuDelegate : public MenuDelegate {
- public:
- TestMenuDelegate();
- ~TestMenuDelegate() override;
-
- bool on_perform_drop_called() { return on_perform_drop_called_; }
-
- int OnPerformDrop(MenuItemView* menu,
- DropPosition position,
- const ui::DropTargetEvent& event) override;
-
- private:
- bool on_perform_drop_called_;
- DISALLOW_COPY_AND_ASSIGN(TestMenuDelegate);
-};
-
-TestMenuDelegate::TestMenuDelegate() : on_perform_drop_called_(false) {}
-
-TestMenuDelegate::~TestMenuDelegate() {}
-
-int TestMenuDelegate::OnPerformDrop(MenuItemView* menu,
- DropPosition position,
- const ui::DropTargetEvent& event) {
- on_perform_drop_called_ = true;
- return ui::DragDropTypes::DRAG_COPY;
-}
-
// Test implementation of MenuControllerDelegate that only reports the values
// called of OnMenuClosed.
class TestMenuControllerDelegate : public internal::MenuControllerDelegate {
@@ -176,26 +149,29 @@ class TestEventHandler : public ui::EventHandler {
// loop is running or not.
class TestMenuMessageLoop : public MenuMessageLoop {
public:
- explicit TestMenuMessageLoop(scoped_ptr<MenuMessageLoop> original);
+ explicit TestMenuMessageLoop(std::unique_ptr<MenuMessageLoop> original);
~TestMenuMessageLoop() override;
bool is_running() const { return is_running_; }
+ // MenuMessageLoop:
+ void QuitNow() override;
+
private:
// MenuMessageLoop:
void Run(MenuController* controller,
Widget* owner,
bool nested_menu) override;
- void QuitNow() override;
void ClearOwner() override;
- scoped_ptr<MenuMessageLoop> original_;
+ std::unique_ptr<MenuMessageLoop> original_;
bool is_running_;
DISALLOW_COPY_AND_ASSIGN(TestMenuMessageLoop);
};
-TestMenuMessageLoop::TestMenuMessageLoop(scoped_ptr<MenuMessageLoop> original)
+TestMenuMessageLoop::TestMenuMessageLoop(
+ std::unique_ptr<MenuMessageLoop> original)
: original_(std::move(original)) {
DCHECK(original_);
}
@@ -269,7 +245,7 @@ class MenuControllerTest : public ViewsTestBase {
// the menu to not handle the key event.
aura::ScopedWindowTargeter scoped_targeter(
owner()->GetNativeWindow()->GetRootWindow(),
- scoped_ptr<ui::EventTargeter>(new ui::NullEventTargeter));
+ std::unique_ptr<ui::EventTargeter>(new ui::NullEventTargeter));
event_generator_->PressKey(ui::VKEY_ESCAPE, 0);
EXPECT_EQ(MenuController::EXIT_NONE, menu_exit_type());
}
@@ -283,7 +259,7 @@ class MenuControllerTest : public ViewsTestBase {
void TestAsynchronousNestedExitAll() {
ASSERT_TRUE(test_message_loop_->is_running());
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
menu_controller()->AddNestedDelegate(nested_delegate.get());
@@ -305,7 +281,7 @@ class MenuControllerTest : public ViewsTestBase {
void TestAsynchronousNestedExitOutermost() {
ASSERT_TRUE(test_message_loop_->is_running());
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
menu_controller()->AddNestedDelegate(nested_delegate.get());
@@ -329,6 +305,17 @@ class MenuControllerTest : public ViewsTestBase {
EXPECT_FALSE(test_message_loop_->is_running());
}
+ // This nested an asynchronous delegate onto a menu with a nested message
+ // loop, then kills the loop. Simulates the loop being killed not by
+ // MenuController.
+ void TestNestedMessageLoopKillsItself(
+ TestMenuControllerDelegate* nested_delegate) {
+ menu_controller_->AddNestedDelegate(nested_delegate);
+ menu_controller_->SetAsyncRun(true);
+
+ test_message_loop_->QuitNow();
+ }
+
protected:
void SetPendingStateItem(MenuItemView* item) {
menu_controller_->pending_state_.item = item;
@@ -416,7 +403,8 @@ class MenuControllerTest : public ViewsTestBase {
void RunMenu() {
#if defined(USE_AURA)
- scoped_ptr<MenuKeyEventHandler> key_event_handler(new MenuKeyEventHandler);
+ std::unique_ptr<MenuKeyEventHandler> key_event_handler(
+ new MenuKeyEventHandler);
#endif
menu_controller_->message_loop_depth_++;
@@ -455,7 +443,8 @@ class MenuControllerTest : public ViewsTestBase {
for (int i = 0; i < 3; ++i) {
LabelButton* button =
new LabelButton(nullptr, base::ASCIIToUTF16("Label"));
- button->SetFocusable(true);
+ // This is an in-menu button. Hence it must be always focusable.
+ button->SetFocusBehavior(View::FocusBehavior::ALWAYS);
item_view->AddChildView(button);
}
menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false);
@@ -521,11 +510,11 @@ class MenuControllerTest : public ViewsTestBase {
menu_item_->SetController(menu_controller_);
}
- scoped_ptr<Widget> owner_;
- scoped_ptr<ui::test::EventGenerator> event_generator_;
- scoped_ptr<TestMenuItemViewShown> menu_item_;
- scoped_ptr<TestMenuControllerDelegate> menu_controller_delegate_;
- scoped_ptr<MenuDelegate> menu_delegate_;
+ std::unique_ptr<Widget> owner_;
+ std::unique_ptr<ui::test::EventGenerator> event_generator_;
+ std::unique_ptr<TestMenuItemViewShown> menu_item_;
+ std::unique_ptr<TestMenuControllerDelegate> menu_controller_delegate_;
+ std::unique_ptr<MenuDelegate> menu_delegate_;
MenuController* menu_controller_;
TestMenuMessageLoop* test_message_loop_;
@@ -958,7 +947,7 @@ TEST_F(MenuControllerTest, AsynchronousCancelAll) {
TEST_F(MenuControllerTest, AsynchronousNestedDelegate) {
MenuController* controller = menu_controller();
TestMenuControllerDelegate* delegate = menu_controller_delegate();
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
ASSERT_FALSE(IsAsyncRun());
@@ -1034,7 +1023,7 @@ TEST_F(MenuControllerTest, AsynchronousDragComplete) {
TEST_F(MenuControllerTest, DoubleAsynchronousNested) {
MenuController* controller = menu_controller();
TestMenuControllerDelegate* delegate = menu_controller_delegate();
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
ASSERT_FALSE(IsAsyncRun());
@@ -1061,7 +1050,7 @@ TEST_F(MenuControllerTest, DoubleAsynchronousNested) {
TEST_F(MenuControllerTest, AsynchronousRepostEvent) {
MenuController* controller = menu_controller();
TestMenuControllerDelegate* delegate = menu_controller_delegate();
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
ASSERT_FALSE(IsAsyncRun());
@@ -1160,7 +1149,7 @@ TEST_F(MenuControllerTest, AsynchronousNestedExitOutermost) {
// cause a crash. ASAN bots should not detect use-after-free in MenuController.
TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) {
MenuController* controller = menu_controller();
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
ASSERT_FALSE(IsAsyncRun());
@@ -1203,7 +1192,7 @@ TEST_F(MenuControllerTest, AsynchronousRepostEventDeletesController) {
// cause a crash. ASAN bots should not detect use-after-free in MenuController.
TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) {
MenuController* controller = menu_controller();
- scoped_ptr<TestMenuControllerDelegate> nested_delegate(
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
new TestMenuControllerDelegate());
ASSERT_FALSE(IsAsyncRun());
@@ -1238,5 +1227,28 @@ TEST_F(MenuControllerTest, AsynchronousGestureDeletesController) {
EXPECT_EQ(1, nested_delegate->on_menu_closed_called());
}
+// Tests that when an asynchronous menu is nested, and the nested message loop
+// is kill not by the MenuController, that the nested menu is notified of
+// destruction.
+TEST_F(MenuControllerTest, NestedMessageLoopDiesWithNestedMenu) {
+ menu_controller()->CancelAll();
+ InstallTestMenuMessageLoop();
+ std::unique_ptr<TestMenuControllerDelegate> nested_delegate(
+ new TestMenuControllerDelegate());
+ // This will nest an asynchronous menu, and then kill the nested message loop.
+ base::MessageLoopForUI::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&MenuControllerTest::TestNestedMessageLoopKillsItself,
+ base::Unretained(this), nested_delegate.get()));
+
+ int result_event_flags = 0;
+ // This creates a nested message loop.
+ EXPECT_EQ(nullptr, menu_controller()->Run(owner(), nullptr, menu_item(),
+ gfx::Rect(), MENU_ANCHOR_TOPLEFT,
+ false, false, &result_event_flags));
+ EXPECT_FALSE(menu_controller_delegate()->on_menu_closed_called());
+ EXPECT_TRUE(nested_delegate->on_menu_closed_called());
+}
+
} // namespace test
} // namespace views
diff --git a/chromium/ui/views/controls/menu/menu_host.h b/chromium/ui/views/controls/menu/menu_host.h
index ba931f8ed20..1de12373563 100644
--- a/chromium/ui/views/controls/menu/menu_host.h
+++ b/chromium/ui/views/controls/menu/menu_host.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_CONTROLS_MENU_MENU_HOST_H_
#define UI_VIEWS_CONTROLS_MENU_MENU_HOST_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/widget/widget.h"
@@ -83,7 +84,7 @@ class MenuHost : public Widget {
#if !defined(OS_MACOSX)
// Handles raw touch events at the moment.
- scoped_ptr<internal::PreMenuEventDispatchHandler> pre_dispatch_handler_;
+ std::unique_ptr<internal::PreMenuEventDispatchHandler> pre_dispatch_handler_;
#endif
DISALLOW_COPY_AND_ASSIGN(MenuHost);
diff --git a/chromium/ui/views/controls/menu/menu_image_util.cc b/chromium/ui/views/controls/menu/menu_image_util.cc
index 55f6e551c2f..7f342ac6dc1 100644
--- a/chromium/ui/views/controls/menu/menu_image_util.cc
+++ b/chromium/ui/views/controls/menu/menu_image_util.cc
@@ -12,8 +12,7 @@
namespace views {
gfx::ImageSkia GetMenuCheckImage(SkColor icon_color) {
- return gfx::CreateVectorIcon(gfx::VectorIconId::MENU_CHECK, kMenuCheckSize,
- icon_color);
+ return gfx::CreateVectorIcon(gfx::VectorIconId::MENU_CHECK, icon_color);
}
gfx::ImageSkia GetRadioButtonImage(bool toggled,
@@ -27,8 +26,7 @@ gfx::ImageSkia GetRadioButtonImage(bool toggled,
}
gfx::ImageSkia GetSubmenuArrowImage(SkColor icon_color) {
- return gfx::CreateVectorIcon(gfx::VectorIconId::SUBMENU_ARROW,
- kSubmenuArrowSize, icon_color);
+ return gfx::CreateVectorIcon(gfx::VectorIconId::SUBMENU_ARROW, icon_color);
}
} // namespace views
diff --git a/chromium/ui/views/controls/menu/menu_message_loop_aura.cc b/chromium/ui/views/controls/menu/menu_message_loop_aura.cc
index f2653751716..dab58be36c9 100644
--- a/chromium/ui/views/controls/menu/menu_message_loop_aura.cc
+++ b/chromium/ui/views/controls/menu/menu_message_loop_aura.cc
@@ -106,8 +106,8 @@ void MenuMessageLoop::RepostEventToWindow(const ui::LocatedEvent* event,
gfx::Point root_loc(screen_loc);
spc->ConvertPointFromScreen(root, &root_loc);
- scoped_ptr<ui::Event> clone = ui::Event::Clone(*event);
- scoped_ptr<ui::LocatedEvent> located_event(
+ std::unique_ptr<ui::Event> clone = ui::Event::Clone(*event);
+ std::unique_ptr<ui::LocatedEvent> located_event(
static_cast<ui::LocatedEvent*>(clone.release()));
located_event->set_location(root_loc);
located_event->set_root_location(root_loc);
@@ -132,7 +132,7 @@ void MenuMessageLoopAura::Run(MenuController* controller,
base::AutoReset<base::Closure> reset_quit_closure(&message_loop_quit_,
base::Closure());
- scoped_ptr<ActivationChangeObserverImpl> observer;
+ std::unique_ptr<ActivationChangeObserverImpl> observer;
if (root) {
if (!nested_menu)
observer.reset(new ActivationChangeObserverImpl(controller, root));
diff --git a/chromium/ui/views/controls/menu/menu_message_loop_aura.h b/chromium/ui/views/controls/menu/menu_message_loop_aura.h
index fce8858dd09..6ebe8393f80 100644
--- a/chromium/ui/views/controls/menu/menu_message_loop_aura.h
+++ b/chromium/ui/views/controls/menu/menu_message_loop_aura.h
@@ -5,10 +5,11 @@
#ifndef UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_LOOP_AURA_H_
#define UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_LOOP_AURA_H_
+#include <memory>
+
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/views/controls/menu/menu_message_loop.h"
namespace ui {
diff --git a/chromium/ui/views/controls/menu/menu_model_adapter_unittest.cc b/chromium/ui/views/controls/menu/menu_model_adapter_unittest.cc
index 63d7788c4bc..9fddfaf9317 100644
--- a/chromium/ui/views/controls/menu/menu_model_adapter_unittest.cc
+++ b/chromium/ui/views/controls/menu/menu_model_adapter_unittest.cc
@@ -154,7 +154,7 @@ class RootModel : public MenuModelBase {
~RootModel() override {}
private:
- scoped_ptr<MenuModel> submenu_model_;
+ std::unique_ptr<MenuModel> submenu_model_;
DISALLOW_COPY_AND_ASSIGN(RootModel);
};
@@ -173,7 +173,7 @@ TEST_F(MenuModelAdapterTest, BasicTest) {
// Create menu. Build menu twice to check that rebuilding works properly.
MenuItemView* menu = new views::MenuItemView(&delegate);
// MenuRunner takes ownership of menu.
- scoped_ptr<MenuRunner> menu_runner(new MenuRunner(menu, 0));
+ std::unique_ptr<MenuRunner> menu_runner(new MenuRunner(menu, 0));
delegate.BuildMenu(menu);
delegate.BuildMenu(menu);
EXPECT_TRUE(menu->HasSubmenu());
diff --git a/chromium/ui/views/controls/menu/menu_runner.cc b/chromium/ui/views/controls/menu/menu_runner.cc
index f639f687f09..4cfdafed99b 100644
--- a/chromium/ui/views/controls/menu/menu_runner.cc
+++ b/chromium/ui/views/controls/menu/menu_runner.cc
@@ -72,7 +72,7 @@ base::TimeDelta MenuRunner::closing_event_time() const {
}
void MenuRunner::SetRunnerHandler(
- scoped_ptr<MenuRunnerHandler> runner_handler) {
+ std::unique_ptr<MenuRunnerHandler> runner_handler) {
runner_handler_ = std::move(runner_handler);
}
diff --git a/chromium/ui/views/controls/menu/menu_runner.h b/chromium/ui/views/controls/menu/menu_runner.h
index ea2438ee980..5d98ec0e1bb 100644
--- a/chromium/ui/views/controls/menu/menu_runner.h
+++ b/chromium/ui/views/controls/menu/menu_runner.h
@@ -7,9 +7,10 @@
#include <stdint.h>
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/base/ui_base_types.h"
#include "ui/views/controls/menu/menu_types.h"
#include "ui/views/views_export.h"
@@ -135,7 +136,7 @@ class VIEWS_EXPORT MenuRunner {
friend class test::MenuRunnerTestAPI;
// Sets an implementation of RunMenuAt. This is intended to be used at test.
- void SetRunnerHandler(scoped_ptr<MenuRunnerHandler> runner_handler);
+ void SetRunnerHandler(std::unique_ptr<MenuRunnerHandler> runner_handler);
const int32_t run_types_;
@@ -144,9 +145,9 @@ class VIEWS_EXPORT MenuRunner {
// An implementation of RunMenuAt. This is usually NULL and ignored. If this
// is not NULL, this implementation will be used.
- scoped_ptr<MenuRunnerHandler> runner_handler_;
+ std::unique_ptr<MenuRunnerHandler> runner_handler_;
- scoped_ptr<internal::DisplayChangeListener> display_change_listener_;
+ std::unique_ptr<internal::DisplayChangeListener> display_change_listener_;
DISALLOW_COPY_AND_ASSIGN(MenuRunner);
};
diff --git a/chromium/ui/views/controls/menu/menu_runner_cocoa_unittest.mm b/chromium/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
index 73e02eca385..ee86b982756 100644
--- a/chromium/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
+++ b/chromium/ui/views/controls/menu/menu_runner_cocoa_unittest.mm
@@ -137,8 +137,14 @@ class MenuRunnerCocoaTest : public ViewsTestBase {
runner_ = nullptr;
}
+ void MenuCancelAndDeleteCallback() {
+ runner_->Cancel();
+ runner_->Release();
+ runner_ = nullptr;
+ }
+
protected:
- scoped_ptr<TestModel> menu_;
+ std::unique_ptr<TestModel> menu_;
internal::MenuRunnerImplCocoa* runner_ = nullptr;
views::Widget* parent_ = nullptr;
NSRect last_anchor_frame_ = NSZeroRect;
@@ -182,6 +188,15 @@ TEST_F(MenuRunnerCocoaTest, RunMenuAndDelete) {
EXPECT_EQ(MenuRunner::MENU_DELETED, result);
}
+// Ensure a menu can be safely released immediately after a call to Cancel() in
+// the same run loop iteration.
+TEST_F(MenuRunnerCocoaTest, DestroyAfterCanceling) {
+ MenuRunner::RunResult result =
+ RunMenu(base::Bind(&MenuRunnerCocoaTest::MenuCancelAndDeleteCallback,
+ base::Unretained(this)));
+ EXPECT_EQ(MenuRunner::MENU_DELETED, result);
+}
+
TEST_F(MenuRunnerCocoaTest, RunMenuTwice) {
for (int i = 0; i < 2; ++i) {
MenuRunner::RunResult result = RunMenu(base::Bind(
diff --git a/chromium/ui/views/controls/menu/menu_runner_impl.cc b/chromium/ui/views/controls/menu/menu_runner_impl.cc
index b48edcdd129..4e35f3aad8f 100644
--- a/chromium/ui/views/controls/menu/menu_runner_impl.cc
+++ b/chromium/ui/views/controls/menu/menu_runner_impl.cc
@@ -60,14 +60,19 @@ void MenuRunnerImpl::Release() {
empty_delegate_.reset(new MenuDelegate());
menu_->set_delegate(empty_delegate_.get());
- DCHECK(controller_);
- // Release is invoked when MenuRunner is destroyed. Assume this is happening
- // because the object referencing the menu has been destroyed and the menu
- // button is no longer valid.
- controller_->Cancel(MenuController::EXIT_DESTROYED);
- } else {
- delete this;
+ // Verify that the MenuController is still active. It may have been
+ // destroyed out of order.
+ if (MenuController::GetActiveInstance()) {
+ DCHECK(controller_);
+ // Release is invoked when MenuRunner is destroyed. Assume this is
+ // happening because the object referencing the menu has been destroyed
+ // and the menu button is no longer valid.
+ controller_->Cancel(MenuController::EXIT_DESTROYED);
+ return;
+ }
}
+
+ delete this;
}
MenuRunner::RunResult MenuRunnerImpl::RunMenuAt(Widget* parent,
diff --git a/chromium/ui/views/controls/menu/menu_runner_impl.h b/chromium/ui/views/controls/menu/menu_runner_impl.h
index cf31f8156e6..c893e4aea39 100644
--- a/chromium/ui/views/controls/menu/menu_runner_impl.h
+++ b/chromium/ui/views/controls/menu/menu_runner_impl.h
@@ -5,16 +5,17 @@
#ifndef UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_IMPL_H_
#define UI_VIEWS_CONTROLS_MENU_MENU_RUNNER_IMPL_H_
-#include "ui/views/controls/menu/menu_runner_impl_interface.h"
-
#include <stdint.h>
#include <set>
+#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/views/controls/menu/menu_controller_delegate.h"
+#include "ui/views/controls/menu/menu_runner_impl_interface.h"
+#include "ui/views/views_export.h"
namespace views {
@@ -25,8 +26,9 @@ class MenuItemView;
namespace internal {
// A menu runner implementation that uses views::MenuItemView to show a menu.
-class MenuRunnerImpl : public MenuRunnerImplInterface,
- public MenuControllerDelegate {
+class VIEWS_EXPORT MenuRunnerImpl
+ : NON_EXPORTED_BASE(public MenuRunnerImplInterface),
+ NON_EXPORTED_BASE(public MenuControllerDelegate) {
public:
explicit MenuRunnerImpl(MenuItemView* menu);
@@ -69,7 +71,7 @@ class MenuRunnerImpl : public MenuRunnerImplInterface,
// invoked. This is done to make sure the delegate isn't notified after
// Release() is invoked. We do this as we assume the delegate is no longer
// valid if MenuRunner has been deleted.
- scoped_ptr<MenuDelegate> empty_delegate_;
+ std::unique_ptr<MenuDelegate> empty_delegate_;
// Are we in run waiting for it to return?
bool running_;
diff --git a/chromium/ui/views/controls/menu/menu_runner_impl_adapter.h b/chromium/ui/views/controls/menu/menu_runner_impl_adapter.h
index f41abe14704..973afdbe870 100644
--- a/chromium/ui/views/controls/menu/menu_runner_impl_adapter.h
+++ b/chromium/ui/views/controls/menu/menu_runner_impl_adapter.h
@@ -34,7 +34,7 @@ class MenuRunnerImplAdapter : public MenuRunnerImplInterface {
private:
~MenuRunnerImplAdapter() override;
- scoped_ptr<MenuModelAdapter> menu_model_adapter_;
+ std::unique_ptr<MenuModelAdapter> menu_model_adapter_;
MenuRunnerImpl* impl_;
DISALLOW_COPY_AND_ASSIGN(MenuRunnerImplAdapter);
diff --git a/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.h b/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.h
index f1ae21fb88d..ac5b263e2b4 100644
--- a/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.h
+++ b/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.h
@@ -39,6 +39,9 @@ class VIEWS_EXPORT MenuRunnerImplCocoa : public MenuRunnerImplInterface {
// The Cocoa menu controller that this instance is bridging.
base::scoped_nsobject<MenuController> menu_controller_;
+ // Are we in run waiting for it to return?
+ bool running_;
+
// Set if |running_| and Release() has been invoked.
bool delete_after_run_;
diff --git a/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.mm b/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.mm
index 454c951817b..c6802381ab6 100644
--- a/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.mm
+++ b/chromium/ui/views/controls/menu/menu_runner_impl_cocoa.mm
@@ -93,13 +93,15 @@ MenuRunnerImplInterface* MenuRunnerImplInterface::Create(
}
MenuRunnerImplCocoa::MenuRunnerImplCocoa(ui::MenuModel* menu)
- : delete_after_run_(false), closing_event_time_(base::TimeDelta()) {
+ : running_(false),
+ delete_after_run_(false),
+ closing_event_time_(base::TimeDelta()) {
menu_controller_.reset(
[[MenuController alloc] initWithModel:menu useWithPopUpButtonCell:NO]);
}
bool MenuRunnerImplCocoa::IsRunning() const {
- return [menu_controller_ isMenuOpen];
+ return running_;
}
void MenuRunnerImplCocoa::Release() {
@@ -123,6 +125,7 @@ MenuRunner::RunResult MenuRunnerImplCocoa::RunMenuAt(Widget* parent,
DCHECK(!IsRunning());
DCHECK(parent);
closing_event_time_ = base::TimeDelta();
+ running_ = true;
if (run_types & MenuRunner::CONTEXT_MENU) {
[NSMenu popUpContextMenu:[menu_controller_ menu]
@@ -143,6 +146,7 @@ MenuRunner::RunResult MenuRunnerImplCocoa::RunMenuAt(Widget* parent,
}
closing_event_time_ = ui::EventTimeForNow();
+ running_ = false;
if (delete_after_run_) {
delete this;
diff --git a/chromium/ui/views/controls/menu/menu_runner_unittest.cc b/chromium/ui/views/controls/menu/menu_runner_unittest.cc
index 49ba8832a1e..6d76f7e92e2 100644
--- a/chromium/ui/views/controls/menu/menu_runner_unittest.cc
+++ b/chromium/ui/views/controls/menu/menu_runner_unittest.cc
@@ -6,73 +6,26 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/ui_base_types.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/controls/menu/menu_item_view.h"
+#include "ui/views/controls/menu/menu_runner_impl.h"
#include "ui/views/controls/menu/menu_types.h"
#include "ui/views/controls/menu/submenu_view.h"
+#include "ui/views/test/menu_test_utils.h"
+#include "ui/views/test/test_views.h"
#include "ui/views/test/views_test_base.h"
+#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/widget.h"
namespace views {
namespace test {
-// Implementation of MenuDelegate that only reports the values of calls to
-// OnMenuClosed and ExecuteCommand.
-class TestMenuDelegate : public MenuDelegate {
- public:
- TestMenuDelegate();
- ~TestMenuDelegate() override;
-
- int execute_command_id() const { return execute_command_id_; }
-
- int on_menu_closed_called() const { return on_menu_closed_called_; }
- MenuItemView* on_menu_closed_menu() const { return on_menu_closed_menu_; }
- MenuRunner::RunResult on_menu_closed_run_result() const {
- return on_menu_closed_run_result_;
- }
-
- // MenuDelegate:
- void ExecuteCommand(int id) override;
- void OnMenuClosed(MenuItemView* menu, MenuRunner::RunResult result) override;
-
- private:
- // ID of last executed command.
- int execute_command_id_;
-
- // The number of times OnMenuClosed was called.
- int on_menu_closed_called_;
-
- // The values of the last call to OnMenuClosed.
- MenuItemView* on_menu_closed_menu_;
- MenuRunner::RunResult on_menu_closed_run_result_;
-
- DISALLOW_COPY_AND_ASSIGN(TestMenuDelegate);
-};
-
-TestMenuDelegate::TestMenuDelegate()
- : execute_command_id_(0),
- on_menu_closed_called_(0),
- on_menu_closed_menu_(nullptr),
- on_menu_closed_run_result_(MenuRunner::MENU_DELETED) {}
-
-TestMenuDelegate::~TestMenuDelegate() {}
-
-void TestMenuDelegate::ExecuteCommand(int id) {
- execute_command_id_ = id;
-}
-
-void TestMenuDelegate::OnMenuClosed(MenuItemView* menu,
- MenuRunner::RunResult result) {
- on_menu_closed_called_++;
- on_menu_closed_menu_ = menu;
- on_menu_closed_run_result_ = result;
-}
-
class MenuRunnerTest : public ViewsTestBase {
public:
MenuRunnerTest();
@@ -95,9 +48,9 @@ class MenuRunnerTest : public ViewsTestBase {
// Owned by MenuRunner.
MenuItemView* menu_item_view_;
- scoped_ptr<TestMenuDelegate> menu_delegate_;
- scoped_ptr<MenuRunner> menu_runner_;
- scoped_ptr<Widget> owner_;
+ std::unique_ptr<TestMenuDelegate> menu_delegate_;
+ std::unique_ptr<MenuRunner> menu_runner_;
+ std::unique_ptr<Widget> owner_;
DISALLOW_COPY_AND_ASSIGN(MenuRunnerTest);
};
@@ -220,9 +173,9 @@ TEST_F(MenuRunnerTest, NestingDuringDrag) {
EXPECT_EQ(MenuRunner::NORMAL_EXIT, result);
EXPECT_TRUE(runner->IsRunning());
- scoped_ptr<TestMenuDelegate> nested_delegate(new TestMenuDelegate);
+ std::unique_ptr<TestMenuDelegate> nested_delegate(new TestMenuDelegate);
MenuItemView* nested_menu = new MenuItemView(nested_delegate.get());
- scoped_ptr<MenuRunner> nested_runner(
+ std::unique_ptr<MenuRunner> nested_runner(
new MenuRunner(nested_menu, MenuRunner::IS_NESTED | MenuRunner::ASYNC));
result = nested_runner->RunMenuAt(owner(), nullptr, gfx::Rect(),
MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_NONE);
@@ -235,5 +188,107 @@ TEST_F(MenuRunnerTest, NestingDuringDrag) {
EXPECT_EQ(MenuRunner::NORMAL_EXIT, delegate->on_menu_closed_run_result());
}
+namespace {
+
+// An EventHandler that launches a menu in response to a mouse press.
+class MenuLauncherEventHandler : public ui::EventHandler {
+ public:
+ MenuLauncherEventHandler(MenuRunner* runner, Widget* owner)
+ : runner_(runner), owner_(owner) {}
+ ~MenuLauncherEventHandler() override {}
+
+ private:
+ // ui::EventHandler:
+ void OnMouseEvent(ui::MouseEvent* event) override {
+ if (event->type() == ui::ET_MOUSE_PRESSED) {
+ runner_->RunMenuAt(owner_, nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
+ ui::MENU_SOURCE_NONE);
+ event->SetHandled();
+ }
+ }
+
+ MenuRunner* runner_;
+ Widget* owner_;
+
+ DISALLOW_COPY_AND_ASSIGN(MenuLauncherEventHandler);
+};
+
+} // namespace
+
+// Tests that when a mouse press launches a menu, that the target widget does
+// not take explicit capture, nor closes the menu.
+TEST_F(MenuRunnerTest, WidgetDoesntTakeCapture) {
+ Widget* widget = new Widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ widget->Init(params);
+ widget->Show();
+ widget->SetSize(gfx::Size(300, 300));
+
+ EventCountView* event_count_view = new EventCountView();
+ event_count_view->SetBounds(0, 0, 300, 300);
+ widget->GetRootView()->AddChildView(event_count_view);
+
+ InitMenuRunner(MenuRunner::ASYNC);
+ MenuRunner* runner = menu_runner();
+
+ MenuLauncherEventHandler consumer(runner, owner());
+ event_count_view->AddPostTargetHandler(&consumer);
+ EXPECT_EQ(nullptr, internal::NativeWidgetPrivate::GetGlobalCapture(
+ widget->GetNativeView()));
+ std::unique_ptr<ui::test::EventGenerator> generator(
+ new ui::test::EventGenerator(
+ IsMus() ? widget->GetNativeWindow() : GetContext(),
+ widget->GetNativeWindow()));
+ // Implicit capture should not be held by |widget|.
+ generator->PressLeftButton();
+ EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_NE(
+ widget->GetNativeView(),
+ internal::NativeWidgetPrivate::GetGlobalCapture(widget->GetNativeView()));
+
+ // The menu should still be open.
+ TestMenuDelegate* delegate = menu_delegate();
+ EXPECT_TRUE(runner->IsRunning());
+ EXPECT_EQ(0, delegate->on_menu_closed_called());
+
+ widget->CloseNow();
+}
+
+typedef MenuRunnerTest MenuRunnerImplTest;
+
+// Tests that when nested menu runners are destroyed out of order, that
+// MenuController is not accessed after it has been destroyed. This should not
+// crash on ASAN bots.
+TEST_F(MenuRunnerImplTest, NestedMenuRunnersDestroyedOutOfOrder) {
+ internal::MenuRunnerImpl* menu_runner =
+ new internal::MenuRunnerImpl(menu_item_view());
+ EXPECT_EQ(MenuRunner::NORMAL_EXIT,
+ menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(),
+ MENU_ANCHOR_TOPLEFT, MenuRunner::ASYNC));
+
+ std::unique_ptr<TestMenuDelegate> menu_delegate2(new TestMenuDelegate);
+ MenuItemView* menu_item_view2 = new MenuItemView(menu_delegate2.get());
+ menu_item_view2->AppendMenuItemWithLabel(1, base::ASCIIToUTF16("One"));
+
+ internal::MenuRunnerImpl* menu_runner2 =
+ new internal::MenuRunnerImpl(menu_item_view2);
+ EXPECT_EQ(MenuRunner::NORMAL_EXIT,
+ menu_runner2->RunMenuAt(owner(), nullptr, gfx::Rect(),
+ MENU_ANCHOR_TOPLEFT,
+ MenuRunner::ASYNC | MenuRunner::IS_NESTED));
+
+ // Hide the controller so we can test out of order destruction.
+ MenuControllerTestApi menu_controller;
+ menu_controller.Hide();
+
+ // This destroyed MenuController
+ menu_runner->OnMenuClosed(internal::MenuControllerDelegate::NOTIFY_DELEGATE,
+ nullptr, 0);
+
+ // This should not access the destroyed MenuController
+ menu_runner2->Release();
+ menu_runner->Release();
+}
+
} // namespace test
} // namespace views
diff --git a/chromium/ui/views/controls/menu/menu_scroll_view_container.cc b/chromium/ui/views/controls/menu/menu_scroll_view_container.cc
index 381bef70f6f..9350283fde1 100644
--- a/chromium/ui/views/controls/menu/menu_scroll_view_container.cc
+++ b/chromium/ui/views/controls/menu/menu_scroll_view_container.cc
@@ -5,6 +5,7 @@
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/accessibility/ax_view_state.h"
@@ -293,7 +294,8 @@ void MenuScrollViewContainer::CreateDefaultBorder() {
ui::NativeTheme::kColorId_MenuBorderColor)
: gfx::kPlaceholderColor;
SetBorder(views::Border::CreateBorderPainter(
- new views::RoundRectPainter(color, menu_config.corner_radius),
+ base::WrapUnique(
+ new views::RoundRectPainter(color, menu_config.corner_radius)),
gfx::Insets(top, left, bottom, right)));
} else {
SetBorder(Border::CreateEmptyBorder(top, left, bottom, right));
@@ -304,7 +306,7 @@ void MenuScrollViewContainer::CreateBubbleBorder() {
bubble_border_ = new BubbleBorder(arrow_,
BubbleBorder::SMALL_SHADOW,
SK_ColorWHITE);
- SetBorder(scoped_ptr<Border>(bubble_border_));
+ SetBorder(std::unique_ptr<Border>(bubble_border_));
set_background(new BubbleBackground(bubble_border_));
}
diff --git a/chromium/ui/views/controls/menu/menu_separator_win.cc b/chromium/ui/views/controls/menu/menu_separator_win.cc
index 182cc2b3294..2ecabdbeb1c 100644
--- a/chromium/ui/views/controls/menu/menu_separator_win.cc
+++ b/chromium/ui/views/controls/menu/menu_separator_win.cc
@@ -8,9 +8,9 @@
#include <uxtheme.h>
#include <Vssym32.h>
+#include "ui/display/win/dpi.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/win/dpi.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/native_theme_aura.h"
#include "ui/views/controls/menu/menu_item_view.h"
@@ -29,7 +29,7 @@ void MenuSeparator::OnPaint(gfx::Canvas* canvas) {
// Hack to get the separator to display correctly on Windows where we may
// have fractional scales. We move the separator 1 pixel down to ensure that
// it falls within the clipping rect which is scaled up.
- float device_scale = gfx::GetDPIScale();
+ float device_scale = display::win::GetDPIScale();
bool is_fractional_scale =
(device_scale - static_cast<int>(device_scale) != 0);
if (is_fractional_scale && separator_bounds.y() == 0)
diff --git a/chromium/ui/views/controls/menu/native_menu_win.cc b/chromium/ui/views/controls/menu/native_menu_win.cc
index 8b66b10e979..e205fda62f9 100644
--- a/chromium/ui/views/controls/menu/native_menu_win.cc
+++ b/chromium/ui/views/controls/menu/native_menu_win.cc
@@ -22,7 +22,7 @@ struct NativeMenuWin::ItemData {
base::string16 label;
// Someone needs to own submenus, it may as well be us.
- scoped_ptr<NativeMenuWin> submenu;
+ std::unique_ptr<NativeMenuWin> submenu;
// We need a pointer back to the containing menu in various circumstances.
NativeMenuWin* native_menu_win;
diff --git a/chromium/ui/views/controls/menu/submenu_view.h b/chromium/ui/views/controls/menu/submenu_view.h
index 11243ff1900..1f929750bbc 100644
--- a/chromium/ui/views/controls/menu/submenu_view.h
+++ b/chromium/ui/views/controls/menu/submenu_view.h
@@ -205,7 +205,7 @@ class VIEWS_EXPORT SubmenuView : public PrefixDelegate,
bool resize_open_menu_;
// The submenu's scroll animator
- scoped_ptr<ScrollAnimator> scroll_animator_;
+ std::unique_ptr<ScrollAnimator> scroll_animator_;
// Difference between current position and cumulative deltas passed to
// OnScroll.
diff --git a/chromium/ui/views/controls/native/native_view_host.h b/chromium/ui/views/controls/native/native_view_host.h
index f0770ba8f8d..6b9aa0ea4ac 100644
--- a/chromium/ui/views/controls/native/native_view_host.h
+++ b/chromium/ui/views/controls/native/native_view_host.h
@@ -108,7 +108,7 @@ class VIEWS_EXPORT NativeViewHost : public View {
// A platform-specific wrapper that does the OS-level manipulation of the
// attached gfx::NativeView.
- scoped_ptr<NativeViewHostWrapper> native_wrapper_;
+ std::unique_ptr<NativeViewHostWrapper> native_wrapper_;
// The preferred size of this View
gfx::Size preferred_size_;
diff --git a/chromium/ui/views/controls/native/native_view_host_aura.h b/chromium/ui/views/controls/native/native_view_host_aura.h
index 67d7756397c..45e859082eb 100644
--- a/chromium/ui/views/controls/native/native_view_host_aura.h
+++ b/chromium/ui/views/controls/native/native_view_host_aura.h
@@ -57,13 +57,13 @@ class VIEWS_EXPORT NativeViewHostAura : public NativeViewHostWrapper,
// Our associated NativeViewHost.
NativeViewHost* host_;
- scoped_ptr<ClippingWindowDelegate> clipping_window_delegate_;
+ std::unique_ptr<ClippingWindowDelegate> clipping_window_delegate_;
// Window that exists between the native view and the parent that allows for
// clipping to occur. This is positioned in the coordinate space of
// host_->GetWidget().
aura::Window clipping_window_;
- scoped_ptr<gfx::Rect> clip_rect_;
+ std::unique_ptr<gfx::Rect> clip_rect_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostAura);
};
diff --git a/chromium/ui/views/controls/native/native_view_host_aura_unittest.cc b/chromium/ui/views/controls/native/native_view_host_aura_unittest.cc
index 685267de3b9..dbc34713528 100644
--- a/chromium/ui/views/controls/native/native_view_host_aura_unittest.cc
+++ b/chromium/ui/views/controls/native/native_view_host_aura_unittest.cc
@@ -4,8 +4,9 @@
#include "ui/views/controls/native/native_view_host_aura.h"
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
@@ -105,7 +106,7 @@ class NativeViewHostAuraTest : public test::NativeViewHostTestBase {
}
private:
- scoped_ptr<Widget> child_;
+ std::unique_ptr<Widget> child_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostAuraTest);
};
diff --git a/chromium/ui/views/controls/native/native_view_host_mac.mm b/chromium/ui/views/controls/native/native_view_host_mac.mm
index b3e0cfcd4b6..45a315736a4 100644
--- a/chromium/ui/views/controls/native/native_view_host_mac.mm
+++ b/chromium/ui/views/controls/native/native_view_host_mac.mm
@@ -59,9 +59,15 @@ void NativeViewHostMac::NativeViewDetaching(bool destroyed) {
// are reference counted so there isn't a reliable signal. Instead, a
// reference is retained until the NativeViewHost is detached.
DCHECK(!destroyed);
+
// |native_view_| can be nil here if RemovedFromWidget() is called before
// NativeViewHost::Detach().
- DCHECK(!native_view_ || native_view_ == host_->native_view());
+ if (!native_view_) {
+ DCHECK(![host_->native_view() superview]);
+ return;
+ }
+
+ DCHECK(native_view_ == host_->native_view());
[host_->native_view() setHidden:YES];
[host_->native_view() removeFromSuperview];
diff --git a/chromium/ui/views/controls/native/native_view_host_mac_unittest.mm b/chromium/ui/views/controls/native/native_view_host_mac_unittest.mm
index ea91605a7fa..0208dc14a5b 100644
--- a/chromium/ui/views/controls/native/native_view_host_mac_unittest.mm
+++ b/chromium/ui/views/controls/native/native_view_host_mac_unittest.mm
@@ -6,10 +6,11 @@
#import <Cocoa/Cocoa.h>
+#include <memory>
+
#import "base/mac/scoped_nsautorelease_pool.h"
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#import "testing/gtest_mac.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/controls/native/native_view_host_test_base.h"
diff --git a/chromium/ui/views/controls/native/native_view_host_test_base.h b/chromium/ui/views/controls/native/native_view_host_test_base.h
index f663956da61..ad39c162d15 100644
--- a/chromium/ui/views/controls/native/native_view_host_test_base.h
+++ b/chromium/ui/views/controls/native/native_view_host_test_base.h
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/views/test/views_test_base.h"
namespace views {
@@ -54,8 +55,8 @@ class NativeViewHostTestBase : public ViewsTestBase {
private:
class NativeViewHostTesting;
- scoped_ptr<Widget> toplevel_;
- scoped_ptr<NativeViewHost> host_;
+ std::unique_ptr<Widget> toplevel_;
+ std::unique_ptr<NativeViewHost> host_;
int host_destroyed_count_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostTestBase);
diff --git a/chromium/ui/views/controls/native/native_view_host_unittest.cc b/chromium/ui/views/controls/native/native_view_host_unittest.cc
index c15295942ff..0baba8257c3 100644
--- a/chromium/ui/views/controls/native/native_view_host_unittest.cc
+++ b/chromium/ui/views/controls/native/native_view_host_unittest.cc
@@ -4,8 +4,9 @@
#include "ui/views/controls/native/native_view_host.h"
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/aura/window.h"
#include "ui/views/controls/native/native_view_host_test_base.h"
#include "ui/views/test/views_test_base.h"
@@ -98,10 +99,8 @@ TEST_F(NativeViewHostTest, NativeViewHierarchyChanged) {
NativeViewHierarchyChangedTestView* test_view =
new NativeViewHierarchyChangedTestView;
NativeViewHost* host = new NativeViewHost;
- scoped_ptr<Widget> child(CreateChildForHost(toplevel()->GetNativeView(),
- toplevel()->GetRootView(),
- test_view,
- host));
+ std::unique_ptr<Widget> child(CreateChildForHost(
+ toplevel()->GetNativeView(), toplevel()->GetRootView(), test_view, host));
#if defined(USE_AURA)
// Two notifications are generated from inserting the native view into the
// clipping window and then inserting the clipping window into the root
@@ -159,20 +158,14 @@ TEST_F(NativeViewHostTest, ViewHierarchyChangedForHost) {
// Add two children widgets attached to a NativeViewHost, and a test
// grandchild as child widget of host0.
NativeViewHost* host0 = new NativeViewHost;
- scoped_ptr<Widget> child0(CreateChildForHost(toplevel()->GetNativeView(),
- toplevel()->GetRootView(),
- new View,
- host0));
+ std::unique_ptr<Widget> child0(CreateChildForHost(
+ toplevel()->GetNativeView(), toplevel()->GetRootView(), new View, host0));
NativeViewHost* host1 = new NativeViewHost;
- scoped_ptr<Widget> child1(CreateChildForHost(toplevel()->GetNativeView(),
- toplevel()->GetRootView(),
- new View,
- host1));
+ std::unique_ptr<Widget> child1(CreateChildForHost(
+ toplevel()->GetNativeView(), toplevel()->GetRootView(), new View, host1));
ViewHierarchyChangedTestHost* test_host = new ViewHierarchyChangedTestHost;
- scoped_ptr<Widget> test_child(CreateChildForHost(host0->native_view(),
- host0,
- new View,
- test_host));
+ std::unique_ptr<Widget> test_child(
+ CreateChildForHost(host0->native_view(), host0, new View, test_host));
// Remove test_host from host0, expect 1 parent change.
test_host->ResetParentChanges();
@@ -224,15 +217,11 @@ TEST_F(NativeViewHostTest, ViewHierarchyChangedForHostParent) {
// To each child view, add a child widget.
ViewHierarchyChangedTestHost* host0 = new ViewHierarchyChangedTestHost;
- scoped_ptr<Widget> child0(CreateChildForHost(toplevel()->GetNativeView(),
- view0,
- new View,
- host0));
+ std::unique_ptr<Widget> child0(
+ CreateChildForHost(toplevel()->GetNativeView(), view0, new View, host0));
ViewHierarchyChangedTestHost* host1 = new ViewHierarchyChangedTestHost;
- scoped_ptr<Widget> child1(CreateChildForHost(toplevel()->GetNativeView(),
- view1,
- new View,
- host1));
+ std::unique_ptr<Widget> child1(
+ CreateChildForHost(toplevel()->GetNativeView(), view1, new View, host1));
// Remove view0 from top level, expect 1 parent change.
host0->ResetParentChanges();
diff --git a/chromium/ui/views/controls/prefix_selector_unittest.cc b/chromium/ui/views/controls/prefix_selector_unittest.cc
index cb109c267a4..8619c76229c 100644
--- a/chromium/ui/views/controls/prefix_selector_unittest.cc
+++ b/chromium/ui/views/controls/prefix_selector_unittest.cc
@@ -54,7 +54,7 @@ class PrefixSelectorTest : public ViewsTestBase {
}
protected:
- scoped_ptr<PrefixSelector> selector_;
+ std::unique_ptr<PrefixSelector> selector_;
TestPrefixDelegate delegate_;
private:
diff --git a/chromium/ui/views/controls/scroll_view_unittest.cc b/chromium/ui/views/controls/scroll_view_unittest.cc
index 011f65d38a1..d90784ca906 100644
--- a/chromium/ui/views/controls/scroll_view_unittest.cc
+++ b/chromium/ui/views/controls/scroll_view_unittest.cc
@@ -476,7 +476,8 @@ TEST(ScrollViewTest, CornerViewVisibility) {
// Tests the overlay scrollbars on Mac. Ensure that they show up properly and
// do not overlap each other.
TEST(ScrollViewTest, CocoaOverlayScrollBars) {
- scoped_ptr<ui::test::ScopedPreferredScrollerStyle> scroller_style_override;
+ std::unique_ptr<ui::test::ScopedPreferredScrollerStyle>
+ scroller_style_override;
scroller_style_override.reset(
new ui::test::ScopedPreferredScrollerStyle(true));
ScrollView scroll_view;
diff --git a/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc b/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc
index e9333e1458c..28da57db9a8 100644
--- a/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc
+++ b/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc
@@ -24,10 +24,6 @@
#include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
#include "ui/views/widget/widget.h"
-#if defined(OS_LINUX)
-#include "ui/gfx/screen.h"
-#endif
-
#undef min
#undef max
diff --git a/chromium/ui/views/controls/scrollbar/base_scroll_bar.h b/chromium/ui/views/controls/scrollbar/base_scroll_bar.h
index 178fdc1e908..6d6944259d3 100644
--- a/chromium/ui/views/controls/scrollbar/base_scroll_bar.h
+++ b/chromium/ui/views/controls/scrollbar/base_scroll_bar.h
@@ -177,8 +177,8 @@ class VIEWS_EXPORT BaseScrollBar : public ScrollBar,
// was invoked.
int context_menu_mouse_position_;
- scoped_ptr<MenuRunner> menu_runner_;
- scoped_ptr<ScrollAnimator> scroll_animator_;
+ std::unique_ptr<MenuRunner> menu_runner_;
+ std::unique_ptr<ScrollAnimator> scroll_animator_;
// Difference between current position and cumulative deltas obtained from
// scroll update events.
diff --git a/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.cc b/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.cc
index d3fb7071ed8..e2befaee43a 100644
--- a/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.cc
+++ b/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.cc
@@ -6,8 +6,8 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
-#include "ui/gfx/screen.h"
namespace views {
@@ -36,7 +36,8 @@ void BaseScrollBarButton::OnMouseCaptureLost() {
void BaseScrollBarButton::RepeaterNotifyClick() {
// TODO(sky): See if we can convert to using |Screen| everywhere.
- gfx::Point cursor_point = gfx::Screen::GetScreen()->GetCursorScreenPoint();
+ gfx::Point cursor_point =
+ display::Screen::GetScreen()->GetCursorScreenPoint();
ui::MouseEvent event(ui::ET_MOUSE_RELEASED, cursor_point, cursor_point,
ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
ui::EF_LEFT_MOUSE_BUTTON);
diff --git a/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.h b/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.h
index cb269baf7b1..6e8716bebb5 100644
--- a/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.h
+++ b/chromium/ui/views/controls/scrollbar/base_scroll_bar_button.h
@@ -11,10 +11,6 @@
#include "build/build_config.h"
#include "ui/views/repeat_controller.h"
-#if defined(OS_LINUX)
-#include "ui/gfx/screen.h"
-#endif
-
namespace views {
///////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/ui/views/controls/scrollbar/native_scroll_bar_views.cc b/chromium/ui/views/controls/scrollbar/native_scroll_bar_views.cc
index 3348b5bcbca..421a56da3f2 100644
--- a/chromium/ui/views/controls/scrollbar/native_scroll_bar_views.cc
+++ b/chromium/ui/views/controls/scrollbar/native_scroll_bar_views.cc
@@ -72,8 +72,7 @@ class ScrollBarThumb : public BaseScrollBarThumb {
ScrollBarButton::ScrollBarButton(ButtonListener* listener, Type type)
: BaseScrollBarButton(listener),
type_(type) {
- SetFocusable(false);
- SetAccessibilityFocusable(false);
+ SetFocusBehavior(FocusBehavior::NEVER);
}
ScrollBarButton::~ScrollBarButton() {
@@ -150,8 +149,6 @@ ui::NativeTheme::State
ScrollBarThumb::ScrollBarThumb(BaseScrollBar* scroll_bar)
: BaseScrollBarThumb(scroll_bar),
scroll_bar_(scroll_bar) {
- SetFocusable(false);
- SetAccessibilityFocusable(false);
}
ScrollBarThumb::~ScrollBarThumb() {
diff --git a/chromium/ui/views/controls/scrollbar/scrollbar_unittest.cc b/chromium/ui/views/controls/scrollbar/scrollbar_unittest.cc
index 84471929234..b225098c7a7 100644
--- a/chromium/ui/views/controls/scrollbar/scrollbar_unittest.cc
+++ b/chromium/ui/views/controls/scrollbar/scrollbar_unittest.cc
@@ -93,7 +93,7 @@ class NativeScrollBarTest : public ViewsTestBase {
// scroll to the middle.
int track_size_;
- scoped_ptr<TestScrollBarController> controller_;
+ std::unique_ptr<TestScrollBarController> controller_;
};
// TODO(dnicoara) Can't run the test on Windows since the scrollbar |Part|
diff --git a/chromium/ui/views/controls/separator.cc b/chromium/ui/views/controls/separator.cc
index e16346127ba..16fb2209789 100644
--- a/chromium/ui/views/controls/separator.cc
+++ b/chromium/ui/views/controls/separator.cc
@@ -22,7 +22,6 @@ Separator::Separator(Orientation orientation)
: orientation_(orientation),
color_(kDefaultColor),
size_(kSeparatorSize) {
- SetFocusable(false);
}
Separator::~Separator() {
diff --git a/chromium/ui/views/controls/slider.cc b/chromium/ui/views/controls/slider.cc
index e063456aaaf..c930e3c66ee 100644
--- a/chromium/ui/views/controls/slider.cc
+++ b/chromium/ui/views/controls/slider.cc
@@ -67,7 +67,12 @@ Slider::Slider(SliderListener* listener, Orientation orientation)
bar_active_images_(kBarImagesActive),
bar_disabled_images_(kBarImagesDisabled) {
EnableCanvasFlippingForRTLUI(true);
- SetFocusable(true);
+#if defined(OS_MACOSX)
+ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+#else
+ SetFocusBehavior(FocusBehavior::ALWAYS);
+#endif
+
UpdateState(true);
}
diff --git a/chromium/ui/views/controls/slider.h b/chromium/ui/views/controls/slider.h
index 294004331a5..3d2090aca47 100644
--- a/chromium/ui/views/controls/slider.h
+++ b/chromium/ui/views/controls/slider.h
@@ -122,7 +122,7 @@ class VIEWS_EXPORT Slider : public View, public gfx::AnimationDelegate {
SliderListener* listener_;
Orientation orientation_;
- scoped_ptr<gfx::SlideAnimation> move_animation_;
+ std::unique_ptr<gfx::SlideAnimation> move_animation_;
float value_;
float keyboard_increment_;
diff --git a/chromium/ui/views/controls/slider_unittest.cc b/chromium/ui/views/controls/slider_unittest.cc
index ded1f367c5a..46641a212e2 100644
--- a/chromium/ui/views/controls/slider_unittest.cc
+++ b/chromium/ui/views/controls/slider_unittest.cc
@@ -4,11 +4,11 @@
#include "ui/views/controls/slider.h"
+#include <memory>
#include <string>
#include "base/i18n/rtl.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
@@ -169,7 +169,7 @@ class SliderTest : public views::ViewsTestBase {
// The widget container for the slider being tested.
views::Widget* widget_;
// An event generator.
- scoped_ptr<ui::test::EventGenerator> event_generator_;
+ std::unique_ptr<ui::test::EventGenerator> event_generator_;
DISALLOW_COPY_AND_ASSIGN(SliderTest);
};
diff --git a/chromium/ui/views/controls/styled_label.cc b/chromium/ui/views/controls/styled_label.cc
index 9c8f720cee1..f46c93c046f 100644
--- a/chromium/ui/views/controls/styled_label.cc
+++ b/chromium/ui/views/controls/styled_label.cc
@@ -32,12 +32,12 @@ int CalculateLineHeight(const gfx::FontList& font_list) {
return label.GetPreferredSize().height();
}
-scoped_ptr<Label> CreateLabelRange(
+std::unique_ptr<Label> CreateLabelRange(
const base::string16& text,
const gfx::FontList& font_list,
const StyledLabel::RangeStyleInfo& style_info,
views::LinkListener* link_listener) {
- scoped_ptr<Label> result;
+ std::unique_ptr<Label> result;
if (style_info.is_link) {
Link* link = new Link(text);
@@ -307,7 +307,7 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
base::string16 chunk = substrings[0];
- scoped_ptr<Label> label;
+ std::unique_ptr<Label> label;
if (position >= range.start()) {
const RangeStyleInfo& style_info = current_range->style_info;
diff --git a/chromium/ui/views/controls/styled_label_unittest.cc b/chromium/ui/views/controls/styled_label_unittest.cc
index cae7f67744e..408212b385c 100644
--- a/chromium/ui/views/controls/styled_label_unittest.cc
+++ b/chromium/ui/views/controls/styled_label_unittest.cc
@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/controls/styled_label.h"
+
#include <stddef.h>
+#include <memory>
#include <string>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/font_list.h"
#include "ui/views/border.h"
#include "ui/views/controls/link.h"
-#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/styled_label_listener.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
@@ -46,7 +47,7 @@ class StyledLabelTest : public ViewsTestBase, public StyledLabelListener {
}
private:
- scoped_ptr<StyledLabel> styled_;
+ std::unique_ptr<StyledLabel> styled_;
DISALLOW_COPY_AND_ASSIGN(StyledLabelTest);
};
diff --git a/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc b/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc
index 5579bb07c04..8b948e70bbf 100644
--- a/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc
+++ b/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -277,7 +277,12 @@ TabbedPane::TabbedPane()
tab_strip_(new TabStrip(this)),
contents_(new View()),
selected_tab_index_(-1) {
- SetFocusable(true);
+#if defined(OS_MACOSX)
+ SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+#else
+ SetFocusBehavior(FocusBehavior::ALWAYS);
+#endif
+
AddChildView(tab_strip_);
AddChildView(contents_);
}
diff --git a/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
index c13e6376828..7152f7eb4f0 100644
--- a/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
+++ b/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -2,12 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/controls/tabbed_pane/tabbed_pane.h"
+
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/views/controls/tabbed_pane/tabbed_pane.h"
#include "ui/views/test/views_test_base.h"
using base::ASCIIToUTF16;
@@ -35,7 +37,7 @@ typedef ViewsTestBase TabbedPaneTest;
// Tests TabbedPane::GetPreferredSize() and TabbedPane::Layout().
TEST_F(TabbedPaneTest, SizeAndLayout) {
- scoped_ptr<TabbedPane> tabbed_pane(new TabbedPane());
+ std::unique_ptr<TabbedPane> tabbed_pane(new TabbedPane());
View* child1 = new FixedSizeView(gfx::Size(20, 10));
tabbed_pane->AddTab(ASCIIToUTF16("tab1"), child1);
View* child2 = new FixedSizeView(gfx::Size(5, 5));
@@ -67,7 +69,7 @@ TEST_F(TabbedPaneTest, SizeAndLayout) {
}
TEST_F(TabbedPaneTest, AddAndSelect) {
- scoped_ptr<TabbedPane> tabbed_pane(new TabbedPane());
+ std::unique_ptr<TabbedPane> tabbed_pane(new TabbedPane());
// Add several tabs; only the first should be a selected automatically.
for (int i = 0; i < 3; ++i) {
View* tab = new View();
diff --git a/chromium/ui/views/controls/table/table_header.h b/chromium/ui/views/controls/table/table_header.h
index 7fd54e91a21..3c671987d5d 100644
--- a/chromium/ui/views/controls/table/table_header.h
+++ b/chromium/ui/views/controls/table/table_header.h
@@ -80,7 +80,7 @@ class VIEWS_EXPORT TableHeader : public views::View {
TableView* table_;
// If non-null a resize is in progress.
- scoped_ptr<ColumnResizeDetails> resize_details_;
+ std::unique_ptr<ColumnResizeDetails> resize_details_;
DISALLOW_COPY_AND_ASSIGN(TableHeader);
};
diff --git a/chromium/ui/views/controls/table/table_view.cc b/chromium/ui/views/controls/table/table_view.cc
index 3a289f3b22c..c09c6ead905 100644
--- a/chromium/ui/views/controls/table/table_view.cc
+++ b/chromium/ui/views/controls/table/table_view.cc
@@ -145,7 +145,8 @@ TableView::TableView(ui::TableModel* model,
visible_column.column = columns[i];
visible_columns_.push_back(visible_column);
}
- SetFocusable(true);
+ // Always focusable, even on Mac (consistent with NSTableView).
+ SetFocusBehavior(FocusBehavior::ALWAYS);
SetModel(model);
}
@@ -178,7 +179,7 @@ View* TableView::CreateParentIfNecessary() {
}
void TableView::SetRowBackgroundPainter(
- scoped_ptr<TableViewRowBackgroundPainter> painter) {
+ std::unique_ptr<TableViewRowBackgroundPainter> painter) {
row_background_painter_ = std::move(painter);
}
diff --git a/chromium/ui/views/controls/table/table_view.h b/chromium/ui/views/controls/table/table_view.h
index 55c7a31d8ff..fc7f028164b 100644
--- a/chromium/ui/views/controls/table/table_view.h
+++ b/chromium/ui/views/controls/table/table_view.h
@@ -5,10 +5,10 @@
#ifndef UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
#define UI_VIEWS_CONTROLS_TABLE_TABLE_VIEW_VIEWS_H_
+#include <memory>
#include <vector>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/base/models/list_selection_model.h"
#include "ui/base/models/table_model.h"
#include "ui/base/models/table_model_observer.h"
@@ -107,7 +107,7 @@ class VIEWS_EXPORT TableView
View* CreateParentIfNecessary();
void SetRowBackgroundPainter(
- scoped_ptr<TableViewRowBackgroundPainter> painter);
+ std::unique_ptr<TableViewRowBackgroundPainter> painter);
// Sets the TableGrouper. TableView does not own |grouper| (common use case is
// to have TableModel implement TableGrouper).
@@ -351,7 +351,7 @@ class VIEWS_EXPORT TableView
std::vector<int> view_to_model_;
std::vector<int> model_to_view_;
- scoped_ptr<TableViewRowBackgroundPainter> row_background_painter_;
+ std::unique_ptr<TableViewRowBackgroundPainter> row_background_painter_;
TableGrouper* grouper_;
diff --git a/chromium/ui/views/controls/table/table_view_unittest.cc b/chromium/ui/views/controls/table/table_view_unittest.cc
index 2618a2f0176..b290c0def29 100644
--- a/chromium/ui/views/controls/table/table_view_unittest.cc
+++ b/chromium/ui/views/controls/table/table_view_unittest.cc
@@ -238,15 +238,15 @@ class TableViewTest : public testing::Test {
}
protected:
- scoped_ptr<TestTableModel2> model_;
+ std::unique_ptr<TestTableModel2> model_;
// Owned by |parent_|.
TableView* table_;
- scoped_ptr<TableViewTestHelper> helper_;
+ std::unique_ptr<TableViewTestHelper> helper_;
private:
- scoped_ptr<View> parent_;
+ std::unique_ptr<View> parent_;
DISALLOW_COPY_AND_ASSIGN(TableViewTest);
};
diff --git a/chromium/ui/views/controls/textfield/textfield.cc b/chromium/ui/views/controls/textfield/textfield.cc
index 74d18b70564..dc0a9f25358 100644
--- a/chromium/ui/views/controls/textfield/textfield.cc
+++ b/chromium/ui/views/controls/textfield/textfield.cc
@@ -21,13 +21,13 @@
#include "ui/base/ui_base_switches_util.h"
#include "ui/compositor/canvas_painter.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
-#include "ui/gfx/display.h"
#include "ui/gfx/geometry/insets.h"
-#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
@@ -40,6 +40,7 @@
#include "ui/views/metrics.h"
#include "ui/views/native_cursor.h"
#include "ui/views/painter.h"
+#include "ui/views/style/platform_style.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/widget.h"
@@ -82,8 +83,8 @@ int GetDragSelectionDelay() {
return 100;
}
-// Get the default command for a given key |event| and selection state.
-int GetCommandForKeyEvent(const ui::KeyEvent& event, bool has_selection) {
+// Get the default command for a given key |event|.
+int GetCommandForKeyEvent(const ui::KeyEvent& event) {
if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode())
return kNoCommand;
@@ -128,7 +129,7 @@ int GetCommandForKeyEvent(const ui::KeyEvent& event, bool has_selection) {
return shift ? IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION :
IDS_MOVE_TO_END_OF_LINE;
case ui::VKEY_BACK:
- if (!control || has_selection)
+ if (!control)
return IDS_DELETE_BACKWARD;
#if defined(OS_LINUX)
// Only erase by line break on Linux and ChromeOS.
@@ -137,14 +138,14 @@ int GetCommandForKeyEvent(const ui::KeyEvent& event, bool has_selection) {
#endif
return IDS_DELETE_WORD_BACKWARD;
case ui::VKEY_DELETE:
- if (!control || has_selection)
- return (shift && has_selection) ? IDS_APP_CUT : IDS_DELETE_FORWARD;
#if defined(OS_LINUX)
// Only erase by line break on Linux and ChromeOS.
- if (shift)
+ if (shift && control)
return IDS_DELETE_TO_END_OF_LINE;
#endif
- return IDS_DELETE_WORD_FORWARD;
+ if (control)
+ return IDS_DELETE_WORD_FORWARD;
+ return shift ? IDS_APP_CUT : IDS_DELETE_FORWARD;
case ui::VKEY_INSERT:
if (control && !shift)
return IDS_APP_COPY;
@@ -292,8 +293,8 @@ Textfield::Textfield()
set_context_menu_controller(this);
set_drag_controller(this);
GetRenderText()->SetFontList(GetDefaultFontList());
- SetBorder(scoped_ptr<Border>(new FocusableBorder()));
- SetFocusable(true);
+ SetBorder(std::unique_ptr<Border>(new FocusableBorder()));
+ SetFocusBehavior(FocusBehavior::ALWAYS);
if (ViewsDelegate::GetInstance()) {
password_reveal_duration_ =
@@ -572,7 +573,7 @@ void Textfield::ExecuteCommand(int command_id) {
ExecuteCommand(command_id, ui::EF_NONE);
}
-void Textfield::SetFocusPainter(scoped_ptr<Painter> focus_painter) {
+void Textfield::SetFocusPainter(std::unique_ptr<Painter> focus_painter) {
focus_painter_ = std::move(focus_painter);
}
@@ -729,7 +730,7 @@ bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
#endif
if (edit_command == kNoCommand)
- edit_command = GetCommandForKeyEvent(event, HasSelection());
+ edit_command = GetCommandForKeyEvent(event);
if (!handled && IsCommandIdEnabled(edit_command)) {
ExecuteCommand(edit_command);
@@ -833,7 +834,7 @@ void Textfield::OnGestureEvent(ui::GestureEvent* event) {
bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) {
ui::KeyEvent event(accelerator.type(), accelerator.key_code(),
accelerator.modifiers());
- ExecuteCommand(GetCommandForKeyEvent(event, HasSelection()));
+ ExecuteCommand(GetCommandForKeyEvent(event));
return true;
}
@@ -1098,11 +1099,11 @@ void Textfield::WriteDragDataForView(View* sender,
label.SetSubpixelRenderingEnabled(false);
gfx::Size size(label.GetPreferredSize());
gfx::NativeView native_view = GetWidget()->GetNativeView();
- gfx::Display display =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(native_view);
+ display::Display display =
+ display::Screen::GetScreen()->GetDisplayNearestWindow(native_view);
size.SetToMin(gfx::Size(display.size().width(), height()));
label.SetBoundsRect(gfx::Rect(size));
- scoped_ptr<gfx::Canvas> canvas(
+ std::unique_ptr<gfx::Canvas> canvas(
GetCanvasForDragImage(GetWidget(), label.size()));
label.SetEnabledColor(GetTextColor());
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
@@ -1302,6 +1303,22 @@ bool Textfield::GetAcceleratorForCommandId(int command_id,
void Textfield::ExecuteCommand(int command_id, int event_flags) {
DestroyTouchSelection();
+
+ // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent
+ // modifications of the command should happen here.
+ if (HasSelection()) {
+ switch (command_id) {
+ case IDS_DELETE_WORD_BACKWARD:
+ case IDS_DELETE_TO_BEGINNING_OF_LINE:
+ command_id = IDS_DELETE_BACKWARD;
+ break;
+ case IDS_DELETE_WORD_FORWARD:
+ case IDS_DELETE_TO_END_OF_LINE:
+ command_id = IDS_DELETE_FORWARD;
+ break;
+ }
+ }
+
if (!IsCommandIdEnabled(command_id))
return;
@@ -1475,7 +1492,7 @@ void Textfield::InsertChar(const ui::KeyEvent& event) {
DoInsertChar(ch);
if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD &&
- password_reveal_duration_ != base::TimeDelta()) {
+ !password_reveal_duration_.is_zero()) {
const size_t change_offset = model_->GetCursorPosition();
DCHECK_GT(change_offset, 0u);
RevealPasswordChar(change_offset - 1);
@@ -1746,7 +1763,18 @@ void Textfield::MoveCursorTo(const gfx::Point& point, bool select) {
void Textfield::SelectThroughLastDragLocation() {
OnBeforeUserAction();
- model_->MoveCursorTo(last_drag_location_, true);
+
+ const bool drags_to_end = PlatformStyle::kTextfieldDragVerticallyDragsToEnd;
+ if (drags_to_end && last_drag_location_.y() < 0) {
+ model_->MoveCursor(gfx::BreakType::LINE_BREAK,
+ gfx::VisualCursorDirection::CURSOR_LEFT, true);
+ } else if (drags_to_end && last_drag_location_.y() > height()) {
+ model_->MoveCursor(gfx::BreakType::LINE_BREAK,
+ gfx::VisualCursorDirection::CURSOR_RIGHT, true);
+ } else {
+ model_->MoveCursorTo(last_drag_location_, true);
+ }
+
if (aggregated_clicks_ == 1) {
model_->SelectWord();
// Expand the selection so the initially selected word remains selected.
diff --git a/chromium/ui/views/controls/textfield/textfield.h b/chromium/ui/views/controls/textfield/textfield.h
index b153edd0d89..738dec2982f 100644
--- a/chromium/ui/views/controls/textfield/textfield.h
+++ b/chromium/ui/views/controls/textfield/textfield.h
@@ -8,11 +8,11 @@
#include <stddef.h>
#include <stdint.h>
+#include <memory>
#include <string>
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/timer/timer.h"
@@ -206,7 +206,7 @@ class VIEWS_EXPORT Textfield : public View,
// Performs the action associated with the specified command id.
void ExecuteCommand(int command_id);
- void SetFocusPainter(scoped_ptr<Painter> focus_painter);
+ void SetFocusPainter(std::unique_ptr<Painter> focus_painter);
// Returns whether there is a drag operation originating from the textfield.
bool HasTextBeingDragged();
@@ -392,7 +392,7 @@ class VIEWS_EXPORT Textfield : public View,
void PasteSelectionClipboard(const ui::MouseEvent& event);
// The text model.
- scoped_ptr<TextfieldModel> model_;
+ std::unique_ptr<TextfieldModel> model_;
// This is the current listener for events from this Textfield.
TextfieldController* controller_;
@@ -410,7 +410,7 @@ class VIEWS_EXPORT Textfield : public View,
// This will be reported as the "desired size". Defaults to 0.
int default_width_in_chars_;
- scoped_ptr<Painter> focus_painter_;
+ std::unique_ptr<Painter> focus_painter_;
// Flags indicating whether various system colors should be used, and if not,
// what overriding color values should be used instead.
@@ -470,7 +470,8 @@ class VIEWS_EXPORT Textfield : public View,
gfx::Point last_click_location_;
gfx::Range double_click_word_;
- scoped_ptr<ui::TouchEditingControllerDeprecated> touch_selection_controller_;
+ std::unique_ptr<ui::TouchEditingControllerDeprecated>
+ touch_selection_controller_;
// Used to track touch drag starting location and offset to enable touch
// scrolling.
@@ -482,8 +483,8 @@ class VIEWS_EXPORT Textfield : public View,
bool touch_handles_hidden_due_to_scroll_;
// Context menu related members.
- scoped_ptr<ui::SimpleMenuModel> context_menu_contents_;
- scoped_ptr<views::MenuRunner> context_menu_runner_;
+ std::unique_ptr<ui::SimpleMenuModel> context_menu_contents_;
+ std::unique_ptr<views::MenuRunner> context_menu_runner_;
// Used to bind callback functions to this object.
base::WeakPtrFactory<Textfield> weak_ptr_factory_;
diff --git a/chromium/ui/views/controls/textfield/textfield_model.h b/chromium/ui/views/controls/textfield/textfield_model.h
index 9bdb48c834f..135524e289a 100644
--- a/chromium/ui/views/controls/textfield/textfield_model.h
+++ b/chromium/ui/views/controls/textfield/textfield_model.h
@@ -8,11 +8,11 @@
#include <stddef.h>
#include <list>
+#include <memory>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "ui/base/ime/composition_text.h"
#include "ui/gfx/render_text.h"
@@ -268,7 +268,7 @@ class VIEWS_EXPORT TextfieldModel {
Delegate* delegate_;
// The stylized text, cursor, selection, and the visual layout model.
- scoped_ptr<gfx::RenderText> render_text_;
+ std::unique_ptr<gfx::RenderText> render_text_;
// The composition range.
gfx::Range composition_range_;
diff --git a/chromium/ui/views/controls/textfield/textfield_model_unittest.cc b/chromium/ui/views/controls/textfield/textfield_model_unittest.cc
index 4908c2bec10..03cb08d76ea 100644
--- a/chromium/ui/views/controls/textfield/textfield_model_unittest.cc
+++ b/chromium/ui/views/controls/textfield/textfield_model_unittest.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/controls/textfield/textfield_model.h"
+
#include <stddef.h>
+#include <memory>
#include <vector>
#include "base/auto_reset.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
@@ -19,7 +21,6 @@
#include "ui/gfx/range/range.h"
#include "ui/gfx/render_text.h"
#include "ui/views/controls/textfield/textfield.h"
-#include "ui/views/controls/textfield/textfield_model.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/test/views_test_base.h"
diff --git a/chromium/ui/views/controls/textfield/textfield_unittest.cc b/chromium/ui/views/controls/textfield/textfield_unittest.cc
index 97595c57cb4..82a712abe53 100644
--- a/chromium/ui/views/controls/textfield/textfield_unittest.cc
+++ b/chromium/ui/views/controls/textfield/textfield_unittest.cc
@@ -12,10 +12,12 @@
#include <vector>
#include "base/command_line.h"
+#include "base/format_macros.h"
#include "base/i18n/rtl.h"
#include "base/macros.h"
#include "base/pickle.h"
#include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_view_state.h"
@@ -39,6 +41,7 @@
#include "ui/views/controls/textfield/textfield_model.h"
#include "ui/views/controls/textfield/textfield_test_api.h"
#include "ui/views/focus/focus_manager.h"
+#include "ui/views/style/platform_style.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/widget_test.h"
@@ -329,7 +332,7 @@ class TextfieldDestroyerController : public views::TextfieldController {
}
private:
- scoped_ptr<views::Textfield> target_;
+ std::unique_ptr<views::Textfield> target_;
};
base::string16 GetClipboardText(ui::ClipboardType type) {
@@ -634,11 +637,49 @@ class TextfieldTest : public ViewsTestBase, public TextfieldController {
EXPECT_TRUE(menu->IsEnabledAt(7 /* SELECT ALL */));
}
+ void PressLeftMouseButton(int extra_flags) {
+ ui::MouseEvent click(ui::ET_MOUSE_PRESSED, mouse_position_, mouse_position_,
+ ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
+ ui::EF_LEFT_MOUSE_BUTTON | extra_flags);
+ textfield_->OnMousePressed(click);
+ }
+
+ void PressLeftMouseButton() {
+ PressLeftMouseButton(0);
+ }
+
+ void ReleaseLeftMouseButton() {
+ ui::MouseEvent release(ui::ET_MOUSE_RELEASED, mouse_position_,
+ mouse_position_, ui::EventTimeForNow(),
+ ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
+ textfield_->OnMouseReleased(release);
+ }
+
+ void ClickLeftMouseButton(int extra_flags) {
+ PressLeftMouseButton(extra_flags);
+ ReleaseLeftMouseButton();
+ }
+
+ void ClickLeftMouseButton() {
+ ClickLeftMouseButton(0);
+ }
+
+ void DragMouseTo(const gfx::Point& where) {
+ mouse_position_ = where;
+ ui::MouseEvent drag(ui::ET_MOUSE_DRAGGED, where, where,
+ ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
+ textfield_->OnMouseDragged(drag);
+ }
+
+ // Textfield does not listen to OnMouseMoved, so this function does not send
+ // an event when it updates the cursor position.
+ void MoveMouseTo(const gfx::Point& where) { mouse_position_ = where; }
+
// We need widget to populate wrapper class.
Widget* widget_;
TestTextfield* textfield_;
- scoped_ptr<TextfieldTestApi> test_api_;
+ std::unique_ptr<TextfieldTestApi> test_api_;
TextfieldModel* model_;
// The string from Controller::ContentsChanged callback.
@@ -654,8 +695,10 @@ class TextfieldTest : public ViewsTestBase, public TextfieldController {
int on_after_user_action_;
private:
+ // Position of the mouse for synthetic mouse events.
+ gfx::Point mouse_position_;
ui::ClipboardType copied_to_clipboard_;
- scoped_ptr<ui::test::EventGenerator> event_generator_;
+ std::unique_ptr<ui::test::EventGenerator> event_generator_;
DISALLOW_COPY_AND_ASSIGN(TextfieldTest);
};
@@ -826,6 +869,33 @@ TEST_F(TextfieldTest, InsertionDeletionTest) {
#endif
}
+// Test that deletion operations behave correctly with an active selection.
+TEST_F(TextfieldTest, DeletionWithSelection) {
+ struct {
+ ui::KeyboardCode key;
+ bool shift;
+ } cases[] = {
+ {ui::VKEY_BACK, false},
+ {ui::VKEY_BACK, true},
+ {ui::VKEY_DELETE, false},
+ {ui::VKEY_DELETE, true},
+ };
+
+ InitTextfield();
+ // [Ctrl] ([Alt] on Mac) + [Delete]/[Backspace] should delete the active
+ // selection, regardless of [Shift].
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+ SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
+ textfield_->SetText(ASCIIToUTF16("one two three"));
+ textfield_->SelectRange(gfx::Range(2, 6));
+ // Make selection as - on|e tw|o three.
+ SendWordEvent(cases[i].key, cases[i].shift);
+ // Verify state is on|o three.
+ EXPECT_STR_EQ("ono three", textfield_->text());
+ EXPECT_EQ(gfx::Range(2), textfield_->GetSelectedRange());
+ }
+}
+
TEST_F(TextfieldTest, PasswordTest) {
InitTextfield();
textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
@@ -922,7 +992,7 @@ TEST_F(TextfieldTest, OnKeyPress) {
EXPECT_TRUE(textfield_->key_handled());
textfield_->clear();
- // F20, up/down key won't be handled.
+ // F20 key won't be handled.
SendKeyEvent(ui::VKEY_F20);
#if defined(OS_MACOSX)
// On Mac, key combinations that don't map to editing commands are forwarded
@@ -934,14 +1004,24 @@ TEST_F(TextfieldTest, OnKeyPress) {
EXPECT_FALSE(textfield_->key_handled());
textfield_->clear();
+ // Up/Down keys won't be handled except on Mac where they map to move
+ // commands.
SendKeyEvent(ui::VKEY_UP);
EXPECT_TRUE(textfield_->key_received());
+#if defined(OS_MACOSX)
+ EXPECT_TRUE(textfield_->key_handled());
+#else
EXPECT_FALSE(textfield_->key_handled());
+#endif
textfield_->clear();
SendKeyEvent(ui::VKEY_DOWN);
EXPECT_TRUE(textfield_->key_received());
+#if defined(OS_MACOSX)
+ EXPECT_TRUE(textfield_->key_handled());
+#else
EXPECT_FALSE(textfield_->key_handled());
+#endif
textfield_->clear();
}
@@ -1073,10 +1153,8 @@ TEST_F(TextfieldTest, FocusTraversalTest) {
// Test if clicking on textfield view sets the focus.
widget_->GetFocusManager()->AdvanceFocus(true);
EXPECT_EQ(3, GetFocusedView()->id());
- ui::MouseEvent click(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(click);
+ MoveMouseTo(gfx::Point());
+ ClickLeftMouseButton();
EXPECT_EQ(1, GetFocusedView()->id());
// Tab/Shift+Tab should also cycle focus, not insert a tab character.
@@ -1125,33 +1203,20 @@ TEST_F(TextfieldTest, ContextMenuDisplayTest) {
TEST_F(TextfieldTest, DoubleAndTripleClickTest) {
InitTextfield();
textfield_->SetText(ASCIIToUTF16("hello world"));
- ui::MouseEvent click(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- ui::MouseEvent double_click(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
- ui::EventTimeForNow(),
- ui::EF_LEFT_MOUSE_BUTTON | ui::EF_IS_DOUBLE_CLICK,
- ui::EF_LEFT_MOUSE_BUTTON);
// Test for double click.
- textfield_->OnMousePressed(click);
- textfield_->OnMouseReleased(release);
+ MoveMouseTo(gfx::Point());
+ ClickLeftMouseButton();
EXPECT_TRUE(textfield_->GetSelectedText().empty());
- textfield_->OnMousePressed(double_click);
- textfield_->OnMouseReleased(release);
+ ClickLeftMouseButton(ui::EF_IS_DOUBLE_CLICK);
EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
// Test for triple click.
- textfield_->OnMousePressed(click);
- textfield_->OnMouseReleased(release);
+ ClickLeftMouseButton();
EXPECT_STR_EQ("hello world", textfield_->GetSelectedText());
// Another click should reset back to double click.
- textfield_->OnMousePressed(click);
- textfield_->OnMouseReleased(release);
+ ClickLeftMouseButton();
EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
}
@@ -1162,39 +1227,70 @@ TEST_F(TextfieldTest, DragToSelect) {
const int kEnd = 500;
gfx::Point start_point(kStart, 0);
gfx::Point end_point(kEnd, 0);
- ui::MouseEvent click_a(ui::ET_MOUSE_PRESSED, start_point, start_point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- ui::MouseEvent click_b(ui::ET_MOUSE_PRESSED, end_point, end_point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- ui::MouseEvent drag_left(ui::ET_MOUSE_DRAGGED, gfx::Point(), gfx::Point(),
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
- ui::MouseEvent drag_right(ui::ET_MOUSE_DRAGGED, end_point, end_point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
- ui::MouseEvent release(ui::ET_MOUSE_RELEASED, end_point, end_point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(click_a);
+
+ MoveMouseTo(start_point);
+ PressLeftMouseButton();
EXPECT_TRUE(textfield_->GetSelectedText().empty());
+
// Check that dragging left selects the beginning of the string.
- textfield_->OnMouseDragged(drag_left);
+ DragMouseTo(gfx::Point());
base::string16 text_left = textfield_->GetSelectedText();
EXPECT_STR_EQ("hello", text_left);
+
// Check that dragging right selects the rest of the string.
- textfield_->OnMouseDragged(drag_right);
+ DragMouseTo(end_point);
base::string16 text_right = textfield_->GetSelectedText();
EXPECT_STR_EQ(" world", text_right);
+
// Check that releasing in the same location does not alter the selection.
- textfield_->OnMouseReleased(release);
+ ReleaseLeftMouseButton();
EXPECT_EQ(text_right, textfield_->GetSelectedText());
+
// Check that dragging from beyond the text length works too.
- textfield_->OnMousePressed(click_b);
- textfield_->OnMouseDragged(drag_left);
- textfield_->OnMouseReleased(release);
+ MoveMouseTo(end_point);
+ PressLeftMouseButton();
+ DragMouseTo(gfx::Point());
+ ReleaseLeftMouseButton();
EXPECT_EQ(textfield_->text(), textfield_->GetSelectedText());
}
+// This test checks that dragging above the textfield selects to the beginning
+// and dragging below the textfield selects to the end, but only on platforms
+// where that is the expected behavior.
+TEST_F(TextfieldTest, DragUpOrDownSelectsToEnd) {
+ InitTextfield();
+ textfield_->SetText(ASCIIToUTF16("hello world"));
+ const base::string16 expected_up = base::ASCIIToUTF16(
+ PlatformStyle::kTextfieldDragVerticallyDragsToEnd ? "hello" : "lo");
+ const base::string16 expected_down = base::ASCIIToUTF16(
+ PlatformStyle::kTextfieldDragVerticallyDragsToEnd ? " world" : " w");
+ const int kStartX = GetCursorPositionX(5);
+ const int kDownX = GetCursorPositionX(7);
+ const int kUpX = GetCursorPositionX(3);
+ gfx::Point start_point(kStartX, 0);
+ gfx::Point down_point(kDownX, 500);
+ gfx::Point up_point(kUpX, -500);
+
+ MoveMouseTo(start_point);
+ PressLeftMouseButton();
+ DragMouseTo(up_point);
+ ReleaseLeftMouseButton();
+ EXPECT_EQ(textfield_->GetSelectedText(), expected_up);
+
+ // Click at |up_point|. This is important because drags do not count as clicks
+ // for the purpose of double-click detection, so if this test doesn't click
+ // somewhere other than |start_point| before the code below runs, the second
+ // click at |start_point| will be interpreted as a double-click instead of the
+ // start of a drag.
+ ClickLeftMouseButton();
+
+ MoveMouseTo(start_point);
+ PressLeftMouseButton();
+ DragMouseTo(down_point);
+ ReleaseLeftMouseButton();
+ EXPECT_EQ(textfield_->GetSelectedText(), expected_down);
+}
+
#if defined(OS_WIN)
TEST_F(TextfieldTest, DragAndDrop_AcceptDrop) {
InitTextfield();
@@ -1277,11 +1373,9 @@ TEST_F(TextfieldTest, DragAndDrop_InitiateDrag) {
EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
textfield_->GetDragOperationsForView(NULL, kStringPoint));
textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
+ MoveMouseTo(kStringPoint);
+ PressLeftMouseButton();
// Ensure that textfields only initiate drag operations inside the selection.
- ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, kStringPoint, kStringPoint,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(press_event);
EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
textfield_->GetDragOperationsForView(NULL, gfx::Point()));
EXPECT_FALSE(textfield_->CanStartDragForView(NULL, gfx::Point(),
@@ -1308,17 +1402,13 @@ TEST_F(TextfieldTest, DragAndDrop_ToTheRight) {
// Start dragging "ello".
textfield_->SelectRange(gfx::Range(1, 5));
gfx::Point point(GetCursorPositionX(3), 0);
- ui::MouseEvent click_a(ui::ET_MOUSE_PRESSED, point, point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(click_a);
- EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, click_a.location(),
- gfx::Point()));
- operations = textfield_->GetDragOperationsForView(textfield_,
- click_a.location());
+ MoveMouseTo(point);
+ PressLeftMouseButton();
+ EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, point, point));
+ operations = textfield_->GetDragOperationsForView(textfield_, point);
EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
operations);
- textfield_->WriteDragDataForView(NULL, click_a.location(), &data);
+ textfield_->WriteDragDataForView(nullptr, point, &data);
EXPECT_TRUE(data.GetString(&string));
EXPECT_EQ(textfield_->GetSelectedText(), string);
EXPECT_TRUE(textfield_->GetDropFormats(&formats, &format_types));
@@ -1362,17 +1452,13 @@ TEST_F(TextfieldTest, DragAndDrop_ToTheLeft) {
// Start dragging " worl".
textfield_->SelectRange(gfx::Range(5, 10));
gfx::Point point(GetCursorPositionX(7), 0);
- ui::MouseEvent click_a(ui::ET_MOUSE_PRESSED, point, point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(click_a);
- EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, click_a.location(),
- gfx::Point()));
- operations = textfield_->GetDragOperationsForView(textfield_,
- click_a.location());
+ MoveMouseTo(point);
+ PressLeftMouseButton();
+ EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, point, gfx::Point()));
+ operations = textfield_->GetDragOperationsForView(textfield_, point);
EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
operations);
- textfield_->WriteDragDataForView(NULL, click_a.location(), &data);
+ textfield_->WriteDragDataForView(nullptr, point, &data);
EXPECT_TRUE(data.GetString(&string));
EXPECT_EQ(textfield_->GetSelectedText(), string);
EXPECT_TRUE(textfield_->GetDropFormats(&formats, &format_types));
@@ -1410,12 +1496,10 @@ TEST_F(TextfieldTest, DragAndDrop_Canceled) {
// Start dragging "worl".
textfield_->SelectRange(gfx::Range(6, 10));
gfx::Point point(GetCursorPositionX(8), 0);
- ui::MouseEvent click(ui::ET_MOUSE_PRESSED, point, point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(click);
+ MoveMouseTo(point);
+ PressLeftMouseButton();
ui::OSExchangeData data;
- textfield_->WriteDragDataForView(NULL, click.location(), &data);
+ textfield_->WriteDragDataForView(nullptr, point, &data);
EXPECT_TRUE(textfield_->CanDrop(data));
// Drag the text over somewhere valid, outside the current selection.
gfx::Point drop_point(GetCursorPositionX(2), 0);
@@ -1424,14 +1508,8 @@ TEST_F(TextfieldTest, DragAndDrop_Canceled) {
EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop));
// "Cancel" the drag, via move and release over the selection, and OnDragDone.
gfx::Point drag_point(GetCursorPositionX(9), 0);
- ui::MouseEvent drag(ui::ET_MOUSE_DRAGGED, drag_point, drag_point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
- ui::MouseEvent release(ui::ET_MOUSE_RELEASED, drag_point, drag_point,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMouseDragged(drag);
- textfield_->OnMouseReleased(release);
- textfield_->OnDragDone();
+ DragMouseTo(drag_point);
+ ReleaseLeftMouseButton();
EXPECT_EQ(ASCIIToUTF16("hello world"), textfield_->text());
}
@@ -1767,6 +1845,17 @@ TEST_F(TextfieldTest, CutCopyPaste) {
EXPECT_STR_EQ("", textfield_->text());
EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
+ // Reset clipboard text.
+ SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "");
+
+ // Ensure [Shift]+[Delete] is a no-op in case there is no selection.
+ textfield_->SetText(ASCIIToUTF16("123"));
+ textfield_->SelectRange(gfx::Range(0));
+ SendAlternateCut();
+ EXPECT_STR_EQ("", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
+ EXPECT_STR_EQ("123", textfield_->text());
+ EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
+
// Ensure IDS_APP_COPY copies.
textfield_->SetText(ASCIIToUTF16("789"));
textfield_->SelectAll(false);
@@ -2205,16 +2294,12 @@ TEST_F(TextfieldTest, KeepInitiallySelectedWord) {
MouseClick(middle_cursor, 0);
const gfx::Point middle(middle_cursor.x(),
middle_cursor.y() + middle_cursor.height() / 2);
- ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, middle, middle,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
- ui::EF_LEFT_MOUSE_BUTTON);
- textfield_->OnMousePressed(press_event);
+ MoveMouseTo(middle);
+ PressLeftMouseButton();
EXPECT_EQ(gfx::Range(4, 7), textfield_->GetSelectedRange());
// Drag the mouse to the beginning of the textfield.
- ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, beginning, beginning,
- ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 0);
- textfield_->OnMouseDragged(drag_event);
+ DragMouseTo(beginning);
EXPECT_EQ(gfx::Range(7, 0), textfield_->GetSelectedRange());
}
@@ -2511,11 +2596,11 @@ TEST_F(TextfieldTouchSelectionTest, TouchSelectionInUnfocusableTextfield) {
// Make textfield unfocusable and tap on it. Touch text selection should not
// get activated.
- textfield_->SetFocusable(false);
+ textfield_->SetFocusBehavior(View::FocusBehavior::NEVER);
Tap(touch_point);
EXPECT_FALSE(textfield_->HasFocus());
EXPECT_FALSE(test_api_->touch_selection_controller());
- textfield_->SetFocusable(true);
+ textfield_->SetFocusBehavior(View::FocusBehavior::ALWAYS);
}
// No touch on desktop Mac. Tracked in http://crbug.com/445520.
diff --git a/chromium/ui/views/controls/tree/tree_view.cc b/chromium/ui/views/controls/tree/tree_view.cc
index 30428a31cad..70501f872ad 100644
--- a/chromium/ui/views/controls/tree/tree_view.cc
+++ b/chromium/ui/views/controls/tree/tree_view.cc
@@ -81,7 +81,8 @@ TreeView::TreeView()
controller_(NULL),
root_shown_(true),
row_height_(font_list_.GetHeight() + kTextVerticalPadding * 2) {
- SetFocusable(true);
+ // Always focusable, even on Mac (consistent with NSOutlineView).
+ SetFocusBehavior(FocusBehavior::ALWAYS);
closed_icon_ = *ui::ResourceBundle::GetSharedInstance().GetImageNamed(
(base::i18n::IsRTL() ? IDR_FOLDER_CLOSED_RTL
: IDR_FOLDER_CLOSED)).ToImageSkia();
diff --git a/chromium/ui/views/controls/tree/tree_view.h b/chromium/ui/views/controls/tree/tree_view.h
index 27a51855aa4..2dc764e7f56 100644
--- a/chromium/ui/views/controls/tree/tree_view.h
+++ b/chromium/ui/views/controls/tree/tree_view.h
@@ -5,11 +5,11 @@
#ifndef UI_VIEWS_CONTROLS_TREE_TREE_VIEW_VIEWS_H_
#define UI_VIEWS_CONTROLS_TREE_TREE_VIEW_VIEWS_H_
+#include <memory>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/base/models/tree_node_model.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/image/image_skia.h"
@@ -386,7 +386,7 @@ class VIEWS_EXPORT TreeView : public ui::TreeModelObserver,
// control, icon and offsets.
int text_offset_;
- scoped_ptr<PrefixSelector> selector_;
+ std::unique_ptr<PrefixSelector> selector_;
DISALLOW_COPY_AND_ASSIGN(TreeView);
};
diff --git a/chromium/ui/views/controls/webview/web_dialog_view.cc b/chromium/ui/views/controls/webview/web_dialog_view.cc
index c5a2b03eb1d..d8afe6ebacc 100644
--- a/chromium/ui/views/controls/webview/web_dialog_view.cc
+++ b/chromium/ui/views/controls/webview/web_dialog_view.cc
@@ -113,7 +113,7 @@ bool WebDialogView::CanClose() {
if (!is_attempting_close_dialog_) {
// Fire beforeunload event when user attempts to close the dialog.
is_attempting_close_dialog_ = true;
- web_view_->web_contents()->DispatchBeforeUnload(false);
+ web_view_->web_contents()->DispatchBeforeUnload();
}
return false;
}
diff --git a/chromium/ui/views/controls/webview/web_dialog_view.h b/chromium/ui/views/controls/webview/web_dialog_view.h
index a978921c5dd..65be6d54d6d 100644
--- a/chromium/ui/views/controls/webview/web_dialog_view.h
+++ b/chromium/ui/views/controls/webview/web_dialog_view.h
@@ -7,12 +7,12 @@
#include <stdint.h>
+#include <memory>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/controls/webview/webview_export.h"
#include "ui/views/widget/widget_delegate.h"
diff --git a/chromium/ui/views/controls/webview/webview.cc b/chromium/ui/views/controls/webview/webview.cc
index 686eeb6ddd4..59f87612fe5 100644
--- a/chromium/ui/views/controls/webview/webview.cc
+++ b/chromium/ui/views/controls/webview/webview.cc
@@ -67,7 +67,8 @@ void WebView::SetWebContents(content::WebContents* replacement) {
observing_render_process_host_->AddObserver(this);
}
// web_contents() now returns |replacement| from here onwards.
- SetFocusable(!!web_contents());
+ SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS
+ : FocusBehavior::NEVER);
if (wc_owner_.get() != replacement)
wc_owner_.reset();
if (embed_fullscreen_widget_mode_enabled_) {
@@ -112,11 +113,11 @@ const char* WebView::GetClassName() const {
return kViewClassName;
}
-scoped_ptr<content::WebContents> WebView::SwapWebContents(
- scoped_ptr<content::WebContents> new_web_contents) {
+std::unique_ptr<content::WebContents> WebView::SwapWebContents(
+ std::unique_ptr<content::WebContents> new_web_contents) {
if (wc_owner_)
wc_owner_->SetDelegate(NULL);
- scoped_ptr<content::WebContents> old_web_contents(std::move(wc_owner_));
+ std::unique_ptr<content::WebContents> old_web_contents(std::move(wc_owner_));
wc_owner_ = std::move(new_web_contents);
if (wc_owner_)
wc_owner_->SetDelegate(this);
@@ -284,12 +285,12 @@ void WebView::WebContentsDestroyed() {
NotifyAccessibilityWebContentsChanged();
}
-void WebView::DidShowFullscreenWidget(int routing_id) {
+void WebView::DidShowFullscreenWidget() {
if (embed_fullscreen_widget_mode_enabled_)
ReattachForFullscreenChange(true);
}
-void WebView::DidDestroyFullscreenWidget(int routing_id) {
+void WebView::DidDestroyFullscreenWidget() {
if (embed_fullscreen_widget_mode_enabled_)
ReattachForFullscreenChange(false);
}
diff --git a/chromium/ui/views/controls/webview/webview.h b/chromium/ui/views/controls/webview/webview.h
index 9ff7c7f6091..e9914e6aa35 100644
--- a/chromium/ui/views/controls/webview/webview.h
+++ b/chromium/ui/views/controls/webview/webview.h
@@ -7,8 +7,9 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
@@ -98,8 +99,8 @@ class WEBVIEW_EXPORT WebView : public View,
protected:
// Swaps the owned WebContents |wc_owner_| with |new_web_contents|. Returns
// the previously owned WebContents.
- scoped_ptr<content::WebContents> SwapWebContents(
- scoped_ptr<content::WebContents> new_web_contents);
+ std::unique_ptr<content::WebContents> SwapWebContents(
+ std::unique_ptr<content::WebContents> new_web_contents);
// Called when the web contents is successfully attached.
virtual void OnWebContentsAttached() {}
@@ -131,8 +132,8 @@ class WEBVIEW_EXPORT WebView : public View,
void RenderViewHostChanged(content::RenderViewHost* old_host,
content::RenderViewHost* new_host) override;
void WebContentsDestroyed() override;
- void DidShowFullscreenWidget(int routing_id) override;
- void DidDestroyFullscreenWidget(int routing_id) override;
+ void DidShowFullscreenWidget() override;
+ void DidDestroyFullscreenWidget() override;
void DidToggleFullscreenModeForTab(bool entered_fullscreen,
bool will_cause_resize) override;
void DidAttachInterstitialPage() override;
@@ -159,7 +160,7 @@ class WEBVIEW_EXPORT WebView : public View,
NativeViewHost* const holder_;
// Non-NULL if |web_contents()| was created and is owned by this WebView.
- scoped_ptr<content::WebContents> wc_owner_;
+ std::unique_ptr<content::WebContents> wc_owner_;
// The RenderProcessHost to which this RenderProcessHostObserver is added.
// Since WebView::GetTextInputClient is relying on RWHV::GetTextInputClient,
// we have to observe the lifecycle of the underlying RWHV through
diff --git a/chromium/ui/views/controls/webview/webview_unittest.cc b/chromium/ui/views/controls/webview/webview_unittest.cc
index 2ecf9578118..7c85a7255b8 100644
--- a/chromium/ui/views/controls/webview/webview_unittest.cc
+++ b/chromium/ui/views/controls/webview/webview_unittest.cc
@@ -6,8 +6,10 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/test_browser_context.h"
@@ -138,7 +140,7 @@ class WebViewUnitTest : public views::test::WidgetTest {
~WebViewUnitTest() override {}
void SetUp() override {
- set_views_delegate(make_scoped_ptr(new WebViewTestViewsDelegate));
+ set_views_delegate(base::WrapUnique(new WebViewTestViewsDelegate));
browser_context_.reset(new content::TestBrowserContext);
WidgetTest::SetUp();
// Set the test content browser client to avoid pulling in needless
@@ -174,8 +176,8 @@ class WebViewUnitTest : public views::test::WidgetTest {
WebView* web_view() const { return web_view_; }
NativeViewHost* holder() const { return web_view_->holder_; }
- scoped_ptr<content::WebContents> CreateWebContents() const {
- return make_scoped_ptr(content::WebContents::Create(
+ std::unique_ptr<content::WebContents> CreateWebContents() const {
+ return base::WrapUnique(content::WebContents::Create(
content::WebContents::CreateParams(browser_context_.get())));
}
@@ -183,7 +185,7 @@ class WebViewUnitTest : public views::test::WidgetTest {
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_blocking_thread_;
content::TestBrowserThread io_thread_;
- scoped_ptr<content::TestBrowserContext> browser_context_;
+ std::unique_ptr<content::TestBrowserContext> browser_context_;
content::TestContentBrowserClient test_browser_client_;
Widget* top_level_widget_;
@@ -197,7 +199,8 @@ class WebViewUnitTest : public views::test::WidgetTest {
TEST_F(WebViewUnitTest, TestWebViewAttachDetachWebContents) {
// Case 1: Create a new WebContents and set it in the webview via
// SetWebContents. This should make the WebContents visible.
- const scoped_ptr<content::WebContents> web_contents1(CreateWebContents());
+ const std::unique_ptr<content::WebContents> web_contents1(
+ CreateWebContents());
WebViewTestWebContentsObserver observer1(web_contents1.get());
EXPECT_FALSE(observer1.was_shown());
@@ -213,7 +216,8 @@ TEST_F(WebViewUnitTest, TestWebViewAttachDetachWebContents) {
// Case 2: Create another WebContents and replace the current WebContents
// via SetWebContents(). This should hide the current WebContents and show
// the new one.
- const scoped_ptr<content::WebContents> web_contents2(CreateWebContents());
+ const std::unique_ptr<content::WebContents> web_contents2(
+ CreateWebContents());
WebViewTestWebContentsObserver observer2(web_contents2.get());
EXPECT_FALSE(observer2.was_shown());
@@ -288,7 +292,7 @@ TEST_F(WebViewUnitTest, EmbeddedFullscreenDuringScreenCapture_Layout) {
web_view()->SetEmbedFullscreenWidgetMode(true);
ASSERT_EQ(1, web_view()->child_count());
- const scoped_ptr<content::WebContents> web_contents(CreateWebContents());
+ const std::unique_ptr<content::WebContents> web_contents(CreateWebContents());
WebViewTestWebContentsDelegate delegate;
web_contents->SetDelegate(&delegate);
web_view()->SetWebContents(web_contents.get());
@@ -341,10 +345,12 @@ TEST_F(WebViewUnitTest, EmbeddedFullscreenDuringScreenCapture_Switching) {
const gfx::NativeView unset_native_view = holder()->native_view();
// Create two WebContentses to switch between.
- const scoped_ptr<content::WebContents> web_contents1(CreateWebContents());
+ const std::unique_ptr<content::WebContents> web_contents1(
+ CreateWebContents());
WebViewTestWebContentsDelegate delegate1;
web_contents1->SetDelegate(&delegate1);
- const scoped_ptr<content::WebContents> web_contents2(CreateWebContents());
+ const std::unique_ptr<content::WebContents> web_contents2(
+ CreateWebContents());
WebViewTestWebContentsDelegate delegate2;
web_contents2->SetDelegate(&delegate2);
@@ -395,13 +401,13 @@ TEST_F(WebViewUnitTest, EmbeddedFullscreenDuringScreenCapture_ClickToFocus) {
web_view()->SetBoundsRect(gfx::Rect(0, 0, 100, 90));
views::View* const something_to_focus = new views::View();
something_to_focus->SetBoundsRect(gfx::Rect(0, 90, 100, 10));
- something_to_focus->SetFocusable(true);
+ something_to_focus->SetFocusBehavior(View::FocusBehavior::ALWAYS);
top_level_widget()->GetContentsView()->AddChildView(something_to_focus);
web_view()->SetEmbedFullscreenWidgetMode(true);
ASSERT_EQ(1, web_view()->child_count());
- const scoped_ptr<content::WebContents> web_contents(CreateWebContents());
+ const std::unique_ptr<content::WebContents> web_contents(CreateWebContents());
WebViewTestWebContentsDelegate delegate;
web_contents->SetDelegate(&delegate);
web_view()->SetWebContents(web_contents.get());
@@ -457,4 +463,23 @@ TEST_F(WebViewUnitTest, EmbeddedFullscreenDuringScreenCapture_ClickToFocus) {
EXPECT_TRUE(something_to_focus->HasFocus());
}
+// Verifies that there is no crash in WebView destructor
+// if WebView is already removed from Widget.
+TEST_F(WebViewUnitTest, DetachedWebViewDestructor) {
+ // Init WebView with attached NativeView.
+ const std::unique_ptr<content::WebContents> web_contents(CreateWebContents());
+ std::unique_ptr<WebView> webview(
+ new WebView(web_contents->GetBrowserContext()));
+ View* contents_view = top_level_widget()->GetContentsView();
+ contents_view->AddChildView(webview.get());
+ webview->SetWebContents(web_contents.get());
+
+ // Remove WebView from views hierarchy. NativeView should be detached
+ // from Widget.
+ contents_view->RemoveChildView(webview.get());
+ // Destroy WebView. NativeView should be detached secondary.
+ // There should be no crash.
+ webview.reset();
+}
+
} // namespace views
diff --git a/chromium/ui/views/corewm/cursor_height_provider_win.cc b/chromium/ui/views/corewm/cursor_height_provider_win.cc
index 398b009b71b..93a8ceddc52 100644
--- a/chromium/ui/views/corewm/cursor_height_provider_win.cc
+++ b/chromium/ui/views/corewm/cursor_height_provider_win.cc
@@ -7,14 +7,15 @@
#include <windows.h>
#include <stddef.h>
#include <stdint.h>
+
#include <algorithm>
#include <map>
+#include <memory>
-#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_hdc.h"
namespace {
-using PixelData = scoped_ptr<uint32_t[]>;
+using PixelData = std::unique_ptr<uint32_t[]>;
using HeightStorage = std::map<HCURSOR, int>;
const uint32_t kBitsPeruint32 = sizeof(uint32_t) * 8;
@@ -39,7 +40,7 @@ PixelData GetBitmapData(HBITMAP handle, const BITMAPINFO& info, HDC hdc) {
// When getting pixel data palette is appended to memory pointed by
// BITMAPINFO passed so allocate additional memory to store additional data.
- scoped_ptr<char[]> header(new char[KHeaderAndPalette]);
+ std::unique_ptr<char[]> header(new char[KHeaderAndPalette]);
memcpy(header.get(), &(info.bmiHeader), sizeof(info.bmiHeader));
data.reset(new uint32_t[info.bmiHeader.biSizeImage / sizeof(uint32_t)]);
diff --git a/chromium/ui/views/corewm/desktop_capture_controller_unittest.cc b/chromium/ui/views/corewm/desktop_capture_controller_unittest.cc
index 879cafc86d0..d3aff0dbea7 100644
--- a/chromium/ui/views/corewm/desktop_capture_controller_unittest.cc
+++ b/chromium/ui/views/corewm/desktop_capture_controller_unittest.cc
@@ -86,8 +86,8 @@ views::Widget* CreateWidget() {
// creates two widgets, does a mouse press in one, sets capture in the other and
// verifies state is reset in the first.
TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) {
- scoped_ptr<Widget> w1(CreateWidget());
- scoped_ptr<Widget> w2(CreateWidget());
+ std::unique_ptr<Widget> w1(CreateWidget());
+ std::unique_ptr<Widget> w2(CreateWidget());
ui::test::EventGenerator generator1(w1->GetNativeView()->GetRootWindow());
generator1.MoveMouseToCenterOf(w1->GetNativeView());
generator1.PressLeftButton();
@@ -111,12 +111,12 @@ TEST_F(DesktopCaptureControllerTest, ResetMouseHandlers) {
// the window which had capture receives the gesture.
// TODO(sky): move this test, it should be part of ScopedCaptureClient tests.
TEST_F(DesktopCaptureControllerTest, CaptureWindowInputEventTest) {
- scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client1;
- scoped_ptr<aura::client::ScreenPositionClient> desktop_position_client2;
+ std::unique_ptr<aura::client::ScreenPositionClient> desktop_position_client1;
+ std::unique_ptr<aura::client::ScreenPositionClient> desktop_position_client2;
- scoped_ptr<Widget> widget1(new Widget());
+ std::unique_ptr<Widget> widget1(new Widget());
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
- scoped_ptr<wm::ScopedCaptureClient> scoped_capture_client(
+ std::unique_ptr<wm::ScopedCaptureClient> scoped_capture_client(
new wm::ScopedCaptureClient(params.context->GetRootWindow()));
aura::client::CaptureClient* capture_client =
scoped_capture_client->capture_client();
@@ -137,7 +137,7 @@ TEST_F(DesktopCaptureControllerTest, CaptureWindowInputEventTest) {
root1->AddChildView(v1);
widget1->Show();
- scoped_ptr<Widget> widget2(new Widget());
+ std::unique_ptr<Widget> widget2(new Widget());
params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
diff --git a/chromium/ui/views/corewm/tooltip_aura.cc b/chromium/ui/views/corewm/tooltip_aura.cc
index 80dac9fd8f6..e51a87265a5 100644
--- a/chromium/ui/views/corewm/tooltip_aura.cc
+++ b/chromium/ui/views/corewm/tooltip_aura.cc
@@ -9,9 +9,10 @@
#include "base/strings/string_util.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/render_text.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/text_utils.h"
#include "ui/native_theme/native_theme.h"
@@ -118,7 +119,7 @@ class TooltipAura::TooltipView : public views::View {
render_text_->SetDisplayRect(gfx::Rect(0, 0, max_text_width, 100000));
}
- scoped_ptr<gfx::RenderText> render_text_;
+ std::unique_ptr<gfx::RenderText> render_text_;
int max_width_;
DISALLOW_COPY_AND_ASSIGN(TooltipView);
@@ -138,7 +139,7 @@ void TooltipAura::SetTooltipBounds(const gfx::Point& mouse_pos,
const gfx::Size& tooltip_size) {
gfx::Rect tooltip_rect(mouse_pos, tooltip_size);
tooltip_rect.Offset(kCursorOffsetX, kCursorOffsetY);
- gfx::Screen* screen = gfx::Screen::GetScreen();
+ display::Screen* screen = display::Screen::GetScreen();
gfx::Rect display_bounds(screen->GetDisplayNearestPoint(mouse_pos).bounds());
// If tooltip is out of bounds on the x axis, we simply shift it
@@ -166,7 +167,7 @@ void TooltipAura::DestroyWidget() {
}
int TooltipAura::GetMaxWidth(const gfx::Point& location) const {
- gfx::Screen* screen = gfx::Screen::GetScreen();
+ display::Screen* screen = display::Screen::GetScreen();
gfx::Rect display_bounds(screen->GetDisplayNearestPoint(location).bounds());
return std::min(kTooltipMaxWidthPixels, (display_bounds.width() + 1) / 2);
}
diff --git a/chromium/ui/views/corewm/tooltip_aura.h b/chromium/ui/views/corewm/tooltip_aura.h
index 781acf97c41..2e8212fcb9f 100644
--- a/chromium/ui/views/corewm/tooltip_aura.h
+++ b/chromium/ui/views/corewm/tooltip_aura.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_COREWM_TOOLTIP_AURA_H_
#define UI_VIEWS_COREWM_TOOLTIP_AURA_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/views/corewm/tooltip.h"
#include "ui/views/widget/widget_observer.h"
@@ -51,7 +52,7 @@ class VIEWS_EXPORT TooltipAura : public Tooltip, public WidgetObserver {
void OnWidgetDestroying(Widget* widget) override;
// The view showing the tooltip.
- scoped_ptr<TooltipView> tooltip_view_;
+ std::unique_ptr<TooltipView> tooltip_view_;
// The widget containing the tooltip. May be NULL.
Widget* widget_;
diff --git a/chromium/ui/views/corewm/tooltip_controller.cc b/chromium/ui/views/corewm/tooltip_controller.cc
index c5dad8c4598..a45b406fec2 100644
--- a/chromium/ui/views/corewm/tooltip_controller.cc
+++ b/chromium/ui/views/corewm/tooltip_controller.cc
@@ -17,10 +17,10 @@
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/gfx/font.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/text_elider.h"
#include "ui/views/corewm/tooltip.h"
#include "ui/views/widget/tooltip_manager.h"
@@ -97,7 +97,7 @@ aura::Window* GetTooltipTarget(const ui::MouseEvent& event,
gfx::Point screen_loc(event.location());
aura::client::GetScreenPositionClient(event_target->GetRootWindow())->
ConvertPointToScreen(event_target, &screen_loc);
- gfx::Screen* screen = gfx::Screen::GetScreen();
+ display::Screen* screen = display::Screen::GetScreen();
aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc);
if (!target)
return NULL;
@@ -124,7 +124,7 @@ aura::Window* GetTooltipTarget(const ui::MouseEvent& event,
////////////////////////////////////////////////////////////////////////////////
// TooltipController public:
-TooltipController::TooltipController(scoped_ptr<Tooltip> tooltip)
+TooltipController::TooltipController(std::unique_ptr<Tooltip> tooltip)
: tooltip_window_(NULL),
tooltip_id_(NULL),
tooltip_window_at_mouse_press_(NULL),
@@ -203,8 +203,8 @@ void TooltipController::OnMouseEvent(ui::MouseEvent* event) {
case ui::ET_MOUSE_DRAGGED: {
curr_mouse_loc_ = event->location();
aura::Window* target = NULL;
- // Avoid a call to gfx::Screen::GetWindowAtScreenPoint() since it can be
- // very expensive on X11 in cases when the tooltip is hidden anyway.
+ // Avoid a call to display::Screen::GetWindowAtScreenPoint() since it can
+ // be very expensive on X11 in cases when the tooltip is hidden anyway.
if (tooltips_enabled_ &&
!aura::Env::GetInstance()->IsMouseButtonDown() &&
!IsDragDropInProgress()) {
diff --git a/chromium/ui/views/corewm/tooltip_controller.h b/chromium/ui/views/corewm/tooltip_controller.h
index 5171726c5dc..5a274e319cd 100644
--- a/chromium/ui/views/corewm/tooltip_controller.h
+++ b/chromium/ui/views/corewm/tooltip_controller.h
@@ -6,9 +6,9 @@
#define UI_VIEWS_COREWM_TOOLTIP_CONTROLLER_H_
#include <map>
+#include <memory>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/timer/timer.h"
#include "ui/aura/window_observer.h"
@@ -35,7 +35,7 @@ class VIEWS_EXPORT TooltipController : public aura::client::TooltipClient,
public ui::EventHandler,
public aura::WindowObserver {
public:
- explicit TooltipController(scoped_ptr<Tooltip> tooltip);
+ explicit TooltipController(std::unique_ptr<Tooltip> tooltip);
~TooltipController() override;
// Overridden from aura::client::TooltipClient.
@@ -88,7 +88,7 @@ class VIEWS_EXPORT TooltipController : public aura::client::TooltipClient,
aura::Window* tooltip_window_at_mouse_press_;
base::string16 tooltip_text_at_mouse_press_;
- scoped_ptr<Tooltip> tooltip_;
+ std::unique_ptr<Tooltip> tooltip_;
base::RepeatingTimer tooltip_timer_;
diff --git a/chromium/ui/views/corewm/tooltip_controller_unittest.cc b/chromium/ui/views/corewm/tooltip_controller_unittest.cc
index 4fc0bc8e428..cd1e7f1a0b7 100644
--- a/chromium/ui/views/corewm/tooltip_controller_unittest.cc
+++ b/chromium/ui/views/corewm/tooltip_controller_unittest.cc
@@ -15,10 +15,10 @@
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
+#include "ui/display/screen.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/font.h"
#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/text_elider.h"
#include "ui/views/corewm/tooltip_aura.h"
#include "ui/views/corewm/tooltip_controller_test_helper.h"
@@ -89,9 +89,9 @@ class TooltipControllerTest : public aura::test::AuraTestBase {
aura::test::AuraTestBase::SetUp();
new wm::DefaultActivationClient(root_window());
#if defined(OS_CHROMEOS)
- controller_.reset(new TooltipController(
- scoped_ptr<views::corewm::Tooltip>(
- new views::corewm::TooltipAura)));
+ controller_.reset(
+ new TooltipController(std::unique_ptr<views::corewm::Tooltip>(
+ new views::corewm::TooltipAura)));
root_window()->AddPreTargetHandler(controller_.get());
SetTooltipClient(root_window(), controller_.get());
#endif
@@ -135,15 +135,15 @@ class TooltipControllerTest : public aura::test::AuraTestBase {
return view2;
}
- scoped_ptr<views::Widget> widget_;
+ std::unique_ptr<views::Widget> widget_;
TooltipTestView* view_;
- scoped_ptr<TooltipControllerTestHelper> helper_;
- scoped_ptr<ui::test::EventGenerator> generator_;
+ std::unique_ptr<TooltipControllerTestHelper> helper_;
+ std::unique_ptr<ui::test::EventGenerator> generator_;
private:
- scoped_ptr<TooltipController> controller_;
+ std::unique_ptr<TooltipController> controller_;
- scoped_ptr<views::TestViewsDelegate> views_delegate_;
+ std::unique_ptr<views::TestViewsDelegate> views_delegate_;
#if defined(OS_WIN)
ui::ScopedOleInitializer ole_initializer_;
@@ -426,13 +426,13 @@ class TooltipControllerCaptureTest : public TooltipControllerTest {
&screen_position_client_);
#if !defined(OS_CHROMEOS)
desktop_screen_.reset(CreateDesktopScreen());
- gfx::Screen::SetScreenInstance(desktop_screen_.get());
+ display::Screen::SetScreenInstance(desktop_screen_.get());
#endif
}
void TearDown() override {
#if !defined(OS_CHROMEOS)
- gfx::Screen::SetScreenInstance(test_screen());
+ display::Screen::SetScreenInstance(test_screen());
desktop_screen_.reset();
#endif
aura::client::SetScreenPositionClient(GetRootWindow(), NULL);
@@ -441,7 +441,7 @@ class TooltipControllerCaptureTest : public TooltipControllerTest {
private:
wm::DefaultScreenPositionClient screen_position_client_;
- scoped_ptr<gfx::Screen> desktop_screen_;
+ std::unique_ptr<display::Screen> desktop_screen_;
DISALLOW_COPY_AND_ASSIGN(TooltipControllerCaptureTest);
};
@@ -469,7 +469,8 @@ TEST_F(TooltipControllerCaptureTest, DISABLED_CloseOnCaptureLost) {
// Disabled on linux as DesktopScreenX11::GetWindowAtScreenPoint() doesn't
// consider z-order.
-#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+// Disabled on Windows due to failing bots. http://crbug.com/604479
+#if (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_WIN)
#define MAYBE_Capture DISABLED_Capture
#else
#define MAYBE_Capture Capture
@@ -482,7 +483,7 @@ TEST_F(TooltipControllerCaptureTest, MAYBE_Capture) {
widget_->SetBounds(gfx::Rect(0, 0, 200, 200));
view_->set_tooltip_text(tooltip_text);
- scoped_ptr<views::Widget> widget2(CreateWidget(root_window()));
+ std::unique_ptr<views::Widget> widget2(CreateWidget(root_window()));
widget2->SetContentsView(new View);
TooltipTestView* view2 = new TooltipTestView;
widget2->GetContentsView()->AddChildView(view2);
@@ -566,8 +567,8 @@ class TooltipControllerTest2 : public aura::test::AuraTestBase {
wm_state_.reset(new wm::WMState);
aura::test::AuraTestBase::SetUp();
new wm::DefaultActivationClient(root_window());
- controller_.reset(new TooltipController(
- scoped_ptr<corewm::Tooltip>(test_tooltip_)));
+ controller_.reset(
+ new TooltipController(std::unique_ptr<corewm::Tooltip>(test_tooltip_)));
root_window()->AddPreTargetHandler(controller_.get());
SetTooltipClient(root_window(), controller_.get());
helper_.reset(new TooltipControllerTestHelper(controller_.get()));
@@ -587,19 +588,19 @@ class TooltipControllerTest2 : public aura::test::AuraTestBase {
protected:
// Owned by |controller_|.
TestTooltip* test_tooltip_;
- scoped_ptr<TooltipControllerTestHelper> helper_;
- scoped_ptr<ui::test::EventGenerator> generator_;
+ std::unique_ptr<TooltipControllerTestHelper> helper_;
+ std::unique_ptr<ui::test::EventGenerator> generator_;
private:
- scoped_ptr<TooltipController> controller_;
- scoped_ptr<wm::WMState> wm_state_;
+ std::unique_ptr<TooltipController> controller_;
+ std::unique_ptr<wm::WMState> wm_state_;
DISALLOW_COPY_AND_ASSIGN(TooltipControllerTest2);
};
TEST_F(TooltipControllerTest2, VerifyLeadingTrailingWhitespaceStripped) {
aura::test::TestWindowDelegate test_delegate;
- scoped_ptr<aura::Window> window(
+ std::unique_ptr<aura::Window> window(
CreateNormalWindow(100, root_window(), &test_delegate));
window->SetBounds(gfx::Rect(0, 0, 300, 300));
base::string16 tooltip_text(ASCIIToUTF16(" \nx "));
@@ -612,7 +613,7 @@ TEST_F(TooltipControllerTest2, VerifyLeadingTrailingWhitespaceStripped) {
// Verifies that tooltip is hidden and tooltip window closed upon cancel mode.
TEST_F(TooltipControllerTest2, CloseOnCancelMode) {
aura::test::TestWindowDelegate test_delegate;
- scoped_ptr<aura::Window> window(
+ std::unique_ptr<aura::Window> window(
CreateNormalWindow(100, root_window(), &test_delegate));
window->SetBounds(gfx::Rect(0, 0, 300, 300));
base::string16 tooltip_text(ASCIIToUTF16("Tooltip Text"));
@@ -650,7 +651,7 @@ class TooltipControllerTest3 : public aura::test::AuraTestBase {
generator_.reset(new ui::test::EventGenerator(GetRootWindow()));
controller_.reset(new TooltipController(
- scoped_ptr<views::corewm::Tooltip>(test_tooltip_)));
+ std::unique_ptr<views::corewm::Tooltip>(test_tooltip_)));
GetRootWindow()->RemovePreTargetHandler(
static_cast<TooltipController*>(aura::client::GetTooltipClient(
widget_->GetNativeWindow()->GetRootWindow())));
@@ -676,14 +677,14 @@ class TooltipControllerTest3 : public aura::test::AuraTestBase {
protected:
// Owned by |controller_|.
TestTooltip* test_tooltip_;
- scoped_ptr<TooltipControllerTestHelper> helper_;
- scoped_ptr<ui::test::EventGenerator> generator_;
- scoped_ptr<views::Widget> widget_;
+ std::unique_ptr<TooltipControllerTestHelper> helper_;
+ std::unique_ptr<ui::test::EventGenerator> generator_;
+ std::unique_ptr<views::Widget> widget_;
TooltipTestView* view_;
private:
- scoped_ptr<TooltipController> controller_;
- scoped_ptr<wm::WMState> wm_state_;
+ std::unique_ptr<TooltipController> controller_;
+ std::unique_ptr<wm::WMState> wm_state_;
#if defined(OS_WIN)
ui::ScopedOleInitializer ole_initializer_;
diff --git a/chromium/ui/views/corewm/tooltip_win.cc b/chromium/ui/views/corewm/tooltip_win.cc
index b892d3871a2..462365750fb 100644
--- a/chromium/ui/views/corewm/tooltip_win.cc
+++ b/chromium/ui/views/corewm/tooltip_win.cc
@@ -10,9 +10,10 @@
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "ui/base/l10n/l10n_util_win.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+#include "ui/display/win/screen_win.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
-#include "ui/gfx/win/dpi.h"
#include "ui/views/corewm/cursor_height_provider_win.h"
namespace views {
@@ -77,7 +78,8 @@ bool TooltipWin::EnsureTooltipWindow() {
}
void TooltipWin::PositionTooltip() {
- gfx::Point screen_point = gfx::win::DIPToScreenPoint(location_);
+ gfx::Point screen_point =
+ display::win::ScreenWin::DIPToScreenPoint(location_);
const int cursoroffset = GetCurrentCursorVisibleHeight();
screen_point.Offset(0, cursoroffset);
@@ -85,19 +87,22 @@ void TooltipWin::PositionTooltip() {
reinterpret_cast<LPARAM>(&toolinfo_));
const gfx::Size size(LOWORD(tooltip_size), HIWORD(tooltip_size));
- const gfx::Display display(
- gfx::Screen::GetScreen()->GetDisplayNearestPoint(screen_point));
+ const display::Display display(
+ display::Screen::GetScreen()->GetDisplayNearestPoint(location_));
gfx::Rect tooltip_bounds(screen_point, size);
- tooltip_bounds.AdjustToFit(gfx::win::DIPToScreenRect(display.work_area()));
+ tooltip_bounds.AdjustToFit(
+ display::win::ScreenWin::DIPToScreenRect(parent_hwnd_,
+ display.work_area()));
SetWindowPos(tooltip_hwnd_, NULL, tooltip_bounds.x(), tooltip_bounds.y(), 0,
0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
int TooltipWin::GetMaxWidth(const gfx::Point& location) const {
- const gfx::Point screen_point = gfx::win::DIPToScreenPoint(location);
- gfx::Display display(
- gfx::Screen::GetScreen()->GetDisplayNearestPoint(screen_point));
+ const gfx::Point screen_point =
+ display::win::ScreenWin::DIPToScreenPoint(location);
+ display::Display display(
+ display::Screen::GetScreen()->GetDisplayNearestPoint(screen_point));
const gfx::Rect monitor_bounds = display.bounds();
return (monitor_bounds.width() + 1) / 2;
}
diff --git a/chromium/ui/views/debug_utils.cc b/chromium/ui/views/debug_utils.cc
index 12b4759b33d..b451c2da50e 100644
--- a/chromium/ui/views/debug_utils.cc
+++ b/chromium/ui/views/debug_utils.cc
@@ -7,26 +7,25 @@
#include <ostream>
#include "base/logging.h"
-#include "base/strings/utf_string_conversions.h"
#include "ui/views/view.h"
namespace views {
namespace {
void PrintViewHierarchyImp(const View* view,
int indent,
- std::wostringstream* out) {
+ std::ostringstream* out) {
int ind = indent;
while (ind-- > 0)
- *out << L' ';
- *out << base::UTF8ToWide(view->GetClassName());
- *out << L' ';
+ *out << ' ';
+ *out << view->GetClassName();
+ *out << ' ';
*out << view->id();
- *out << L' ';
- *out << view->x() << L"," << view->y() << L",";
- *out << view->bounds().right() << L"," << view->bounds().bottom();
- *out << L' ';
+ *out << ' ';
+ *out << view->x() << "," << view->y() << ",";
+ *out << view->bounds().right() << "," << view->bounds().bottom();
+ *out << ' ';
*out << view;
- *out << L'\n';
+ *out << '\n';
for (int i = 0, count = view->child_count(); i < count; ++i)
PrintViewHierarchyImp(view->child_at(i), indent + 2, out);
@@ -34,18 +33,18 @@ void PrintViewHierarchyImp(const View* view,
void PrintFocusHierarchyImp(const View* view,
int indent,
- std::wostringstream* out) {
+ std::ostringstream* out) {
int ind = indent;
while (ind-- > 0)
- *out << L' ';
- *out << base::UTF8ToWide(view->GetClassName());
- *out << L' ';
+ *out << ' ';
+ *out << view->GetClassName();
+ *out << ' ';
*out << view->id();
- *out << L' ';
+ *out << ' ';
*out << view->GetClassName();
- *out << L' ';
+ *out << ' ';
*out << view;
- *out << L'\n';
+ *out << '\n';
if (view->child_count() > 0)
PrintFocusHierarchyImp(view->child_at(0), indent + 2, out);
@@ -57,16 +56,16 @@ void PrintFocusHierarchyImp(const View* view,
} // namespace
void PrintViewHierarchy(const View* view) {
- std::wostringstream out;
- out << L"View hierarchy:\n";
+ std::ostringstream out;
+ out << "View hierarchy:\n";
PrintViewHierarchyImp(view, 0, &out);
// Error so users in the field can generate and upload logs.
LOG(ERROR) << out.str();
}
void PrintFocusHierarchy(const View* view) {
- std::wostringstream out;
- out << L"Focus hierarchy:\n";
+ std::ostringstream out;
+ out << "Focus hierarchy:\n";
PrintFocusHierarchyImp(view, 0, &out);
// Error so users in the field can generate and upload logs.
LOG(ERROR) << out.str();
diff --git a/chromium/ui/views/drag_utils.cc b/chromium/ui/views/drag_utils.cc
index 9eae9f6472b..f9e6c8be5ab 100644
--- a/chromium/ui/views/drag_utils.cc
+++ b/chromium/ui/views/drag_utils.cc
@@ -4,10 +4,10 @@
#include "ui/views/drag_utils.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/gfx/canvas.h"
-#include "ui/gfx/display.h"
#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/screen.h"
#include "ui/views/widget/widget.h"
namespace {
@@ -16,8 +16,8 @@ float GetDeviceScaleForNativeView(views::Widget* widget) {
float device_scale = 1.0f;
if (widget && widget->GetNativeView()) {
gfx::NativeView view = widget->GetNativeView();
- gfx::Display display =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(view);
+ display::Display display =
+ display::Screen::GetScreen()->GetDisplayNearestWindow(view);
device_scale = display.device_scale_factor();
}
return device_scale;
diff --git a/chromium/ui/views/event_monitor.h b/chromium/ui/views/event_monitor.h
index 183e0950418..2867ecb14bc 100644
--- a/chromium/ui/views/event_monitor.h
+++ b/chromium/ui/views/event_monitor.h
@@ -5,7 +5,8 @@
#ifndef UI_VIEWS_EVENT_MONITOR_H_
#define UI_VIEWS_EVENT_MONITOR_H_
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"
@@ -25,14 +26,14 @@ class VIEWS_EXPORT EventMonitor {
// Create an instance for monitoring application events.
// Events will be forwarded to |event_handler| before they are dispatched to
// the application.
- static scoped_ptr<EventMonitor> CreateApplicationMonitor(
+ static std::unique_ptr<EventMonitor> CreateApplicationMonitor(
ui::EventHandler* event_handler);
// Create an instance for monitoring events on a specific window.
// Events will be forwarded to |event_handler| before they are dispatched to
// |target_window|.
// The EventMonitor instance must be destroyed before |target_window|.
- static scoped_ptr<EventMonitor> CreateWindowMonitor(
+ static std::unique_ptr<EventMonitor> CreateWindowMonitor(
ui::EventHandler* event_handler,
gfx::NativeWindow target_window);
diff --git a/chromium/ui/views/event_monitor_aura.cc b/chromium/ui/views/event_monitor_aura.cc
index 73f55b6bc23..6c52620b157 100644
--- a/chromium/ui/views/event_monitor_aura.cc
+++ b/chromium/ui/views/event_monitor_aura.cc
@@ -5,6 +5,7 @@
#include "ui/views/event_monitor_aura.h"
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/events/event_target.h"
@@ -12,17 +13,17 @@
namespace views {
// static
-scoped_ptr<EventMonitor> EventMonitor::CreateApplicationMonitor(
+std::unique_ptr<EventMonitor> EventMonitor::CreateApplicationMonitor(
ui::EventHandler* event_handler) {
- return make_scoped_ptr(
+ return base::WrapUnique(
new EventMonitorAura(event_handler, aura::Env::GetInstance()));
}
// static
-scoped_ptr<EventMonitor> EventMonitor::CreateWindowMonitor(
+std::unique_ptr<EventMonitor> EventMonitor::CreateWindowMonitor(
ui::EventHandler* event_handler,
gfx::NativeWindow target_window) {
- return make_scoped_ptr(new EventMonitorAura(event_handler, target_window));
+ return base::WrapUnique(new EventMonitorAura(event_handler, target_window));
}
// static
diff --git a/chromium/ui/views/event_monitor_mac.mm b/chromium/ui/views/event_monitor_mac.mm
index f21aae7cdd3..8fb0e0e9a3d 100644
--- a/chromium/ui/views/event_monitor_mac.mm
+++ b/chromium/ui/views/event_monitor_mac.mm
@@ -7,29 +7,30 @@
#import <Cocoa/Cocoa.h>
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_utils.h"
-#include "ui/gfx/screen.h"
namespace views {
// static
-scoped_ptr<EventMonitor> EventMonitor::CreateApplicationMonitor(
+std::unique_ptr<EventMonitor> EventMonitor::CreateApplicationMonitor(
ui::EventHandler* event_handler) {
- return make_scoped_ptr(new EventMonitorMac(event_handler, nullptr));
+ return base::WrapUnique(new EventMonitorMac(event_handler, nullptr));
}
// static
-scoped_ptr<EventMonitor> EventMonitor::CreateWindowMonitor(
+std::unique_ptr<EventMonitor> EventMonitor::CreateWindowMonitor(
ui::EventHandler* event_handler,
gfx::NativeWindow target_window) {
- return make_scoped_ptr(new EventMonitorMac(event_handler, target_window));
+ return base::WrapUnique(new EventMonitorMac(event_handler, target_window));
}
// static
gfx::Point EventMonitor::GetLastMouseLocation() {
- return gfx::Screen::GetScreen()->GetCursorScreenPoint();
+ return display::Screen::GetScreen()->GetCursorScreenPoint();
}
EventMonitorMac::EventMonitorMac(ui::EventHandler* event_handler,
@@ -38,7 +39,7 @@ EventMonitorMac::EventMonitorMac(ui::EventHandler* event_handler,
monitor_ = [NSEvent addLocalMonitorForEventsMatchingMask:NSAnyEventMask
handler:^NSEvent*(NSEvent* event) {
if (!target_window || [event window] == target_window) {
- scoped_ptr<ui::Event> ui_event = ui::EventFromNative(event);
+ std::unique_ptr<ui::Event> ui_event = ui::EventFromNative(event);
if (ui_event)
event_handler->OnEvent(ui_event.get());
}
diff --git a/chromium/ui/views/event_monitor_unittest.cc b/chromium/ui/views/event_monitor_unittest.cc
index 92b364c9105..a73b1f4d148 100644
--- a/chromium/ui/views/event_monitor_unittest.cc
+++ b/chromium/ui/views/event_monitor_unittest.cc
@@ -32,7 +32,7 @@ class EventMonitorTest : public WidgetTest {
protected:
Widget* widget_;
- scoped_ptr<ui::test::EventGenerator> generator_;
+ std::unique_ptr<ui::test::EventGenerator> generator_;
ui::test::TestEventHandler handler_;
private:
@@ -40,7 +40,7 @@ class EventMonitorTest : public WidgetTest {
};
TEST_F(EventMonitorTest, ShouldReceiveAppEventsWhileInstalled) {
- scoped_ptr<EventMonitor> monitor(
+ std::unique_ptr<EventMonitor> monitor(
EventMonitor::CreateApplicationMonitor(&handler_));
generator_->ClickLeftButton();
@@ -52,7 +52,7 @@ TEST_F(EventMonitorTest, ShouldReceiveAppEventsWhileInstalled) {
}
TEST_F(EventMonitorTest, ShouldReceiveWindowEventsWhileInstalled) {
- scoped_ptr<EventMonitor> monitor(
+ std::unique_ptr<EventMonitor> monitor(
EventMonitor::CreateWindowMonitor(&handler_, widget_->GetNativeWindow()));
generator_->ClickLeftButton();
@@ -65,7 +65,7 @@ TEST_F(EventMonitorTest, ShouldReceiveWindowEventsWhileInstalled) {
TEST_F(EventMonitorTest, ShouldNotReceiveEventsFromOtherWindow) {
Widget* widget2 = CreateTopLevelNativeWidget();
- scoped_ptr<EventMonitor> monitor(
+ std::unique_ptr<EventMonitor> monitor(
EventMonitor::CreateWindowMonitor(&handler_, widget2->GetNativeWindow()));
generator_->ClickLeftButton();
diff --git a/chromium/ui/views/examples/BUILD.gn b/chromium/ui/views/examples/BUILD.gn
index 6fe7e162852..5e1cfb6492c 100644
--- a/chromium/ui/views/examples/BUILD.gn
+++ b/chromium/ui/views/examples/BUILD.gn
@@ -105,11 +105,12 @@ executable("views_examples_exe") {
"//base",
"//base:i18n",
"//build/config/sanitizers:deps",
+ "//build/win:default_exe_manifest",
"//ui/base",
"//ui/compositor",
"//ui/compositor:test_support",
"//ui/gfx",
- "//ui/gl",
+ "//ui/gl/init",
"//ui/resources:ui_test_pak",
"//ui/views",
"//ui/views:test_support",
@@ -161,6 +162,7 @@ executable("views_examples_with_content_exe") {
":views_examples_with_content_lib",
"//base",
"//build/config/sanitizers:deps",
+ "//build/win:default_exe_manifest",
"//content",
"//content:sandbox_helper_win",
"//sandbox",
diff --git a/chromium/ui/views/examples/DEPS b/chromium/ui/views/examples/DEPS
index 06e440bbb91..47e7bcdb2eb 100644
--- a/chromium/ui/views/examples/DEPS
+++ b/chromium/ui/views/examples/DEPS
@@ -2,6 +2,6 @@ include_rules = [
"+content/public",
"+content/shell",
"+sandbox",
- "+ui/gl/gl_surface.h", # To initialize GL bindings.
+ "+ui/gl/init/gl_factory.h", # To initialize GL bindings.
"+ui/views_content_client",
]
diff --git a/chromium/ui/views/examples/bubble_example.cc b/chromium/ui/views/examples/bubble_example.cc
index 597b7adcc61..6aa47909522 100644
--- a/chromium/ui/views/examples/bubble_example.cc
+++ b/chromium/ui/views/examples/bubble_example.cc
@@ -6,7 +6,7 @@
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
@@ -49,12 +49,14 @@ base::string16 GetArrowName(BubbleBorder::Arrow arrow) {
return ASCIIToUTF16("INVALID");
}
-class ExampleBubble : public BubbleDelegateView {
+class ExampleBubble : public BubbleDialogDelegateView {
public:
- ExampleBubble(View* anchor, BubbleBorder::Arrow arrow)
- : BubbleDelegateView(anchor, arrow) {}
+ ExampleBubble(View* anchor, BubbleBorder::Arrow arrow)
+ : BubbleDialogDelegateView(anchor, arrow) {}
protected:
+ int GetDialogButtons() const override { return ui::DIALOG_BUTTON_NONE; }
+
void Init() override {
SetLayoutManager(new BoxLayout(BoxLayout::kVertical, 50, 50, 0));
AddChildView(new Label(GetArrowName(arrow())));
@@ -117,7 +119,7 @@ void BubbleExample::ButtonPressed(Button* sender, const ui::Event& event) {
if (sender == persistent_)
bubble->set_close_on_deactivate(false);
- BubbleDelegateView::CreateBubble(bubble);
+ BubbleDialogDelegateView::CreateBubble(bubble);
if (sender == align_to_edge_)
bubble->SetAlignment(BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
diff --git a/chromium/ui/views/examples/button_example.cc b/chromium/ui/views/examples/button_example.cc
index 2cf42afa9e3..9736f85e139 100644
--- a/chromium/ui/views/examples/button_example.cc
+++ b/chromium/ui/views/examples/button_example.cc
@@ -29,12 +29,7 @@ const char kLongText[] = "Start of Really Really Really Really Really Really "
namespace views {
namespace examples {
-ButtonExample::ButtonExample()
- : ExampleBase("Button"),
- label_button_(NULL),
- image_button_(NULL),
- icon_(NULL),
- count_(0) {
+ButtonExample::ButtonExample() : ExampleBase("Button") {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
icon_ = rb.GetImageNamed(IDR_CLOSE_H).ToImageSkia();
}
@@ -49,19 +44,18 @@ void ButtonExample::CreateExampleView(View* container) {
container->SetLayoutManager(layout);
label_button_ = new LabelButton(this, ASCIIToUTF16(kLabelButton));
- label_button_->SetFocusable(true);
+ label_button_->SetFocusForPlatform();
+ label_button_->set_request_focus_on_press(true);
container->AddChildView(label_button_);
- LabelButton* styled_button =
- new LabelButton(this, ASCIIToUTF16("Styled Button"));
- styled_button->SetStyle(Button::STYLE_BUTTON);
- container->AddChildView(styled_button);
+ styled_button_ = new LabelButton(this, ASCIIToUTF16("Styled Button"));
+ styled_button_->SetStyle(Button::STYLE_BUTTON);
+ container->AddChildView(styled_button_);
- LabelButton* disabled_button =
- new LabelButton(this, ASCIIToUTF16("Disabled Button"));
- disabled_button->SetStyle(Button::STYLE_BUTTON);
- disabled_button->SetState(Button::STATE_DISABLED);
- container->AddChildView(disabled_button);
+ disabled_button_ = new LabelButton(this, ASCIIToUTF16("Disabled Button"));
+ disabled_button_->SetStyle(Button::STYLE_BUTTON);
+ disabled_button_->SetState(Button::STATE_DISABLED);
+ container->AddChildView(disabled_button_);
container->AddChildView(new BlueButton(this, ASCIIToUTF16("Blue Button")));
@@ -78,7 +72,8 @@ void ButtonExample::CreateExampleView(View* container) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
image_button_ = new ImageButton(this);
- image_button_->SetFocusable(true);
+ image_button_->SetFocusForPlatform();
+ image_button_->set_request_focus_on_press(true);
image_button_->SetImage(ImageButton::STATE_NORMAL,
rb.GetImageNamed(IDR_CLOSE).ToImageSkia());
image_button_->SetImage(ImageButton::STATE_HOVERED,
@@ -88,41 +83,51 @@ void ButtonExample::CreateExampleView(View* container) {
container->AddChildView(image_button_);
}
-void ButtonExample::LabelButtonPressed(const ui::Event& event) {
+void ButtonExample::LabelButtonPressed(LabelButton* label_button,
+ const ui::Event& event) {
PrintStatus("Label Button Pressed! count: %d", ++count_);
if (event.IsControlDown()) {
if (event.IsShiftDown()) {
- label_button_->SetText(ASCIIToUTF16(
- label_button_->GetText().empty()
+ label_button->SetText(ASCIIToUTF16(
+ label_button->GetText().empty()
? kLongText
- : label_button_->GetText().length() > 50 ? kLabelButton : ""));
+ : label_button->GetText().length() > 50 ? kLabelButton : ""));
} else if (event.IsAltDown()) {
- label_button_->SetImage(Button::STATE_NORMAL,
- label_button_->GetImage(Button::STATE_NORMAL).isNull() ?
- *icon_ : gfx::ImageSkia());
+ label_button->SetImage(
+ Button::STATE_NORMAL,
+ label_button->GetImage(Button::STATE_NORMAL).isNull()
+ ? *icon_
+ : gfx::ImageSkia());
} else {
static int alignment = 0;
- label_button_->SetHorizontalAlignment(
+ label_button->SetHorizontalAlignment(
static_cast<gfx::HorizontalAlignment>(++alignment % 3));
}
} else if (event.IsShiftDown()) {
if (event.IsAltDown()) {
- label_button_->SetFocusable(!label_button_->IsFocusable());
+ // Toggle focusability.
+ label_button_->IsAccessibilityFocusable()
+ ? label_button_->SetFocusBehavior(View::FocusBehavior::NEVER)
+ : label_button_->SetFocusForPlatform();
} else {
- label_button_->SetStyle(static_cast<Button::ButtonStyle>(
- (label_button_->style() + 1) % Button::STYLE_COUNT));
+ label_button->SetStyle(static_cast<Button::ButtonStyle>(
+ (label_button->style() + 1) % Button::STYLE_COUNT));
}
} else if (event.IsAltDown()) {
- label_button_->SetIsDefault(!label_button_->is_default());
+ label_button->SetIsDefault(!label_button->is_default());
} else {
- label_button_->SetMinSize(gfx::Size());
+ label_button->SetMinSize(gfx::Size());
}
example_view()->GetLayoutManager()->Layout(example_view());
}
void ButtonExample::ButtonPressed(Button* sender, const ui::Event& event) {
if (sender == label_button_)
- LabelButtonPressed(event);
+ LabelButtonPressed(label_button_, event);
+ else if (sender == styled_button_)
+ LabelButtonPressed(styled_button_, event);
+ else if (sender == disabled_button_)
+ LabelButtonPressed(disabled_button_, event);
else
PrintStatus("Image Button Pressed! count: %d", ++count_);
}
diff --git a/chromium/ui/views/examples/button_example.h b/chromium/ui/views/examples/button_example.h
index 566d3f09bf2..956759cf412 100644
--- a/chromium/ui/views/examples/button_example.h
+++ b/chromium/ui/views/examples/button_example.h
@@ -27,19 +27,21 @@ class VIEWS_EXAMPLES_EXPORT ButtonExample : public ExampleBase,
void CreateExampleView(View* container) override;
private:
- void LabelButtonPressed(const ui::Event& event);
+ void LabelButtonPressed(LabelButton* label_button, const ui::Event& event);
// ButtonListener:
void ButtonPressed(Button* sender, const ui::Event& event) override;
// Example buttons.
- LabelButton* label_button_;
- ImageButton* image_button_;
+ LabelButton* label_button_ = nullptr;
+ LabelButton* styled_button_ = nullptr;
+ LabelButton* disabled_button_ = nullptr;
+ ImageButton* image_button_ = nullptr;
- const gfx::ImageSkia* icon_;
+ const gfx::ImageSkia* icon_ = nullptr;
// The number of times the buttons are pressed.
- int count_;
+ int count_ = 0;
DISALLOW_COPY_AND_ASSIGN(ButtonExample);
};
diff --git a/chromium/ui/views/examples/combobox_example.cc b/chromium/ui/views/examples/combobox_example.cc
index 4c4fdb300b9..aedc8fbdef7 100644
--- a/chromium/ui/views/examples/combobox_example.cc
+++ b/chromium/ui/views/examples/combobox_example.cc
@@ -49,9 +49,8 @@ void ComboboxExample::CreateExampleView(View* container) {
disabled_combobox_->SetSelectedIndex(4);
disabled_combobox_->SetEnabled(false);
- action_combobox_ = new Combobox(&combobox_model_);
+ action_combobox_ = new Combobox(&combobox_model_, Combobox::STYLE_ACTION);
action_combobox_->set_listener(this);
- action_combobox_->SetStyle(Combobox::STYLE_ACTION);
// Note: STYLE_ACTION comboboxes always have the first item selected by
// default.
diff --git a/chromium/ui/views/examples/examples.gyp b/chromium/ui/views/examples/examples.gyp
index 50790ad639a..4038d615027 100644
--- a/chromium/ui/views/examples/examples.gyp
+++ b/chromium/ui/views/examples/examples.gyp
@@ -19,6 +19,7 @@
'../../events/events.gyp:events',
'../../gfx/gfx.gyp:gfx',
'../../gfx/gfx.gyp:gfx_geometry',
+ '../../gfx/gfx.gyp:gfx_range',
'../../gfx/gfx.gyp:gfx_vector_icons',
'../../resources/ui_resources.gyp:ui_resources',
'../../resources/ui_resources.gyp:ui_test_pak',
@@ -161,6 +162,7 @@
'target_name': 'views_examples_with_content_exe',
'type': 'executable',
'dependencies': [
+ '../resources/views_resources.gyp:views_resources',
'../../views_content_client/views_content_client.gyp:views_content_client',
'views_examples_with_content_lib',
],
diff --git a/chromium/ui/views/examples/examples_main.cc b/chromium/ui/views/examples/examples_main.cc
index 11096a781c1..d3889a89a95 100644
--- a/chromium/ui/views/examples/examples_main.cc
+++ b/chromium/ui/views/examples/examples_main.cc
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/i18n/icu_util.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/power_monitor/power_monitor.h"
@@ -13,11 +16,12 @@
#include "base/run_loop.h"
#include "build/build_config.h"
#include "ui/base/ime/input_method_initializer.h"
+#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/compositor/test/in_process_context_factory.h"
-#include "ui/gfx/screen.h"
-#include "ui/gl/gl_surface.h"
+#include "ui/display/screen.h"
+#include "ui/gl/init/gl_factory.h"
#include "ui/views/examples/example_base.h"
#include "ui/views/examples/examples_window.h"
#include "ui/views/test/desktop_test_views_delegate.h"
@@ -55,11 +59,11 @@ int main(int argc, char** argv) {
gfx::InitializeThreadedX11();
#endif
- gfx::GLSurface::InitializeOneOff();
+ gl::init::InitializeGLOneOff();
// The ContextFactory must exist before any Compositors are created.
bool context_factory_for_test = false;
- scoped_ptr<ui::InProcessContextFactory> context_factory(
+ std::unique_ptr<ui::InProcessContextFactory> context_factory(
new ui::InProcessContextFactory(context_factory_for_test, nullptr));
context_factory->set_use_test_surface(false);
@@ -73,18 +77,19 @@ int main(int argc, char** argv) {
CHECK(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
- base::PowerMonitor power_monitor(make_scoped_ptr(
- new base::PowerMonitorDeviceSource));
+ base::PowerMonitor power_monitor(
+ base::WrapUnique(new base::PowerMonitorDeviceSource));
#if defined(OS_WIN)
gfx::win::MaybeInitializeDirectWrite();
#endif
#if defined(USE_AURA)
- aura::Env::CreateInstance(true);
+ std::unique_ptr<aura::Env> env = aura::Env::CreateInstance();
aura::Env::GetInstance()->set_context_factory(context_factory.get());
#endif
ui::InitializeInputMethodForTesting();
+ ui::MaterialDesignController::Initialize();
{
views::DesktopTestViewsDelegate views_delegate;
@@ -92,13 +97,14 @@ int main(int argc, char** argv) {
wm::WMState wm_state;
#endif
#if !defined(OS_CHROMEOS) && defined(USE_AURA)
- scoped_ptr<gfx::Screen> desktop_screen(views::CreateDesktopScreen());
- gfx::Screen::SetScreenInstance(desktop_screen.get());
+ std::unique_ptr<display::Screen> desktop_screen(
+ views::CreateDesktopScreen());
+ display::Screen::SetScreenInstance(desktop_screen.get());
#endif
views::examples::ShowExamplesWindow(
views::examples::QUIT_ON_CLOSE, nullptr,
- scoped_ptr<ScopedVector<views::examples::ExampleBase>>());
+ std::unique_ptr<ScopedVector<views::examples::ExampleBase>>());
base::RunLoop().Run();
@@ -108,7 +114,7 @@ int main(int argc, char** argv) {
ui::ShutdownInputMethod();
#if defined(USE_AURA)
- aura::Env::DeleteInstance();
+ env.reset();
#endif
return 0;
diff --git a/chromium/ui/views/examples/examples_window.cc b/chromium/ui/views/examples/examples_window.cc
index c391b7e2b6d..57be047069c 100644
--- a/chromium/ui/views/examples/examples_window.cc
+++ b/chromium/ui/views/examples/examples_window.cc
@@ -47,7 +47,7 @@
namespace views {
namespace examples {
-typedef scoped_ptr<ScopedVector<ExampleBase> > ScopedExamples;
+typedef std::unique_ptr<ScopedVector<ExampleBase>> ScopedExamples;
namespace {
@@ -186,7 +186,7 @@ class ExamplesWindowContents : public WidgetDelegateView,
void WindowClosing() override {
instance_ = NULL;
if (operation_ == QUIT_ON_CLOSE)
- base::MessageLoopForUI::current()->QuitWhenIdle();
+ base::MessageLoop::current()->QuitWhenIdle();
}
gfx::Size GetPreferredSize() const override { return gfx::Size(800, 300); }
diff --git a/chromium/ui/views/examples/examples_window.h b/chromium/ui/views/examples/examples_window.h
index 339389502f5..d35b8fc9a9d 100644
--- a/chromium/ui/views/examples/examples_window.h
+++ b/chromium/ui/views/examples/examples_window.h
@@ -5,7 +5,8 @@
#ifndef UI_VIEWS_EXAMPLES_EXAMPLES_WINDOW_H_
#define UI_VIEWS_EXAMPLES_EXAMPLES_WINDOW_H_
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "base/memory/scoped_vector.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/examples/views_examples_export.h"
@@ -30,7 +31,7 @@ enum Operation {
VIEWS_EXAMPLES_EXPORT void ShowExamplesWindow(
Operation operation,
gfx::NativeWindow window_context,
- scoped_ptr<ScopedVector<ExampleBase> > extra_examples);
+ std::unique_ptr<ScopedVector<ExampleBase>> extra_examples);
} // namespace examples
} // namespace views
diff --git a/chromium/ui/views/examples/examples_window_with_content.cc b/chromium/ui/views/examples/examples_window_with_content.cc
index 87d30b7b193..a2843a76aae 100644
--- a/chromium/ui/views/examples/examples_window_with_content.cc
+++ b/chromium/ui/views/examples/examples_window_with_content.cc
@@ -15,7 +15,7 @@ namespace examples {
void ShowExamplesWindowWithContent(Operation operation,
content::BrowserContext* browser_context,
gfx::NativeWindow window_context) {
- scoped_ptr<ScopedVector<ExampleBase> > extra_examples(
+ std::unique_ptr<ScopedVector<ExampleBase>> extra_examples(
new ScopedVector<ExampleBase>);
extra_examples->push_back(new WebViewExample(browser_context));
ShowExamplesWindow(operation, window_context, std::move(extra_examples));
diff --git a/chromium/ui/views/examples/label_example.cc b/chromium/ui/views/examples/label_example.cc
index 98ea080ac08..6683626e376 100644
--- a/chromium/ui/views/examples/label_example.cc
+++ b/chromium/ui/views/examples/label_example.cc
@@ -5,6 +5,7 @@
#include "ui/views/examples/label_example.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/views/background.h"
@@ -210,7 +211,7 @@ Combobox* LabelExample::AddCombobox(GridLayout* layout,
layout->StartRow(0, 0);
layout->AddView(new Label(base::ASCIIToUTF16(name)));
ExampleComboboxModel* model = new ExampleComboboxModel(strings, count);
- example_combobox_models_.push_back(make_scoped_ptr(model));
+ example_combobox_models_.push_back(base::WrapUnique(model));
Combobox* combobox = new Combobox(model);
combobox->SetSelectedIndex(0);
combobox->set_listener(this);
diff --git a/chromium/ui/views/examples/label_example.h b/chromium/ui/views/examples/label_example.h
index 3f58fff39c5..80b0d9f8b57 100644
--- a/chromium/ui/views/examples/label_example.h
+++ b/chromium/ui/views/examples/label_example.h
@@ -55,7 +55,7 @@ class VIEWS_EXAMPLES_EXPORT LabelExample : public ExampleBase,
Textfield* textfield_;
Combobox* alignment_;
Combobox* elide_behavior_;
- std::vector<scoped_ptr<ExampleComboboxModel>> example_combobox_models_;
+ std::vector<std::unique_ptr<ExampleComboboxModel>> example_combobox_models_;
Checkbox* multiline_;
Checkbox* shadows_;
Label* custom_label_;
diff --git a/chromium/ui/views/examples/menu_example.cc b/chromium/ui/views/examples/menu_example.cc
index 166a792a847..378c90a76bc 100644
--- a/chromium/ui/views/examples/menu_example.cc
+++ b/chromium/ui/views/examples/menu_example.cc
@@ -51,7 +51,7 @@ class ExampleMenuModel : public ui::SimpleMenuModel,
COMMAND_GO_HOME,
};
- scoped_ptr<ui::SimpleMenuModel> submenu_;
+ std::unique_ptr<ui::SimpleMenuModel> submenu_;
std::set<int> checked_fruits_;
int current_encoding_command_id_;
@@ -71,8 +71,8 @@ class ExampleMenuButton : public MenuButton, public MenuButtonListener {
ui::SimpleMenuModel* GetMenuModel();
- scoped_ptr<ExampleMenuModel> menu_model_;
- scoped_ptr<MenuRunner> menu_runner_;
+ std::unique_ptr<ExampleMenuModel> menu_model_;
+ std::unique_ptr<MenuRunner> menu_runner_;
DISALLOW_COPY_AND_ASSIGN(ExampleMenuButton);
};
diff --git a/chromium/ui/views/examples/multiline_example.cc b/chromium/ui/views/examples/multiline_example.cc
index d01b31e2d91..c6971adee33 100644
--- a/chromium/ui/views/examples/multiline_example.cc
+++ b/chromium/ui/views/examples/multiline_example.cc
@@ -106,6 +106,11 @@ class MultilineExample::RenderTextView : public View {
InvalidateLayout();
}
+ void SetMaxLines(int max_lines) {
+ render_text_->SetMaxLines(max_lines);
+ render_text_->SetElideBehavior(max_lines ? gfx::ELIDE_TAIL : gfx::NO_ELIDE);
+ }
+
private:
void OnBoundsChanged(const gfx::Rect& previous_bounds) override {
gfx::Rect bounds = GetLocalBounds();
@@ -113,7 +118,7 @@ class MultilineExample::RenderTextView : public View {
render_text_->SetDisplayRect(bounds);
}
- scoped_ptr<gfx::RenderText> render_text_;
+ std::unique_ptr<gfx::RenderText> render_text_;
DISALLOW_COPY_AND_ASSIGN(RenderTextView);
};
@@ -123,8 +128,8 @@ MultilineExample::MultilineExample()
render_text_view_(NULL),
label_(NULL),
textfield_(NULL),
- label_checkbox_(NULL) {
-}
+ label_checkbox_(NULL),
+ elision_checkbox_(NULL) {}
MultilineExample::~MultilineExample() {
}
@@ -147,6 +152,11 @@ void MultilineExample::CreateExampleView(View* container) {
label_checkbox_->set_listener(this);
label_checkbox_->set_request_focus_on_press(false);
+ elision_checkbox_ = new Checkbox(ASCIIToUTF16("elide text?"));
+ elision_checkbox_->SetChecked(false);
+ elision_checkbox_->set_listener(this);
+ elision_checkbox_->set_request_focus_on_press(false);
+
textfield_ = new Textfield();
textfield_->set_controller(this);
textfield_->SetText(kTestString);
@@ -169,6 +179,9 @@ void MultilineExample::CreateExampleView(View* container) {
layout->AddView(label_);
layout->StartRow(0, 0);
+ layout->AddView(elision_checkbox_);
+
+ layout->StartRow(0, 0);
layout->AddView(new Label(ASCIIToUTF16("Sample Text:")));
layout->AddView(textfield_);
}
@@ -183,9 +196,12 @@ void MultilineExample::ContentsChanged(Textfield* sender,
}
void MultilineExample::ButtonPressed(Button* sender, const ui::Event& event) {
- DCHECK_EQ(sender, label_checkbox_);
- label_->SetText(label_checkbox_->checked() ? textfield_->text() :
- base::string16());
+ if (sender == label_checkbox_) {
+ label_->SetText(label_checkbox_->checked() ? textfield_->text()
+ : base::string16());
+ } else if (sender == elision_checkbox_) {
+ render_text_view_->SetMaxLines(elision_checkbox_->checked() ? 3 : 0);
+ }
container()->Layout();
container()->SchedulePaint();
}
diff --git a/chromium/ui/views/examples/multiline_example.h b/chromium/ui/views/examples/multiline_example.h
index a4c3ba56ea0..4bb5b61ffe5 100644
--- a/chromium/ui/views/examples/multiline_example.h
+++ b/chromium/ui/views/examples/multiline_example.h
@@ -45,6 +45,9 @@ class VIEWS_EXAMPLES_EXPORT MultilineExample : public ExampleBase,
// Checkbox to enable and disable text rendering in |label_|.
Checkbox* label_checkbox_;
+ // Checkbox to toggle text elision in |render_text_view_|.
+ Checkbox* elision_checkbox_;
+
DISALLOW_COPY_AND_ASSIGN(MultilineExample);
};
diff --git a/chromium/ui/views/examples/tree_view_example.cc b/chromium/ui/views/examples/tree_view_example.cc
index 5da97f755bb..68f99e2fa8c 100644
--- a/chromium/ui/views/examples/tree_view_example.cc
+++ b/chromium/ui/views/examples/tree_view_example.cc
@@ -47,11 +47,14 @@ void TreeViewExample::CreateExampleView(View* container) {
tree_view_->SetModel(&model_);
tree_view_->SetController(this);
add_ = new LabelButton(this, ASCIIToUTF16("Add"));
- add_->SetFocusable(true);
+ add_->SetFocusForPlatform();
+ add_->set_request_focus_on_press(true);
remove_ = new LabelButton(this, ASCIIToUTF16("Remove"));
- remove_->SetFocusable(true);
+ remove_->SetFocusForPlatform();
+ remove_->set_request_focus_on_press(true);
change_title_ = new LabelButton(this, ASCIIToUTF16("Change Title"));
- change_title_->SetFocusable(true);
+ change_title_->SetFocusForPlatform();
+ change_title_->set_request_focus_on_press(true);
GridLayout* layout = new GridLayout(container);
container->SetLayoutManager(layout);
diff --git a/chromium/ui/views/examples/tree_view_example.h b/chromium/ui/views/examples/tree_view_example.h
index 9ef57603823..fb0ccf93db6 100644
--- a/chromium/ui/views/examples/tree_view_example.h
+++ b/chromium/ui/views/examples/tree_view_example.h
@@ -15,6 +15,7 @@
namespace views {
+class LabelButton;
class MenuRunner;
class TreeView;
@@ -70,15 +71,15 @@ class VIEWS_EXAMPLES_EXPORT TreeViewExample
TreeView* tree_view_;
// Control buttons to modify the model.
- Button* add_;
- Button* remove_;
- Button* change_title_;
+ LabelButton* add_;
+ LabelButton* remove_;
+ LabelButton* change_title_;
typedef ui::TreeNodeWithValue<int> NodeType;
ui::TreeNodeModel<NodeType> model_;
- scoped_ptr<MenuRunner> context_menu_runner_;
+ std::unique_ptr<MenuRunner> context_menu_runner_;
DISALLOW_COPY_AND_ASSIGN(TreeViewExample);
};
diff --git a/chromium/ui/views/examples/widget_example.cc b/chromium/ui/views/examples/widget_example.cc
index 0165de3f9dc..71bd71be41a 100644
--- a/chromium/ui/views/examples/widget_example.cc
+++ b/chromium/ui/views/examples/widget_example.cc
@@ -87,7 +87,8 @@ void WidgetExample::BuildButton(View* container,
const std::string& label,
int tag) {
LabelButton* button = new LabelButton(this, ASCIIToUTF16(label));
- button->SetFocusable(true);
+ button->SetFocusForPlatform();
+ button->set_request_focus_on_press(true);
button->set_tag(tag);
container->AddChildView(button);
}
diff --git a/chromium/ui/views/focus/focus_manager.cc b/chromium/ui/views/focus/focus_manager.cc
index c84c3152734..bd6b0dc19fe 100644
--- a/chromium/ui/views/focus/focus_manager.cc
+++ b/chromium/ui/views/focus/focus_manager.cc
@@ -35,7 +35,8 @@ FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate)
accelerator_manager_(new ui::AcceleratorManager),
shortcut_handling_suspended_(false),
focus_change_reason_(kReasonDirectFocusChange),
- is_changing_focus_(false) {
+ is_changing_focus_(false),
+ keyboard_accessible_(false) {
DCHECK(widget_);
stored_focused_view_storage_id_ =
ViewStorage::GetInstance()->CreateStorageID();
@@ -297,6 +298,16 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view,
return NULL;
}
+void FocusManager::SetKeyboardAccessible(bool keyboard_accessible) {
+ if (keyboard_accessible == keyboard_accessible_)
+ return;
+
+ keyboard_accessible_ = keyboard_accessible;
+ // Disabling keyboard accessibility may cause the focused view to become not
+ // focusable. Hence advance focus if necessary.
+ AdvanceFocusIfNecessary();
+}
+
void FocusManager::SetFocusedViewWithReason(
View* view, FocusChangeReason reason) {
if (focused_view_ == view)
@@ -341,9 +352,9 @@ void FocusManager::AdvanceFocusIfNecessary() {
// If widget is active and focused view is not focusable, advance focus or,
// if not possible, clear focus.
- if (focused_view_ && !focused_view_->IsAccessibilityFocusable()) {
+ if (focused_view_ && !IsFocusable(focused_view_)) {
AdvanceFocus(false);
- if (focused_view_ && !focused_view_->IsAccessibilityFocusable())
+ if (focused_view_ && !IsFocusable(focused_view_))
ClearFocus();
}
}
@@ -393,9 +404,11 @@ bool FocusManager::RestoreFocusedView() {
focus_change_reason_ = kReasonFocusRestore;
}
}
- return true;
+ // The |keyboard_accessible_| mode may have changed while the widget was
+ // inactive.
+ AdvanceFocusIfNecessary();
}
- return false;
+ return view && view == focused_view_;
}
void FocusManager::SetStoredFocusView(View* focus_view) {
@@ -489,15 +502,6 @@ bool FocusManager::ProcessAccelerator(const ui::Accelerator& accelerator) {
return false;
}
-ui::AcceleratorTarget* FocusManager::GetCurrentTargetForAccelerator(
- const ui::Accelerator& accelerator) const {
- ui::AcceleratorTarget* target =
- accelerator_manager_->GetCurrentTarget(accelerator);
- if (!target && delegate_.get())
- target = delegate_->GetCurrentTargetForAccelerator(accelerator);
- return target;
-}
-
bool FocusManager::HasPriorityHandler(
const ui::Accelerator& accelerator) const {
return accelerator_manager_->HasPriorityHandler(accelerator);
@@ -542,4 +546,16 @@ bool FocusManager::ProcessArrowKeyTraversal(const ui::KeyEvent& event) {
return false;
}
+bool FocusManager::IsFocusable(View* view) const {
+ DCHECK(view);
+
+// |keyboard_accessible_| is only used on Mac.
+#if defined(OS_MACOSX)
+ return keyboard_accessible_ ? view->IsAccessibilityFocusable()
+ : view->IsFocusable();
+#else
+ return view->IsAccessibilityFocusable();
+#endif
+}
+
} // namespace views
diff --git a/chromium/ui/views/focus/focus_manager.h b/chromium/ui/views/focus/focus_manager.h
index 6d5195e45e6..99ca6e67726 100644
--- a/chromium/ui/views/focus/focus_manager.h
+++ b/chromium/ui/views/focus/focus_manager.h
@@ -7,9 +7,9 @@
#include <list>
#include <map>
+#include <memory>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/accelerator_manager.h"
@@ -201,7 +201,8 @@ class VIEWS_EXPORT FocusManager {
// Restore the view saved with a previous call to StoreFocusedView(). Used
// when the widget becomes active. Returns true when the previous view was
- // successfully refocused - otherwise false.
+ // successfully refocused. In case the stored view is no longer focusable,
+ // it advances focus and returns false.
bool RestoreFocusedView();
// Sets the |view| to be restored when calling RestoreFocusView. This is used
@@ -277,12 +278,6 @@ class VIEWS_EXPORT FocusManager {
void AddFocusChangeListener(FocusChangeListener* listener);
void RemoveFocusChangeListener(FocusChangeListener* listener);
- // Returns the AcceleratorTarget that should be activated for the specified
- // keyboard accelerator, or NULL if no view is registered for that keyboard
- // accelerator.
- ui::AcceleratorTarget* GetCurrentTargetForAccelerator(
- const ui::Accelerator& accelerator) const;
-
// Whether the given |accelerator| has a priority handler associated with it.
bool HasPriorityHandler(const ui::Accelerator& accelerator) const;
@@ -325,6 +320,12 @@ class VIEWS_EXPORT FocusManager {
bool reverse,
bool dont_loop);
+ bool keyboard_accessible() const { return keyboard_accessible_; }
+
+ // Updates |keyboard_accessible_| to the given value and advances focus if
+ // necessary.
+ void SetKeyboardAccessible(bool keyboard_accessible);
+
private:
// Returns the focusable view found in the FocusTraversable specified starting
// at the specified view. This traverses down along the FocusTraversable
@@ -338,6 +339,10 @@ class VIEWS_EXPORT FocusManager {
// and should not be processed further.
bool ProcessArrowKeyTraversal(const ui::KeyEvent& event);
+ // Whether |view| is currently focusable as per the platform's interpretation
+ // of |keyboard_accesible_|.
+ bool IsFocusable(View* view) const;
+
// Whether arrow key traversal is enabled.
static bool arrow_key_traversal_enabled_;
@@ -346,13 +351,13 @@ class VIEWS_EXPORT FocusManager {
// The object which handles an accelerator when |accelerator_manager_| doesn't
// handle it.
- scoped_ptr<FocusManagerDelegate> delegate_;
+ std::unique_ptr<FocusManagerDelegate> delegate_;
// The view that currently is focused.
View* focused_view_;
// The AcceleratorManager this FocusManager is associated with.
- scoped_ptr<ui::AcceleratorManager> accelerator_manager_;
+ std::unique_ptr<ui::AcceleratorManager> accelerator_manager_;
// Keeps track of whether shortcut handling is currently suspended.
bool shortcut_handling_suspended_;
@@ -370,6 +375,15 @@ class VIEWS_EXPORT FocusManager {
// See description above getter.
bool is_changing_focus_;
+ // This is true if full keyboard accessibility is needed. This causes
+ // IsAccessibilityFocusable() to be checked rather than IsFocusable(). This
+ // can be set depending on platform constraints. FocusSearch uses this in
+ // addition to its own accessibility mode, which handles accessibility at the
+ // FocusTraversable level. Currently only used on Mac, when Full Keyboard
+ // access is enabled.
+ // Default value is false.
+ bool keyboard_accessible_;
+
DISALLOW_COPY_AND_ASSIGN(FocusManager);
};
diff --git a/chromium/ui/views/focus/focus_manager_delegate.h b/chromium/ui/views/focus/focus_manager_delegate.h
index ca9bd71a55c..e6122c3c93c 100644
--- a/chromium/ui/views/focus/focus_manager_delegate.h
+++ b/chromium/ui/views/focus/focus_manager_delegate.h
@@ -26,12 +26,6 @@ class VIEWS_EXPORT FocusManagerDelegate {
// target, and so on.
// Returns true if an accelerator was activated.
virtual bool ProcessAccelerator(const ui::Accelerator& accelerator) = 0;
-
- // Returns the AcceleratorTarget that should be activated for the specified
- // keyboard accelerator, or NULL if no view is registered for that keyboard
- // accelerator.
- virtual ui::AcceleratorTarget* GetCurrentTargetForAccelerator(
- const ui::Accelerator& accelerator) const = 0;
};
} // namespace views
diff --git a/chromium/ui/views/focus/focus_manager_unittest.cc b/chromium/ui/views/focus/focus_manager_unittest.cc
index 1c4f3502dbd..c37b77f2822 100644
--- a/chromium/ui/views/focus/focus_manager_unittest.cc
+++ b/chromium/ui/views/focus/focus_manager_unittest.cc
@@ -43,7 +43,7 @@ class SimpleTestView : public View {
public:
SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id)
: event_list_(event_list) {
- SetFocusable(true);
+ SetFocusBehavior(FocusBehavior::ALWAYS);
set_id(view_id);
}
@@ -95,9 +95,9 @@ TEST_F(FocusManagerTest, ViewFocusCallbacks) {
TEST_F(FocusManagerTest, FocusChangeListener) {
View* view1 = new View();
- view1->SetFocusable(true);
+ view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
View* view2 = new View();
- view2->SetFocusable(true);
+ view2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
GetContentsView()->AddChildView(view1);
GetContentsView()->AddChildView(view2);
@@ -135,11 +135,11 @@ TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
params.bounds = gfx::Rect(10, 10, 100, 100);
params.parent = GetWidget()->GetNativeView();
- scoped_ptr<Widget> widget1(new Widget);
+ std::unique_ptr<Widget> widget1(new Widget);
widget1->Init(params);
widget1->Show();
- scoped_ptr<Widget> widget2(new Widget);
+ std::unique_ptr<Widget> widget2(new Widget);
widget2->Init(params);
widget2->Show();
@@ -198,10 +198,6 @@ TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
TestAcceleratorTarget escape_target(true);
EXPECT_EQ(return_target.accelerator_count(), 0);
EXPECT_EQ(escape_target.accelerator_count(), 0);
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
// Register targets.
focus_manager->RegisterAccelerator(return_accelerator,
@@ -211,12 +207,6 @@ TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
ui::AcceleratorManager::kNormalPriority,
&escape_target);
- // Checks if the correct target is registered.
- EXPECT_EQ(&return_target,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
- EXPECT_EQ(&escape_target,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
-
// Hitting the return key.
EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
EXPECT_EQ(return_target.accelerator_count(), 1);
@@ -233,8 +223,6 @@ TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
focus_manager->RegisterAccelerator(return_accelerator,
ui::AcceleratorManager::kNormalPriority,
&return_target2);
- EXPECT_EQ(&return_target2,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
// Hitting the return key; return_target2 has the priority.
EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
@@ -247,9 +235,6 @@ TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
focus_manager->RegisterAccelerator(return_accelerator,
ui::AcceleratorManager::kNormalPriority,
&return_target3);
- EXPECT_EQ(&return_target3,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
-
// Hitting the return key.
// Since the event handler of return_target3 returns false, return_target2
// should be called too.
@@ -260,8 +245,6 @@ TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
// Unregister return_target2.
focus_manager->UnregisterAccelerator(return_accelerator, &return_target2);
- EXPECT_EQ(&return_target3,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
// Hitting the return key. return_target3 and return_target should be called.
EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
@@ -274,12 +257,6 @@ TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
focus_manager->UnregisterAccelerator(return_accelerator, &return_target3);
focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target);
- // Now there is no target registered.
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
-
// Hitting the return key and the escape key. Nothing should happen.
EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
EXPECT_EQ(return_target.accelerator_count(), 2);
@@ -297,16 +274,12 @@ TEST_F(FocusManagerTest, HighPriorityHandlers) {
TestAcceleratorTarget escape_target_normal(true);
EXPECT_EQ(escape_target_high.accelerator_count(), 0);
EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
// Register high priority target.
focus_manager->RegisterAccelerator(escape_accelerator,
ui::AcceleratorManager::kHighPriority,
&escape_target_high);
- EXPECT_EQ(&escape_target_high,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
// Hit the escape key.
@@ -321,8 +294,6 @@ TEST_F(FocusManagerTest, HighPriorityHandlers) {
// Checks if the correct target is registered (same as before, the high
// priority one).
- EXPECT_EQ(&escape_target_high,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
// Hit the escape key.
@@ -332,8 +303,6 @@ TEST_F(FocusManagerTest, HighPriorityHandlers) {
// Unregister the high priority accelerator.
focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
- EXPECT_EQ(&escape_target_normal,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
// Hit the escape key.
@@ -345,8 +314,6 @@ TEST_F(FocusManagerTest, HighPriorityHandlers) {
focus_manager->RegisterAccelerator(escape_accelerator,
ui::AcceleratorManager::kHighPriority,
&escape_target_high);
- EXPECT_EQ(&escape_target_high,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
// Hit the escape key.
@@ -357,8 +324,6 @@ TEST_F(FocusManagerTest, HighPriorityHandlers) {
// Unregister the normal priority accelerator.
focus_manager->UnregisterAccelerator(
escape_accelerator, &escape_target_normal);
- EXPECT_EQ(&escape_target_high,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));
// Hit the escape key.
@@ -368,8 +333,6 @@ TEST_F(FocusManagerTest, HighPriorityHandlers) {
// Unregister the high priority accelerator.
focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));
// Hit the escape key (no change, no targets registered).
@@ -449,21 +412,15 @@ TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) {
ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager);
EXPECT_EQ(target.accelerator_count(), 0);
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
// Register the target.
focus_manager->RegisterAccelerator(return_accelerator,
ui::AcceleratorManager::kNormalPriority,
&target);
- EXPECT_EQ(&target,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
// Hitting the return key. The target will be unregistered.
EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
EXPECT_EQ(target.accelerator_count(), 1);
- EXPECT_EQ(NULL,
- focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
// Hitting the return key again; nothing should happen.
EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
@@ -602,17 +559,17 @@ TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) {
// Create 3 views focuses the 3 and advances to the second. The 2nd views
// implementation of AboutToRequestFocusFromTabTraversal() focuses the first.
views::View* v1 = new View;
- v1->SetFocusable(true);
+ v1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
GetContentsView()->AddChildView(v1);
FocusInAboutToRequestFocusFromTabTraversalView* v2 =
new FocusInAboutToRequestFocusFromTabTraversalView;
- v2->SetFocusable(true);
+ v2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
v2->set_view_to_focus(v1);
GetContentsView()->AddChildView(v2);
views::View* v3 = new View;
- v3->SetFocusable(true);
+ v3->SetFocusBehavior(View::FocusBehavior::ALWAYS);
GetContentsView()->AddChildView(v3);
v3->RequestFocus();
@@ -625,22 +582,22 @@ TEST_F(FocusManagerTest, RotatePaneFocus) {
GetContentsView()->AddChildView(pane1);
views::View* v1 = new View;
- v1->SetFocusable(true);
+ v1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
pane1->AddChildView(v1);
views::View* v2 = new View;
- v2->SetFocusable(true);
+ v2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
pane1->AddChildView(v2);
views::AccessiblePaneView* pane2 = new AccessiblePaneView();
GetContentsView()->AddChildView(pane2);
views::View* v3 = new View;
- v3->SetFocusable(true);
+ v3->SetFocusBehavior(View::FocusBehavior::ALWAYS);
pane2->AddChildView(v3);
views::View* v4 = new View;
- v4->SetFocusable(true);
+ v4->SetFocusBehavior(View::FocusBehavior::ALWAYS);
pane2->AddChildView(v4);
std::vector<views::View*> panes;
@@ -695,11 +652,11 @@ TEST_F(FocusManagerTest, RotatePaneFocus) {
// Verifies the stored focus view tracks the focused view.
TEST_F(FocusManagerTest, ImplicitlyStoresFocus) {
views::View* v1 = new View;
- v1->SetFocusable(true);
+ v1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
GetContentsView()->AddChildView(v1);
views::View* v2 = new View;
- v2->SetFocusable(true);
+ v2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
GetContentsView()->AddChildView(v2);
// Verify a focus request on |v1| implicitly updates the stored focus view.
@@ -753,7 +710,7 @@ TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) {
std::vector<views::View*> v;
for (size_t i = 0; i < 2; ++i) {
views::View* view = new View;
- view->SetFocusable(true);
+ view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
GetContentsView()->AddChildView(view);
v.push_back(view);
}
@@ -784,21 +741,98 @@ TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) {
}
TEST_F(FocusManagerTest, StoreFocusedView) {
- View view;
- GetFocusManager()->SetFocusedView(&view);
+ View* view = new View;
+ // Add view to the view hierarchy and make it focusable.
+ GetWidget()->GetRootView()->AddChildView(view);
+ view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+
+ GetFocusManager()->SetFocusedView(view);
GetFocusManager()->StoreFocusedView(false);
EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
- EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
+ EXPECT_EQ(view, GetFocusManager()->GetStoredFocusView());
// Repeat with |true|.
- GetFocusManager()->SetFocusedView(&view);
+ GetFocusManager()->SetFocusedView(view);
GetFocusManager()->StoreFocusedView(true);
EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
- EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
+ EXPECT_EQ(view, GetFocusManager()->GetStoredFocusView());
+}
+
+#if defined(OS_MACOSX)
+// Test that the correct view is restored if full keyboard access is changed.
+TEST_F(FocusManagerTest, StoreFocusedViewFullKeyboardAccess) {
+ View* view1 = new View;
+ View* view2 = new View;
+ View* view3 = new View;
+
+ // Make view1 focusable in accessibility mode, view2 not focusable and view3
+ // always focusable.
+ view1->SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY);
+ view2->SetFocusBehavior(View::FocusBehavior::NEVER);
+ view3->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+
+ // Add views to the view hierarchy
+ GetWidget()->GetRootView()->AddChildView(view1);
+ GetWidget()->GetRootView()->AddChildView(view2);
+ GetWidget()->GetRootView()->AddChildView(view3);
+
+ view1->RequestFocus();
+ EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
+ GetFocusManager()->StoreFocusedView(true);
+ EXPECT_EQ(nullptr, GetFocusManager()->GetFocusedView());
+
+ // Turn off full keyboard access mode and restore focused view. Since view1 is
+ // no longer focusable, view3 should have focus.
+ GetFocusManager()->SetKeyboardAccessible(false);
+ EXPECT_FALSE(GetFocusManager()->RestoreFocusedView());
+ EXPECT_EQ(view3, GetFocusManager()->GetFocusedView());
+
+ GetFocusManager()->StoreFocusedView(false);
+ EXPECT_EQ(nullptr, GetFocusManager()->GetFocusedView());
+
+ // Turn on full keyboard access mode and restore focused view. Since view3 is
+ // still focusable, view3 should have focus.
+ GetFocusManager()->SetKeyboardAccessible(true);
+ EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
+ EXPECT_EQ(view3, GetFocusManager()->GetFocusedView());
}
+// Test that View::RequestFocus() respects full keyboard access mode.
+TEST_F(FocusManagerTest, RequestFocus) {
+ View* view1 = new View();
+ View* view2 = new View();
+
+ // Make view1 always focusable, view2 only focusable in accessibility mode.
+ view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ view2->SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY);
+
+ // Adds views to the view hierarchy.
+ GetWidget()->GetRootView()->AddChildView(view1);
+ GetWidget()->GetRootView()->AddChildView(view2);
+
+ // Verify view1 can always get focus via View::RequestFocus, while view2 can
+ // only get focus in full keyboard accessibility mode.
+ EXPECT_TRUE(GetFocusManager()->keyboard_accessible());
+ view1->RequestFocus();
+ EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
+ view2->RequestFocus();
+ EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());
+
+ // Toggle full keyboard accessibility.
+ GetFocusManager()->SetKeyboardAccessible(false);
+
+ GetFocusManager()->ClearFocus();
+ EXPECT_NE(view1, GetFocusManager()->GetFocusedView());
+ view1->RequestFocus();
+ EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
+ view2->RequestFocus();
+ EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());
+}
+
+#endif
+
namespace {
// Trivial WidgetDelegate implementation that allows setting return value of
@@ -834,12 +868,12 @@ class AdvanceFocusWidgetDelegate : public WidgetDelegate {
TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) {
// Add |widget_view| as a child of the Widget.
View* widget_view = new View;
- widget_view->SetFocusable(true);
+ widget_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget_view->SetBounds(20, 0, 20, 20);
GetContentsView()->AddChildView(widget_view);
// Create a widget with two views, focus the second.
- scoped_ptr<AdvanceFocusWidgetDelegate> delegate;
+ std::unique_ptr<AdvanceFocusWidgetDelegate> delegate;
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.child = true;
@@ -850,10 +884,10 @@ TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) {
params.delegate = delegate.get();
child_widget.Init(params);
View* view1 = new View;
- view1->SetFocusable(true);
+ view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
view1->SetBounds(0, 0, 20, 20);
View* view2 = new View;
- view2->SetFocusable(true);
+ view2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
view2->SetBounds(20, 0, 20, 20);
child_widget.client_view()->AddChildView(view1);
child_widget.client_view()->AddChildView(view2);
diff --git a/chromium/ui/views/focus/focus_search.cc b/chromium/ui/views/focus/focus_search.cc
index a7ede3b0bf3..e91a701fd10 100644
--- a/chromium/ui/views/focus/focus_search.cc
+++ b/chromium/ui/views/focus/focus_search.cc
@@ -6,6 +6,7 @@
#include "ui/views/focus/focus_manager.h"
#include "ui/views/focus/focus_search.h"
#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
namespace views {
@@ -13,6 +14,12 @@ FocusSearch::FocusSearch(View* root, bool cycle, bool accessibility_mode)
: root_(root),
cycle_(cycle),
accessibility_mode_(accessibility_mode) {
+#if defined(OS_MACOSX)
+ // On Mac, only the keyboard accessibility mode defined in FocusManager is
+ // used. No special accessibility mode should be applicable for a
+ // FocusTraversable.
+ accessibility_mode_ = false;
+#endif
}
View* FocusSearch::FindNextFocusableView(View* starting_view,
@@ -99,7 +106,13 @@ bool FocusSearch::IsViewFocusableCandidate(View* v, int skip_group_id) {
}
bool FocusSearch::IsFocusable(View* v) {
- if (accessibility_mode_)
+ DCHECK(root_);
+ // Sanity Check. Currently the FocusManager keyboard accessibility mode is
+ // only used on Mac, for which |accessibility_mode_| is false.
+ DCHECK(!(accessibility_mode_ &&
+ root_->GetWidget()->GetFocusManager()->keyboard_accessible()));
+ if (accessibility_mode_ ||
+ root_->GetWidget()->GetFocusManager()->keyboard_accessible())
return v && v->IsAccessibilityFocusable();
return v && v->IsFocusable();
}
diff --git a/chromium/ui/views/focus/focus_search.h b/chromium/ui/views/focus/focus_search.h
index dd139187c6a..9da7df45ae9 100644
--- a/chromium/ui/views/focus/focus_search.h
+++ b/chromium/ui/views/focus/focus_search.h
@@ -87,7 +87,8 @@ class VIEWS_EXPORT FocusSearch {
bool IsViewFocusableCandidate(View* v, int skip_group_id);
// Convenience method; returns true if a view is not NULL and is focusable
- // (checking IsAccessibilityFocusable() if |accessibility_mode_| is true).
+ // (checking IsAccessibilityFocusable() if |accessibility_mode_| is true or
+ // the associated FocusManager has keyboard accessibility enabled).
bool IsFocusable(View* v);
// Returns the view selected for the group of the selected view. If the view
diff --git a/chromium/ui/views/focus/focus_traversal_unittest.cc b/chromium/ui/views/focus/focus_traversal_unittest.cc
index f1bee540cc4..4bc43614590 100644
--- a/chromium/ui/views/focus/focus_traversal_unittest.cc
+++ b/chromium/ui/views/focus/focus_traversal_unittest.cc
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/focus/focus_manager.h"
-
#include <stddef.h>
#include "base/macros.h"
@@ -23,6 +21,7 @@
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/tabbed_pane/tabbed_pane.h"
#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/focus/focus_manager.h"
#include "ui/views/test/focus_manager_test.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
@@ -134,7 +133,7 @@ class BorderView : public NativeViewHost {
public:
explicit BorderView(View* child) : child_(child), widget_(NULL) {
DCHECK(child);
- SetFocusable(false);
+ SetFocusBehavior(FocusBehavior::NEVER);
}
~BorderView() override {}
@@ -202,6 +201,24 @@ class FocusTraversalTest : public FocusManagerTest {
}
protected:
+ // Helper function to advance focus multiple times in a loop. |traversal_ids|
+ // is an array of view ids of length |N|. |reverse| denotes the direction in
+ // which focus should be advanced.
+ template <size_t N>
+ void AdvanceEntireFocusLoop(const int (&traversal_ids)[N], bool reverse) {
+ for (size_t i = 0; i < 3; ++i) {
+ for (size_t j = 0; j < N; j++) {
+ SCOPED_TRACE(testing::Message() << "reverse:" << reverse << " i:" << i
+ << " j:" << j);
+ GetFocusManager()->AdvanceFocus(reverse);
+ View* focused_view = GetFocusManager()->GetFocusedView();
+ EXPECT_NE(nullptr, focused_view);
+ if (focused_view)
+ EXPECT_EQ(traversal_ids[reverse ? N - j - 1 : j], focused_view->id());
+ }
+ }
+ }
+
TabbedPane* style_tab_;
BorderView* search_border_view_;
DummyComboboxModel combobox_model_;
@@ -543,7 +560,7 @@ void FocusTraversalTest::InitContentView() {
y += 60;
contents = new View();
- contents->SetFocusable(true);
+ contents->SetFocusBehavior(View::FocusBehavior::ALWAYS);
contents->set_background(Background::CreateSolidBackground(SK_ColorBLUE));
contents->set_id(kThumbnailContainerID);
button = new LabelButton(NULL, ASCIIToUTF16("Star"));
@@ -577,32 +594,74 @@ TEST_F(FocusTraversalTest, NormalTraversal) {
kSearchTextfieldID, kSearchButtonID, kHelpLinkID,
kThumbnailContainerID, kThumbnailStarID, kThumbnailSuperStarID };
+ SCOPED_TRACE("NormalTraversal");
+
// Let's traverse the whole focus hierarchy (several times, to make sure it
// loops OK).
GetFocusManager()->ClearFocus();
- for (int i = 0; i < 3; ++i) {
- for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
- GetFocusManager()->AdvanceFocus(false);
- View* focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kTraversalIDs, false);
// Let's traverse in reverse order.
GetFocusManager()->ClearFocus();
- for (int i = 0; i < 3; ++i) {
- for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) {
- GetFocusManager()->AdvanceFocus(true);
- View* focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kTraversalIDs, true);
+}
+
+#if defined(OS_MACOSX)
+// Test focus traversal with full keyboard access off on Mac.
+TEST_F(FocusTraversalTest, NormalTraversalMac) {
+ GetFocusManager()->SetKeyboardAccessible(false);
+
+ // Now only views with FocusBehavior of ALWAYS will be focusable.
+ const int kTraversalIDs[] = {kAppleTextfieldID, kOrangeTextfieldID,
+ kBananaTextfieldID, kKiwiTextfieldID,
+ kStyleTextEditID, kSearchTextfieldID,
+ kThumbnailContainerID};
+
+ SCOPED_TRACE("NormalTraversalMac");
+
+ // Let's traverse the whole focus hierarchy (several times, to make sure it
+ // loops OK).
+ GetFocusManager()->ClearFocus();
+ AdvanceEntireFocusLoop(kTraversalIDs, false);
+
+ // Let's traverse in reverse order.
+ GetFocusManager()->ClearFocus();
+ AdvanceEntireFocusLoop(kTraversalIDs, true);
}
+// Test toggling full keyboard access correctly changes the focused view on Mac.
+TEST_F(FocusTraversalTest, FullKeyboardToggle) {
+ // Give focus to kTopCheckBoxID .
+ FindViewByID(kTopCheckBoxID)->RequestFocus();
+ EXPECT_EQ(kTopCheckBoxID, GetFocusManager()->GetFocusedView()->id());
+
+ // Turn off full keyboard access. Focus should move to next view with ALWAYS
+ // focus behavior.
+ GetFocusManager()->SetKeyboardAccessible(false);
+ EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id());
+
+ // Turning on full keyboard access should not change the focused view.
+ GetFocusManager()->SetKeyboardAccessible(true);
+ EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id());
+
+ // Give focus to kSearchButtonID.
+ FindViewByID(kSearchButtonID)->RequestFocus();
+ EXPECT_EQ(kSearchButtonID, GetFocusManager()->GetFocusedView()->id());
+
+ // Turn off full keyboard access. Focus should move to next view with ALWAYS
+ // focus behavior.
+ GetFocusManager()->SetKeyboardAccessible(false);
+ EXPECT_EQ(kThumbnailContainerID, GetFocusManager()->GetFocusedView()->id());
+
+ // See focus advances correctly in both directions.
+ GetFocusManager()->AdvanceFocus(false);
+ EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id());
+
+ GetFocusManager()->AdvanceFocus(true);
+ EXPECT_EQ(kThumbnailContainerID, GetFocusManager()->GetFocusedView()->id());
+}
+#endif // OS_MACOSX
+
TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
const int kDisabledIDs[] = {
kBananaTextfieldID, kFruitCheckBoxID, kComboboxID, kAsparagusButtonID,
@@ -619,6 +678,8 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
kSearchButtonID, kThumbnailContainerID, kThumbnailStarID,
kThumbnailSuperStarID };
+ SCOPED_TRACE("TraversalWithNonEnabledViews");
+
// Let's disable some views.
for (size_t i = 0; i < arraysize(kDisabledIDs); i++) {
View* v = FindViewByID(kDisabledIDs[i]);
@@ -626,30 +687,13 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
v->SetEnabled(false);
}
- View* focused_view;
// Let's do one traversal (several times, to make sure it loops ok).
GetFocusManager()->ClearFocus();
- for (int i = 0; i < 3; ++i) {
- for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
- GetFocusManager()->AdvanceFocus(false);
- focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kTraversalIDs, false);
// Same thing in reverse.
GetFocusManager()->ClearFocus();
- for (int i = 0; i < 3; ++i) {
- for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) {
- GetFocusManager()->AdvanceFocus(true);
- focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kTraversalIDs, true);
}
TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
@@ -666,6 +710,7 @@ TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
kItalicCheckBoxID, kUnderlinedCheckBoxID, kStyleHelpLinkID,
kStyleTextEditID, kSearchTextfieldID, kSearchButtonID, kHelpLinkID };
+ SCOPED_TRACE("TraversalWithInvisibleViews");
// Let's make some views invisible.
for (size_t i = 0; i < arraysize(kInvisibleIDs); i++) {
@@ -674,30 +719,13 @@ TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
v->SetVisible(false);
}
- View* focused_view;
// Let's do one traversal (several times, to make sure it loops ok).
GetFocusManager()->ClearFocus();
- for (int i = 0; i < 3; ++i) {
- for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
- GetFocusManager()->AdvanceFocus(false);
- focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kTraversalIDs, false);
// Same thing in reverse.
GetFocusManager()->ClearFocus();
- for (int i = 0; i < 3; ++i) {
- for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) {
- GetFocusManager()->AdvanceFocus(true);
- focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kTraversalIDs, true);
}
TEST_F(FocusTraversalTest, PaneTraversal) {
@@ -710,32 +738,18 @@ TEST_F(FocusTraversalTest, PaneTraversal) {
kOrangeTextfieldID, kBananaTextfieldID, kKiwiTextfieldID,
kFruitButtonID, kFruitCheckBoxID, kComboboxID };
+ SCOPED_TRACE("PaneTraversal");
+
FocusSearch focus_search_left(left_container_, true, false);
left_container_->EnablePaneFocus(&focus_search_left);
FindViewByID(kComboboxID)->RequestFocus();
// Traverse the focus hierarchy within the pane several times.
- for (int i = 0; i < 3; ++i) {
- for (size_t j = 0; j < arraysize(kLeftTraversalIDs); j++) {
- GetFocusManager()->AdvanceFocus(false);
- View* focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kLeftTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kLeftTraversalIDs, false);
// Traverse in reverse order.
FindViewByID(kAppleTextfieldID)->RequestFocus();
- for (int i = 0; i < 3; ++i) {
- for (int j = arraysize(kLeftTraversalIDs) - 1; j >= 0; --j) {
- GetFocusManager()->AdvanceFocus(true);
- View* focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kLeftTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kLeftTraversalIDs, true);
// Now test the right container, but this time with accessibility mode.
// Make some links not focusable, but mark one of them as
@@ -747,34 +761,19 @@ TEST_F(FocusTraversalTest, PaneTraversal) {
FocusSearch focus_search_right(right_container_, true, true);
right_container_->EnablePaneFocus(&focus_search_right);
- FindViewByID(kRosettaLinkID)->SetFocusable(false);
- FindViewByID(kStupeurEtTremblementLinkID)->SetFocusable(false);
- FindViewByID(kDinerGameLinkID)->SetAccessibilityFocusable(true);
- FindViewByID(kDinerGameLinkID)->SetFocusable(false);
+ FindViewByID(kRosettaLinkID)->SetFocusBehavior(View::FocusBehavior::NEVER);
+ FindViewByID(kStupeurEtTremblementLinkID)
+ ->SetFocusBehavior(View::FocusBehavior::NEVER);
+ FindViewByID(kDinerGameLinkID)
+ ->SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY);
FindViewByID(kAsterixLinkID)->RequestFocus();
// Traverse the focus hierarchy within the pane several times.
- for (int i = 0; i < 3; ++i) {
- for (size_t j = 0; j < arraysize(kRightTraversalIDs); j++) {
- GetFocusManager()->AdvanceFocus(false);
- View* focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kRightTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kRightTraversalIDs, false);
// Traverse in reverse order.
FindViewByID(kBroccoliButtonID)->RequestFocus();
- for (int i = 0; i < 3; ++i) {
- for (int j = arraysize(kRightTraversalIDs) - 1; j >= 0; --j) {
- GetFocusManager()->AdvanceFocus(true);
- View* focused_view = GetFocusManager()->GetFocusedView();
- EXPECT_TRUE(focused_view != NULL);
- if (focused_view)
- EXPECT_EQ(kRightTraversalIDs[j], focused_view->id());
- }
- }
+ AdvanceEntireFocusLoop(kRightTraversalIDs, true);
}
class FocusTraversalNonFocusableTest : public FocusManagerTest {
diff --git a/chromium/ui/views/layout/box_layout_unittest.cc b/chromium/ui/views/layout/box_layout_unittest.cc
index 0ef2fbad808..4b4fec21abc 100644
--- a/chromium/ui/views/layout/box_layout_unittest.cc
+++ b/chromium/ui/views/layout/box_layout_unittest.cc
@@ -18,7 +18,7 @@ class BoxLayoutTest : public testing::Test {
public:
void SetUp() override { host_.reset(new View); }
- scoped_ptr<View> host_;
+ std::unique_ptr<View> host_;
};
} // namespace
diff --git a/chromium/ui/views/linux_ui/linux_ui.h b/chromium/ui/views/linux_ui/linux_ui.h
index d795d7c488a..6eb3c269ff9 100644
--- a/chromium/ui/views/linux_ui/linux_ui.h
+++ b/chromium/ui/views/linux_ui/linux_ui.h
@@ -80,6 +80,9 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
static LinuxUI* instance();
virtual void Initialize() = 0;
+ // TODO(varkha): This should not be necessary once Material Design is on
+ // unconditionally.
+ virtual void MaterialDesignControllerReady() = 0;
// Returns a themed image per theme_provider.h
virtual gfx::Image GetThemeImageNamed(int id) const = 0;
@@ -118,7 +121,7 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
virtual bool IsStatusIconSupported() const = 0;
// Create a native status icon.
- virtual scoped_ptr<StatusIconLinux> CreateLinuxStatusIcon(
+ virtual std::unique_ptr<StatusIconLinux> CreateLinuxStatusIcon(
const gfx::ImageSkia& image,
const base::string16& tool_tip) const = 0;
@@ -129,9 +132,9 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
const std::string& content_type, int size) const = 0;
// Builds a Border which paints the native button style.
- virtual scoped_ptr<Border> CreateNativeBorder(
+ virtual std::unique_ptr<Border> CreateNativeBorder(
views::LabelButton* owning_button,
- scoped_ptr<views::LabelButtonBorder> border) = 0;
+ std::unique_ptr<views::LabelButtonBorder> border) = 0;
// Notifies the observer about changes about how window buttons should be
// laid out. If the order is anything other than the default min,max,close on
diff --git a/chromium/ui/views/mouse_watcher.cc b/chromium/ui/views/mouse_watcher.cc
index c28005fdc54..686cb071d93 100644
--- a/chromium/ui/views/mouse_watcher.cc
+++ b/chromium/ui/views/mouse_watcher.cc
@@ -83,7 +83,7 @@ class MouseWatcher::Observer : public ui::EventHandler {
private:
MouseWatcher* mouse_watcher_;
- scoped_ptr<views::EventMonitor> event_monitor_;
+ std::unique_ptr<views::EventMonitor> event_monitor_;
// A factory that is used to construct a delayed callback to the listener.
base::WeakPtrFactory<Observer> notify_listener_factory_;
diff --git a/chromium/ui/views/mouse_watcher.h b/chromium/ui/views/mouse_watcher.h
index 89e13584a74..4737d81d1b6 100644
--- a/chromium/ui/views/mouse_watcher.h
+++ b/chromium/ui/views/mouse_watcher.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_MOUSE_WATCHER_H_
#define UI_VIEWS_MOUSE_WATCHER_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/views_export.h"
@@ -78,13 +79,13 @@ class VIEWS_EXPORT MouseWatcher {
void NotifyListener();
// Host we're listening for events over.
- scoped_ptr<MouseWatcherHost> host_;
+ std::unique_ptr<MouseWatcherHost> host_;
// Our listener.
MouseWatcherListener* listener_;
// Does the actual work of listening for mouse events.
- scoped_ptr<Observer> observer_;
+ std::unique_ptr<Observer> observer_;
// See description above setter.
base::TimeDelta notify_on_exit_time_;
diff --git a/chromium/ui/views/mouse_watcher_view_host.cc b/chromium/ui/views/mouse_watcher_view_host.cc
index ac02b3cf4bf..b6856e03863 100644
--- a/chromium/ui/views/mouse_watcher_view_host.cc
+++ b/chromium/ui/views/mouse_watcher_view_host.cc
@@ -4,7 +4,7 @@
#include "ui/views/mouse_watcher_view_host.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/screen.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
@@ -49,8 +49,8 @@ bool MouseWatcherViewHost::IsMouseOverWindow() {
if (!widget)
return false;
- return gfx::Screen::GetScreen()->GetWindowUnderCursor() ==
- widget->GetNativeWindow();
+ return display::Screen::GetScreen()->IsWindowUnderCursor(
+ widget->GetNativeWindow());
}
} // namespace views
diff --git a/chromium/ui/views/mus/BUILD.gn b/chromium/ui/views/mus/BUILD.gn
index a9005760549..4fdfca356ea 100644
--- a/chromium/ui/views/mus/BUILD.gn
+++ b/chromium/ui/views/mus/BUILD.gn
@@ -5,6 +5,7 @@
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//mojo/public/mojo_application.gni")
+import("//mojo/public/mojo_application_manifest.gni")
import("//testing/test.gni")
import("//tools/grit/repack.gni")
@@ -16,6 +17,8 @@ component("mus") {
"aura_init.h",
"display_converter.cc",
"display_converter.h",
+ "display_list.cc",
+ "display_list.h",
"input_method_mus.cc",
"input_method_mus.h",
"mus_export.h",
@@ -57,8 +60,6 @@ component("mus") {
"//components/mus/gles2:lib",
"//components/mus/public/cpp",
"//components/mus/public/interfaces",
- "//components/resource_provider/public/cpp",
- "//components/resource_provider/public/interfaces",
"//mojo/converters/geometry",
"//mojo/converters/ime",
"//mojo/converters/input_events",
@@ -66,32 +67,33 @@ component("mus") {
"//mojo/platform_handle:for_component",
"//mojo/public/c/system:for_component",
"//mojo/public/cpp/bindings",
- "//mojo/shell/public/cpp",
- "//mojo/shell/public/interfaces",
+ "//services/catalog/public/cpp",
+ "//services/shell/public/cpp",
+ "//services/shell/public/interfaces",
"//skia",
"//third_party/icu",
"//ui/aura",
"//ui/compositor",
+ "//ui/display",
"//ui/events",
"//ui/events:events_base",
+ "//ui/events/devices",
"//ui/gfx",
"//ui/gfx/geometry",
"//ui/gl",
+ "//ui/mojo/display",
"//ui/mojo/ime:interfaces_cpp_sources",
- "//ui/mojo/init",
"//ui/native_theme",
"//ui/platform_window",
"//ui/views",
"//ui/wm",
]
- data_deps = [
- "//components/resource_provider",
- ]
-
if (is_linux && !is_android) {
deps += [ "//components/font_service/public/cpp" ]
- data_deps += [ "//components/font_service" ]
+ data_deps = [
+ "//components/font_service",
+ ]
}
}
@@ -127,11 +129,36 @@ group("for_shared_library") {
}
}
-group("tests") {
+source_set("test_support") {
testonly = true
+ sources = [
+ "../test/native_widget_factory_mus.cc",
+ "../views_test_suite.cc",
+ "../views_test_suite.h",
+ "views_mus_test_suite.cc",
+ "views_mus_test_suite.h",
+ ]
+
deps = [
- ":views_mus_unittests",
+ ":mus",
+ "//base",
+ "//base/test:test_support",
+ "//components/mus/common:mus_common",
+ "//services/shell/background:lib",
+ "//services/shell/background/tests:test_support",
+ "//services/shell/public/cpp:sources",
+ "//testing/gtest",
+ "//ui/aura",
+ "//ui/gl:test_support",
+ "//ui/resources",
+ "//ui/resources:ui_test_pak",
+ "//ui/views",
+ "//ui/views:test_support_internal",
+ ]
+
+ data_deps = [
+ "//ui/resources:ui_test_pak_data",
]
}
@@ -142,30 +169,26 @@ test("views_mus_unittests") {
# TODO(sky): add more files.
sources = [
- "../run_all_unittests.cc",
- "../run_all_unittests.h",
- "../test/native_widget_factory_mus.cc",
"../view_targeter_unittest.cc",
"../widget/native_widget_unittest.cc",
"../widget/widget_unittest.cc",
+ "display_list_unittest.cc",
"native_widget_mus_unittest.cc",
- "platform_test_helper_mus.cc",
"run_all_unittests_mus.cc",
+ "screen_mus_unittest.cc",
+ "window_manager_connection_unittest.cc",
]
deps = [
":mus",
+ ":test_support",
"//base",
"//base:i18n",
- "//base/test:test_support",
"//cc",
"//components/mus/public/cpp",
+ "//components/mus/public/cpp/tests:unittest_support",
"//components/mus/public/interfaces",
- "//mojo/shell/background:lib",
- "//mojo/shell/background:main",
- "//mojo/shell/background/tests:test_support",
- "//mojo/shell/public/cpp:sources",
- "//mojo/shell/runner/host:lib",
+ "//services/shell/background:main", # Provides main().
"//skia",
"//testing/gtest",
"//third_party/icu",
@@ -182,10 +205,7 @@ test("views_mus_unittests") {
"//ui/events/platform",
"//ui/gfx:test_support",
"//ui/gfx/geometry",
- "//ui/gl:test_support",
- "//ui/resources",
"//ui/strings",
- "//ui/touch_selection",
"//ui/views",
"//ui/views:test_support_internal",
"//ui/wm",
@@ -193,15 +213,10 @@ test("views_mus_unittests") {
]
data_deps = [
+ ":unittests_manifest",
"//mash/wm",
]
- # TODO(thakis): This should be a data_deps on //ui/resources:ui_test_pak, but
- # that has no effect. (See similar TODOs elsewhere ui_test.pak is listed)
- data = [
- "$root_out_dir/ui_test.pak",
- ]
-
if (is_win) {
deps += [
"//build/win:default_exe_manifest",
@@ -228,6 +243,66 @@ test("views_mus_unittests") {
}
}
+# Tests that must run sequentially because they access system-wide features
+# like capture.
+test("views_mus_interactive_ui_tests") {
+ testonly = true
+
+ configs += [ "//build/config:precompiled_headers" ]
+
+ sources = [
+ "../widget/widget_interactive_uitest.cc",
+ "interactive_ui_tests_mus.cc",
+ ]
+
+ deps = [
+ ":mus",
+ ":test_support",
+ "//base",
+ "//services/shell/background:main", # Provides main().
+ "//ui/aura",
+ "//ui/base",
+ "//ui/base/ime",
+ "//ui/events:events_base",
+ "//ui/events:test_support",
+ "//ui/gl:test_support",
+ "//ui/touch_selection",
+ "//ui/views",
+ "//ui/views:test_support_internal",
+ "//ui/wm",
+ ]
+
+ data_deps = [
+ ":interactive_ui_tests_manifest",
+ "//mash/wm",
+ ]
+
+ if (is_win) {
+ deps += [
+ "//build/win:default_exe_manifest",
+ "//third_party/iaccessible2",
+ "//third_party/wtl",
+ ]
+ libs = [
+ "imm32.lib",
+ "oleacc.lib",
+ "comctl32.lib",
+ ]
+ }
+}
+
+mojo_application_manifest("unittests_manifest") {
+ type = "exe"
+ application_name = "views_mus_unittests"
+ source = "unittests_manifest.json"
+}
+
+mojo_application_manifest("interactive_ui_tests_manifest") {
+ type = "exe"
+ application_name = "views_mus_interactive_ui_tests"
+ source = "interactive_ui_tests_manifest.json"
+}
+
group("for_component") {
public_deps = [
":mus",
diff --git a/chromium/ui/views/mus/DEPS b/chromium/ui/views/mus/DEPS
index a6ef8809458..9f23b5b7592 100644
--- a/chromium/ui/views/mus/DEPS
+++ b/chromium/ui/views/mus/DEPS
@@ -5,11 +5,11 @@ include_rules = [
"+components/bitmap_uploader",
"+components/gpu",
"+components/mus",
- "+components/resource_provider",
- "+mojo/shell/public",
"+mojo/cc",
"+mojo/converters",
"+mojo/public",
+ "+services/catalog/public",
+ "+services/shell/public",
"+skia",
"+ui/aura",
"+ui/base",
@@ -17,14 +17,14 @@ include_rules = [
"+ui/events",
"+ui/gfx",
"+ui/gl",
+ "+ui/mojo/display",
"+ui/mojo/ime",
- "+ui/mojo/init",
"+ui/platform_window",
"+ui/wm",
]
specific_include_rules = {
- "platform_test_helper_mus.cc": [
- "+mojo/shell/background",
+ "views_mus_test_suite.cc": [
+ "+services/shell/background",
],
}
diff --git a/chromium/ui/views/mus/aura_init.cc b/chromium/ui/views/mus/aura_init.cc
index 2b08108882e..5335188700b 100644
--- a/chromium/ui/views/mus/aura_init.cc
+++ b/chromium/ui/views/mus/aura_init.cc
@@ -10,10 +10,11 @@
#include "base/macros.h"
#include "base/path_service.h"
#include "build/build_config.h"
-#include "components/resource_provider/public/cpp/resource_loader.h"
-#include "mojo/shell/public/cpp/connector.h"
+#include "services/catalog/public/cpp/resource_loader.h"
+#include "services/shell/public/cpp/connector.h"
#include "ui/aura/env.h"
#include "ui/base/ime/input_method_initializer.h"
+#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_paths.h"
#include "ui/views/views_delegate.h"
@@ -50,11 +51,12 @@ class MusViewsDelegate : public ViewsDelegate {
} // namespace
-AuraInit::AuraInit(mojo::Connector* connector, const std::string& resource_file)
+AuraInit::AuraInit(shell::Connector* connector,
+ const std::string& resource_file)
: resource_file_(resource_file),
+ env_(aura::Env::CreateInstance()),
views_delegate_(new MusViewsDelegate) {
- aura::Env::CreateInstance(false);
-
+ ui::MaterialDesignController::Initialize();
InitializeResources(connector);
ui::InitializeInputMethodForTesting();
@@ -72,15 +74,16 @@ AuraInit::~AuraInit() {
#endif
}
-void AuraInit::InitializeResources(mojo::Connector* connector) {
+void AuraInit::InitializeResources(shell::Connector* connector) {
if (ui::ResourceBundle::HasSharedInstance())
return;
- resource_provider::ResourceLoader resource_loader(
- connector, GetResourcePaths(resource_file_));
- CHECK(resource_loader.BlockUntilLoaded());
- CHECK(resource_loader.loaded());
+ catalog::ResourceLoader loader;
+ filesystem::mojom::DirectoryPtr directory;
+ connector->ConnectToInterface("mojo:catalog", &directory);
+ CHECK(loader.OpenFiles(std::move(directory),
+ GetResourcePaths(resource_file_)));
ui::RegisterPathProvider();
- base::File pak_file = resource_loader.ReleaseFile(resource_file_);
+ base::File pak_file = loader.TakeFile(resource_file_);
base::File pak_file_2 = pak_file.Duplicate();
ui::ResourceBundle::InitSharedInstanceWithPakFileRegion(
std::move(pak_file), base::MemoryMappedFile::Region::kWholeFile);
@@ -89,7 +92,7 @@ void AuraInit::InitializeResources(mojo::Connector* connector) {
// Initialize the skia font code to go ask fontconfig underneath.
#if defined(OS_LINUX) && !defined(OS_ANDROID)
- font_loader_ = skia::AdoptRef(new font_service::FontLoader(connector));
+ font_loader_ = sk_make_sp<font_service::FontLoader>(connector);
SkFontConfigInterface::SetGlobal(font_loader_.get());
#endif
diff --git a/chromium/ui/views/mus/aura_init.h b/chromium/ui/views/mus/aura_init.h
index 521acac91ee..9330845f17b 100644
--- a/chromium/ui/views/mus/aura_init.h
+++ b/chromium/ui/views/mus/aura_init.h
@@ -5,19 +5,23 @@
#ifndef UI_VIEWS_MUS_AURA_INIT_H_
#define UI_VIEWS_MUS_AURA_INIT_H_
+#include <memory>
#include <string>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
-#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/views/mus/mus_export.h"
+namespace aura {
+class Env;
+}
+
namespace font_service {
class FontLoader;
}
-namespace mojo {
+namespace shell {
class Connector;
}
@@ -28,19 +32,20 @@ class ViewsDelegate;
// |resource_file| is the path to the apk file containing the resources.
class VIEWS_MUS_EXPORT AuraInit {
public:
- AuraInit(mojo::Connector* connector, const std::string& resource_file);
+ AuraInit(shell::Connector* connector, const std::string& resource_file);
~AuraInit();
private:
- void InitializeResources(mojo::Connector* connector);
+ void InitializeResources(shell::Connector* connector);
#if defined(OS_LINUX) && !defined(OS_ANDROID)
- skia::RefPtr<font_service::FontLoader> font_loader_;
+ sk_sp<font_service::FontLoader> font_loader_;
#endif
const std::string resource_file_;
- scoped_ptr<ViewsDelegate> views_delegate_;
+ std::unique_ptr<aura::Env> env_;
+ std::unique_ptr<ViewsDelegate> views_delegate_;
DISALLOW_COPY_AND_ASSIGN(AuraInit);
};
diff --git a/chromium/ui/views/mus/display_converter.cc b/chromium/ui/views/mus/display_converter.cc
index fce58f6a114..0a66aa62ff2 100644
--- a/chromium/ui/views/mus/display_converter.cc
+++ b/chromium/ui/views/mus/display_converter.cc
@@ -11,14 +11,14 @@
namespace views {
-std::vector<gfx::Display> GetDisplaysFromWindow(mus::Window* window) {
+std::vector<display::Display> GetDisplaysFromWindow(mus::Window* window) {
static int64_t synthesized_display_id = 2000;
- gfx::Display display;
+ display::Display display;
display.set_id(synthesized_display_id++);
display.SetScaleAndBounds(
window->viewport_metrics().device_pixel_ratio,
gfx::Rect(window->viewport_metrics().size_in_pixels.To<gfx::Size>()));
- std::vector<gfx::Display> displays;
+ std::vector<display::Display> displays;
displays.push_back(display);
return displays;
}
diff --git a/chromium/ui/views/mus/display_converter.h b/chromium/ui/views/mus/display_converter.h
index 6e61bf395db..74de33d5400 100644
--- a/chromium/ui/views/mus/display_converter.h
+++ b/chromium/ui/views/mus/display_converter.h
@@ -7,7 +7,7 @@
#include <vector>
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
#include "ui/views/mus/mus_export.h"
namespace mus {
@@ -16,8 +16,8 @@ class Window;
namespace views {
-std::vector<gfx::Display> VIEWS_MUS_EXPORT GetDisplaysFromWindow(
- mus::Window* window);
+std::vector<display::Display> VIEWS_MUS_EXPORT
+GetDisplaysFromWindow(mus::Window* window);
} // namespace views
diff --git a/chromium/ui/views/mus/display_list.cc b/chromium/ui/views/mus/display_list.cc
new file mode 100644
index 00000000000..5be844ca52f
--- /dev/null
+++ b/chromium/ui/views/mus/display_list.cc
@@ -0,0 +1,109 @@
+// Copyright 2016 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.
+
+#include "ui/views/mus/display_list.h"
+
+#include "ui/display/display_finder.h"
+#include "ui/display/display_observer.h"
+
+namespace views {
+
+DisplayList::DisplayList() {}
+
+DisplayList::~DisplayList() {}
+
+void DisplayList::AddObserver(display::DisplayObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void DisplayList::RemoveObserver(display::DisplayObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+DisplayList::Displays::const_iterator DisplayList::FindDisplayById(
+ int64_t id) const {
+ for (auto iter = displays_.begin(); iter != displays_.end(); ++iter) {
+ if (iter->id() == id)
+ return iter;
+ }
+ return displays_.end();
+}
+
+DisplayList::Displays::iterator DisplayList::FindDisplayById(int64_t id) {
+ for (auto iter = displays_.begin(); iter != displays_.end(); ++iter) {
+ if (iter->id() == id)
+ return iter;
+ }
+ return displays_.end();
+}
+
+DisplayList::Displays::const_iterator DisplayList::GetPrimaryDisplayIterator()
+ const {
+ return primary_display_index_ == -1
+ ? displays_.end()
+ : displays_.begin() + primary_display_index_;
+}
+
+void DisplayList::UpdateDisplay(const display::Display& display, Type type) {
+ auto iter = FindDisplayById(display.id());
+ DCHECK(iter != displays_.end());
+
+ display::Display* local_display = &(*iter);
+ uint32_t changed_values = 0;
+ if (type == Type::PRIMARY &&
+ static_cast<int>(iter - displays_.begin()) !=
+ static_cast<int>(GetPrimaryDisplayIterator() - displays_.begin())) {
+ primary_display_index_ = static_cast<int>(iter - displays_.begin());
+ // ash::DisplayManager only notifies for the Display gaining primary, not
+ // the one losing it.
+ changed_values |= display::DisplayObserver::DISPLAY_METRIC_PRIMARY;
+ }
+ if (local_display->bounds() != display.bounds()) {
+ local_display->set_bounds(display.bounds());
+ changed_values |= display::DisplayObserver::DISPLAY_METRIC_BOUNDS;
+ }
+ if (local_display->work_area() != display.work_area()) {
+ local_display->set_work_area(display.work_area());
+ changed_values |= display::DisplayObserver::DISPLAY_METRIC_WORK_AREA;
+ }
+ if (local_display->rotation() != display.rotation()) {
+ local_display->set_rotation(display.rotation());
+ changed_values |= display::DisplayObserver::DISPLAY_METRIC_ROTATION;
+ }
+ if (local_display->device_scale_factor() != display.device_scale_factor()) {
+ local_display->set_device_scale_factor(display.device_scale_factor());
+ changed_values |=
+ display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
+ }
+ FOR_EACH_OBSERVER(display::DisplayObserver, observers_,
+ OnDisplayMetricsChanged(*local_display, changed_values));
+}
+
+void DisplayList::AddDisplay(const display::Display& display, Type type) {
+ DCHECK(displays_.end() == FindDisplayById(display.id()));
+ displays_.push_back(display);
+ if (type == Type::PRIMARY)
+ primary_display_index_ = static_cast<int>(displays_.size()) - 1;
+ FOR_EACH_OBSERVER(display::DisplayObserver, observers_,
+ OnDisplayAdded(display));
+}
+
+void DisplayList::RemoveDisplay(int64_t id) {
+ auto iter = FindDisplayById(id);
+ DCHECK(displays_.end() != iter);
+ if (primary_display_index_ == static_cast<int>(iter - displays_.begin())) {
+ // We expect the primary to change before removing it. The only case we
+ // allow removal of the primary is if it is the list display.
+ DCHECK_EQ(1u, displays_.size());
+ primary_display_index_ = -1;
+ } else if (primary_display_index_ >
+ static_cast<int>(iter - displays_.begin())) {
+ primary_display_index_--;
+ }
+ const display::Display display = *iter;
+ displays_.erase(iter);
+ FOR_EACH_OBSERVER(display::DisplayObserver, observers_,
+ OnDisplayRemoved(display));
+}
+} // namespace views
diff --git a/chromium/ui/views/mus/display_list.h b/chromium/ui/views/mus/display_list.h
new file mode 100644
index 00000000000..19b0ac97f11
--- /dev/null
+++ b/chromium/ui/views/mus/display_list.h
@@ -0,0 +1,69 @@
+// Copyright 2016 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_VIEWS_MUS_DISPLAY_LIST_H_
+#define UI_VIEWS_MUS_DISPLAY_LIST_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "base/observer_list.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "ui/display/display.h"
+#include "ui/views/mus/mus_export.h"
+
+namespace display {
+class Display;
+class DisplayObserver;
+}
+
+namespace views {
+
+// Maintains an ordered list of display::Displays as well as operations to add,
+// remove and update said list. Additionally maintains display::DisplayObservers
+// and updates them as appropriate.
+class VIEWS_MUS_EXPORT DisplayList {
+ public:
+ using Displays = std::vector<display::Display>;
+
+ enum class Type {
+ PRIMARY,
+ NOT_PRIMARY,
+ };
+
+ DisplayList();
+ ~DisplayList();
+
+ void AddObserver(display::DisplayObserver* observer);
+ void RemoveObserver(display::DisplayObserver* observer);
+
+ const Displays& displays() const { return displays_; }
+
+ Displays::const_iterator FindDisplayById(int64_t id) const;
+ Displays::iterator FindDisplayById(int64_t id);
+
+ Displays::const_iterator GetPrimaryDisplayIterator() const;
+
+ // Updates the cached id based on display.id() as well as whether the Display
+ // is the primary display.
+ void UpdateDisplay(const display::Display& display, Type type);
+
+ // Adds a new Display.
+ void AddDisplay(const display::Display& display, Type type);
+
+ // Removes the Display with the specified id.
+ void RemoveDisplay(int64_t id);
+
+ private:
+ std::vector<display::Display> displays_;
+ int primary_display_index_ = -1;
+ base::ObserverList<display::DisplayObserver> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(DisplayList);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_MUS_DISPLAY_LIST_H_
diff --git a/chromium/ui/views/mus/display_list_unittest.cc b/chromium/ui/views/mus/display_list_unittest.cc
new file mode 100644
index 00000000000..93cdc81e608
--- /dev/null
+++ b/chromium/ui/views/mus/display_list_unittest.cc
@@ -0,0 +1,113 @@
+// Copyright 2016 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.
+
+#include "ui/views/mus/display_list.h"
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/display.h"
+#include "ui/display/display_observer.h"
+
+using display::Display;
+
+namespace views {
+namespace {
+
+class DisplayObserverImpl : public display::DisplayObserver {
+ public:
+ DisplayObserverImpl() {}
+ ~DisplayObserverImpl() override {}
+
+ std::string GetAndClearChanges() {
+ std::string changes;
+ std::swap(changes, changes_);
+ return changes;
+ }
+
+ private:
+ static void AddPartChange(uint32_t changed,
+ uint32_t part,
+ const std::string& description,
+ std::string* changed_string) {
+ if ((changed & part) != part)
+ return;
+
+ *changed_string += " ";
+ *changed_string += description;
+ }
+
+ void AddChange(const std::string& change) {
+ if (!changes_.empty())
+ changes_ += "\n";
+ changes_ += change;
+ }
+
+ void OnDisplayAdded(const Display& new_display) override {
+ AddChange("Added id=" + base::Int64ToString(new_display.id()));
+ }
+ void OnDisplayRemoved(const Display& old_display) override {
+ AddChange("Removed id=" + base::Int64ToString(old_display.id()));
+ }
+ void OnDisplayMetricsChanged(const Display& display,
+ uint32_t changed_metrics) override {
+ std::string parts;
+ AddPartChange(changed_metrics, DISPLAY_METRIC_BOUNDS, "bounds", &parts);
+ AddPartChange(changed_metrics, DISPLAY_METRIC_WORK_AREA, "work_area",
+ &parts);
+ AddPartChange(changed_metrics, DISPLAY_METRIC_DEVICE_SCALE_FACTOR,
+ "scale_factor", &parts);
+ AddPartChange(changed_metrics, DISPLAY_METRIC_ROTATION, "rotation", &parts);
+ AddPartChange(changed_metrics, DISPLAY_METRIC_PRIMARY, "primary", &parts);
+
+ AddChange("Changed id=" + base::Int64ToString(display.id()) + parts);
+ }
+
+ std::string changes_;
+
+ DISALLOW_COPY_AND_ASSIGN(DisplayObserverImpl);
+};
+
+TEST(DisplayListTest, AddUpdateRemove) {
+ DisplayList display_list;
+ DisplayObserverImpl observer;
+ display_list.AddObserver(&observer);
+ display_list.AddDisplay(display::Display(2, gfx::Rect(0, 0, 801, 802)),
+ DisplayList::Type::PRIMARY);
+ EXPECT_EQ("Added id=2", observer.GetAndClearChanges());
+
+ // Update the bounds.
+ {
+ display::Display updated_display = *(display_list.displays().begin());
+ updated_display.set_bounds(gfx::Rect(0, 0, 803, 802));
+ display_list.UpdateDisplay(updated_display, DisplayList::Type::PRIMARY);
+ EXPECT_EQ("Changed id=2 bounds", observer.GetAndClearChanges());
+ }
+
+ // Add another.
+ display_list.AddDisplay(display::Display(3, gfx::Rect(0, 0, 809, 802)),
+ DisplayList::Type::NOT_PRIMARY);
+ EXPECT_EQ("Added id=3", observer.GetAndClearChanges());
+ ASSERT_EQ(2u, display_list.displays().size());
+ EXPECT_EQ(2, display_list.displays()[0].id());
+ EXPECT_EQ(3, display_list.displays()[1].id());
+ EXPECT_EQ(2, display_list.GetPrimaryDisplayIterator()->id());
+
+ // Make the second the primary.
+ display_list.UpdateDisplay(display_list.displays()[1],
+ DisplayList::Type::PRIMARY);
+ EXPECT_EQ("Changed id=3 primary", observer.GetAndClearChanges());
+ EXPECT_EQ(3, display_list.GetPrimaryDisplayIterator()->id());
+
+ // Delete the first.
+ display_list.RemoveDisplay(2);
+ ASSERT_EQ(1u, display_list.displays().size());
+ EXPECT_EQ("Removed id=2", observer.GetAndClearChanges());
+ EXPECT_EQ(3, display_list.GetPrimaryDisplayIterator()->id());
+}
+
+} // namespace
+} // namespace views
diff --git a/chromium/ui/views/mus/interactive_ui_tests_manifest.json b/chromium/ui/views/mus/interactive_ui_tests_manifest.json
new file mode 100644
index 00000000000..a0b81fcb72e
--- /dev/null
+++ b/chromium/ui/views/mus/interactive_ui_tests_manifest.json
@@ -0,0 +1,10 @@
+{
+ "manifest_version": 1,
+ "name": "mojo:views_mus_interactive_ui_tests",
+ "display_name": "Views Mus Interactive UI Tests",
+ "capabilities": {
+ "required": {
+ "*": { "classes": [ "app" ] }
+ }
+ }
+}
diff --git a/chromium/ui/views/mus/interactive_ui_tests_mus.cc b/chromium/ui/views/mus/interactive_ui_tests_mus.cc
new file mode 100644
index 00000000000..4181166def3
--- /dev/null
+++ b/chromium/ui/views/mus/interactive_ui_tests_mus.cc
@@ -0,0 +1,9 @@
+// Copyright 2016 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.
+
+#include "ui/views/mus/views_mus_test_suite.h"
+
+int MasterProcessMain(int argc, char** argv) {
+ return views::ViewsMusTestSuite(argc, argv).RunTestsSerially();
+}
diff --git a/chromium/ui/views/mus/native_widget_mus.cc b/chromium/ui/views/mus/native_widget_mus.cc
index 70dd986d2c6..46a3ede494c 100644
--- a/chromium/ui/views/mus/native_widget_mus.cc
+++ b/chromium/ui/views/mus/native_widget_mus.cc
@@ -4,13 +4,19 @@
#include "ui/views/mus/native_widget_mus.h"
+#include "base/callback.h"
#include "base/macros.h"
-#include "base/thread_task_runner_handle.h"
+#include "base/message_loop/message_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "components/mus/public/cpp/property_type_converters.h"
#include "components/mus/public/cpp/window.h"
#include "components/mus/public/cpp/window_observer.h"
#include "components/mus/public/cpp/window_property.h"
#include "components/mus/public/cpp/window_tree_connection.h"
+#include "components/mus/public/interfaces/cursor.mojom.h"
+#include "components/mus/public/interfaces/window_manager.mojom.h"
+#include "components/mus/public/interfaces/window_manager_constants.mojom.h"
+#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
#include "ui/aura/client/default_capture_client.h"
#include "ui/aura/client/window_tree_client.h"
@@ -20,8 +26,10 @@
#include "ui/aura/window.h"
#include "ui/aura/window_property.h"
#include "ui/base/hit_test.h"
+#include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/native_theme/native_theme_aura.h"
+#include "ui/platform_window/platform_window_delegate.h"
#include "ui/views/mus/platform_window_mus.h"
#include "ui/views/mus/surface_context_factory.h"
#include "ui/views/mus/window_manager_constants_converters.h"
@@ -32,11 +40,15 @@
#include "ui/views/window/custom_frame_view.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/capture_controller.h"
+#include "ui/wm/core/cursor_manager.h"
#include "ui/wm/core/default_screen_position_client.h"
#include "ui/wm/core/focus_controller.h"
+#include "ui/wm/core/native_cursor_manager.h"
DECLARE_WINDOW_PROPERTY_TYPE(mus::Window*);
+using mus::mojom::EventResult;
+
namespace views {
namespace {
@@ -44,17 +56,19 @@ DEFINE_WINDOW_PROPERTY_KEY(mus::Window*, kMusWindow, nullptr);
MUS_DEFINE_WINDOW_PROPERTY_KEY(NativeWidgetMus*, kNativeWidgetMusKey, nullptr);
-// TODO: figure out what this should be.
+// This ensures that only the top-level aura Window can be activated.
class FocusRulesImpl : public wm::BaseFocusRules {
public:
- FocusRulesImpl() {}
+ explicit FocusRulesImpl(aura::Window* root) : root_(root) {}
~FocusRulesImpl() override {}
bool SupportsChildActivation(aura::Window* window) const override {
- return true;
+ return root_ == window;
}
private:
+ aura::Window* root_;
+
DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl);
};
@@ -108,6 +122,88 @@ class NativeWidgetMusWindowTreeClient : public aura::client::WindowTreeClient {
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMusWindowTreeClient);
};
+// A screen position client that applies the offset of the mus::Window.
+class ScreenPositionClientMus : public wm::DefaultScreenPositionClient {
+ public:
+ explicit ScreenPositionClientMus(mus::Window* mus_window)
+ : mus_window_(mus_window) {}
+ ~ScreenPositionClientMus() override {}
+
+ // wm::DefaultScreenPositionClient:
+ void ConvertPointToScreen(const aura::Window* window,
+ gfx::Point* point) override {
+ wm::DefaultScreenPositionClient::ConvertPointToScreen(window, point);
+ gfx::Rect mus_bounds = mus_window_->GetBoundsInRoot();
+ point->Offset(-mus_bounds.x(), -mus_bounds.y());
+ }
+ void ConvertPointFromScreen(const aura::Window* window,
+ gfx::Point* point) override {
+ gfx::Rect mus_bounds = mus_window_->GetBoundsInRoot();
+ point->Offset(mus_bounds.x(), mus_bounds.y());
+ wm::DefaultScreenPositionClient::ConvertPointFromScreen(window, point);
+ }
+
+ private:
+ mus::Window* mus_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenPositionClientMus);
+};
+
+class NativeCursorManagerMus : public wm::NativeCursorManager {
+ public:
+ explicit NativeCursorManagerMus(mus::Window* mus_window)
+ : mus_window_(mus_window) {}
+ ~NativeCursorManagerMus() override {}
+
+ // wm::NativeCursorManager:
+ void SetDisplay(const display::Display& display,
+ wm::NativeCursorManagerDelegate* delegate) override {
+ // We ignore this entirely, as cursor are set on the client.
+ }
+
+ void SetCursor(gfx::NativeCursor cursor,
+ wm::NativeCursorManagerDelegate* delegate) override {
+ mus_window_->SetPredefinedCursor(mus::mojom::Cursor(cursor.native_type()));
+ delegate->CommitCursor(cursor);
+ }
+
+ void SetVisibility(bool visible,
+ wm::NativeCursorManagerDelegate* delegate) override {
+ delegate->CommitVisibility(visible);
+
+ if (visible)
+ SetCursor(delegate->GetCursor(), delegate);
+ else
+ mus_window_->SetPredefinedCursor(mus::mojom::Cursor::NONE);
+ }
+
+ void SetCursorSet(ui::CursorSetType cursor_set,
+ wm::NativeCursorManagerDelegate* delegate) override {
+ // TODO(erg): For now, ignore the difference between SET_NORMAL and
+ // SET_LARGE here. This feels like a thing that mus should decide instead.
+ //
+ // Also, it's NOTIMPLEMENTED() in the desktop version!? Including not
+ // acknowledging the call in the delegate.
+ NOTIMPLEMENTED();
+ }
+
+ void SetMouseEventsEnabled(
+ bool enabled,
+ wm::NativeCursorManagerDelegate* delegate) override {
+ // TODO(erg): How do we actually implement this?
+ //
+ // Mouse event dispatch is potentially done in a different process,
+ // definitely in a different mojo service. Each app is fairly locked down.
+ delegate->CommitMouseEventsEnabled(enabled);
+ NOTIMPLEMENTED();
+ }
+
+ private:
+ mus::Window* mus_window_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeCursorManagerMus);
+};
+
// As the window manager renderers the non-client decorations this class does
// very little but honor the client area insets from the window manager.
class ClientSideNonClientFrameView : public NonClientFrameView {
@@ -146,15 +242,15 @@ class ClientSideNonClientFrameView : public NonClientFrameView {
void ResetWindowControls() override {
// TODO(sky): push to wm?
}
- void UpdateWindowIcon() override {
- // NOTIMPLEMENTED();
- }
- void UpdateWindowTitle() override {
- // NOTIMPLEMENTED();
- }
- void SizeConstraintsChanged() override {
- // NOTIMPLEMENTED();
- }
+
+ // These have no implementation. The Window Manager handles the actual
+ // rendering of the icon/title. See NonClientFrameViewMash. The values
+ // associated with these methods are pushed to the server by the way of
+ // NativeWidgetMus functions.
+ void UpdateWindowIcon() override {}
+ void UpdateWindowTitle() override {}
+ void SizeConstraintsChanged() override {}
+
gfx::Size GetPreferredSize() const override {
return widget_->non_client_view()
->GetWindowBoundsForClientBounds(
@@ -207,19 +303,60 @@ SkBitmap AppIconFromDelegate(WidgetDelegate* delegate) {
return app_icon.GetRepresentation(1.f).sk_bitmap();
}
+// Handles acknowledgement of an input event, either immediately when a nested
+// message loop starts, or upon destruction.
+class EventAckHandler : public base::MessageLoop::NestingObserver {
+ public:
+ explicit EventAckHandler(
+ std::unique_ptr<base::Callback<void(EventResult)>> ack_callback)
+ : ack_callback_(std::move(ack_callback)) {
+ DCHECK(ack_callback_);
+ base::MessageLoop::current()->AddNestingObserver(this);
+ }
+
+ ~EventAckHandler() override {
+ base::MessageLoop::current()->RemoveNestingObserver(this);
+ if (ack_callback_) {
+ ack_callback_->Run(handled_ ? EventResult::HANDLED
+ : EventResult::UNHANDLED);
+ }
+ }
+
+ void set_handled(bool handled) { handled_ = handled; }
+
+ // base::MessageLoop::NestingObserver:
+ void OnBeginNestedMessageLoop() override {
+ // Acknowledge the event immediately if a nested message loop starts.
+ // Otherwise we appear unresponsive for the life of the nested message loop.
+ if (ack_callback_) {
+ ack_callback_->Run(EventResult::HANDLED);
+ ack_callback_.reset();
+ }
+ }
+
+ private:
+ std::unique_ptr<base::Callback<void(EventResult)>> ack_callback_;
+ bool handled_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(EventAckHandler);
+};
+
} // namespace
class NativeWidgetMus::MusWindowObserver : public mus::WindowObserver {
public:
explicit MusWindowObserver(NativeWidgetMus* native_widget_mus)
- : native_widget_mus_(native_widget_mus) {
- native_widget_mus_->window_->AddObserver(this);
+ : native_widget_mus_(native_widget_mus),
+ show_state_(mus::mojom::ShowState::DEFAULT) {
+ mus_window()->AddObserver(this);
}
~MusWindowObserver() override {
- native_widget_mus_->window_->RemoveObserver(this);
+ mus_window()->RemoveObserver(this);
}
+ mus::mojom::ShowState show_state() { return show_state_; }
+
// mus::WindowObserver:
void OnWindowVisibilityChanging(mus::Window* window) override {
native_widget_mus_->OnMusWindowVisibilityChanging(window);
@@ -227,9 +364,76 @@ class NativeWidgetMus::MusWindowObserver : public mus::WindowObserver {
void OnWindowVisibilityChanged(mus::Window* window) override {
native_widget_mus_->OnMusWindowVisibilityChanged(window);
}
+ void OnWindowBoundsChanged(mus::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) override {
+ platform_window_delegate()->OnBoundsChanged(new_bounds);
+ }
+ void OnWindowPredefinedCursorChanged(mus::Window* window,
+ mus::mojom::Cursor cursor) override {
+ DCHECK_EQ(window, mus_window());
+ native_widget_mus_->set_last_cursor(cursor);
+ }
+ void OnWindowSharedPropertyChanged(
+ mus::Window* window,
+ const std::string& name,
+ const std::vector<uint8_t>* old_data,
+ const std::vector<uint8_t>* new_data) override {
+ if (name != mus::mojom::WindowManager::kShowState_Property)
+ return;
+ mus::mojom::ShowState show_state =
+ static_cast<mus::mojom::ShowState>(window->GetSharedProperty<int32_t>(
+ mus::mojom::WindowManager::kShowState_Property));
+ if (show_state == show_state_)
+ return;
+ show_state_ = show_state;
+ ui::PlatformWindowState state = ui::PLATFORM_WINDOW_STATE_UNKNOWN;
+ switch (show_state_) {
+ case mus::mojom::ShowState::MINIMIZED:
+ state = ui::PLATFORM_WINDOW_STATE_MINIMIZED;
+ break;
+ case mus::mojom::ShowState::MAXIMIZED:
+ state = ui::PLATFORM_WINDOW_STATE_MAXIMIZED;
+ break;
+ case mus::mojom::ShowState::DEFAULT:
+ case mus::mojom::ShowState::INACTIVE:
+ case mus::mojom::ShowState::NORMAL:
+ case mus::mojom::ShowState::DOCKED:
+ // TODO(sky): support docked.
+ state = ui::PLATFORM_WINDOW_STATE_NORMAL;
+ break;
+ case mus::mojom::ShowState::FULLSCREEN:
+ state = ui::PLATFORM_WINDOW_STATE_FULLSCREEN;
+ break;
+ }
+ platform_window_delegate()->OnWindowStateChanged(state);
+ }
+ void OnWindowDestroyed(mus::Window* window) override {
+ DCHECK_EQ(mus_window(), window);
+ platform_window_delegate()->OnClosed();
+ }
+ void OnWindowFocusChanged(mus::Window* gained_focus,
+ mus::Window* lost_focus) override {
+ if (gained_focus == mus_window())
+ platform_window_delegate()->OnActivationChanged(true);
+ else if (lost_focus == mus_window())
+ platform_window_delegate()->OnActivationChanged(false);
+ }
+ void OnRequestClose(mus::Window* window) override {
+ platform_window_delegate()->OnCloseRequest();
+ }
private:
+ mus::Window* mus_window() { return native_widget_mus_->window(); }
+ WindowTreeHostMus* window_tree_host() {
+ return native_widget_mus_->window_tree_host();
+ }
+ ui::PlatformWindowDelegate* platform_window_delegate() {
+ return native_widget_mus_->window_tree_host();
+ }
+
NativeWidgetMus* native_widget_mus_;
+ mus::mojom::ShowState show_state_;
DISALLOW_COPY_AND_ASSIGN(MusWindowObserver);
};
@@ -238,16 +442,18 @@ class NativeWidgetMus::MusWindowObserver : public mus::WindowObserver {
// NativeWidgetMus, public:
NativeWidgetMus::NativeWidgetMus(internal::NativeWidgetDelegate* delegate,
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::Window* window,
mus::mojom::SurfaceType surface_type)
: window_(window),
+ last_cursor_(mus::mojom::Cursor::CURSOR_NULL),
native_widget_delegate_(delegate),
surface_type_(surface_type),
- show_state_before_fullscreen_(ui::PLATFORM_WINDOW_STATE_UNKNOWN),
+ show_state_before_fullscreen_(mus::mojom::ShowState::DEFAULT),
ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET),
content_(new aura::Window(this)),
close_widget_factory_(this) {
+ window_->set_input_event_handler(this);
mus_window_observer_.reset(new MusWindowObserver(this));
// TODO(fsamuel): Figure out lifetime of |window_|.
@@ -262,7 +468,7 @@ NativeWidgetMus::NativeWidgetMus(internal::NativeWidgetDelegate* delegate,
// For Chrome, we need the GpuProcessTransportFactory so that renderer and
// browser pixels are composited into a single backing
// SoftwareOutputDeviceMus.
- if (!default_context_factory) {
+ if (!default_context_factory && connector) {
context_factory_.reset(
new SurfaceContextFactory(connector, window_, surface_type_));
aura::Env::GetInstance()->set_context_factory(context_factory_.get());
@@ -272,10 +478,14 @@ NativeWidgetMus::NativeWidgetMus(internal::NativeWidgetDelegate* delegate,
}
NativeWidgetMus::~NativeWidgetMus() {
- if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET)
+ if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) {
+ DCHECK(!window_);
delete native_widget_delegate_;
- else
+ } else {
+ if (window_)
+ window_->set_input_event_handler(nullptr);
CloseNow();
+ }
}
// static
@@ -292,6 +502,17 @@ void NativeWidgetMus::NotifyFrameChanged(
}
}
+// static
+Widget* NativeWidgetMus::GetWidgetForWindow(mus::Window* window) {
+ if (!window)
+ return nullptr;
+ NativeWidgetMus* native_widget =
+ window->GetLocalProperty(kNativeWidgetMusKey);
+ if (!native_widget)
+ return nullptr;
+ return native_widget->GetWidget();
+}
+
aura::Window* NativeWidgetMus::GetRootWindow() {
return window_tree_host_->window();
}
@@ -305,6 +526,8 @@ void NativeWidgetMus::OnPlatformWindowClosed() {
window_tree_host_->RemoveObserver(this);
window_tree_host_.reset();
+ cursor_manager_.reset(); // Uses |window_|.
+
mus_window_observer_.reset(nullptr);
window_ = nullptr;
@@ -348,10 +571,18 @@ void NativeWidgetMus::UpdateClientArea() {
void NativeWidgetMus::ConfigurePropertiesForNewWindow(
const Widget::InitParams& init_params,
std::map<std::string, std::vector<uint8_t>>* properties) {
+ properties->insert(init_params.mus_properties.begin(),
+ init_params.mus_properties.end());
if (!init_params.bounds.IsEmpty()) {
(*properties)[mus::mojom::WindowManager::kUserSetBounds_Property] =
mojo::ConvertTo<std::vector<uint8_t>>(init_params.bounds);
}
+ if (!init_params.name.empty()) {
+ (*properties)[mus::mojom::WindowManager::kName_Property] =
+ mojo::ConvertTo<std::vector<uint8_t>>(init_params.name);
+ }
+ (*properties)[mus::mojom::WindowManager::kAlwaysOnTop_Property] =
+ mojo::ConvertTo<std::vector<uint8_t>>(init_params.keep_on_top);
if (!Widget::RequiresNonClientView(init_params.type))
return;
@@ -387,16 +618,27 @@ void NativeWidgetMus::InitNativeWidget(const Widget::InitParams& params) {
window_tree_host_->InitHost();
window_tree_host_->window()->SetProperty(kMusWindow, window_);
- focus_client_.reset(new wm::FocusController(new FocusRulesImpl));
+ focus_client_.reset(
+ new wm::FocusController(new FocusRulesImpl(window_tree_host_->window())));
aura::client::SetFocusClient(window_tree_host_->window(),
focus_client_.get());
aura::client::SetActivationClient(window_tree_host_->window(),
focus_client_.get());
- screen_position_client_.reset(new wm::DefaultScreenPositionClient());
+ screen_position_client_.reset(new ScreenPositionClientMus(window_));
aura::client::SetScreenPositionClient(window_tree_host_->window(),
screen_position_client_.get());
+ // TODO(erg): Remove this check when mash/wm/frame/move_event_handler.cc's
+ // direct usage of mus::Window::SetPredefinedCursor() is switched to a
+ // private method on WindowManagerClient.
+ if (surface_type_ == mus::mojom::SurfaceType::DEFAULT) {
+ cursor_manager_.reset(new wm::CursorManager(
+ base::WrapUnique(new NativeCursorManagerMus(window_))));
+ aura::client::SetCursorClient(window_tree_host_->window(),
+ cursor_manager_.get());
+ }
+
window_tree_client_.reset(
new NativeWidgetMusWindowTreeClient(window_tree_host_->window()));
window_tree_host_->window()->AddPreTargetHandler(focus_client_.get());
@@ -421,6 +663,9 @@ void NativeWidgetMus::InitNativeWidget(const Widget::InitParams& params) {
parent_mus->AddTransientWindow(window_);
}
+ if (params.parent_mus)
+ params.parent_mus->AddChild(window_);
+
// TODO(sky): deal with show state.
if (!params.bounds.size().IsEmpty())
SetBounds(params.bounds);
@@ -600,8 +845,12 @@ gfx::Rect NativeWidgetMus::GetRestoredBounds() const {
return GetWindowBoundsInScreen();
}
+std::string NativeWidgetMus::GetWorkspace() const {
+ return std::string();
+}
+
void NativeWidgetMus::SetBounds(const gfx::Rect& bounds) {
- if (!window_tree_host_)
+ if (!(window_ && window_tree_host_))
return;
gfx::Size size(bounds.size());
@@ -611,6 +860,7 @@ void NativeWidgetMus::SetBounds(const gfx::Rect& bounds) {
size.SetToMin(max_size);
size.SetToMax(min_size);
window_tree_host_->SetBounds(gfx::Rect(bounds.origin(), size));
+ window_->SetBounds(gfx::Rect(bounds.origin(), size));
}
void NativeWidgetMus::SetSize(const gfx::Size& size) {
@@ -657,10 +907,11 @@ void NativeWidgetMus::Show() {
}
void NativeWidgetMus::Hide() {
- if (!window_tree_host_)
+ if (!(window_ && window_tree_host_))
return;
window_tree_host_->Hide();
+ window_->SetVisible(false);
GetNativeWindow()->Hide();
}
@@ -670,14 +921,17 @@ void NativeWidgetMus::ShowMaximizedWithBounds(
}
void NativeWidgetMus::ShowWithWindowState(ui::WindowShowState state) {
- if (!window_tree_host_)
+ if (!(window_ && window_tree_host_))
return;
window_tree_host_->Show();
+ window_->SetVisible(true);
GetNativeWindow()->Show();
- if (state != ui::SHOW_STATE_INACTIVE)
- Activate();
- GetWidget()->SetInitialFocus(state);
+ if (native_widget_delegate_->CanActivate()) {
+ if (state != ui::SHOW_STATE_INACTIVE)
+ Activate();
+ GetWidget()->SetInitialFocus(state);
+ }
}
bool NativeWidgetMus::IsVisible() const {
@@ -686,8 +940,10 @@ bool NativeWidgetMus::IsVisible() const {
}
void NativeWidgetMus::Activate() {
- if (window_tree_host_)
- window_tree_host_->platform_window()->Activate();
+ if (window_)
+ window_->SetFocus();
+ static_cast<aura::client::ActivationClient*>(focus_client_.get())
+ ->ActivateWindow(content_);
}
void NativeWidgetMus::Deactivate() {
@@ -702,60 +958,65 @@ bool NativeWidgetMus::IsActive() const {
}
void NativeWidgetMus::SetAlwaysOnTop(bool always_on_top) {
- // NOTIMPLEMENTED();
+ if (window_) {
+ window_->SetSharedProperty<bool>(
+ mus::mojom::WindowManager::kAlwaysOnTop_Property, always_on_top);
+ }
}
bool NativeWidgetMus::IsAlwaysOnTop() const {
- // NOTIMPLEMENTED();
- return false;
+ return window_ &&
+ window_->HasSharedProperty(
+ mus::mojom::WindowManager::kAlwaysOnTop_Property) &&
+ window_->GetSharedProperty<bool>(
+ mus::mojom::WindowManager::kAlwaysOnTop_Property);
}
void NativeWidgetMus::SetVisibleOnAllWorkspaces(bool always_visible) {
- // NOTIMPLEMENTED();
+ // Not needed for chromeos.
}
void NativeWidgetMus::Maximize() {
- if (window_tree_host_)
- window_tree_host_->platform_window()->Maximize();
+ SetShowState(mus::mojom::ShowState::MAXIMIZED);
}
void NativeWidgetMus::Minimize() {
- if (window_tree_host_)
- window_tree_host_->platform_window()->Minimize();
+ SetShowState(mus::mojom::ShowState::MINIMIZED);
}
bool NativeWidgetMus::IsMaximized() const {
- return window_tree_host_ &&
- window_tree_host_->show_state() == ui::PLATFORM_WINDOW_STATE_MAXIMIZED;
+ return mus_window_observer_ &&
+ mus_window_observer_->show_state() == mus::mojom::ShowState::MAXIMIZED;
}
bool NativeWidgetMus::IsMinimized() const {
- return window_tree_host_ &&
- window_tree_host_->show_state() == ui::PLATFORM_WINDOW_STATE_MINIMIZED;
+ return mus_window_observer_ &&
+ mus_window_observer_->show_state() == mus::mojom::ShowState::MINIMIZED;
}
void NativeWidgetMus::Restore() {
- if (window_tree_host_)
- window_tree_host_->platform_window()->Restore();
+ SetShowState(mus::mojom::ShowState::NORMAL);
}
void NativeWidgetMus::SetFullscreen(bool fullscreen) {
if (!window_tree_host_ || IsFullscreen() == fullscreen)
return;
if (fullscreen) {
- show_state_before_fullscreen_ = window_tree_host_->show_state();
+ show_state_before_fullscreen_ = mus_window_observer_->show_state();
window_tree_host_->platform_window()->ToggleFullscreen();
} else {
switch (show_state_before_fullscreen_) {
- case ui::PLATFORM_WINDOW_STATE_MAXIMIZED:
+ case mus::mojom::ShowState::MAXIMIZED:
Maximize();
break;
- case ui::PLATFORM_WINDOW_STATE_MINIMIZED:
+ case mus::mojom::ShowState::MINIMIZED:
Minimize();
break;
- case ui::PLATFORM_WINDOW_STATE_UNKNOWN:
- case ui::PLATFORM_WINDOW_STATE_NORMAL:
- case ui::PLATFORM_WINDOW_STATE_FULLSCREEN:
+ case mus::mojom::ShowState::DEFAULT:
+ case mus::mojom::ShowState::NORMAL:
+ case mus::mojom::ShowState::INACTIVE:
+ case mus::mojom::ShowState::FULLSCREEN:
+ case mus::mojom::ShowState::DOCKED:
// TODO(sad): This may not be sufficient.
Restore();
break;
@@ -764,9 +1025,8 @@ void NativeWidgetMus::SetFullscreen(bool fullscreen) {
}
bool NativeWidgetMus::IsFullscreen() const {
- return window_tree_host_ &&
- window_tree_host_->show_state() ==
- ui::PLATFORM_WINDOW_STATE_FULLSCREEN;
+ return mus_window_observer_ &&
+ mus_window_observer_->show_state() == mus::mojom::ShowState::FULLSCREEN;
}
void NativeWidgetMus::SetOpacity(unsigned char opacity) {
@@ -793,16 +1053,18 @@ void NativeWidgetMus::SchedulePaintInRect(const gfx::Rect& rect) {
}
void NativeWidgetMus::SetCursor(gfx::NativeCursor cursor) {
- if (!window_tree_host_)
+ if (!window_)
return;
+
// TODO(erg): In aura, our incoming cursor is really two
// parts. cursor.native_type() is an integer for standard cursors and is all
// we support right now. If native_type() == kCursorCustom, than we should
// also send an image, but as the cursor code is currently written, the image
// is in a platform native format that's already uploaded to the window
// server.
- window_tree_host_->platform_window()->SetCursorById(
- mus::mojom::Cursor(cursor.native_type()));
+ mus::mojom::Cursor new_cursor = mus::mojom::Cursor(cursor.native_type());
+ if (last_cursor_ != new_cursor)
+ window_->SetPredefinedCursor(new_cursor);
}
bool NativeWidgetMus::IsMouseEventsEnabled() const {
@@ -817,6 +1079,10 @@ void NativeWidgetMus::ClearNativeFocus() {
window_ ? window_->connection()->GetFocusedWindow() : nullptr;
if (focused && window_->Contains(focused) && focused != window_)
window_->SetFocus();
+ // Move aura-focus back to |content_|, so that the Widget still receives
+ // events correctly.
+ aura::client::GetFocusClient(content_)->ResetFocusWithinActiveWindow(
+ content_);
}
gfx::Rect NativeWidgetMus::GetWorkAreaBoundsInScreen() const {
@@ -876,6 +1142,10 @@ void NativeWidgetMus::RepostNativeEvent(gfx::NativeEvent native_event) {
// NOTIMPLEMENTED();
}
+std::string NativeWidgetMus::GetName() const {
+ return window_->GetName();
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetMus, aura::WindowDelegate implementation:
@@ -951,6 +1221,14 @@ void NativeWidgetMus::GetHitTestMask(gfx::Path* mask) const {
native_widget_delegate_->GetHitTestMask(mask);
}
+void NativeWidgetMus::SetShowState(mus::mojom::ShowState show_state) {
+ if (!window_)
+ return;
+ window_->SetSharedProperty<int32_t>(
+ mus::mojom::WindowManager::kShowState_Property,
+ static_cast<int32_t>(show_state));
+}
+
void NativeWidgetMus::OnKeyEvent(ui::KeyEvent* event) {
if (event->is_char()) {
// If a ui::InputMethod object is attached to the root window, character
@@ -998,11 +1276,34 @@ void NativeWidgetMus::OnHostCloseRequested(const aura::WindowTreeHost* host) {
GetWidget()->Close();
}
+void NativeWidgetMus::OnWindowInputEvent(
+ mus::Window* view,
+ const ui::Event& event_in,
+ std::unique_ptr<base::Callback<void(EventResult)>>* ack_callback) {
+ // Take ownership of the callback, indicating that we will handle it.
+ EventAckHandler ack_handler(std::move(*ack_callback));
+
+ std::unique_ptr<ui::Event> event = ui::Event::Clone(event_in);
+ // TODO(markdittmer): This should be this->OnEvent(event.get()), but that
+ // can't happen until IME is refactored out of in WindowTreeHostMus.
+ platform_window_delegate()->DispatchEvent(event.get());
+ // NOTE: |this| may be deleted.
+
+ ack_handler.set_handled(event->handled());
+ // |ack_handler| acks the event on destruction if necessary.
+}
+
void NativeWidgetMus::OnMusWindowVisibilityChanging(mus::Window* window) {
- native_widget_delegate_->OnNativeWidgetVisibilityChanging(!window->visible());
+ if (window == window_) {
+ native_widget_delegate_->OnNativeWidgetVisibilityChanging(
+ !window->visible());
+ }
}
void NativeWidgetMus::OnMusWindowVisibilityChanged(mus::Window* window) {
+ if (window != window_)
+ return;
+
if (window->visible()) {
window_tree_host_->Show();
GetNativeWindow()->Show();
diff --git a/chromium/ui/views/mus/native_widget_mus.h b/chromium/ui/views/mus/native_widget_mus.h
index 3419c064e05..7532719db35 100644
--- a/chromium/ui/views/mus/native_widget_mus.h
+++ b/chromium/ui/views/mus/native_widget_mus.h
@@ -8,16 +8,19 @@
#include <stdint.h>
#include <map>
+#include <memory>
#include <string>
+#include "base/callback.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "components/mus/public/cpp/input_event_handler.h"
#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/views/mus/mus_export.h"
+#include "ui/views/mus/window_tree_host_mus.h"
#include "ui/views/widget/native_widget_private.h"
namespace aura {
@@ -29,23 +32,31 @@ class WindowTreeClient;
class Window;
}
-namespace mojo {
-class Connector;
-}
-
namespace mus {
class Window;
class WindowTreeConnection;
+namespace mojom {
+enum class Cursor;
+enum class EventResult;
+}
+}
+
+namespace shell {
+class Connector;
+}
+
+namespace ui {
+class Event;
}
namespace wm {
+class CursorManager;
class FocusController;
}
namespace views {
class SurfaceContextFactory;
class WidgetDelegate;
-class WindowTreeHostMus;
// An implementation of NativeWidget that binds to a mus::Window. Because Aura
// is used extensively within Views code, this code uses aura and binds to the
@@ -53,12 +64,14 @@ class WindowTreeHostMus;
// aura::Window in a hierarchy is created without a delegate by the
// aura::WindowTreeHost, we must create a child aura::Window in this class
// (content_) and attach it to the root.
-class VIEWS_MUS_EXPORT NativeWidgetMus : public internal::NativeWidgetPrivate,
- public aura::WindowDelegate,
- public aura::WindowTreeHostObserver {
+class VIEWS_MUS_EXPORT NativeWidgetMus
+ : public internal::NativeWidgetPrivate,
+ public aura::WindowDelegate,
+ public aura::WindowTreeHostObserver,
+ public NON_EXPORTED_BASE(mus::InputEventHandler) {
public:
NativeWidgetMus(internal::NativeWidgetDelegate* delegate,
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::Window* window,
mus::mojom::SurfaceType surface_type);
~NativeWidgetMus() override;
@@ -72,7 +85,11 @@ class VIEWS_MUS_EXPORT NativeWidgetMus : public internal::NativeWidgetPrivate,
// Notifies all widgets the frame constants changed in some way.
static void NotifyFrameChanged(mus::WindowTreeConnection* connection);
+ // Returns the widget for a mus::Window, or null if there is none.
+ static Widget* GetWidgetForWindow(mus::Window* window);
+
mus::Window* window() { return window_; }
+ WindowTreeHostMus* window_tree_host() { return window_tree_host_.get(); }
aura::Window* GetRootWindow();
@@ -116,6 +133,7 @@ class VIEWS_MUS_EXPORT NativeWidgetMus : public internal::NativeWidgetPrivate,
gfx::Rect GetWindowBoundsInScreen() const override;
gfx::Rect GetClientAreaBoundsInScreen() const override;
gfx::Rect GetRestoredBounds() const override;
+ std::string GetWorkspace() const override;
void SetBounds(const gfx::Rect& bounds) override;
void SetSize(const gfx::Size& size) override;
void StackAbove(gfx::NativeView native_view) override;
@@ -168,6 +186,7 @@ class VIEWS_MUS_EXPORT NativeWidgetMus : public internal::NativeWidgetPrivate,
bool IsTranslucentWindowOpacitySupported() const override;
void OnSizeConstraintsChanged() override;
void RepostNativeEvent(gfx::NativeEvent native_event) override;
+ std::string GetName() const override;
// Overridden from aura::WindowDelegate:
gfx::Size GetMinimumSize() const override;
@@ -198,34 +217,51 @@ class VIEWS_MUS_EXPORT NativeWidgetMus : public internal::NativeWidgetPrivate,
// Overridden from aura::WindowTreeHostObserver:
void OnHostCloseRequested(const aura::WindowTreeHost* host) override;
- private:
+ // Overridden from mus::InputEventHandler:
+ void OnWindowInputEvent(
+ mus::Window* view,
+ const ui::Event& event,
+ std::unique_ptr<base::Callback<void(mus::mojom::EventResult)>>*
+ ack_callback) override;
+
+private:
+ friend class NativeWidgetMusTest;
class MusWindowObserver;
+ ui::PlatformWindowDelegate* platform_window_delegate() {
+ return window_tree_host();
+ }
+
+ void set_last_cursor(mus::mojom::Cursor cursor) { last_cursor_ = cursor; }
+ void SetShowState(mus::mojom::ShowState show_state);
+
void OnMusWindowVisibilityChanging(mus::Window* window);
void OnMusWindowVisibilityChanged(mus::Window* window);
mus::Window* window_;
+ mus::mojom::Cursor last_cursor_;
internal::NativeWidgetDelegate* native_widget_delegate_;
const mus::mojom::SurfaceType surface_type_;
- ui::PlatformWindowState show_state_before_fullscreen_;
+ mus::mojom::ShowState show_state_before_fullscreen_;
// See class documentation for Widget in widget.h for a note about ownership.
Widget::InitParams::Ownership ownership_;
// Functions with the same name require the mus::WindowObserver to be in
// a separate class.
- scoped_ptr<MusWindowObserver> mus_window_observer_;
+ std::unique_ptr<MusWindowObserver> mus_window_observer_;
// Aura configuration.
- scoped_ptr<SurfaceContextFactory> context_factory_;
- scoped_ptr<WindowTreeHostMus> window_tree_host_;
+ std::unique_ptr<SurfaceContextFactory> context_factory_;
+ std::unique_ptr<WindowTreeHostMus> window_tree_host_;
aura::Window* content_;
- scoped_ptr<wm::FocusController> focus_client_;
- scoped_ptr<aura::client::DefaultCaptureClient> capture_client_;
- scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
- scoped_ptr<aura::client::ScreenPositionClient> screen_position_client_;
+ std::unique_ptr<wm::FocusController> focus_client_;
+ std::unique_ptr<aura::client::DefaultCaptureClient> capture_client_;
+ std::unique_ptr<aura::client::WindowTreeClient> window_tree_client_;
+ std::unique_ptr<aura::client::ScreenPositionClient> screen_position_client_;
+ std::unique_ptr<wm::CursorManager> cursor_manager_;
base::WeakPtrFactory<NativeWidgetMus> close_widget_factory_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMus);
diff --git a/chromium/ui/views/mus/native_widget_mus_unittest.cc b/chromium/ui/views/mus/native_widget_mus_unittest.cc
index 78155814861..e4b7fb34c63 100644
--- a/chromium/ui/views/mus/native_widget_mus_unittest.cc
+++ b/chromium/ui/views/mus/native_widget_mus_unittest.cc
@@ -4,27 +4,68 @@
#include "ui/views/mus/native_widget_mus.h"
+#include "base/callback.h"
#include "base/macros.h"
#include "components/mus/public/cpp/property_type_converters.h"
+#include "components/mus/public/cpp/tests/window_tree_client_impl_private.h"
#include "components/mus/public/cpp/window.h"
#include "components/mus/public/cpp/window_property.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
#include "components/mus/public/interfaces/window_manager.mojom.h"
+#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/window.h"
+#include "ui/events/event.h"
+#include "ui/events/test/test_event_handler.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/skia_util.h"
+#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/test/focus_manager_test.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/widget/widget_observer.h"
+#include "ui/wm/public/activation_client.h"
+
+using mus::mojom::EventResult;
namespace views {
namespace {
+// A view that reports any mouse press as handled.
+class HandleMousePressView : public View {
+ public:
+ HandleMousePressView() {}
+ ~HandleMousePressView() override {}
+
+ // View:
+ bool OnMousePressed(const ui::MouseEvent& event) override { return true; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HandleMousePressView);
+};
+
+// A view that deletes a widget on mouse press.
+class DeleteWidgetView : public View {
+ public:
+ explicit DeleteWidgetView(std::unique_ptr<Widget>* widget_ptr)
+ : widget_ptr_(widget_ptr) {}
+ ~DeleteWidgetView() override {}
+
+ // View:
+ bool OnMousePressed(const ui::MouseEvent& event) override {
+ widget_ptr_->reset();
+ return true;
+ }
+
+ private:
+ std::unique_ptr<Widget>* widget_ptr_;
+ DISALLOW_COPY_AND_ASSIGN(DeleteWidgetView);
+};
+
// Returns a small colored bitmap.
SkBitmap MakeBitmap(SkColor color) {
SkBitmap bitmap;
@@ -80,14 +121,16 @@ class TestWidgetDelegate : public WidgetDelegateView {
DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
};
+} // namespace
+
class NativeWidgetMusTest : public ViewsTestBase {
public:
NativeWidgetMusTest() {}
~NativeWidgetMusTest() override {}
// Creates a test widget. Takes ownership of |delegate|.
- scoped_ptr<Widget> CreateWidget(TestWidgetDelegate* delegate) {
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> CreateWidget(TestWidgetDelegate* delegate) {
+ std::unique_ptr<Widget> widget(new Widget());
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.delegate = delegate;
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -96,14 +139,42 @@ class NativeWidgetMusTest : public ViewsTestBase {
return widget;
}
+ int ack_callback_count() { return ack_callback_count_; }
+
+ void AckCallback(mus::mojom::EventResult result) {
+ ack_callback_count_++;
+ EXPECT_EQ(mus::mojom::EventResult::HANDLED, result);
+ }
+
+ // Returns a mouse pressed event inside the widget. Tests that place views
+ // within the widget that respond to the event must be constructed within the
+ // widget coordinate space such that they respond correctly.
+ std::unique_ptr<ui::MouseEvent> CreateMouseEvent() {
+ return base::WrapUnique(new ui::MouseEvent(
+ ui::ET_MOUSE_PRESSED, gfx::Point(50, 50), gfx::Point(50, 50),
+ base::TimeDelta(), ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
+ }
+
+ // Simulates an input event to the NativeWidget.
+ void OnWindowInputEvent(
+ NativeWidgetMus* native_widget,
+ const ui::Event& event,
+ std::unique_ptr<base::Callback<void(mus::mojom::EventResult)>>*
+ ack_callback) {
+ native_widget->OnWindowInputEvent(native_widget->window(), event,
+ ack_callback);
+ }
+
private:
+ int ack_callback_count_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMusTest);
};
// Tests communication of activation and focus between Widget and
// NativeWidgetMus.
TEST_F(NativeWidgetMusTest, OnActivationChanged) {
- scoped_ptr<Widget> widget(CreateWidget(nullptr));
+ std::unique_ptr<Widget> widget(CreateWidget(nullptr));
widget->Show();
// Track activation, focus and blur events.
@@ -132,11 +203,31 @@ TEST_F(NativeWidgetMusTest, OnActivationChanged) {
WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(&focus_listener);
}
+// Tests that showing a non-activatable widget does not activate it.
+// TODO(jamescook): Remove this test when widget_interactive_uittests.cc runs
+// under mus.
+TEST_F(NativeWidgetMusTest, ShowNonActivatableWidget) {
+ Widget widget;
+ WidgetActivationObserver activation_observer(&widget);
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_BUBBLE);
+ params.activatable = Widget::InitParams::ACTIVATABLE_NO;
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.bounds = gfx::Rect(10, 20, 100, 200);
+ widget.Init(params);
+ widget.Show();
+
+ // The widget is not currently active.
+ EXPECT_FALSE(widget.IsActive());
+
+ // The widget was never active.
+ EXPECT_EQ(0u, activation_observer.changes().size());
+}
+
// Tests that a window with an icon sets the mus::Window icon property.
TEST_F(NativeWidgetMusTest, AppIcon) {
// Create a Widget with a bitmap as the icon.
SkBitmap source_bitmap = MakeBitmap(SK_ColorRED);
- scoped_ptr<Widget> widget(
+ std::unique_ptr<Widget> widget(
CreateWidget(new TestWidgetDelegate(source_bitmap)));
// The mus::Window has the icon property.
@@ -155,7 +246,7 @@ TEST_F(NativeWidgetMusTest, AppIcon) {
// property.
TEST_F(NativeWidgetMusTest, NoAppIcon) {
// Create a Widget without a special icon.
- scoped_ptr<Widget> widget(CreateWidget(nullptr));
+ std::unique_ptr<Widget> widget(CreateWidget(nullptr));
// The mus::Window does not have an icon property.
mus::Window* window =
@@ -170,7 +261,7 @@ TEST_F(NativeWidgetMusTest, ChangeAppIcon) {
// Create a Widget with an icon.
SkBitmap bitmap1 = MakeBitmap(SK_ColorRED);
TestWidgetDelegate* delegate = new TestWidgetDelegate(bitmap1);
- scoped_ptr<Widget> widget(CreateWidget(delegate));
+ std::unique_ptr<Widget> widget(CreateWidget(delegate));
// Update the icon to a new image.
SkBitmap bitmap2 = MakeBitmap(SK_ColorGREEN);
@@ -186,12 +277,163 @@ TEST_F(NativeWidgetMusTest, ChangeAppIcon) {
}
TEST_F(NativeWidgetMusTest, ValidLayerTree) {
- scoped_ptr<Widget> widget(CreateWidget(nullptr));
+ std::unique_ptr<Widget> widget(CreateWidget(nullptr));
View* content = new View;
content->SetPaintToLayer(true);
widget->GetContentsView()->AddChildView(content);
EXPECT_TRUE(widget->GetNativeWindow()->layer()->Contains(content->layer()));
}
-} // namespace
+// Tests that the internal name is propagated from the Widget to the
+// mus::Window.
+TEST_F(NativeWidgetMusTest, GetName) {
+ Widget widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.name = "MyWidget";
+ widget.Init(params);
+ mus::Window* window =
+ static_cast<NativeWidgetMus*>(widget.native_widget_private())->window();
+ EXPECT_EQ("MyWidget", window->GetName());
+}
+
+// Verifies changing the visibility of a child mus::Window doesn't change the
+// visibility of the parent.
+TEST_F(NativeWidgetMusTest, ChildVisibilityDoesntEffectParent) {
+ Widget widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(params);
+ widget.Show();
+ mus::Window* window =
+ static_cast<NativeWidgetMus*>(widget.native_widget_private())->window();
+ ASSERT_TRUE(window->visible());
+
+ // Create a child window, make it visible and parent it to the Widget's
+ // window.
+ mus::Window* child_window = window->connection()->NewWindow();
+ child_window->SetVisible(true);
+ window->AddChild(child_window);
+
+ // Hide the child, this should not impact the visibility of the parent.
+ child_window->SetVisible(false);
+ EXPECT_TRUE(window->visible());
+}
+
+// Tests that child aura::Windows cannot be activated.
+TEST_F(NativeWidgetMusTest, FocusChildAuraWindow) {
+ Widget widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(params);
+
+ View* focusable = new View;
+ focusable->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ widget.GetContentsView()->AddChildView(focusable);
+
+ NativeViewHost* native_host = new NativeViewHost;
+ widget.GetContentsView()->AddChildView(native_host);
+
+ std::unique_ptr<aura::Window> window(new aura::Window(nullptr));
+ window->Init(ui::LayerType::LAYER_SOLID_COLOR);
+ native_host->SetBounds(5, 10, 20, 30);
+ native_host->Attach(window.get());
+ widget.Show();
+ window->Show();
+ widget.SetBounds(gfx::Rect(10, 20, 30, 40));
+
+ // Sanity check that the |window| is a descendent of the Widget's window.
+ ASSERT_TRUE(widget.GetNativeView()->Contains(window->parent()));
+
+ // Focusing the child window should not activate it.
+ window->Focus();
+ EXPECT_TRUE(window->HasFocus());
+ aura::Window* active_window =
+ aura::client::GetActivationClient(window.get()->GetRootWindow())
+ ->GetActiveWindow();
+ EXPECT_NE(window.get(), active_window);
+ EXPECT_EQ(widget.GetNativeView(), active_window);
+
+ // Moving focus to a child View should move focus away from |window|, and to
+ // the Widget's window instead.
+ focusable->RequestFocus();
+ EXPECT_FALSE(window->HasFocus());
+ EXPECT_TRUE(widget.GetNativeView()->HasFocus());
+ active_window =
+ aura::client::GetActivationClient(window.get()->GetRootWindow())
+ ->GetActiveWindow();
+ EXPECT_EQ(widget.GetNativeView(), active_window);
+}
+
+TEST_F(NativeWidgetMusTest, WidgetReceivesEvent) {
+ std::unique_ptr<Widget> widget(CreateWidget(nullptr));
+ widget->Show();
+
+ View* content = new HandleMousePressView;
+ content->SetBounds(10, 20, 90, 180);
+ widget->GetContentsView()->AddChildView(content);
+
+ ui::test::TestEventHandler handler;
+ content->AddPreTargetHandler(&handler);
+
+ std::unique_ptr<ui::MouseEvent> mouse = CreateMouseEvent();
+ NativeWidgetMus* native_widget =
+ static_cast<NativeWidgetMus*>(widget->native_widget_private());
+ mus::WindowTreeClientImplPrivate test_api(native_widget->window());
+ test_api.CallOnWindowInputEvent(native_widget->window(), *mouse);
+ EXPECT_EQ(1, handler.num_mouse_events());
+}
+
+// Tests that an incoming UI event is acked with the handled status.
+TEST_F(NativeWidgetMusTest, EventAcked) {
+ std::unique_ptr<Widget> widget(CreateWidget(nullptr));
+ widget->Show();
+
+ View* content = new HandleMousePressView;
+ content->SetBounds(10, 20, 90, 180);
+ widget->GetContentsView()->AddChildView(content);
+
+ // Dispatch an input event to the window and view.
+ std::unique_ptr<ui::MouseEvent> event = CreateMouseEvent();
+ std::unique_ptr<base::Callback<void(EventResult)>> ack_callback(
+ new base::Callback<void(EventResult)>(base::Bind(
+ &NativeWidgetMusTest::AckCallback, base::Unretained(this))));
+ OnWindowInputEvent(
+ static_cast<NativeWidgetMus*>(widget->native_widget_private()),
+ *event,
+ &ack_callback);
+
+ // The test took ownership of the callback and called it.
+ EXPECT_FALSE(ack_callback);
+ EXPECT_EQ(1, ack_callback_count());
+}
+
+// Tests that a window that is deleted during event handling properly acks the
+// event.
+TEST_F(NativeWidgetMusTest, EventAckedWithWindowDestruction) {
+ std::unique_ptr<Widget> widget(CreateWidget(nullptr));
+ widget->Show();
+
+ View* content = new DeleteWidgetView(&widget);
+ content->SetBounds(10, 20, 90, 180);
+ widget->GetContentsView()->AddChildView(content);
+
+ // Dispatch an input event to the window and view.
+ std::unique_ptr<ui::MouseEvent> event = CreateMouseEvent();
+ std::unique_ptr<base::Callback<void(EventResult)>> ack_callback(
+ new base::Callback<void(EventResult)>(base::Bind(
+ &NativeWidgetMusTest::AckCallback, base::Unretained(this))));
+ OnWindowInputEvent(
+ static_cast<NativeWidgetMus*>(widget->native_widget_private()),
+ *event,
+ &ack_callback);
+
+ // The widget was deleted.
+ EXPECT_FALSE(widget.get());
+
+ // The test took ownership of the callback and called it.
+ EXPECT_FALSE(ack_callback);
+ EXPECT_EQ(1, ack_callback_count());
+}
+
} // namespace views
diff --git a/chromium/ui/views/mus/platform_test_helper_mus.cc b/chromium/ui/views/mus/platform_test_helper_mus.cc
deleted file mode 100644
index 80e6a74a1ec..00000000000
--- a/chromium/ui/views/mus/platform_test_helper_mus.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2016 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.
-
-#include "ui/views/test/platform_test_helper.h"
-
-#include "base/command_line.h"
-#include "base/run_loop.h"
-#include "mojo/shell/background/background_shell.h"
-#include "mojo/shell/background/tests/test_catalog_store.h"
-#include "mojo/shell/public/cpp/connector.h"
-#include "mojo/shell/public/cpp/shell_client.h"
-#include "mojo/shell/public/cpp/shell_connection.h"
-#include "ui/aura/env.h"
-#include "ui/views/mus/window_manager_connection.h"
-#include "ui/views/views_delegate.h"
-
-using mojo::shell::BackgroundShell;
-
-namespace views {
-namespace {
-
-const char kTestName[] = "mojo:test-app";
-
-class DefaultShellClient : public mojo::ShellClient {
- public:
- DefaultShellClient() {}
- ~DefaultShellClient() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DefaultShellClient);
-};
-
-scoped_ptr<mojo::shell::TestCatalogStore> BuildTestCatalogStore() {
- scoped_ptr<base::ListValue> apps(new base::ListValue);
- apps->Append(
- mojo::shell::BuildPermissiveSerializedAppInfo(kTestName, "test"));
- return make_scoped_ptr(new mojo::shell::TestCatalogStore(std::move(apps)));
-}
-
-class PlatformTestHelperMus : public PlatformTestHelper {
- public:
- PlatformTestHelperMus() {
- background_shell_.reset(new BackgroundShell);
- scoped_ptr<BackgroundShell::InitParams> init_params(
- new BackgroundShell::InitParams);
- init_params->catalog_store = BuildTestCatalogStore();
- background_shell_->Init(std::move(init_params));
- shell_client_.reset(new DefaultShellClient);
- shell_connection_.reset(new mojo::ShellConnection(
- shell_client_.get(),
- background_shell_->CreateShellClientRequest(kTestName)));
-
- // TODO(rockot): Remove this RunLoop. http://crbug.com/594852.
- base::RunLoop wait_loop;
- shell_connection_->set_initialize_handler(wait_loop.QuitClosure());
- wait_loop.Run();
-
- // ui/views/mus requires a WindowManager running, for now use the desktop
- // one.
- mojo::Connector* connector = shell_connection_->connector();
- connector->Connect("mojo:desktop_wm");
- WindowManagerConnection::Create(connector);
-
- // On X we need to reset the ContextFactory before every NativeWidgetMus
- // is created.
- // TODO(sad): this is a hack, figure out a better solution.
- ViewsDelegate::GetInstance()->set_native_widget_factory(base::Bind(
- &PlatformTestHelperMus::CreateNativeWidgetMus, base::Unretained(this),
- std::map<std::string, std::vector<uint8_t>>()));
- }
-
- ~PlatformTestHelperMus() override {
- WindowManagerConnection::Reset();
- // |app_| has a reference to us, destroy it while we are still valid.
- shell_connection_.reset();
- }
-
- bool IsMus() const override { return true; }
-
- private:
- NativeWidget* CreateNativeWidgetMus(
- const std::map<std::string, std::vector<uint8_t>>& props,
- const Widget::InitParams& init_params,
- internal::NativeWidgetDelegate* delegate) {
- ui::ContextFactory* factory = aura::Env::GetInstance()->context_factory();
- aura::Env::GetInstance()->set_context_factory(nullptr);
- NativeWidget* result =
- WindowManagerConnection::Get()->CreateNativeWidgetMus(
- props, init_params, delegate);
- aura::Env::GetInstance()->set_context_factory(factory);
- return result;
- }
-
- scoped_ptr<BackgroundShell> background_shell_;
- scoped_ptr<mojo::ShellConnection> shell_connection_;
- scoped_ptr<DefaultShellClient> shell_client_;
-
- DISALLOW_COPY_AND_ASSIGN(PlatformTestHelperMus);
-};
-
-} // namespace
-
-// static
-scoped_ptr<PlatformTestHelper> PlatformTestHelper::Create() {
- return make_scoped_ptr(new PlatformTestHelperMus);
-}
-
-} // namespace views
diff --git a/chromium/ui/views/mus/platform_window_mus.cc b/chromium/ui/views/mus/platform_window_mus.cc
index d42a9a77908..d9dc54b0759 100644
--- a/chromium/ui/views/mus/platform_window_mus.cc
+++ b/chromium/ui/views/mus/platform_window_mus.cc
@@ -14,25 +14,24 @@
#include "ui/platform_window/platform_window_delegate.h"
#include "ui/views/mus/window_manager_connection.h"
+using mus::mojom::EventResult;
+
namespace views {
namespace {
+
static uint32_t accelerated_widget_count = 1;
} // namespace
PlatformWindowMus::PlatformWindowMus(ui::PlatformWindowDelegate* delegate,
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::Window* mus_window)
: delegate_(delegate),
mus_window_(mus_window),
- show_state_(mus::mojom::ShowState::RESTORED),
- last_cursor_(mus::mojom::Cursor::CURSOR_NULL),
mus_window_destroyed_(false) {
DCHECK(delegate_);
DCHECK(mus_window_);
- mus_window_->AddObserver(this);
- mus_window_->set_input_event_handler(this);
// We need accelerated widget numbers to be different for each
// window and fit in the smallest sizeof(AcceleratedWidget) uint32_t
@@ -47,52 +46,27 @@ PlatformWindowMus::PlatformWindowMus(ui::PlatformWindowDelegate* delegate,
delegate_->OnAcceleratedWidgetAvailable(
accelerated_widget, mus_window_->viewport_metrics().device_pixel_ratio);
- bitmap_uploader_.reset(new bitmap_uploader::BitmapUploader(mus_window_));
- bitmap_uploader_->Init(connector);
- prop_.reset(new ui::ViewProp(
- accelerated_widget, bitmap_uploader::kBitmapUploaderForAcceleratedWidget,
- bitmap_uploader_.get()));
-}
-
-PlatformWindowMus::~PlatformWindowMus() {
- if (!mus_window_)
- return;
- mus_window_->RemoveObserver(this);
- mus_window_->set_input_event_handler(nullptr);
- if (!mus_window_destroyed_)
- mus_window_->Destroy();
-}
-
-void PlatformWindowMus::Activate() {
- mus_window_->SetFocus();
-}
-
-void PlatformWindowMus::SetCursorById(mus::mojom::Cursor cursor) {
- if (last_cursor_ != cursor) {
- // The ui::PlatformWindow interface uses ui::PlatformCursor at this level,
- // instead of ui::Cursor. All of the cursor abstractions in ui right now are
- // sort of leaky; despite being nominally cross platform, they all drop down
- // to platform types almost immediately, which makes them unusable as
- // transport types.
- mus_window_->SetPredefinedCursor(cursor);
+ if (connector) {
+ bitmap_uploader_.reset(new bitmap_uploader::BitmapUploader(mus_window_));
+ bitmap_uploader_->Init(connector);
+ prop_.reset(
+ new ui::ViewProp(accelerated_widget,
+ bitmap_uploader::kBitmapUploaderForAcceleratedWidget,
+ bitmap_uploader_.get()));
}
}
-void PlatformWindowMus::Show() {
- mus_window_->SetVisible(true);
-}
+PlatformWindowMus::~PlatformWindowMus() {}
-void PlatformWindowMus::Hide() {
- mus_window_->SetVisible(false);
-}
+void PlatformWindowMus::Show() {}
+
+void PlatformWindowMus::Hide() {}
void PlatformWindowMus::Close() {
NOTIMPLEMENTED();
}
-void PlatformWindowMus::SetBounds(const gfx::Rect& bounds) {
- mus_window_->SetBounds(bounds);
-}
+void PlatformWindowMus::SetBounds(const gfx::Rect& bounds) {}
gfx::Rect PlatformWindowMus::GetBounds() {
return mus_window_->bounds();
@@ -114,17 +88,11 @@ void PlatformWindowMus::ToggleFullscreen() {
NOTIMPLEMENTED();
}
-void PlatformWindowMus::Maximize() {
- SetShowState(mus::mojom::ShowState::MAXIMIZED);
-}
+void PlatformWindowMus::Maximize() {}
-void PlatformWindowMus::Minimize() {
- SetShowState(mus::mojom::ShowState::MINIMIZED);
-}
+void PlatformWindowMus::Minimize() {}
-void PlatformWindowMus::Restore() {
- SetShowState(mus::mojom::ShowState::RESTORED);
-}
+void PlatformWindowMus::Restore() {}
void PlatformWindowMus::SetCursor(ui::PlatformCursor cursor) {
NOTIMPLEMENTED();
@@ -142,96 +110,4 @@ ui::PlatformImeController* PlatformWindowMus::GetPlatformImeController() {
return nullptr;
}
-void PlatformWindowMus::SetShowState(mus::mojom::ShowState show_state) {
- mus_window_->SetSharedProperty<int32_t>(
- mus::mojom::WindowManager::kShowState_Property,
- static_cast<int32_t>(show_state));
-}
-
-void PlatformWindowMus::OnWindowDestroyed(mus::Window* window) {
- DCHECK_EQ(mus_window_, window);
- mus_window_destroyed_ = true;
-#ifndef NDEBUG
- weak_factory_.reset(new base::WeakPtrFactory<PlatformWindowMus>(this));
- base::WeakPtr<PlatformWindowMus> weak_ptr = weak_factory_->GetWeakPtr();
-#endif
- delegate_->OnClosed();
- // |this| has been destroyed at this point.
-#ifndef NDEBUG
- DCHECK(!weak_ptr);
-#endif
-}
-
-void PlatformWindowMus::OnWindowBoundsChanged(mus::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) {
- delegate_->OnBoundsChanged(new_bounds);
-}
-
-void PlatformWindowMus::OnWindowFocusChanged(mus::Window* gained_focus,
- mus::Window* lost_focus) {
- if (gained_focus == mus_window_)
- delegate_->OnActivationChanged(true);
- else if (lost_focus == mus_window_)
- delegate_->OnActivationChanged(false);
-}
-
-void PlatformWindowMus::OnWindowPredefinedCursorChanged(
- mus::Window* window,
- mus::mojom::Cursor cursor) {
- DCHECK_EQ(window, mus_window_);
- last_cursor_ = cursor;
-}
-
-void PlatformWindowMus::OnWindowSharedPropertyChanged(
- mus::Window* window,
- const std::string& name,
- const std::vector<uint8_t>* old_data,
- const std::vector<uint8_t>* new_data) {
- if (name != mus::mojom::WindowManager::kShowState_Property)
- return;
- mus::mojom::ShowState show_state =
- static_cast<mus::mojom::ShowState>(window->GetSharedProperty<int32_t>(
- mus::mojom::WindowManager::kShowState_Property));
- if (show_state == show_state_)
- return;
- show_state_ = show_state;
- ui::PlatformWindowState state = ui::PLATFORM_WINDOW_STATE_UNKNOWN;
- switch (show_state_) {
- case mus::mojom::ShowState::MINIMIZED:
- state = ui::PLATFORM_WINDOW_STATE_MINIMIZED;
- break;
- case mus::mojom::ShowState::MAXIMIZED:
- state = ui::PLATFORM_WINDOW_STATE_MAXIMIZED;
- break;
- case mus::mojom::ShowState::RESTORED:
- state = ui::PLATFORM_WINDOW_STATE_NORMAL;
- break;
- case mus::mojom::ShowState::IMMERSIVE:
- case mus::mojom::ShowState::PRESENTATION:
- // This may not be sufficient.
- state = ui::PLATFORM_WINDOW_STATE_FULLSCREEN;
- break;
- }
- delegate_->OnWindowStateChanged(state);
-}
-
-void PlatformWindowMus::OnRequestClose(mus::Window* window) {
- delegate_->OnCloseRequest();
-}
-
-void PlatformWindowMus::OnWindowInputEvent(
- mus::Window* view,
- const ui::Event& event,
- scoped_ptr<base::Callback<void(bool)>>* ack_callback) {
- // It's possible dispatching the event will spin a nested message loop. Ack
- // the callback now, otherwise we appear unresponsive for the life of the
- // nested message loop.
- (*ack_callback)->Run(true);
- ack_callback->reset();
- // TODO(moshayedi): Avoid cloning after updating PlatformWindowDelegate to
- // accept constant pointers.
- delegate_->DispatchEvent(ui::Event::Clone(event).get());
-}
-
} // namespace views
diff --git a/chromium/ui/views/mus/platform_window_mus.h b/chromium/ui/views/mus/platform_window_mus.h
index ba206713f08..c17b9c80b04 100644
--- a/chromium/ui/views/mus/platform_window_mus.h
+++ b/chromium/ui/views/mus/platform_window_mus.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/macros.h"
-#include "components/mus/public/cpp/input_event_handler.h"
#include "components/mus/public/cpp/window_observer.h"
#include "ui/platform_window/platform_window.h"
#include "ui/views/mus/mus_export.h"
@@ -20,31 +19,26 @@ namespace bitmap_uploader {
class BitmapUploader;
}
-namespace mojo {
+namespace shell {
class Connector;
}
namespace ui {
-class Event;
class ViewProp;
}
namespace views {
+// This class has been marked for deletion. Its implementation is being rolled
+// into views::NativeWidgetMus. See crbug.com/609555 for details.
class VIEWS_MUS_EXPORT PlatformWindowMus
- : public NON_EXPORTED_BASE(ui::PlatformWindow),
- public mus::WindowObserver,
- public NON_EXPORTED_BASE(mus::InputEventHandler) {
+ : public NON_EXPORTED_BASE(ui::PlatformWindow) {
public:
PlatformWindowMus(ui::PlatformWindowDelegate* delegate,
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::Window* mus_window);
~PlatformWindowMus() override;
- void Activate();
-
- void SetCursorById(mus::mojom::Cursor cursor);
-
// ui::PlatformWindow:
void Show() override;
void Hide() override;
@@ -64,42 +58,18 @@ class VIEWS_MUS_EXPORT PlatformWindowMus
ui::PlatformImeController* GetPlatformImeController() override;
private:
- void SetShowState(mus::mojom::ShowState show_state);
-
- // mus::WindowObserver:
- void OnWindowDestroyed(mus::Window* window) override;
- void OnWindowBoundsChanged(mus::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) override;
- void OnWindowFocusChanged(mus::Window* gained_focus,
- mus::Window* lost_focus) override;
- void OnWindowPredefinedCursorChanged(mus::Window* window,
- mus::mojom::Cursor cursor) override;
- void OnWindowSharedPropertyChanged(
- mus::Window* window,
- const std::string& name,
- const std::vector<uint8_t>* old_data,
- const std::vector<uint8_t>* new_data) override;
- void OnRequestClose(mus::Window* window) override;
-
- // mus::InputEventHandler:
- void OnWindowInputEvent(
- mus::Window* view,
- const ui::Event& event,
- scoped_ptr<base::Callback<void(bool)>>* ack_callback) override;
+ friend class PlatformWindowMusTest;
ui::PlatformWindowDelegate* delegate_;
mus::Window* mus_window_;
- mus::mojom::ShowState show_state_;
- mus::mojom::Cursor last_cursor_;
// True if OnWindowDestroyed() has been received.
bool mus_window_destroyed_;
- scoped_ptr<bitmap_uploader::BitmapUploader> bitmap_uploader_;
- scoped_ptr<ui::ViewProp> prop_;
+ std::unique_ptr<bitmap_uploader::BitmapUploader> bitmap_uploader_;
+ std::unique_ptr<ui::ViewProp> prop_;
#ifndef NDEBUG
- scoped_ptr<base::WeakPtrFactory<PlatformWindowMus>> weak_factory_;
+ std::unique_ptr<base::WeakPtrFactory<PlatformWindowMus>> weak_factory_;
#endif
DISALLOW_COPY_AND_ASSIGN(PlatformWindowMus);
diff --git a/chromium/ui/views/mus/run_all_unittests_mus.cc b/chromium/ui/views/mus/run_all_unittests_mus.cc
index 4de8cdb1839..05e4f0c82a2 100644
--- a/chromium/ui/views/mus/run_all_unittests_mus.cc
+++ b/chromium/ui/views/mus/run_all_unittests_mus.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/run_all_unittests.h"
+#include "ui/views/mus/views_mus_test_suite.h"
int MasterProcessMain(int argc, char** argv) {
- return views::RunAllUnittests(argc, argv);
+ return views::ViewsMusTestSuite(argc, argv).RunTests();
}
diff --git a/chromium/ui/views/mus/screen_mus.cc b/chromium/ui/views/mus/screen_mus.cc
index 855f475674e..227170606ae 100644
--- a/chromium/ui/views/mus/screen_mus.cc
+++ b/chromium/ui/views/mus/screen_mus.cc
@@ -5,51 +5,18 @@
#include "ui/views/mus/screen_mus.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/shell/public/cpp/connection.h"
-#include "mojo/shell/public/cpp/connector.h"
-#include "ui/gfx/display_finder.h"
-#include "ui/gfx/display_observer.h"
+#include "services/shell/public/cpp/connection.h"
+#include "services/shell/public/cpp/connector.h"
+#include "ui/aura/window.h"
+#include "ui/display/display_finder.h"
+#include "ui/display/display_observer.h"
+#include "ui/mojo/display/display_type_converters.h"
#include "ui/views/mus/screen_mus_delegate.h"
#include "ui/views/mus/window_manager_frame_values.h"
namespace mojo {
template <>
-struct TypeConverter<gfx::Display, mus::mojom::DisplayPtr> {
- static gfx::Display Convert(const mus::mojom::DisplayPtr& input) {
- gfx::Display result(input->id, input->bounds.To<gfx::Rect>());
- result.set_work_area(input->work_area.To<gfx::Rect>());
- result.set_device_scale_factor(input->device_pixel_ratio);
- switch (input->rotation) {
- case mus::mojom::Rotation::VALUE_0:
- result.set_rotation(gfx::Display::ROTATE_0);
- break;
- case mus::mojom::Rotation::VALUE_90:
- result.set_rotation(gfx::Display::ROTATE_90);
- break;
- case mus::mojom::Rotation::VALUE_180:
- result.set_rotation(gfx::Display::ROTATE_180);
- break;
- case mus::mojom::Rotation::VALUE_270:
- result.set_rotation(gfx::Display::ROTATE_270);
- break;
- }
- switch (input->touch_support) {
- case mus::mojom::TouchSupport::UNKNOWN:
- result.set_touch_support(gfx::Display::TOUCH_SUPPORT_UNKNOWN);
- break;
- case mus::mojom::TouchSupport::AVAILABLE:
- result.set_touch_support(gfx::Display::TOUCH_SUPPORT_AVAILABLE);
- break;
- case mus::mojom::TouchSupport::UNAVAILABLE:
- result.set_touch_support(gfx::Display::TOUCH_SUPPORT_UNAVAILABLE);
- break;
- }
- return result;
- }
-};
-
-template <>
struct TypeConverter<views::WindowManagerFrameValues,
mus::mojom::FrameDecorationValuesPtr> {
static views::WindowManagerFrameValues Convert(
@@ -69,13 +36,13 @@ namespace views {
ScreenMus::ScreenMus(ScreenMusDelegate* delegate)
: delegate_(delegate),
- primary_display_index_(0),
- display_manager_observer_binding_(this) {}
+ display_manager_observer_binding_(this) {
+}
ScreenMus::~ScreenMus() {}
-void ScreenMus::Init(mojo::Connector* connector) {
- gfx::Screen::SetScreenInstance(this);
+void ScreenMus::Init(shell::Connector* connector) {
+ display::Screen::SetScreenInstance(this);
connector->ConnectToInterface("mojo:mus", &display_manager_);
@@ -86,70 +53,52 @@ void ScreenMus::Init(mojo::Connector* connector) {
//
// TODO(rockot): Do something better here. This should not have to block tasks
// from running on the calling thread. http://crbug.com/594852.
- display_manager_observer_binding_.WaitForIncomingMethodCall();
-
- // The WaitForIncomingMethodCall() should have supplied the set of Displays.
- DCHECK(displays_.size());
-}
-
-int ScreenMus::FindDisplayIndexById(int64_t id) const {
- for (size_t i = 0; i < displays_.size(); ++i) {
- if (displays_[i].id() == id)
- return static_cast<int>(i);
+ bool success = display_manager_observer_binding_.WaitForIncomingMethodCall();
+
+ // The WaitForIncomingMethodCall() should have supplied the set of Displays,
+ // unless mus is going down, in which case encountered_error() is true, or the
+ // call to WaitForIncomingMethodCall() failed.
+ if (display_list_.displays().empty()) {
+ DCHECK(display_manager_.encountered_error() || !success);
+ // In this case we install a default display and assume the process is
+ // going to exit shortly so that the real value doesn't matter.
+ display_list_.AddDisplay(
+ display::Display(0xFFFFFFFF, gfx::Rect(0, 0, 801, 802)),
+ DisplayList::Type::PRIMARY);
}
- return -1;
}
-void ScreenMus::ProcessDisplayChanged(const gfx::Display& changed_display,
+void ScreenMus::ProcessDisplayChanged(const display::Display& changed_display,
bool is_primary) {
- const int display_index = FindDisplayIndexById(changed_display.id());
- if (display_index == -1) {
- displays_.push_back(changed_display);
- if (is_primary)
- primary_display_index_ = static_cast<int>(displays_.size()) - 1;
- FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_,
- OnDisplayAdded(changed_display));
+ if (display_list_.FindDisplayById(changed_display.id()) ==
+ display_list_.displays().end()) {
+ display_list_.AddDisplay(changed_display,
+ is_primary ? DisplayList::Type::PRIMARY
+ : DisplayList::Type::NOT_PRIMARY);
return;
}
-
- gfx::Display* local_display = &displays_[display_index];
- uint32_t changed_values = 0;
- if (is_primary && display_index != primary_display_index_) {
- primary_display_index_ = display_index;
- // ash::DisplayManager only notifies for the Display gaining primary, not
- // the one losing it.
- changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_PRIMARY;
- }
- if (local_display->bounds() != changed_display.bounds()) {
- local_display->set_bounds(changed_display.bounds());
- changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS;
- }
- if (local_display->work_area() != changed_display.work_area()) {
- local_display->set_work_area(changed_display.work_area());
- changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA;
- }
- if (local_display->rotation() != changed_display.rotation()) {
- local_display->set_rotation(changed_display.rotation());
- changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_ROTATION;
- }
- if (local_display->device_scale_factor() !=
- changed_display.device_scale_factor()) {
- local_display->set_device_scale_factor(
- changed_display.device_scale_factor());
- changed_values |= gfx::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR;
- }
- FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_,
- OnDisplayMetricsChanged(*local_display, changed_values));
+ display_list_.UpdateDisplay(
+ changed_display,
+ is_primary ? DisplayList::Type::PRIMARY : DisplayList::Type::NOT_PRIMARY);
}
gfx::Point ScreenMus::GetCursorScreenPoint() {
- NOTIMPLEMENTED();
- return gfx::Point();
+ if (!delegate_) {
+ // TODO(erg): If we need the cursor point in the window manager, we'll need
+ // to make |delegate_| required. It only recently changed to be optional.
+ NOTIMPLEMENTED();
+ return gfx::Point();
+ }
+
+ return delegate_->GetCursorScreenPoint();
}
-gfx::NativeWindow ScreenMus::GetWindowUnderCursor() {
- NOTIMPLEMENTED();
- return nullptr;
+bool ScreenMus::IsWindowUnderCursor(gfx::NativeWindow window) {
+ if (!window)
+ return false;
+
+ return window->IsVisible() &&
+ window->GetBoundsInScreen().Contains(GetCursorScreenPoint());
}
gfx::NativeWindow ScreenMus::GetWindowAtScreenPoint(const gfx::Point& point) {
@@ -157,81 +106,86 @@ gfx::NativeWindow ScreenMus::GetWindowAtScreenPoint(const gfx::Point& point) {
return nullptr;
}
-gfx::Display ScreenMus::GetPrimaryDisplay() const {
- return displays_[primary_display_index_];
+display::Display ScreenMus::GetPrimaryDisplay() const {
+ return *display_list_.GetPrimaryDisplayIterator();
}
-gfx::Display ScreenMus::GetDisplayNearestWindow(gfx::NativeView view) const {
+display::Display ScreenMus::GetDisplayNearestWindow(
+ gfx::NativeView view) const {
//NOTIMPLEMENTED();
- return GetPrimaryDisplay();
+ return *display_list_.GetPrimaryDisplayIterator();
}
-gfx::Display ScreenMus::GetDisplayNearestPoint(const gfx::Point& point) const {
- return *gfx::FindDisplayNearestPoint(displays_, point);
+display::Display ScreenMus::GetDisplayNearestPoint(
+ const gfx::Point& point) const {
+ return *display::FindDisplayNearestPoint(display_list_.displays(), point);
}
int ScreenMus::GetNumDisplays() const {
- return static_cast<int>(displays_.size());
+ return static_cast<int>(display_list_.displays().size());
}
-std::vector<gfx::Display> ScreenMus::GetAllDisplays() const {
- return displays_;
+std::vector<display::Display> ScreenMus::GetAllDisplays() const {
+ return display_list_.displays();
}
-gfx::Display ScreenMus::GetDisplayMatching(const gfx::Rect& match_rect) const {
- const gfx::Display* match =
- gfx::FindDisplayWithBiggestIntersection(displays_, match_rect);
+display::Display ScreenMus::GetDisplayMatching(
+ const gfx::Rect& match_rect) const {
+ const display::Display* match = display::FindDisplayWithBiggestIntersection(
+ display_list_.displays(), match_rect);
return match ? *match : GetPrimaryDisplay();
}
-void ScreenMus::AddObserver(gfx::DisplayObserver* observer) {
- observers_.AddObserver(observer);
+void ScreenMus::AddObserver(display::DisplayObserver* observer) {
+ display_list_.AddObserver(observer);
}
-void ScreenMus::RemoveObserver(gfx::DisplayObserver* observer) {
- observers_.RemoveObserver(observer);
+void ScreenMus::RemoveObserver(display::DisplayObserver* observer) {
+ display_list_.RemoveObserver(observer);
}
-void ScreenMus::OnDisplays(mojo::Array<mus::mojom::DisplayPtr> displays) {
+void ScreenMus::OnDisplays(
+ mojo::Array<mus::mojom::DisplayPtr> transport_displays) {
// This should only be called once from Init() before any observers have been
// added.
- DCHECK(displays_.empty());
- displays_ = displays.To<std::vector<gfx::Display>>();
+ DCHECK(display_list_.displays().empty());
+ std::vector<display::Display> displays =
+ transport_displays.To<std::vector<display::Display>>();
for (size_t i = 0; i < displays.size(); ++i) {
- if (displays[i]->is_primary) {
- primary_display_index_ = static_cast<int>(i);
+ const bool is_primary = transport_displays[i]->is_primary;
+ display_list_.AddDisplay(displays[i], is_primary
+ ? DisplayList::Type::PRIMARY
+ : DisplayList::Type::NOT_PRIMARY);
+ if (is_primary) {
// TODO(sky): Make WindowManagerFrameValues per display.
WindowManagerFrameValues frame_values =
- displays[i]->frame_decoration_values.To<WindowManagerFrameValues>();
+ transport_displays[i]
+ ->frame_decoration_values.To<WindowManagerFrameValues>();
WindowManagerFrameValues::SetInstance(frame_values);
}
}
+ DCHECK(!display_list_.displays().empty());
}
void ScreenMus::OnDisplaysChanged(
mojo::Array<mus::mojom::DisplayPtr> transport_displays) {
for (size_t i = 0; i < transport_displays.size(); ++i) {
const bool is_primary = transport_displays[i]->is_primary;
- ProcessDisplayChanged(transport_displays[i].To<gfx::Display>(), is_primary);
+ ProcessDisplayChanged(transport_displays[i].To<display::Display>(),
+ is_primary);
if (is_primary) {
WindowManagerFrameValues frame_values =
transport_displays[i]
->frame_decoration_values.To<WindowManagerFrameValues>();
WindowManagerFrameValues::SetInstance(frame_values);
- delegate_->OnWindowManagerFrameValuesChanged();
+ if (delegate_)
+ delegate_->OnWindowManagerFrameValuesChanged();
}
}
}
void ScreenMus::OnDisplayRemoved(int64_t id) {
- const int index = FindDisplayIndexById(id);
- DCHECK_NE(-1, index);
- // Another display must become primary before the existing primary is
- // removed.
- DCHECK_NE(index, primary_display_index_);
- const gfx::Display display = displays_[index];
- FOR_EACH_OBSERVER(gfx::DisplayObserver, observers_,
- OnDisplayRemoved(display));
+ display_list_.RemoveDisplay(id);
}
} // namespace views
diff --git a/chromium/ui/views/mus/screen_mus.h b/chromium/ui/views/mus/screen_mus.h
index a6800afd72e..ddd9c14077d 100644
--- a/chromium/ui/views/mus/screen_mus.h
+++ b/chromium/ui/views/mus/screen_mus.h
@@ -11,11 +11,12 @@
#include "base/run_loop.h"
#include "components/mus/public/interfaces/display.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+#include "ui/views/mus/display_list.h"
#include "ui/views/mus/mus_export.h"
-namespace mojo {
+namespace shell {
class Connector;
}
@@ -25,47 +26,48 @@ class ScreenMusDelegate;
// Screen implementation backed by mus::mojom::DisplayManager.
class VIEWS_MUS_EXPORT ScreenMus
- : public gfx::Screen,
+ : public display::Screen,
public NON_EXPORTED_BASE(mus::mojom::DisplayManagerObserver) {
public:
+ // |delegate| can be nullptr.
explicit ScreenMus(ScreenMusDelegate* delegate);
~ScreenMus() override;
- void Init(mojo::Connector* connector);
+ void Init(shell::Connector* connector);
private:
- int FindDisplayIndexById(int64_t id) const;
-
// Invoked when a display changed in some weay, including being added.
// If |is_primary| is true, |changed_display| is the primary display.
- void ProcessDisplayChanged(const gfx::Display& changed_display,
+ void ProcessDisplayChanged(const display::Display& changed_display,
bool is_primary);
- // gfx::Screen:
+ // display::Screen:
gfx::Point GetCursorScreenPoint() override;
- gfx::NativeWindow GetWindowUnderCursor() override;
+ bool IsWindowUnderCursor(gfx::NativeWindow window) override;
gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
- gfx::Display GetPrimaryDisplay() const override;
- gfx::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
- gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override;
+ display::Display GetPrimaryDisplay() const override;
+ display::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
+ display::Display GetDisplayNearestPoint(
+ const gfx::Point& point) const override;
int GetNumDisplays() const override;
- std::vector<gfx::Display> GetAllDisplays() const override;
- gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
- void AddObserver(gfx::DisplayObserver* observer) override;
- void RemoveObserver(gfx::DisplayObserver* observer) override;
+ std::vector<display::Display> GetAllDisplays() const override;
+ display::Display GetDisplayMatching(
+ const gfx::Rect& match_rect) const override;
+ void AddObserver(display::DisplayObserver* observer) override;
+ void RemoveObserver(display::DisplayObserver* observer) override;
// mus::mojom::DisplayManager:
- void OnDisplays(mojo::Array<mus::mojom::DisplayPtr> displays) override;
- void OnDisplaysChanged(mojo::Array<mus::mojom::DisplayPtr> display) override;
+ void OnDisplays(
+ mojo::Array<mus::mojom::DisplayPtr> transport_displays) override;
+ void OnDisplaysChanged(
+ mojo::Array<mus::mojom::DisplayPtr> transport_displays) override;
void OnDisplayRemoved(int64_t id) override;
- ScreenMusDelegate* delegate_;
+ ScreenMusDelegate* delegate_; // Can be nullptr.
mus::mojom::DisplayManagerPtr display_manager_;
- std::vector<gfx::Display> displays_;
- int primary_display_index_;
mojo::Binding<mus::mojom::DisplayManagerObserver>
display_manager_observer_binding_;
- base::ObserverList<gfx::DisplayObserver> observers_;
+ DisplayList display_list_;
DISALLOW_COPY_AND_ASSIGN(ScreenMus);
};
diff --git a/chromium/ui/views/mus/screen_mus_delegate.h b/chromium/ui/views/mus/screen_mus_delegate.h
index 4c7940088c5..1db1b67faaa 100644
--- a/chromium/ui/views/mus/screen_mus_delegate.h
+++ b/chromium/ui/views/mus/screen_mus_delegate.h
@@ -7,6 +7,10 @@
#include "ui/views/mus/mus_export.h"
+namespace gfx {
+class Point;
+}
+
namespace views {
// Screen implementation backed by mus::mojom::DisplayManager.
@@ -14,7 +18,9 @@ class VIEWS_MUS_EXPORT ScreenMusDelegate {
public:
virtual void OnWindowManagerFrameValuesChanged() = 0;
- protected:
+ virtual gfx::Point GetCursorScreenPoint() = 0;
+
+protected:
virtual ~ScreenMusDelegate() {}
};
diff --git a/chromium/ui/views/mus/screen_mus_unittest.cc b/chromium/ui/views/mus/screen_mus_unittest.cc
new file mode 100644
index 00000000000..1d71fbaa4a4
--- /dev/null
+++ b/chromium/ui/views/mus/screen_mus_unittest.cc
@@ -0,0 +1,32 @@
+// Copyright 2016 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.
+
+#include "ui/views/mus/screen_mus.h"
+
+#include "base/command_line.h"
+#include "ui/display/display_switches.h"
+#include "ui/display/screen.h"
+#include "ui/views/mus/window_manager_connection.h"
+#include "ui/views/test/scoped_views_test_helper.h"
+#include "ui/views/test/views_test_base.h"
+
+namespace views {
+namespace {
+
+TEST(ScreenMusTest, ConsistentDisplayInHighDPI) {
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kForceDeviceScaleFactor, "2");
+ ScopedViewsTestHelper test_helper;
+ display::Screen* screen = display::Screen::GetScreen();
+ std::vector<display::Display> displays = screen->GetAllDisplays();
+ ASSERT_FALSE(displays.empty());
+ for (const display::Display& display : displays) {
+ EXPECT_EQ(2.f, display.device_scale_factor());
+ EXPECT_EQ(display.work_area(), display.bounds());
+ }
+}
+
+} // namespace
+} // namespace views
diff --git a/chromium/ui/views/mus/surface_binding.cc b/chromium/ui/views/mus/surface_binding.cc
index e33e3247bd7..a3dc98fb730 100644
--- a/chromium/ui/views/mus/surface_binding.cc
+++ b/chromium/ui/views/mus/surface_binding.cc
@@ -12,6 +12,7 @@
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/threading/thread_local.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface.h"
@@ -26,7 +27,7 @@
#include "mojo/converters/geometry/geometry_type_converters.h"
#include "mojo/converters/surfaces/surfaces_type_converters.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/shell/public/cpp/connector.h"
+#include "services/shell/public/cpp/connector.h"
#include "ui/views/mus/window_tree_host_mus.h"
namespace views {
@@ -41,10 +42,10 @@ namespace views {
class SurfaceBinding::PerConnectionState
: public base::RefCounted<PerConnectionState> {
public:
- static PerConnectionState* Get(mojo::Connector* connector,
+ static PerConnectionState* Get(shell::Connector* connector,
mus::WindowTreeConnection* connection);
- scoped_ptr<cc::OutputSurface> CreateOutputSurface(
+ std::unique_ptr<cc::OutputSurface> CreateOutputSurface(
mus::Window* window,
mus::mojom::SurfaceType type);
@@ -54,7 +55,7 @@ class SurfaceBinding::PerConnectionState
friend class base::RefCounted<PerConnectionState>;
- PerConnectionState(mojo::Connector* connector,
+ PerConnectionState(shell::Connector* connector,
mus::WindowTreeConnection* connection);
~PerConnectionState();
@@ -63,7 +64,7 @@ class SurfaceBinding::PerConnectionState
static base::LazyInstance<
base::ThreadLocalPointer<ConnectionToStateMap>>::Leaky window_states;
- mojo::Connector* connector_;
+ shell::Connector* connector_;
mus::WindowTreeConnection* connection_;
// Set of state needed to create an OutputSurface.
@@ -79,7 +80,7 @@ base::LazyInstance<base::ThreadLocalPointer<
// static
SurfaceBinding::PerConnectionState* SurfaceBinding::PerConnectionState::Get(
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::WindowTreeConnection* connection) {
ConnectionToStateMap* window_map = window_states.Pointer()->Get();
if (!window_map) {
@@ -93,10 +94,12 @@ SurfaceBinding::PerConnectionState* SurfaceBinding::PerConnectionState::Get(
return (*window_map)[connection];
}
-scoped_ptr<cc::OutputSurface>
+std::unique_ptr<cc::OutputSurface>
SurfaceBinding::PerConnectionState::CreateOutputSurface(
mus::Window* window,
mus::mojom::SurfaceType surface_type) {
+ if (gpu_.encountered_error())
+ return nullptr;
// TODO(sky): figure out lifetime here. Do I need to worry about the return
// value outliving this?
mus::mojom::CommandBufferPtr cb;
@@ -104,12 +107,12 @@ SurfaceBinding::PerConnectionState::CreateOutputSurface(
scoped_refptr<cc::ContextProvider> context_provider(
new mus::ContextProvider(cb.PassInterface().PassHandle()));
- return make_scoped_ptr(new mus::OutputSurface(
+ return base::WrapUnique(new mus::OutputSurface(
context_provider, window->RequestSurface(surface_type)));
}
SurfaceBinding::PerConnectionState::PerConnectionState(
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::WindowTreeConnection* connection)
: connector_(connector), connection_(connection) {}
@@ -126,11 +129,17 @@ SurfaceBinding::PerConnectionState::~PerConnectionState() {
void SurfaceBinding::PerConnectionState::Init() {
connector_->ConnectToInterface("mojo:mus", &gpu_);
+
+ // TODO(sad): If connection is lost (e.g. if gpu crashes), then the
+ // connections need to be restored. https://crbug.com/613366
+ // TODO(rockot|yzshen): It is necessary to install a connection-error handler,
+ // even if the handler doesn't actually do anything. https://crbug.com/613371
+ gpu_.set_connection_error_handler([]{});
}
// SurfaceBinding --------------------------------------------------------------
-SurfaceBinding::SurfaceBinding(mojo::Connector* connector,
+SurfaceBinding::SurfaceBinding(shell::Connector* connector,
mus::Window* window,
mus::mojom::SurfaceType surface_type)
: window_(window),
@@ -139,7 +148,7 @@ SurfaceBinding::SurfaceBinding(mojo::Connector* connector,
SurfaceBinding::~SurfaceBinding() {}
-scoped_ptr<cc::OutputSurface> SurfaceBinding::CreateOutputSurface() {
+std::unique_ptr<cc::OutputSurface> SurfaceBinding::CreateOutputSurface() {
return state_->CreateOutputSurface(window_, surface_type_);
}
diff --git a/chromium/ui/views/mus/surface_binding.h b/chromium/ui/views/mus/surface_binding.h
index 2c6c5b68a33..2e04c3d488a 100644
--- a/chromium/ui/views/mus/surface_binding.h
+++ b/chromium/ui/views/mus/surface_binding.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_MUS_SURFACE_BINDING_H_
#define UI_VIEWS_MUS_SURFACE_BINDING_H_
+#include <memory>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "ui/views/mus/mus_export.h"
@@ -15,14 +16,14 @@ namespace cc {
class OutputSurface;
}
-namespace mojo {
-class Connector;
-}
-
namespace mus {
class Window;
}
+namespace shell {
+class Connector;
+}
+
namespace views {
// SurfaceBinding is responsible for managing the connections necessary to
@@ -32,14 +33,14 @@ namespace views {
// connection.
class VIEWS_MUS_EXPORT SurfaceBinding {
public:
- SurfaceBinding(mojo::Connector* connector,
+ SurfaceBinding(shell::Connector* connector,
mus::Window* window,
mus::mojom::SurfaceType surface_type);
~SurfaceBinding();
// Creates an OutputSurface that renders to the Window supplied to the
// constructor.
- scoped_ptr<cc::OutputSurface> CreateOutputSurface();
+ std::unique_ptr<cc::OutputSurface> CreateOutputSurface();
private:
class PerConnectionState;
diff --git a/chromium/ui/views/mus/surface_context_factory.cc b/chromium/ui/views/mus/surface_context_factory.cc
index bb27a08fb06..316d14e3c27 100644
--- a/chromium/ui/views/mus/surface_context_factory.cc
+++ b/chromium/ui/views/mus/surface_context_factory.cc
@@ -4,11 +4,12 @@
#include "ui/views/mus/surface_context_factory.h"
+#include "base/memory/ptr_util.h"
#include "cc/output/output_surface.h"
#include "cc/resources/shared_bitmap_manager.h"
#include "cc/surfaces/surface_id_allocator.h"
#include "components/mus/public/cpp/window.h"
-#include "mojo/shell/public/interfaces/connector.mojom.h"
+#include "services/shell/public/interfaces/connector.mojom.h"
#include "ui/compositor/reflector.h"
#include "ui/gl/gl_bindings.h"
@@ -27,7 +28,7 @@ class FakeReflector : public ui::Reflector {
} // namespace
SurfaceContextFactory::SurfaceContextFactory(
- mojo::Connector* connector,
+ shell::Connector* connector,
mus::Window* window,
mus::mojom::SurfaceType surface_type)
: surface_binding_(connector, window, surface_type),
@@ -38,14 +39,17 @@ SurfaceContextFactory::~SurfaceContextFactory() {}
void SurfaceContextFactory::CreateOutputSurface(
base::WeakPtr<ui::Compositor> compositor) {
// NOTIMPLEMENTED();
- compositor->SetOutputSurface(surface_binding_.CreateOutputSurface());
+ std::unique_ptr<cc::OutputSurface> surface =
+ surface_binding_.CreateOutputSurface();
+ if (surface)
+ compositor->SetOutputSurface(std::move(surface));
}
-scoped_ptr<ui::Reflector> SurfaceContextFactory::CreateReflector(
+std::unique_ptr<ui::Reflector> SurfaceContextFactory::CreateReflector(
ui::Compositor* mirroed_compositor,
ui::Layer* mirroring_layer) {
// NOTIMPLEMENTED();
- return make_scoped_ptr(new FakeReflector);
+ return base::WrapUnique(new FakeReflector);
}
void SurfaceContextFactory::RemoveReflector(ui::Reflector* reflector) {
@@ -86,12 +90,17 @@ cc::TaskGraphRunner* SurfaceContextFactory::GetTaskGraphRunner() {
return raster_thread_helper_.task_graph_runner();
}
-scoped_ptr<cc::SurfaceIdAllocator>
+std::unique_ptr<cc::SurfaceIdAllocator>
SurfaceContextFactory::CreateSurfaceIdAllocator() {
- return make_scoped_ptr(
+ return base::WrapUnique(
new cc::SurfaceIdAllocator(next_surface_id_namespace_++));
}
+cc::SurfaceManager* SurfaceContextFactory::GetSurfaceManager() {
+ // NOTIMPLEMENTED();
+ return nullptr;
+}
+
void SurfaceContextFactory::ResizeDisplay(ui::Compositor* compositor,
const gfx::Size& size) {
// NOTIMPLEMENTED();
diff --git a/chromium/ui/views/mus/surface_context_factory.h b/chromium/ui/views/mus/surface_context_factory.h
index 6399d5a011b..61701e63e74 100644
--- a/chromium/ui/views/mus/surface_context_factory.h
+++ b/chromium/ui/views/mus/surface_context_factory.h
@@ -27,7 +27,7 @@ namespace views {
class VIEWS_MUS_EXPORT SurfaceContextFactory : public ui::ContextFactory {
public:
- SurfaceContextFactory(mojo::Connector* connector,
+ SurfaceContextFactory(shell::Connector* connector,
mus::Window* window,
mus::mojom::SurfaceType surface_type);
~SurfaceContextFactory() override;
@@ -35,7 +35,7 @@ class VIEWS_MUS_EXPORT SurfaceContextFactory : public ui::ContextFactory {
private:
// ContextFactory:
void CreateOutputSurface(base::WeakPtr<ui::Compositor> compositor) override;
- scoped_ptr<ui::Reflector> CreateReflector(
+ std::unique_ptr<ui::Reflector> CreateReflector(
ui::Compositor* mirrored_compositor,
ui::Layer* mirroring_layer) override;
void RemoveReflector(ui::Reflector* reflector) override;
@@ -47,9 +47,13 @@ class VIEWS_MUS_EXPORT SurfaceContextFactory : public ui::ContextFactory {
cc::SharedBitmapManager* GetSharedBitmapManager() override;
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
cc::TaskGraphRunner* GetTaskGraphRunner() override;
- scoped_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() override;
+ std::unique_ptr<cc::SurfaceIdAllocator> CreateSurfaceIdAllocator() override;
+ cc::SurfaceManager* GetSurfaceManager() override;
void ResizeDisplay(ui::Compositor* compositor,
const gfx::Size& size) override;
+ void SetAuthoritativeVSyncInterval(ui::Compositor* compositor,
+ base::TimeDelta interval) override {}
+ void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override {}
SurfaceBinding surface_binding_;
uint32_t next_surface_id_namespace_;
diff --git a/chromium/ui/views/mus/unittests_manifest.json b/chromium/ui/views/mus/unittests_manifest.json
new file mode 100644
index 00000000000..23ef6e3fd84
--- /dev/null
+++ b/chromium/ui/views/mus/unittests_manifest.json
@@ -0,0 +1,10 @@
+{
+ "manifest_version": 1,
+ "name": "mojo:views_mus_unittests",
+ "display_name": "Views Mus Unittests",
+ "capabilities": {
+ "required": {
+ "*": { "classes": [ "app" ] }
+ }
+ }
+}
diff --git a/chromium/ui/views/mus/views_mus_test_suite.cc b/chromium/ui/views/mus/views_mus_test_suite.cc
new file mode 100644
index 00000000000..a101f3b19be
--- /dev/null
+++ b/chromium/ui/views/mus/views_mus_test_suite.cc
@@ -0,0 +1,160 @@
+// Copyright 2016 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.
+
+#include "ui/views/mus/views_mus_test_suite.h"
+
+#include <memory>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/simple_thread.h"
+#include "base/threading/thread.h"
+#include "components/mus/common/switches.h"
+#include "services/shell/background/background_shell.h"
+#include "services/shell/public/cpp/connector.h"
+#include "services/shell/public/cpp/shell_client.h"
+#include "services/shell/public/cpp/shell_connection.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/views/mus/window_manager_connection.h"
+#include "ui/views/test/platform_test_helper.h"
+#include "ui/views/views_delegate.h"
+
+namespace views {
+namespace {
+
+void EnsureCommandLineSwitch(const std::string& name) {
+ base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+ if (!cmd_line->HasSwitch(name))
+ cmd_line->AppendSwitch(name);
+}
+
+class DefaultShellClient : public shell::ShellClient {
+ public:
+ DefaultShellClient() {}
+ ~DefaultShellClient() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultShellClient);
+};
+
+class PlatformTestHelperMus : public PlatformTestHelper {
+ public:
+ PlatformTestHelperMus() {
+ ViewsDelegate::GetInstance()->set_native_widget_factory(base::Bind(
+ &WindowManagerConnection::CreateNativeWidgetMus,
+ base::Unretained(WindowManagerConnection::Get()),
+ std::map<std::string, std::vector<uint8_t>>()));
+ }
+ ~PlatformTestHelperMus() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformTestHelperMus);
+};
+
+std::unique_ptr<PlatformTestHelper> CreatePlatformTestHelper(
+ shell::Connector* connector,
+ const shell::Identity& identity) {
+ if (!WindowManagerConnection::Exists())
+ WindowManagerConnection::Create(connector, identity);
+ return base::WrapUnique(new PlatformTestHelperMus);
+}
+
+} // namespace
+
+class ShellConnection {
+ public:
+ ShellConnection() : thread_("Persistent shell connections") {
+ base::WaitableEvent wait(false, false);
+ base::Thread::Options options;
+ thread_.StartWithOptions(options);
+ thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&ShellConnection::SetUpConnections,
+ base::Unretained(this), &wait));
+ wait.Wait();
+
+ // WindowManagerConnection cannot be created from here yet, although the
+ // connector and identity are available at this point. This is because
+ // WindowManagerConnection needs a ViewsDelegate and a MessageLoop to have
+ // been installed first. So delay the creation until the necessary
+ // dependencies have been met.
+ PlatformTestHelper::set_factory(base::Bind(
+ &CreatePlatformTestHelper, shell_connector_.get(), shell_identity_));
+ }
+
+ ~ShellConnection() {
+ if (views::WindowManagerConnection::Exists())
+ views::WindowManagerConnection::Reset();
+ base::WaitableEvent wait(false, false);
+ thread_.task_runner()->PostTask(
+ FROM_HERE, base::Bind(&ShellConnection::TearDownConnections,
+ base::Unretained(this), &wait));
+ wait.Wait();
+ }
+
+ private:
+ void SetUpConnections(base::WaitableEvent* wait) {
+ background_shell_.reset(new shell::BackgroundShell);
+ background_shell_->Init(nullptr);
+ shell_client_.reset(new DefaultShellClient);
+ shell_connection_.reset(new shell::ShellConnection(
+ shell_client_.get(),
+ background_shell_->CreateShellClientRequest(GetTestName())));
+
+ // ui/views/mus requires a WindowManager running, for now use the desktop
+ // one.
+ shell::Connector* connector = shell_connection_->connector();
+ connector->Connect("mojo:desktop_wm");
+ shell_connector_ = connector->Clone();
+ shell_identity_ = shell_connection_->identity();
+ wait->Signal();
+ }
+
+ void TearDownConnections(base::WaitableEvent* wait) {
+ shell_connection_.reset();
+ wait->Signal();
+ }
+
+ // Returns the name of the test executable, e.g. "exe:views_mus_unittests".
+ std::string GetTestName() {
+ base::FilePath executable = base::CommandLine::ForCurrentProcess()
+ ->GetProgram()
+ .BaseName()
+ .RemoveExtension();
+ return std::string("exe:") + executable.MaybeAsASCII();
+ }
+
+ base::Thread thread_;
+ std::unique_ptr<shell::BackgroundShell> background_shell_;
+ std::unique_ptr<shell::ShellConnection> shell_connection_;
+ std::unique_ptr<DefaultShellClient> shell_client_;
+ std::unique_ptr<shell::Connector> shell_connector_;
+ shell::Identity shell_identity_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShellConnection);
+};
+
+ViewsMusTestSuite::ViewsMusTestSuite(int argc, char** argv)
+ : ViewsTestSuite(argc, argv) {}
+
+ViewsMusTestSuite::~ViewsMusTestSuite() {}
+
+void ViewsMusTestSuite::Initialize() {
+ PlatformTestHelper::SetIsMus();
+ // Let other mojo apps know that we're running in tests. Do this with a
+ // command line flag to avoid making blocking calls to other processes for
+ // setup for tests (e.g. to unlock the screen in the window manager).
+ EnsureCommandLineSwitch(mus::switches::kUseTestConfig);
+
+ ViewsTestSuite::Initialize();
+ shell_connections_.reset(new ShellConnection);
+}
+
+void ViewsMusTestSuite::Shutdown() {
+ shell_connections_.reset();
+ ViewsTestSuite::Shutdown();
+}
+
+} // namespace views
diff --git a/chromium/ui/views/mus/views_mus_test_suite.h b/chromium/ui/views/mus/views_mus_test_suite.h
new file mode 100644
index 00000000000..0f801bf1a84
--- /dev/null
+++ b/chromium/ui/views/mus/views_mus_test_suite.h
@@ -0,0 +1,34 @@
+// Copyright 2016 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_VIEWS_MUS_VIEWS_MUS_TEST_SUITE_H_
+#define UI_VIEWS_MUS_VIEWS_MUS_TEST_SUITE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "ui/views/views_test_suite.h"
+
+namespace views {
+
+class ShellConnection;
+
+class ViewsMusTestSuite : public ViewsTestSuite {
+ public:
+ ViewsMusTestSuite(int argc, char** argv);
+ ~ViewsMusTestSuite() override;
+
+ private:
+ // ViewsTestSuite:
+ void Initialize() override;
+ void Shutdown() override;
+
+ std::unique_ptr<ShellConnection> shell_connections_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewsMusTestSuite);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_MUS_VIEWS_MUS_TEST_SUITE_H_
diff --git a/chromium/ui/views/mus/window_manager_connection.cc b/chromium/ui/views/mus/window_manager_connection.cc
index fc41913602f..a76ffa6ebd4 100644
--- a/chromium/ui/views/mus/window_manager_connection.cc
+++ b/chromium/ui/views/mus/window_manager_connection.cc
@@ -8,13 +8,19 @@
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
+#include "components/mus/public/cpp/property_type_converters.h"
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_property.h"
#include "components/mus/public/cpp/window_tree_connection.h"
+#include "components/mus/public/interfaces/event_matcher.mojom.h"
#include "components/mus/public/interfaces/window_tree.mojom.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
-#include "mojo/shell/public/cpp/connection.h"
-#include "mojo/shell/public/cpp/connector.h"
+#include "services/shell/public/cpp/connection.h"
+#include "services/shell/public/cpp/connector.h"
+#include "ui/events/devices/device_data_manager.h"
#include "ui/views/mus/native_widget_mus.h"
#include "ui/views/mus/screen_mus.h"
+#include "ui/views/pointer_watcher.h"
#include "ui/views/views_delegate.h"
namespace views {
@@ -30,9 +36,10 @@ base::LazyInstance<WindowManagerConnectionPtr>::Leaky lazy_tls_ptr =
} // namespace
// static
-void WindowManagerConnection::Create(mojo::Connector* connector) {
+void WindowManagerConnection::Create(shell::Connector* connector,
+ const shell::Identity& identity) {
DCHECK(!lazy_tls_ptr.Pointer()->Get());
- lazy_tls_ptr.Pointer()->Set(new WindowManagerConnection(connector));
+ lazy_tls_ptr.Pointer()->Set(new WindowManagerConnection(connector, identity));
}
// static
@@ -64,18 +71,50 @@ NativeWidget* WindowManagerConnection::CreateNativeWidgetMus(
internal::NativeWidgetDelegate* delegate) {
std::map<std::string, std::vector<uint8_t>> properties = props;
NativeWidgetMus::ConfigurePropertiesForNewWindow(init_params, &properties);
+ properties[mus::mojom::WindowManager::kAppID_Property] =
+ mojo::ConvertTo<std::vector<uint8_t>>(identity_.name());
return new NativeWidgetMus(delegate, connector_, NewWindow(properties),
mus::mojom::SurfaceType::DEFAULT);
}
-WindowManagerConnection::WindowManagerConnection(mojo::Connector* connector)
- : connector_(connector), window_tree_connection_(nullptr) {
+void WindowManagerConnection::AddPointerWatcher(PointerWatcher* watcher) {
+ bool had_watcher = HasPointerWatcher();
+ pointer_watchers_.AddObserver(watcher);
+ if (!had_watcher) {
+ // Start a watcher for pointer down.
+ // TODO(jamescook): Extend event observers to handle multiple event types.
+ mus::mojom::EventMatcherPtr matcher = mus::mojom::EventMatcher::New();
+ matcher->type_matcher = mus::mojom::EventTypeMatcher::New();
+ matcher->type_matcher->type = mus::mojom::EventType::POINTER_DOWN;
+ window_tree_connection_->SetEventObserver(std::move(matcher));
+ }
+}
+
+void WindowManagerConnection::RemovePointerWatcher(PointerWatcher* watcher) {
+ pointer_watchers_.RemoveObserver(watcher);
+ if (!HasPointerWatcher()) {
+ // Last PointerWatcher removed, stop the event observer.
+ window_tree_connection_->SetEventObserver(nullptr);
+ }
+}
+
+WindowManagerConnection::WindowManagerConnection(
+ shell::Connector* connector,
+ const shell::Identity& identity)
+ : connector_(connector),
+ identity_(identity),
+ window_tree_connection_(nullptr) {
window_tree_connection_.reset(
mus::WindowTreeConnection::Create(this, connector_));
screen_.reset(new ScreenMus(this));
screen_->Init(connector);
+ // TODO(sad): We should have a DeviceDataManager implementation that talks to
+ // a mojo service to learn about the input-devices on the system.
+ // http://crbug.com/601981
+ ui::DeviceDataManager::CreateInstance();
+
ViewsDelegate::GetInstance()->set_native_widget_factory(base::Bind(
&WindowManagerConnection::CreateNativeWidgetMus,
base::Unretained(this),
@@ -86,6 +125,16 @@ WindowManagerConnection::~WindowManagerConnection() {
// ~WindowTreeConnection calls back to us (we're the WindowTreeDelegate),
// destroy it while we are still valid.
window_tree_connection_.reset();
+
+ ui::DeviceDataManager::DeleteInstance();
+}
+
+bool WindowManagerConnection::HasPointerWatcher() {
+ // Check to see if we really have any observers left. This doesn't use
+ // base::ObserverList<>::might_have_observers() because that returns true
+ // during iteration over the list even when the last observer is removed.
+ base::ObserverList<PointerWatcher>::Iterator iterator(&pointer_watchers_);
+ return !!iterator.GetNext();
}
void WindowManagerConnection::OnEmbed(mus::Window* root) {}
@@ -93,9 +142,38 @@ void WindowManagerConnection::OnEmbed(mus::Window* root) {}
void WindowManagerConnection::OnConnectionLost(
mus::WindowTreeConnection* connection) {}
+void WindowManagerConnection::OnEventObserved(const ui::Event& event,
+ mus::Window* target) {
+ if (!event.IsLocatedEvent())
+ return;
+ Widget* target_widget = nullptr;
+ if (target) {
+ mus::Window* root = target->GetRoot();
+ target_widget = NativeWidgetMus::GetWidgetForWindow(root);
+ }
+
+ // The mojo input events type converter uses the event root_location field
+ // to store screen coordinates. Screen coordinates really should be returned
+ // separately. See http://crbug.com/608547
+ gfx::Point location_in_screen = event.AsLocatedEvent()->root_location();
+ if (event.type() == ui::ET_MOUSE_PRESSED) {
+ FOR_EACH_OBSERVER(PointerWatcher, pointer_watchers_,
+ OnMousePressed(*event.AsMouseEvent(), location_in_screen,
+ target_widget));
+ } else if (event.type() == ui::ET_TOUCH_PRESSED) {
+ FOR_EACH_OBSERVER(PointerWatcher, pointer_watchers_,
+ OnTouchPressed(*event.AsTouchEvent(), location_in_screen,
+ target_widget));
+ }
+}
+
void WindowManagerConnection::OnWindowManagerFrameValuesChanged() {
if (window_tree_connection_)
NativeWidgetMus::NotifyFrameChanged(window_tree_connection_.get());
}
+gfx::Point WindowManagerConnection::GetCursorScreenPoint() {
+ return window_tree_connection_->GetCursorScreenPoint();
+}
+
} // namespace views
diff --git a/chromium/ui/views/mus/window_manager_connection.h b/chromium/ui/views/mus/window_manager_connection.h
index 69059893346..049e09509af 100644
--- a/chromium/ui/views/mus/window_manager_connection.h
+++ b/chromium/ui/views/mus/window_manager_connection.h
@@ -7,19 +7,23 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
#include "components/mus/public/cpp/window_tree_delegate.h"
+#include "services/shell/public/cpp/identity.h"
#include "ui/views/mus/mus_export.h"
#include "ui/views/mus/screen_mus_delegate.h"
#include "ui/views/widget/widget.h"
-namespace mojo {
+namespace shell {
class Connector;
}
namespace views {
class NativeWidget;
+class PointerWatcher;
class ScreenMus;
namespace internal {
class NativeWidgetDelegate;
@@ -37,14 +41,15 @@ class VIEWS_MUS_EXPORT WindowManagerConnection
: public NON_EXPORTED_BASE(mus::WindowTreeDelegate),
public ScreenMusDelegate {
public:
- static void Create(mojo::Connector* connector);
+ static void Create(shell::Connector* connector,
+ const shell::Identity& identity);
static WindowManagerConnection* Get();
static bool Exists();
// Destroys the singleton instance.
static void Reset();
- mojo::Connector* connector() { return connector_; }
+ shell::Connector* connector() { return connector_; }
mus::Window* NewWindow(const std::map<std::string,
std::vector<uint8_t>>& properties);
@@ -54,20 +59,34 @@ class VIEWS_MUS_EXPORT WindowManagerConnection
const Widget::InitParams& init_params,
internal::NativeWidgetDelegate* delegate);
+ void AddPointerWatcher(PointerWatcher* watcher);
+ void RemovePointerWatcher(PointerWatcher* watcher);
+
private:
- explicit WindowManagerConnection(mojo::Connector* connector);
+ friend class WindowManagerConnectionTest;
+
+ WindowManagerConnection(shell::Connector* connector,
+ const shell::Identity& identity);
~WindowManagerConnection() override;
+ // Returns true if there is one or more pointer watchers for this client.
+ bool HasPointerWatcher();
+
// mus::WindowTreeDelegate:
void OnEmbed(mus::Window* root) override;
void OnConnectionLost(mus::WindowTreeConnection* connection) override;
+ void OnEventObserved(const ui::Event& event, mus::Window* target) override;
// ScreenMusDelegate:
void OnWindowManagerFrameValuesChanged() override;
-
- mojo::Connector* connector_;
- scoped_ptr<ScreenMus> screen_;
- scoped_ptr<mus::WindowTreeConnection> window_tree_connection_;
+ gfx::Point GetCursorScreenPoint() override;
+
+ shell::Connector* connector_;
+ shell::Identity identity_;
+ std::unique_ptr<ScreenMus> screen_;
+ std::unique_ptr<mus::WindowTreeConnection> window_tree_connection_;
+ // Must be empty on destruction.
+ base::ObserverList<PointerWatcher, true> pointer_watchers_;
DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection);
};
diff --git a/chromium/ui/views/mus/window_manager_connection_unittest.cc b/chromium/ui/views/mus/window_manager_connection_unittest.cc
new file mode 100644
index 00000000000..8d86447c5be
--- /dev/null
+++ b/chromium/ui/views/mus/window_manager_connection_unittest.cc
@@ -0,0 +1,118 @@
+// Copyright 2016 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.
+
+#include "ui/views/mus/window_manager_connection.h"
+
+#include <memory>
+
+#include "base/message_loop/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event.h"
+#include "ui/views/pointer_watcher.h"
+#include "ui/views/test/scoped_views_test_helper.h"
+
+namespace views {
+namespace {
+
+class TestPointerWatcher : public PointerWatcher {
+ public:
+ TestPointerWatcher() {}
+ ~TestPointerWatcher() override {}
+
+ bool mouse_pressed() const { return mouse_pressed_; }
+ bool touch_pressed() const { return touch_pressed_; }
+
+ void Reset() {
+ mouse_pressed_ = false;
+ touch_pressed_ = false;
+ }
+
+ // PointerWatcher:
+ void OnMousePressed(const ui::MouseEvent& event,
+ const gfx::Point& location_in_screen,
+ Widget* target) override {
+ mouse_pressed_ = true;
+ }
+ void OnTouchPressed(const ui::TouchEvent& event,
+ const gfx::Point& location_in_screen,
+ Widget* target) override {
+ touch_pressed_ = true;
+ }
+
+ private:
+ bool mouse_pressed_ = false;
+ bool touch_pressed_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(TestPointerWatcher);
+};
+
+} // namespace
+
+class WindowManagerConnectionTest : public testing::Test {
+ public:
+ WindowManagerConnectionTest() {}
+ ~WindowManagerConnectionTest() override {}
+
+ void OnEventObserved(const ui::Event& event) {
+ WindowManagerConnection::Get()->OnEventObserved(event, nullptr);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WindowManagerConnectionTest);
+};
+
+TEST_F(WindowManagerConnectionTest, PointerWatcher) {
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
+ ScopedViewsTestHelper helper;
+ WindowManagerConnection* connection = WindowManagerConnection::Get();
+ ASSERT_TRUE(connection);
+ ui::MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
+ base::TimeDelta(), ui::EF_NONE, 0);
+ ui::TouchEvent touch_pressed(ui::ET_TOUCH_PRESSED, gfx::Point(), 1,
+ base::TimeDelta());
+ ui::KeyEvent key_pressed(ui::ET_KEY_PRESSED, ui::VKEY_A, 0);
+
+ // PointerWatchers receive mouse events.
+ TestPointerWatcher watcher1;
+ connection->AddPointerWatcher(&watcher1);
+ OnEventObserved(mouse_pressed);
+ EXPECT_TRUE(watcher1.mouse_pressed());
+ watcher1.Reset();
+
+ // PointerWatchers receive touch events.
+ OnEventObserved(touch_pressed);
+ EXPECT_TRUE(watcher1.touch_pressed());
+ watcher1.Reset();
+
+ // PointerWatchers do not trigger for key events.
+ OnEventObserved(key_pressed);
+ EXPECT_FALSE(watcher1.mouse_pressed());
+ EXPECT_FALSE(watcher1.touch_pressed());
+ watcher1.Reset();
+
+ // Two PointerWatchers can both receive a single observed event.
+ TestPointerWatcher watcher2;
+ connection->AddPointerWatcher(&watcher2);
+ OnEventObserved(mouse_pressed);
+ EXPECT_TRUE(watcher1.mouse_pressed());
+ EXPECT_TRUE(watcher2.mouse_pressed());
+ watcher1.Reset();
+ watcher2.Reset();
+
+ // Removing the first PointerWatcher stops sending events to it.
+ connection->RemovePointerWatcher(&watcher1);
+ OnEventObserved(mouse_pressed);
+ EXPECT_FALSE(watcher1.mouse_pressed());
+ EXPECT_TRUE(watcher2.mouse_pressed());
+ watcher1.Reset();
+ watcher2.Reset();
+
+ // Removing the last PointerWatcher stops sending events to it.
+ connection->RemovePointerWatcher(&watcher2);
+ OnEventObserved(mouse_pressed);
+ EXPECT_FALSE(watcher1.mouse_pressed());
+ EXPECT_FALSE(watcher1.touch_pressed());
+}
+
+} // namespace views
diff --git a/chromium/ui/views/mus/window_tree_host_mus.cc b/chromium/ui/views/mus/window_tree_host_mus.cc
index 2880c0bf480..e360eb05b46 100644
--- a/chromium/ui/views/mus/window_tree_host_mus.cc
+++ b/chromium/ui/views/mus/window_tree_host_mus.cc
@@ -4,6 +4,7 @@
#include "ui/views/mus/window_tree_host_mus.h"
+#include "base/memory/ptr_util.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
@@ -16,13 +17,12 @@ namespace views {
////////////////////////////////////////////////////////////////////////////////
// WindowTreeHostMus, public:
-WindowTreeHostMus::WindowTreeHostMus(mojo::Connector* connector,
+WindowTreeHostMus::WindowTreeHostMus(shell::Connector* connector,
NativeWidgetMus* native_widget,
mus::Window* window)
- : native_widget_(native_widget),
- show_state_(ui::PLATFORM_WINDOW_STATE_UNKNOWN) {
+ : native_widget_(native_widget) {
SetPlatformWindow(
- make_scoped_ptr(new PlatformWindowMus(this, connector, window)));
+ base::WrapUnique(new PlatformWindowMus(this, connector, window)));
// The location of events is already transformed, and there is no way to
// correctly determine the reverse transform. So, don't attempt to transform
// event locations, else the root location is wrong.
@@ -58,10 +58,6 @@ void WindowTreeHostMus::OnClosed() {
native_widget_->OnPlatformWindowClosed();
}
-void WindowTreeHostMus::OnWindowStateChanged(ui::PlatformWindowState state) {
- show_state_ = state;
-}
-
void WindowTreeHostMus::OnActivationChanged(bool active) {
if (active)
GetInputMethod()->OnFocus();
diff --git a/chromium/ui/views/mus/window_tree_host_mus.h b/chromium/ui/views/mus/window_tree_host_mus.h
index 0bffe25ea13..30da7ed2d3f 100644
--- a/chromium/ui/views/mus/window_tree_host_mus.h
+++ b/chromium/ui/views/mus/window_tree_host_mus.h
@@ -11,14 +11,14 @@
class SkBitmap;
-namespace mojo {
-class Connector;
-}
-
namespace mus {
class Window;
}
+namespace shell {
+class Connector;
+}
+
namespace views {
class InputMethodMUS;
@@ -27,25 +27,22 @@ class PlatformWindowMus;
class VIEWS_MUS_EXPORT WindowTreeHostMus : public aura::WindowTreeHostPlatform {
public:
- WindowTreeHostMus(mojo::Connector* connector,
+ WindowTreeHostMus(shell::Connector* connector,
NativeWidgetMus* native_widget,
mus::Window* window);
~WindowTreeHostMus() override;
PlatformWindowMus* platform_window();
- ui::PlatformWindowState show_state() const { return show_state_; }
private:
// aura::WindowTreeHostPlatform:
void DispatchEvent(ui::Event* event) override;
void OnClosed() override;
- void OnWindowStateChanged(ui::PlatformWindowState new_state) override;
void OnActivationChanged(bool active) override;
void OnCloseRequest() override;
NativeWidgetMus* native_widget_;
- scoped_ptr<InputMethodMUS> input_method_;
- ui::PlatformWindowState show_state_;
+ std::unique_ptr<InputMethodMUS> input_method_;
DISALLOW_COPY_AND_ASSIGN(WindowTreeHostMus);
};
diff --git a/chromium/ui/views/painter.cc b/chromium/ui/views/painter.cc
index 9a677956f84..d48a7ef2ef5 100644
--- a/chromium/ui/views/painter.cc
+++ b/chromium/ui/views/painter.cc
@@ -4,9 +4,11 @@
#include "ui/views/painter.h"
+#include <memory>
+
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
@@ -149,9 +151,9 @@ class GradientPainter : public Painter {
// If |horizontal_| is true then the gradient is painted horizontally.
bool horizontal_;
// The gradient colors.
- scoped_ptr<SkColor[]> colors_;
+ std::unique_ptr<SkColor[]> colors_;
// The relative positions of the corresponding gradient colors.
- scoped_ptr<SkScalar[]> pos_;
+ std::unique_ptr<SkScalar[]> pos_;
// The number of elements in |colors_| and |pos_|.
size_t count_;
@@ -216,7 +218,7 @@ class ImagePainter : public Painter {
void Paint(gfx::Canvas* canvas, const gfx::Size& size) override;
private:
- scoped_ptr<gfx::NineImagePainter> nine_painter_;
+ std::unique_ptr<gfx::NineImagePainter> nine_painter_;
DISALLOW_COPY_AND_ASSIGN(ImagePainter);
};
@@ -256,7 +258,8 @@ Painter::~Painter() {
void Painter::PaintPainterAt(gfx::Canvas* canvas,
Painter* painter,
const gfx::Rect& rect) {
- DCHECK(canvas && painter);
+ DCHECK(canvas);
+ DCHECK(painter);
canvas->Save();
canvas->Translate(rect.OffsetFromOrigin());
painter->Paint(canvas, rect.size());
@@ -313,21 +316,21 @@ Painter* Painter::CreateImageGridPainter(const int image_ids[]) {
}
// static
-scoped_ptr<Painter> Painter::CreateDashedFocusPainter() {
- return make_scoped_ptr(new DashedFocusPainter(gfx::Insets()));
+std::unique_ptr<Painter> Painter::CreateDashedFocusPainter() {
+ return base::WrapUnique(new DashedFocusPainter(gfx::Insets()));
}
// static
-scoped_ptr<Painter> Painter::CreateDashedFocusPainterWithInsets(
+std::unique_ptr<Painter> Painter::CreateDashedFocusPainterWithInsets(
const gfx::Insets& insets) {
- return make_scoped_ptr(new DashedFocusPainter(insets));
+ return base::WrapUnique(new DashedFocusPainter(insets));
}
// static
-scoped_ptr<Painter> Painter::CreateSolidFocusPainter(
+std::unique_ptr<Painter> Painter::CreateSolidFocusPainter(
SkColor color,
const gfx::Insets& insets) {
- return make_scoped_ptr(new SolidFocusPainter(color, insets));
+ return base::WrapUnique(new SolidFocusPainter(color, insets));
}
// HorizontalPainter ----------------------------------------------------------
diff --git a/chromium/ui/views/painter.h b/chromium/ui/views/painter.h
index 76cc996f50c..cffe1c166b4 100644
--- a/chromium/ui/views/painter.h
+++ b/chromium/ui/views/painter.h
@@ -7,9 +7,10 @@
#include <stddef.h>
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/nine_image_painter_factory.h"
#include "ui/views/views_export.h"
@@ -77,11 +78,12 @@ class VIEWS_EXPORT Painter {
static Painter* CreateImageGridPainter(const int image_ids[]);
// Factory methods for creating painters intended for rendering focus.
- static scoped_ptr<Painter> CreateDashedFocusPainter();
- static scoped_ptr<Painter> CreateDashedFocusPainterWithInsets(
+ static std::unique_ptr<Painter> CreateDashedFocusPainter();
+ static std::unique_ptr<Painter> CreateDashedFocusPainterWithInsets(
+ const gfx::Insets& insets);
+ static std::unique_ptr<Painter> CreateSolidFocusPainter(
+ SkColor color,
const gfx::Insets& insets);
- static scoped_ptr<Painter> CreateSolidFocusPainter(SkColor color,
- const gfx::Insets& insets);
// Returns the minimum size this painter can paint without obvious graphical
// problems (e.g. overlapping images).
diff --git a/chromium/ui/views/pointer_watcher.h b/chromium/ui/views/pointer_watcher.h
new file mode 100644
index 00000000000..2abc4cb42d2
--- /dev/null
+++ b/chromium/ui/views/pointer_watcher.h
@@ -0,0 +1,42 @@
+// Copyright 2016 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_VIEWS_POINTER_WATCHER_H_
+#define UI_VIEWS_POINTER_WATCHER_H_
+
+#include "ui/views/views_export.h"
+
+namespace gfx {
+class Point;
+}
+
+namespace ui {
+class MouseEvent;
+class TouchEvent;
+}
+
+namespace views {
+class Widget;
+
+// An interface for read-only observation of pointer events (in particular, the
+// events cannot be marked as handled). Only certain event types are supported.
+// The |target| is the top-level widget that will receive the event, if any.
+// NOTE: On mus this allows observation of events outside of windows owned
+// by the current process, in which case the |target| will be null. On mus
+// event.target() is always null.
+class VIEWS_EXPORT PointerWatcher {
+ public:
+ virtual ~PointerWatcher() {}
+
+ virtual void OnMousePressed(const ui::MouseEvent& event,
+ const gfx::Point& location_in_screen,
+ Widget* target) = 0;
+ virtual void OnTouchPressed(const ui::TouchEvent& event,
+ const gfx::Point& location_in_screen,
+ Widget* target) = 0;
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_POINTER_WATCHER_H_
diff --git a/chromium/ui/views/run_all_unittests.cc b/chromium/ui/views/run_all_unittests.cc
deleted file mode 100644
index 922343bdc91..00000000000
--- a/chromium/ui/views/run_all_unittests.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/path_service.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_paths.h"
-#include "ui/gl/test/gl_surface_test_support.h"
-
-#if defined(USE_AURA)
-#include "ui/aura/env.h"
-#endif
-
-namespace views {
-
-class ViewTestSuite : public base::TestSuite {
- public:
- ViewTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {}
-
- protected:
- void Initialize() override {
- base::TestSuite::Initialize();
- gfx::GLSurfaceTestSupport::InitializeOneOff();
- ui::RegisterPathProvider();
-
- base::FilePath ui_test_pak_path;
- ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
- ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
-#if defined(USE_AURA)
- aura::Env::CreateInstance(true);
-#endif
- }
-
- void Shutdown() override {
-#if defined(USE_AURA)
- aura::Env::DeleteInstance();
-#endif
- ui::ResourceBundle::CleanupSharedInstance();
- base::TestSuite::Shutdown();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ViewTestSuite);
-};
-
-int RunAllUnittests(int argc, char** argv) {
- ViewTestSuite test_suite(argc, argv);
-
- return base::LaunchUnitTests(
- argc, argv, base::Bind(&ViewTestSuite::Run,
- base::Unretained(&test_suite)));
-}
-
-} // namespace views
diff --git a/chromium/ui/views/run_all_unittests.h b/chromium/ui/views/run_all_unittests.h
deleted file mode 100644
index 43239f80772..00000000000
--- a/chromium/ui/views/run_all_unittests.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2016 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_VIEWS_RUN_ALL_UNITTESTS_H_
-#define UI_VIEWS_RUN_ALL_UNITTESTS_H_
-
-namespace views {
-
-int RunAllUnittests(int argc, char** argv);
-
-} // namespace
-
-#endif // UI_VIEWS_RUN_ALL_UNITTESTS_H_
diff --git a/chromium/ui/views/run_all_unittests_main.cc b/chromium/ui/views/run_all_unittests_main.cc
index 5b26c760050..f3b39f0e557 100644
--- a/chromium/ui/views/run_all_unittests_main.cc
+++ b/chromium/ui/views/run_all_unittests_main.cc
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/views/run_all_unittests.h"
+#include "ui/views/views_test_suite.h"
int main(int argc, char** argv) {
- views::RunAllUnittests(argc, argv);
+ return views::ViewsTestSuite(argc, argv).RunTests();
}
diff --git a/chromium/ui/views/style/mac/combobox_background_mac.cc b/chromium/ui/views/style/mac/combobox_background_mac.cc
index 31997b15b78..1a97a7e412a 100644
--- a/chromium/ui/views/style/mac/combobox_background_mac.cc
+++ b/chromium/ui/views/style/mac/combobox_background_mac.cc
@@ -7,35 +7,39 @@
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "ui/gfx/canvas.h"
+#include "ui/gfx/scoped_canvas.h"
#include "ui/native_theme/native_theme_mac.h"
-#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/view.h"
+using ui::NativeThemeMac;
+
namespace views {
-ComboboxBackgroundMac::ComboboxBackgroundMac() {}
+ComboboxBackgroundMac::ComboboxBackgroundMac(int container_width)
+ : container_width_(container_width) {}
ComboboxBackgroundMac::~ComboboxBackgroundMac() {}
void ComboboxBackgroundMac::Paint(gfx::Canvas* canvas, View* view) const {
- DCHECK_EQ(view->GetClassName(), Combobox::kViewClassName);
- Combobox* combobox = static_cast<Combobox*>(view);
+ gfx::RectF bounds(view->GetLocalBounds());
+ gfx::ScopedRTLFlipCanvas scoped_canvas(canvas, view->bounds());
- gfx::RectF bounds(combobox->GetLocalBounds());
// Inset the left side far enough to draw only the arrow button, and inset the
// other three sides by half a pixel so the edge of the background doesn't
// paint outside the border.
- bounds.Inset(bounds.width() - combobox->GetArrowButtonWidth(), 0.5, 0.5, 0.5);
+ bounds.Inset(bounds.width() - container_width_, 0.5, 0.5, 0.5);
- ui::NativeTheme::State state = ui::NativeTheme::kNormal;
- if (!combobox->enabled())
- state = ui::NativeTheme::kDisabled;
+ // TODO(tapted): Check whether the Widget is active, and use the NORMAL
+ // BackgroundType if it is inactive. Handling this properly also requires the
+ // control to observe the Widget for activation changes and invalidate.
+ NativeThemeMac::ButtonBackgroundType type =
+ NativeThemeMac::ButtonBackgroundType::HIGHLIGHTED;
+ if (!view->enabled())
+ type = NativeThemeMac::ButtonBackgroundType::DISABLED;
SkPaint paint;
paint.setShader(
- ui::NativeThemeMac::GetButtonBackgroundShader(
- state,
- bounds.height()));
+ NativeThemeMac::GetButtonBackgroundShader(type, bounds.height()));
paint.setStyle(SkPaint::kFill_Style);
paint.setAntiAlias(true);
diff --git a/chromium/ui/views/style/mac/combobox_background_mac.h b/chromium/ui/views/style/mac/combobox_background_mac.h
index 5be50858d75..353deab74d7 100644
--- a/chromium/ui/views/style/mac/combobox_background_mac.h
+++ b/chromium/ui/views/style/mac/combobox_background_mac.h
@@ -23,12 +23,17 @@ namespace views {
// Mac look and feel.
class ComboboxBackgroundMac : public Background {
public:
- ComboboxBackgroundMac();
+ // The |container_width| argument is the width of the "arrows" section from
+ // the diagram above, including any necessary padding around the actual arrow.
+ explicit ComboboxBackgroundMac(int container_width);
~ComboboxBackgroundMac() override;
// Background:
void Paint(gfx::Canvas* canvas, View* view) const override;
+
private:
+ int container_width_;
+
DISALLOW_COPY_AND_ASSIGN(ComboboxBackgroundMac);
};
diff --git a/chromium/ui/views/style/mac/dialog_button_border_mac.cc b/chromium/ui/views/style/mac/dialog_button_border_mac.cc
index 366fbc28e9c..232c66d9ce8 100644
--- a/chromium/ui/views/style/mac/dialog_button_border_mac.cc
+++ b/chromium/ui/views/style/mac/dialog_button_border_mac.cc
@@ -5,116 +5,62 @@
#include "ui/views/style/mac/dialog_button_border_mac.h"
#include "base/logging.h"
-#include "skia/ext/refptr.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDrawLooper.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/canvas.h"
+#include "ui/native_theme/native_theme_mac.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/custom_button.h"
+#include "ui/views/controls/button/label_button.h"
+
+using ui::NativeThemeMac;
namespace views {
namespace {
-// Type to map button states to a corresponding SkColor.
-typedef const SkColor ColorByState[Button::STATE_COUNT];
-
-// If a state is added, ColorByState will silently fill with zeros, so assert.
-static_assert(Button::STATE_COUNT == 4,
- "DialogButtonBorderMac assumes 4 button states.");
-
// Corner radius of rounded rectangles.
const SkScalar kCornerRadius = 2;
+const SkScalar kFocusCornerRadius = 4;
+const SkScalar kFocusRingThickness = 3;
-// Vertical offset of the drop shadow and the inner highlight shadow.
-const SkScalar kShadowOffsetY = 1;
-
-// Shadow blur radius of the inner highlight shadow.
-const double kInnerShadowBlurRadius = 2.0;
+const SkColor kDefaultBorderColor = SkColorSetARGB(0xF2, 0xBA, 0xBA, 0xBA);
+const SkColor kHighlightedBorderColor = SkColorSetARGB(0xFF, 0x52, 0x76, 0xFF);
+const SkColor kFocusRingColor = SkColorSetARGB(0x80, 0x3B, 0x9A, 0xFC);
// Default border insets, to provide text padding.
-const int kPaddingX = 14;
-const int kPaddingY = 4;
-
-sk_sp<SkShader> CreateButtonGradient(int height,
- Button::ButtonState state) {
- ColorByState start = {0xFFF0F0F0, 0xFFF4F4F4, 0xFFEBEBEB, 0xFFEDEDED};
- ColorByState end = {0xFFE0E0E0, 0xFFE4E4E4, 0xFFDBDBDB, 0xFFDEDEDE};
-
- SkPoint gradient_points[2];
- gradient_points[0].iset(0, 0);
- gradient_points[1].iset(0, height);
+const int kPaddingX = 19;
+const int kPaddingY = 7;
- SkColor gradient_colors[] = {start[state], start[state], end[state]};
- SkScalar gradient_positions[] = {0.0, 0.38, 1.0};
-
- return SkGradientShader::MakeLinear(
- gradient_points, gradient_colors, gradient_positions, 3,
- SkShader::kClamp_TileMode);
-}
-
-void DrawConstrainedButtonBackground(const SkRect& button_rect,
- SkCanvas* canvas,
- Button::ButtonState button_state) {
+void DrawDialogButtonBackground(const SkRect& button_rect,
+ SkCanvas* canvas,
+ const LabelButton& button) {
// Extend the size of the SkRect so the border stroke is drawn over it on all
// sides.
SkRect rect(button_rect);
rect.fRight += 1;
rect.fBottom += 1;
- SkPaint paint;
-
- // Drop Shadow.
- ColorByState shadow = {0x14000000, 0x1F000000, 0x00000000, 0x00000000};
- const double blur = 0.0;
- std::vector<gfx::ShadowValue> shadows(
- 1, gfx::ShadowValue(gfx::Vector2d(0, kShadowOffsetY), blur,
- shadow[button_state]));
- paint.setLooper(gfx::CreateShadowDrawLooper(shadows));
+ NativeThemeMac::ButtonBackgroundType type =
+ NativeThemeMac::ButtonBackgroundType::NORMAL;
+ if (!button.enabled() || button.state() == Button::STATE_DISABLED)
+ type = NativeThemeMac::ButtonBackgroundType::DISABLED;
+ else if (button.state() == Button::STATE_PRESSED)
+ type = NativeThemeMac::ButtonBackgroundType::PRESSED;
+ else if (DialogButtonBorderMac::ShouldRenderDefault(button))
+ type = NativeThemeMac::ButtonBackgroundType::HIGHLIGHTED;
// Background.
- paint.setShader(CreateButtonGradient(rect.height(), button_state));
+ SkPaint paint;
+ paint.setShader(
+ NativeThemeMac::GetButtonBackgroundShader(type, rect.height()));
paint.setStyle(SkPaint::kFill_Style);
paint.setFlags(SkPaint::kAntiAlias_Flag);
canvas->drawRoundRect(rect, kCornerRadius, kCornerRadius, paint);
}
-// Draws an inner box shadow inside a rounded rectangle of size |rect|. The
-// technique: draw a black "ring" around the outside of the button cell. Then
-// clip out everything except the shadow it casts. Works similar to Blink's
-// GraphicsContext::drawInnerShadow().
-void DrawRoundRectInnerShadow(const SkRect& rect,
- SkCanvas* canvas,
- SkColor shadow_color) {
- const gfx::Vector2d shadow_offset(0, kShadowOffsetY);
- SkRect outer(rect);
- outer.outset(abs(shadow_offset.x()) + kInnerShadowBlurRadius,
- abs(shadow_offset.y()) + kInnerShadowBlurRadius);
-
- SkPath path;
- path.addRect(outer);
- path.setFillType(SkPath::kEvenOdd_FillType);
- path.addRoundRect(rect, kCornerRadius, kCornerRadius); // Poke a hole.
-
- // Inset the clip to cater for the border stroke.
- SkPath clip;
- clip.addRoundRect(rect.makeInset(0.5, 0.5), kCornerRadius, kCornerRadius);
-
- SkPaint paint;
- std::vector<gfx::ShadowValue> shadows(
- 1, gfx::ShadowValue(shadow_offset, kInnerShadowBlurRadius, shadow_color));
- paint.setLooper(gfx::CreateShadowDrawLooper(shadows));
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(SK_ColorBLACK); // Note: Entirely clipped.
-
- canvas->save();
- canvas->clipPath(clip, SkRegion::kIntersect_Op, true /* antialias */);
- canvas->drawPath(path, paint);
- canvas->restore();
-}
-
} // namespace
DialogButtonBorderMac::DialogButtonBorderMac() {
@@ -123,39 +69,56 @@ DialogButtonBorderMac::DialogButtonBorderMac() {
DialogButtonBorderMac::~DialogButtonBorderMac() {}
+// static
+bool DialogButtonBorderMac::ShouldRenderDefault(const LabelButton& button) {
+ // TODO(tapted): Check whether the Widget is active, and only return true here
+ // if it is. Plumbing this requires default buttons to also observe Widget
+ // activations to ensure text and background colors are properly invalidated.
+ return button.is_default();
+}
+
void DialogButtonBorderMac::Paint(const View& view, gfx::Canvas* canvas) {
+ // Actually, |view| should be a LabelButton as well, but don't rely too much
+ // on RTTI.
DCHECK(CustomButton::AsCustomButton(&view));
- const CustomButton& button = static_cast<const CustomButton&>(view);
+ const LabelButton& button = static_cast<const LabelButton&>(view);
SkCanvas* canvas_skia = canvas->sk_canvas();
// Inset all sides for the rounded rectangle stroke. Inset again to make room
- // for the shadows (while keeping the text centered).
+ // for the shadows and static focus ring (while keeping the text centered).
SkRect sk_rect = gfx::RectToSkRect(view.GetLocalBounds());
- sk_rect.inset(2.0, 2.0);
+ sk_rect.inset(kFocusRingThickness, kFocusRingThickness);
- DrawConstrainedButtonBackground(sk_rect, canvas_skia, button.state());
+ DrawDialogButtonBackground(sk_rect, canvas_skia, button);
// Offset so that strokes are contained within the pixel boundary.
sk_rect.offset(0.5, 0.5);
- ColorByState highlight = {0xBFFFFFFF, 0xF2FFFFFF, 0x24000000, 0x00000000};
- DrawRoundRectInnerShadow(sk_rect, canvas_skia, highlight[button.state()]);
- // Border or focus ring.
+ // Border and focus ring.
+ SkColor border_color = kDefaultBorderColor;
+ if (button.state() == Button::STATE_PRESSED || ShouldRenderDefault(button))
+ border_color = kHighlightedBorderColor;
+
SkPaint paint;
- ColorByState border = {0x40000000, 0x4D000000, 0x4D000000, 0x1F000000};
- const SkColor focus_border = {0xFF5DA5FF};
- paint.setStrokeWidth(1);
paint.setStyle(SkPaint::kStroke_Style);
paint.setFlags(SkPaint::kAntiAlias_Flag);
- if (button.HasFocus() && button.state() != Button::STATE_PRESSED)
- paint.setColor(focus_border);
- else
- paint.setColor(border[button.state()]);
+ paint.setStrokeWidth(1);
+ paint.setColor(border_color);
canvas_skia->drawRoundRect(sk_rect, kCornerRadius, kCornerRadius, paint);
+
+ if (button.HasFocus()) {
+ paint.setStrokeWidth(kFocusRingThickness);
+ paint.setColor(kFocusRingColor);
+ sk_rect.inset(-1, -1);
+ canvas_skia->drawRoundRect(sk_rect, kFocusCornerRadius, kFocusCornerRadius,
+ paint);
+ }
}
gfx::Size DialogButtonBorderMac::GetMinimumSize() const {
- return gfx::Size(100, 30);
+ // Overridden by PlatformStyle. Here, just ensure the minimum size is
+ // consistent with the padding.
+ return gfx::Size(2 * kPaddingX, 2 * kPaddingY);
}
} // namespace views
diff --git a/chromium/ui/views/style/mac/dialog_button_border_mac.h b/chromium/ui/views/style/mac/dialog_button_border_mac.h
index a45bc48e574..b10b09a9b7e 100644
--- a/chromium/ui/views/style/mac/dialog_button_border_mac.h
+++ b/chromium/ui/views/style/mac/dialog_button_border_mac.h
@@ -11,6 +11,8 @@
namespace views {
+class LabelButton;
+
// Skia port of the default button style used for dialogs on Chrome Mac.
// Originally provided by ConstrainedWindowButton, which used Quartz-backed
// Cocoa drawing routines.
@@ -19,6 +21,9 @@ class VIEWS_EXPORT DialogButtonBorderMac : public LabelButtonBorder {
DialogButtonBorderMac();
~DialogButtonBorderMac() override;
+ // Whether the given |button| should get a highlighted background.
+ static bool ShouldRenderDefault(const LabelButton& button);
+
// views::Border:
void Paint(const View& view, gfx::Canvas* canvas) override;
gfx::Size GetMinimumSize() const override;
diff --git a/chromium/ui/views/style/mac/dialog_button_border_mac_unittest.cc b/chromium/ui/views/style/mac/dialog_button_border_mac_unittest.cc
index 471715b7613..950697481e1 100644
--- a/chromium/ui/views/style/mac/dialog_button_border_mac_unittest.cc
+++ b/chromium/ui/views/style/mac/dialog_button_border_mac_unittest.cc
@@ -5,6 +5,7 @@
#include "ui/views/style/mac/dialog_button_border_mac.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/compositor/canvas_painter.h"
@@ -26,11 +27,11 @@ class TestLabelButton : public LabelButton {
void set_provide_custom_border(bool value) { provide_custom_border_ = value; }
// LabelButton:
- scoped_ptr<LabelButtonBorder> CreateDefaultBorder() const override {
+ std::unique_ptr<LabelButtonBorder> CreateDefaultBorder() const override {
if (!provide_custom_border_)
return LabelButton::CreateDefaultBorder();
- return make_scoped_ptr(new LabelButtonAssetBorder(style()));
+ return base::WrapUnique(new LabelButtonAssetBorder(style()));
}
private:
@@ -113,12 +114,9 @@ TEST_F(DialogButtonBorderMacTest, DrawMinimumSize) {
EXPECT_LE(border_min_size.width(), view_preferred_size.width());
EXPECT_LE(border_min_size.height(), view_preferred_size.height());
- // Calling SetStyle(STYLE_BUTTON) sets a default minimum height that is larger
- // than the border minimum height. Override that to match the border.
- button.SetMinSize(gfx::Size());
- view_preferred_size = button.GetPreferredSize();
- EXPECT_EQ(border_min_size.width(), view_preferred_size.width());
- EXPECT_EQ(border_min_size.height(), view_preferred_size.height());
+ // Note that Mac's PlatformStyle specifies a minimum button size, but it
+ // shouldn't be larger than the size of the button's label plus border insets.
+ // If it was, a Button::SetMinSize() call would be needed here to override it.
button.SizeToPreferredSize();
EXPECT_EQ(view_preferred_size.width(), button.width());
@@ -147,19 +145,24 @@ TEST_F(DialogButtonBorderMacTest, DrawMinimumSize) {
// Test drawing with some text. The usual case.
TEST_F(DialogButtonBorderMacTest, DrawWithLabel) {
- TestLabelButton button("Label Text That Exceeds the Minimum Button Size");
+ TestLabelButton button("");
button.SetStyle(Button::STYLE_BUTTON);
button.SimulateAddToWidget();
EXPECT_TRUE(BorderIsDialogButton(button));
- button.SetMinSize(gfx::Size());
button.SizeToPreferredSize();
+ const gfx::Size no_label_size = button.size();
- // Long label, so the button width should be greater than in DrawMinimumSize.
- const gfx::Size border_min_size = DialogButtonBorderMacSize();
- EXPECT_LT(border_min_size.width(), button.width());
- EXPECT_EQ(border_min_size.height(), button.height());
+ button.SetText(
+ base::ASCIIToUTF16("Label Text That Exceeds the Minimum Button Size"));
+ button.SizeToPreferredSize();
+
+ // Long label, so the button width should be greater than the empty button.
+ EXPECT_LT(no_label_size.width(), button.width());
+
+ // The height shouldn't change.
+ EXPECT_EQ(no_label_size.height(), button.height());
TestPaintAllStates(&button, true);
}
diff --git a/chromium/ui/views/style/platform_style.cc b/chromium/ui/views/style/platform_style.cc
index 6719c9ba46b..e74281cdc88 100644
--- a/chromium/ui/views/style/platform_style.cc
+++ b/chromium/ui/views/style/platform_style.cc
@@ -4,9 +4,12 @@
#include "ui/views/style/platform_style.h"
+#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/shadow_value.h"
+#include "ui/native_theme/native_theme.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
@@ -14,10 +17,28 @@
#include "ui/views/controls/focusable_border.h"
#include "ui/views/controls/scrollbar/native_scroll_bar.h"
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#define DESKTOP_LINUX
+#endif
+
namespace views {
+namespace {
+
+#if !defined(DESKTOP_LINUX) && !defined(OS_MACOSX)
+// Default text and shadow colors for STYLE_BUTTON.
+const SkColor kStyleButtonTextColor = SK_ColorBLACK;
+const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
+#endif
+
+} // namespace
#if !defined(OS_MACOSX)
+const int PlatformStyle::kMinLabelButtonWidth = 70;
+const int PlatformStyle::kMinLabelButtonHeight = 33;
+const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = true;
+const bool PlatformStyle::kTextfieldDragVerticallyDragsToEnd = false;
+
// static
gfx::ImageSkia PlatformStyle::CreateComboboxArrow(bool is_enabled,
Combobox::Style style) {
@@ -26,38 +47,66 @@ gfx::ImageSkia PlatformStyle::CreateComboboxArrow(bool is_enabled,
}
// static
-scoped_ptr<FocusableBorder> PlatformStyle::CreateComboboxBorder() {
- return make_scoped_ptr(new FocusableBorder());
+std::unique_ptr<FocusableBorder> PlatformStyle::CreateComboboxBorder() {
+ return base::WrapUnique(new FocusableBorder());
}
// static
-scoped_ptr<Background> PlatformStyle::CreateComboboxBackground() {
+std::unique_ptr<Background> PlatformStyle::CreateComboboxBackground(
+ int shoulder_width) {
return nullptr;
}
// static
-scoped_ptr<LabelButtonBorder> PlatformStyle::CreateLabelButtonBorder(
+std::unique_ptr<LabelButtonBorder> PlatformStyle::CreateLabelButtonBorder(
Button::ButtonStyle style) {
if (!ui::MaterialDesignController::IsModeMaterial() ||
style != Button::STYLE_TEXTBUTTON) {
- return make_scoped_ptr(new LabelButtonAssetBorder(style));
+ return base::WrapUnique(new LabelButtonAssetBorder(style));
}
- scoped_ptr<LabelButtonBorder> border(new views::LabelButtonBorder());
+ std::unique_ptr<LabelButtonBorder> border(new views::LabelButtonBorder());
border->set_insets(views::LabelButtonAssetBorder::GetDefaultInsetsForStyle(
Button::STYLE_TEXTBUTTON));
return border;
}
// static
-scoped_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
- return make_scoped_ptr(new NativeScrollBar(is_horizontal));
+std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
+ return base::WrapUnique(new NativeScrollBar(is_horizontal));
+}
+
+// static
+SkColor PlatformStyle::TextColorForButton(
+ const ButtonColorByState& color_by_state,
+ const LabelButton& button) {
+ return color_by_state[button.state()];
+}
+
+#endif // OS_MACOSX
+
+#if !defined(DESKTOP_LINUX) && !defined(OS_MACOSX)
+// static
+void PlatformStyle::ApplyLabelButtonTextStyle(
+ Label* label,
+ ButtonColorByState* color_by_state) {
+ ButtonColorByState& colors = *color_by_state;
+ colors[Button::STATE_NORMAL] = kStyleButtonTextColor;
+ colors[Button::STATE_HOVERED] = kStyleButtonTextColor;
+ colors[Button::STATE_PRESSED] = kStyleButtonTextColor;
+
+ const ui::NativeTheme* theme = label->GetNativeTheme();
+ label->SetBackgroundColor(
+ theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonBackgroundColor));
+ label->SetAutoColorReadabilityEnabled(false);
+ label->SetShadows(gfx::ShadowValues(
+ 1, gfx::ShadowValue(gfx::Vector2d(0, 1), 0, kStyleButtonShadowColor)));
}
#endif
-#if !defined(OS_LINUX) || defined(OS_CHROMEOS)
+#if !defined(DESKTOP_LINUX)
// static
-scoped_ptr<Border> PlatformStyle::CreateThemedLabelButtonBorder(
+std::unique_ptr<Border> PlatformStyle::CreateThemedLabelButtonBorder(
LabelButton* button) {
return button->CreateDefaultBorder();
}
diff --git a/chromium/ui/views/style/platform_style.h b/chromium/ui/views/style/platform_style.h
index 3103691642a..3a6392622d4 100644
--- a/chromium/ui/views/style/platform_style.h
+++ b/chromium/ui/views/style/platform_style.h
@@ -5,22 +5,39 @@
#ifndef UI_VIEWS_STYLE_PLATFORM_STYLE_H_
#define UI_VIEWS_STYLE_PLATFORM_STYLE_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/combobox/combobox.h"
+#include "ui/views/views_export.h"
namespace views {
class Border;
class FocusableBorder;
+class Label;
class LabelButton;
class LabelButtonBorder;
class ScrollBar;
// Cross-platform API for providing platform-specific styling for toolkit-views.
-class PlatformStyle {
+class VIEWS_EXPORT PlatformStyle {
public:
+ // Type used by LabelButton to map button states to text colors.
+ using ButtonColorByState = SkColor[Button::STATE_COUNT];
+
+ // Minimum size for platform-styled buttons (Button::STYLE_BUTTON).
+ static const int kMinLabelButtonWidth;
+ static const int kMinLabelButtonHeight;
+
+ // Whether dialog-default buttons are given a bold font style.
+ static const bool kDefaultLabelButtonHasBoldFont;
+
+ // Whether dragging vertically above or below a textfield's bounds selects to
+ // the left or right end of the text from the cursor, respectively.
+ static const bool kTextfieldDragVerticallyDragsToEnd;
+
// Creates an ImageSkia containing the image to use for the combobox arrow.
// The |is_enabled| argument is true if the control the arrow is for is
// enabled, and false if the control is disabled. The |style| argument is the
@@ -29,21 +46,33 @@ class PlatformStyle {
Combobox::Style style);
// Creates the appropriate border for a focusable Combobox.
- static scoped_ptr<FocusableBorder> CreateComboboxBorder();
+ static std::unique_ptr<FocusableBorder> CreateComboboxBorder();
// Creates the appropriate background for a Combobox.
- static scoped_ptr<Background> CreateComboboxBackground();
+ static std::unique_ptr<Background> CreateComboboxBackground(
+ int shoulder_width);
// Creates the default label button border for the given |style|. Used when a
// custom default border is not provided for a particular LabelButton class.
- static scoped_ptr<LabelButtonBorder> CreateLabelButtonBorder(
+ static std::unique_ptr<LabelButtonBorder> CreateLabelButtonBorder(
Button::ButtonStyle style);
- // Applies the current system theme to the default border created by |button|.
- static scoped_ptr<Border> CreateThemedLabelButtonBorder(LabelButton* button);
-
// Creates the default scrollbar for the given orientation.
- static scoped_ptr<ScrollBar> CreateScrollBar(bool is_horizontal);
+ static std::unique_ptr<ScrollBar> CreateScrollBar(bool is_horizontal);
+
+ // Returns the current text color for the current button state.
+ static SkColor TextColorForButton(const ButtonColorByState& color_by_state,
+ const LabelButton& button);
+
+ // Applies platform styles to |label| and fills |color_by_state| with the text
+ // colors for normal, pressed, hovered, and disabled states, if the colors for
+ // Button::STYLE_BUTTON buttons differ from those provided by ui::NativeTheme.
+ static void ApplyLabelButtonTextStyle(Label* label,
+ ButtonColorByState* color_by_state);
+
+ // Applies the current system theme to the default border created by |button|.
+ static std::unique_ptr<Border> CreateThemedLabelButtonBorder(
+ LabelButton* button);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformStyle);
diff --git a/chromium/ui/views/style/platform_style_linux.cc b/chromium/ui/views/style/platform_style_linux.cc
index 36e3de58f4d..3e644c4be45 100644
--- a/chromium/ui/views/style/platform_style_linux.cc
+++ b/chromium/ui/views/style/platform_style_linux.cc
@@ -11,7 +11,7 @@
namespace views {
// static
-scoped_ptr<Border> PlatformStyle::CreateThemedLabelButtonBorder(
+std::unique_ptr<Border> PlatformStyle::CreateThemedLabelButtonBorder(
LabelButton* button) {
views::LinuxUI* linux_ui = views::LinuxUI::instance();
if (linux_ui)
@@ -19,4 +19,12 @@ scoped_ptr<Border> PlatformStyle::CreateThemedLabelButtonBorder(
return button->CreateDefaultBorder();
}
+void PlatformStyle::ApplyLabelButtonTextStyle(Label* label,
+ ButtonColorByState* colors) {
+ // TODO(erg): This is disabled on desktop linux because of the binary asset
+ // confusion. These details should either be pushed into ui::NativeThemeWin
+ // or should be obsoleted by rendering buttons with paint calls instead of
+ // with static assets. http://crbug.com/350498
+}
+
} // namespace views
diff --git a/chromium/ui/views/style/platform_style_mac.mm b/chromium/ui/views/style/platform_style_mac.mm
index cbe9be51ce1..5e06da5d281 100644
--- a/chromium/ui/views/style/platform_style_mac.mm
+++ b/chromium/ui/views/style/platform_style_mac.mm
@@ -4,6 +4,7 @@
#include "ui/views/style/platform_style.h"
+#include "base/memory/ptr_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icons.h"
@@ -17,6 +18,11 @@
namespace views {
+const int PlatformStyle::kMinLabelButtonWidth = 32;
+const int PlatformStyle::kMinLabelButtonHeight = 30;
+const bool PlatformStyle::kDefaultLabelButtonHasBoldFont = false;
+const bool PlatformStyle::kTextfieldDragVerticallyDragsToEnd = true;
+
// static
gfx::ImageSkia PlatformStyle::CreateComboboxArrow(bool is_enabled,
Combobox::Style style) {
@@ -33,27 +39,52 @@ gfx::ImageSkia PlatformStyle::CreateComboboxArrow(bool is_enabled,
}
// static
-scoped_ptr<FocusableBorder> PlatformStyle::CreateComboboxBorder() {
- return make_scoped_ptr(new FocusableRoundedBorder);
+std::unique_ptr<FocusableBorder> PlatformStyle::CreateComboboxBorder() {
+ return base::WrapUnique(new FocusableRoundedBorder);
}
// static
-scoped_ptr<Background> PlatformStyle::CreateComboboxBackground() {
- return make_scoped_ptr(new ComboboxBackgroundMac);
+std::unique_ptr<Background> PlatformStyle::CreateComboboxBackground(
+ int shoulder_width) {
+ return base::WrapUnique(new ComboboxBackgroundMac(shoulder_width));
}
// static
-scoped_ptr<LabelButtonBorder> PlatformStyle::CreateLabelButtonBorder(
+std::unique_ptr<LabelButtonBorder> PlatformStyle::CreateLabelButtonBorder(
Button::ButtonStyle style) {
if (style == Button::STYLE_BUTTON)
- return make_scoped_ptr(new DialogButtonBorderMac());
+ return base::WrapUnique(new DialogButtonBorderMac());
+
+ return base::WrapUnique(new LabelButtonAssetBorder(style));
+}
+
+// static
+std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
+ return base::WrapUnique(new CocoaScrollBar(is_horizontal));
+}
- return make_scoped_ptr(new LabelButtonAssetBorder(style));
+// static
+SkColor PlatformStyle::TextColorForButton(
+ const ButtonColorByState& color_by_state,
+ const LabelButton& button) {
+ Button::ButtonState state = button.state();
+ if (button.style() == Button::STYLE_BUTTON &&
+ DialogButtonBorderMac::ShouldRenderDefault(button)) {
+ // For convenience, we currently assume Mac wants the color corresponding to
+ // the pressed state for default buttons.
+ state = Button::STATE_PRESSED;
+ }
+ return color_by_state[state];
}
// static
-scoped_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
- return make_scoped_ptr(new CocoaScrollBar(is_horizontal));
+void PlatformStyle::ApplyLabelButtonTextStyle(
+ views::Label* label,
+ ButtonColorByState* color_by_state) {
+ const ui::NativeTheme* theme = label->GetNativeTheme();
+ ButtonColorByState& colors = *color_by_state;
+ colors[Button::STATE_PRESSED] =
+ theme->GetSystemColor(ui::NativeTheme::kColorId_ButtonHighlightColor);
}
} // namespace views
diff --git a/chromium/ui/views/touchui/touch_selection_controller_impl.cc b/chromium/ui/views/touchui/touch_selection_controller_impl.cc
index c0e4ef943a6..8508ffc55aa 100644
--- a/chromium/ui/views/touchui/touch_selection_controller_impl.cc
+++ b/chromium/ui/views/touchui/touch_selection_controller_impl.cc
@@ -16,7 +16,6 @@
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/path.h"
-#include "ui/gfx/screen.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/resources/grit/views_resources.h"
@@ -126,7 +125,7 @@ gfx::Image* GetHandleImage(ui::SelectionBound::Type bound_type) {
case ui::SelectionBound::RIGHT:
return GetRightHandleImage();
default:
- NOTREACHED() << "Invalid touch handle bound type.";
+ NOTREACHED() << "Invalid touch handle bound type: " << bound_type;
return nullptr;
};
}
@@ -241,7 +240,7 @@ class TouchSelectionControllerImpl::EditingHandleView
widget_->SetContentsView(this);
aura::Window* window = widget_->GetNativeWindow();
- window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
+ window->SetEventTargeter(std::unique_ptr<ui::EventTargeter>(
new TouchHandleWindowTargeter(window, this)));
// We are owned by the TouchSelectionControllerImpl.
@@ -250,6 +249,10 @@ class TouchSelectionControllerImpl::EditingHandleView
~EditingHandleView() override { SetWidgetVisible(false, false); }
+ ui::SelectionBound::Type selection_bound_type() {
+ return selection_bound_.type();
+ }
+
// Overridden from views::WidgetDelegateView:
bool WidgetHasHitTestMask() const override { return true; }
@@ -337,7 +340,11 @@ class TouchSelectionControllerImpl::EditingHandleView
widget_->Hide();
}
- void SetBoundInScreen(const ui::SelectionBound& bound) {
+ // If |is_visible| is true, this will update the widget and trigger a repaint
+ // if necessary. Otherwise this will only update the internal state:
+ // |selection_bound_| and |image_|, so that the state is valid for the time
+ // this becomes visible.
+ void SetBoundInScreen(const ui::SelectionBound& bound, bool is_visible) {
bool update_bound_type = false;
// Cursor handle should always have the bound type CENTER
DCHECK(!is_cursor_handle_ || bound.type() == ui::SelectionBound::CENTER);
@@ -354,8 +361,13 @@ class TouchSelectionControllerImpl::EditingHandleView
if (update_bound_type) {
selection_bound_.set_type(bound.type());
image_ = GetHandleImage(bound.type());
- SchedulePaint();
+ if (is_visible)
+ SchedulePaint();
}
+
+ if (!is_visible)
+ return;
+
selection_bound_.SetEdge(bound.edge_top(), bound.edge_bottom());
widget_->SetBounds(GetSelectionWidgetBounds(selection_bound_));
@@ -376,7 +388,7 @@ class TouchSelectionControllerImpl::EditingHandleView
}
private:
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
TouchSelectionControllerImpl* controller_;
// In local coordinates
@@ -493,7 +505,7 @@ void TouchSelectionControllerImpl::SelectionChanged() {
// If the new location of this handle is out of client view, its widget
// should not get hidden, since it should still receive touch events.
// Hence, we are not using |SetHandleBound()| method here.
- dragging_handle_->SetBoundInScreen(screen_bound_focus_clipped);
+ dragging_handle_->SetBoundInScreen(screen_bound_focus_clipped, true);
// Temporary fix for selection handle going outside a window. On a webpage,
// the page should scroll if the selection handle is dragged outside the
@@ -593,8 +605,7 @@ void TouchSelectionControllerImpl::SetHandleBound(
const ui::SelectionBound& bound,
const ui::SelectionBound& bound_in_screen) {
handle->SetWidgetVisible(ShouldShowHandleFor(bound), false);
- if (handle->IsWidgetVisible())
- handle->SetBoundInScreen(bound_in_screen);
+ handle->SetBoundInScreen(bound_in_screen, handle->IsWidgetVisible());
}
bool TouchSelectionControllerImpl::ShouldShowHandleFor(
@@ -740,6 +751,11 @@ gfx::NativeView TouchSelectionControllerImpl::GetCursorHandleNativeView() {
return cursor_handle_->GetWidget()->GetNativeView();
}
+ui::SelectionBound::Type
+TouchSelectionControllerImpl::GetSelectionHandle1Type() {
+ return selection_handle_1_->selection_bound_type();
+}
+
gfx::Rect TouchSelectionControllerImpl::GetSelectionHandle1Bounds() {
return selection_handle_1_->GetBoundsInScreen();
}
diff --git a/chromium/ui/views/touchui/touch_selection_controller_impl.h b/chromium/ui/views/touchui/touch_selection_controller_impl.h
index 006b89782dc..1580bfb1f5c 100644
--- a/chromium/ui/views/touchui/touch_selection_controller_impl.h
+++ b/chromium/ui/views/touchui/touch_selection_controller_impl.h
@@ -110,6 +110,7 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
// Convenience methods for testing.
gfx::NativeView GetCursorHandleNativeView();
+ ui::SelectionBound::Type GetSelectionHandle1Type();
gfx::Rect GetSelectionHandle1Bounds();
gfx::Rect GetSelectionHandle2Bounds();
gfx::Rect GetCursorHandleBounds();
@@ -122,9 +123,9 @@ class VIEWS_EXPORT TouchSelectionControllerImpl
ui::TouchEditable* client_view_;
Widget* client_widget_;
- scoped_ptr<EditingHandleView> selection_handle_1_;
- scoped_ptr<EditingHandleView> selection_handle_2_;
- scoped_ptr<EditingHandleView> cursor_handle_;
+ std::unique_ptr<EditingHandleView> selection_handle_1_;
+ std::unique_ptr<EditingHandleView> selection_handle_2_;
+ std::unique_ptr<EditingHandleView> cursor_handle_;
bool command_executed_;
base::TimeTicks selection_start_time_;
diff --git a/chromium/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/chromium/ui/views/touchui/touch_selection_controller_impl_unittest.cc
index 3bdbbd5f6c5..602795aec8f 100644
--- a/chromium/ui/views/touchui/touch_selection_controller_impl_unittest.cc
+++ b/chromium/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -181,6 +181,10 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
return GetSelectionController()->GetCursorHandleNativeView();
}
+ ui::SelectionBound::Type GetSelectionHandle1Type() {
+ return GetSelectionController()->GetSelectionHandle1Type();
+ }
+
gfx::Rect GetSelectionHandle1Bounds() {
return GetSelectionController()->GetSelectionHandle1Bounds();
}
@@ -269,13 +273,43 @@ class TouchSelectionControllerImplTest : public ViewsTestBase {
}
}
+ // Sets up a textfield with a long text string such that it doesn't all fit
+ // into the textfield. Then selects the text - the first handle is expected
+ // to be invisible. |selection_start| is the position of the first handle.
+ void SetupSelectionInvisibleHandle(uint32_t selection_start) {
+ // Create a textfield with lots of text in it.
+ CreateTextfield();
+ std::string some_text("some text");
+ std::string textfield_text;
+ for (int i = 0; i < 10; ++i)
+ textfield_text += some_text;
+ textfield_->SetText(ASCIIToUTF16(textfield_text));
+
+ // Tap the textfield to invoke selection.
+ ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
+ details.set_tap_count(1);
+ ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
+ textfield_->OnGestureEvent(&tap);
+
+ // Select some text such that one handle is hidden.
+ textfield_->SelectRange(gfx::Range(
+ selection_start, static_cast<uint32_t>(textfield_text.length())));
+
+ // Check that one selection handle is hidden.
+ EXPECT_FALSE(IsSelectionHandle1Visible());
+ EXPECT_TRUE(IsSelectionHandle2Visible());
+ EXPECT_EQ(gfx::Range(selection_start,
+ static_cast<uint32_t>(textfield_text.length())),
+ textfield_->GetSelectedRange());
+ }
+
Widget* textfield_widget_;
Widget* widget_;
Textfield* textfield_;
- scoped_ptr<TextfieldTestApi> textfield_test_api_;
- scoped_ptr<ViewsTouchEditingControllerFactory> views_tsc_factory_;
- scoped_ptr<aura::test::TestCursorClient> test_cursor_client_;
+ std::unique_ptr<TextfieldTestApi> textfield_test_api_;
+ std::unique_ptr<ViewsTouchEditingControllerFactory> views_tsc_factory_;
+ std::unique_ptr<aura::test::TestCursorClient> test_cursor_client_;
private:
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest);
@@ -539,29 +573,8 @@ TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) {
TEST_F(TouchSelectionControllerImplTest,
HiddenSelectionHandleRetainsCursorPosition) {
- // Create a textfield with lots of text in it.
- CreateTextfield();
- std::string textfield_text("some text");
- for (int i = 0; i < 10; ++i)
- textfield_text += textfield_text;
- textfield_->SetText(ASCIIToUTF16(textfield_text));
-
- // Tap the textfield to invoke selection.
- ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
- details.set_tap_count(1);
- ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
- textfield_->OnGestureEvent(&tap);
-
- // Select some text such that one handle is hidden.
- textfield_->SelectRange(
- gfx::Range(10u, static_cast<uint32_t>(textfield_text.length())));
-
- // Check that one selection handle is hidden.
- EXPECT_FALSE(IsSelectionHandle1Visible());
- EXPECT_TRUE(IsSelectionHandle2Visible());
- EXPECT_EQ(
- gfx::Range(10u, static_cast<uint32_t>(textfield_text.length())),
- textfield_->GetSelectedRange());
+ static const uint32_t selection_start = 10u;
+ SetupSelectionInvisibleHandle(selection_start);
// Drag the visible handle around and make sure the selection end point of the
// invisible handle does not change.
@@ -576,6 +589,24 @@ TEST_F(TouchSelectionControllerImplTest,
}
}
+// Tests that we can handle the hidden handle getting exposed as a result of a
+// drag and that it maintains the correct orientation when exposed.
+TEST_F(TouchSelectionControllerImplTest, HiddenSelectionHandleExposed) {
+ static const uint32_t selection_start = 0u;
+ SetupSelectionInvisibleHandle(selection_start);
+
+ // Drag the handle until the selection shrinks such that the other handle
+ // becomes visible.
+ while (!IsSelectionHandle1Visible()) {
+ static const int drag_diff = -10;
+ SimulateSelectionHandleDrag(gfx::Vector2d(drag_diff, 0), 2);
+ }
+
+ // Confirm that the exposed handle maintains the LEFT orientation
+ // (and does not reset to ui::SelectionBound::Type::CENTER).
+ EXPECT_EQ(ui::SelectionBound::Type::LEFT, GetSelectionHandle1Type());
+}
+
TEST_F(TouchSelectionControllerImplTest,
DoubleTapInTextfieldWithCursorHandleShouldSelectText) {
CreateTextfield();
@@ -685,8 +716,9 @@ TEST_F(TouchSelectionControllerImplTest,
CreateWidget();
TestTouchEditable touch_editable(widget_->GetNativeView());
- scoped_ptr<ui::TouchEditingControllerDeprecated> touch_selection_controller(
- ui::TouchEditingControllerDeprecated::Create(&touch_editable));
+ std::unique_ptr<ui::TouchEditingControllerDeprecated>
+ touch_selection_controller(
+ ui::TouchEditingControllerDeprecated::Create(&touch_editable));
touch_editable.set_bounds(gfx::Rect(0, 0, 100, 20));
diff --git a/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc b/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc
index d5928a3353d..b506f787de5 100644
--- a/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc
+++ b/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc
@@ -16,7 +16,7 @@
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/text_utils.h"
#include "ui/strings/grit/ui_strings.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/layout/box_layout.h"
@@ -37,8 +37,8 @@ const int kEllipsesButtonTag = -1;
} // namespace
// A bubble that contains actions available for the selected text. An object of
-// this type, as a BubbleDelegateView, manages its own lifetime.
-class TouchSelectionMenuRunnerViews::Menu : public BubbleDelegateView,
+// this type, as a BubbleDialogDelegateView, manages its own lifetime.
+class TouchSelectionMenuRunnerViews::Menu : public BubbleDialogDelegateView,
public ButtonListener {
public:
Menu(TouchSelectionMenuRunnerViews* owner,
@@ -51,7 +51,7 @@ class TouchSelectionMenuRunnerViews::Menu : public BubbleDelegateView,
static bool IsMenuAvailable(const ui::TouchSelectionMenuClient* client);
// Closes the menu. This will eventually self-destroy the object.
- void Close();
+ void CloseMenu();
private:
friend class TouchSelectionMenuRunnerViews::TestApi;
@@ -68,9 +68,10 @@ class TouchSelectionMenuRunnerViews::Menu : public BubbleDelegateView,
// Helper to disconnect this menu object from its owning menu runner.
void DisconnectOwner();
- // BubbleDelegateView:
+ // BubbleDialogDelegateView:
void OnPaint(gfx::Canvas* canvas) override;
void WindowClosing() override;
+ int GetDialogButtons() const override;
// ButtonListener:
void ButtonPressed(Button* sender, const ui::Event& event) override;
@@ -86,7 +87,7 @@ TouchSelectionMenuRunnerViews::Menu::Menu(TouchSelectionMenuRunnerViews* owner,
const gfx::Rect& anchor_rect,
const gfx::Size& handle_image_size,
aura::Window* context)
- : BubbleDelegateView(nullptr, BubbleBorder::BOTTOM_CENTER),
+ : BubbleDialogDelegateView(nullptr, BubbleBorder::BOTTOM_CENTER),
owner_(owner),
client_(client) {
DCHECK(owner_);
@@ -117,7 +118,7 @@ TouchSelectionMenuRunnerViews::Menu::Menu(TouchSelectionMenuRunnerViews* owner,
adjusted_anchor_rect.Inset(0, 0, 0, -handle_image_size.height());
SetAnchorRect(adjusted_anchor_rect);
- BubbleDelegateView::CreateBubble(this);
+ BubbleDialogDelegateView::CreateBubble(this);
GetWidget()->Show();
}
@@ -159,8 +160,7 @@ Button* TouchSelectionMenuRunnerViews::Menu::CreateButton(
gfx::RemoveAcceleratorChar(title, '&', nullptr, nullptr);
LabelButton* button = new LabelButton(this, label);
button->SetMinSize(gfx::Size(kMenuButtonMinWidth, kMenuButtonMinHeight));
- button->SetFocusable(true);
- button->set_request_focus_on_press(false);
+ button->SetFocusForPlatform();
const gfx::FontList& font_list =
ui::ResourceBundle::GetSharedInstance().GetFontList(
ui::ResourceBundle::SmallFont);
@@ -170,7 +170,7 @@ Button* TouchSelectionMenuRunnerViews::Menu::CreateButton(
return button;
}
-void TouchSelectionMenuRunnerViews::Menu::Close() {
+void TouchSelectionMenuRunnerViews::Menu::CloseMenu() {
DisconnectOwner();
// Closing the widget will self-destroy this object.
Widget* widget = GetWidget();
@@ -185,7 +185,7 @@ void TouchSelectionMenuRunnerViews::Menu::DisconnectOwner() {
}
void TouchSelectionMenuRunnerViews::Menu::OnPaint(gfx::Canvas* canvas) {
- BubbleDelegateView::OnPaint(canvas);
+ BubbleDialogDelegateView::OnPaint(canvas);
// Draw separator bars.
for (int i = 0; i < child_count() - 1; ++i) {
@@ -198,15 +198,19 @@ void TouchSelectionMenuRunnerViews::Menu::OnPaint(gfx::Canvas* canvas) {
void TouchSelectionMenuRunnerViews::Menu::WindowClosing() {
DCHECK(!owner_ || owner_->menu_ == this);
- BubbleDelegateView::WindowClosing();
+ BubbleDialogDelegateView::WindowClosing();
if (owner_)
DisconnectOwner();
}
+int TouchSelectionMenuRunnerViews::Menu::GetDialogButtons() const {
+ return ui::DIALOG_BUTTON_NONE;
+}
+
void TouchSelectionMenuRunnerViews::Menu::ButtonPressed(
Button* sender,
const ui::Event& event) {
- Close();
+ CloseMenu();
if (sender->tag() != kEllipsesButtonTag)
client_->ExecuteCommand(sender->tag(), event.flags());
else
@@ -264,7 +268,7 @@ void TouchSelectionMenuRunnerViews::CloseMenu() {
return;
// Closing the menu sets |menu_| to nullptr and eventually deletes the object.
- menu_->Close();
+ menu_->CloseMenu();
DCHECK(!menu_);
}
diff --git a/chromium/ui/views/touchui/touch_selection_menu_runner_views.h b/chromium/ui/views/touchui/touch_selection_menu_runner_views.h
index 03a8967afa5..0ce40600a99 100644
--- a/chromium/ui/views/touchui/touch_selection_menu_runner_views.h
+++ b/chromium/ui/views/touchui/touch_selection_menu_runner_views.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_TOUCHUI_TOUCH_SELECTION_MENU_RUNNER_VIEWS_H_
#define UI_VIEWS_TOUCHUI_TOUCH_SELECTION_MENU_RUNNER_VIEWS_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/touch_selection/touch_selection_menu_runner.h"
#include "ui/views/views_export.h"
diff --git a/chromium/ui/views/view.cc b/chromium/ui/views/view.cc
index d733034153b..be3bbf5b7ed 100644
--- a/chromium/ui/views/view.cc
+++ b/chromium/ui/views/view.cc
@@ -8,11 +8,12 @@
#include <algorithm>
#include <cmath>
+#include <memory>
#include <utility>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
@@ -32,6 +33,7 @@
#include "ui/compositor/paint_context.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/compositor/transform_recorder.h"
+#include "ui/display/screen.h"
#include "ui/events/event_target_iterator.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/point3_f.h"
@@ -39,7 +41,6 @@
#include "ui/gfx/interpolated_transform.h"
#include "ui/gfx/path.h"
#include "ui/gfx/scoped_canvas.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
#include "ui/native_theme/native_theme.h"
@@ -114,8 +115,7 @@ View::View()
registered_accelerator_count_(0),
next_focusable_view_(NULL),
previous_focusable_view_(NULL),
- focusable_(false),
- accessibility_focusable_(false),
+ focus_behavior_(FocusBehavior::NEVER),
context_menu_controller_(NULL),
drag_controller_(NULL),
native_view_accessibility_(NULL) {
@@ -479,8 +479,8 @@ void View::SetPaintToLayer(bool paint_to_layer) {
}
}
-scoped_ptr<ui::Layer> View::RecreateLayer() {
- scoped_ptr<ui::Layer> old_layer = LayerOwner::RecreateLayer();
+std::unique_ptr<ui::Layer> View::RecreateLayer() {
+ std::unique_ptr<ui::Layer> old_layer = LayerOwner::RecreateLayer();
Widget* widget = GetWidget();
if (widget)
widget->UpdateRootLayers();
@@ -858,7 +858,7 @@ void View::set_background(Background* b) {
background_.reset(b);
}
-void View::SetBorder(scoped_ptr<Border> b) {
+void View::SetBorder(std::unique_ptr<Border> b) {
border_ = std::move(b);
}
@@ -953,7 +953,7 @@ bool View::IsMouseHovered() const {
if (!GetWidget()->IsMouseEventsEnabled())
return false;
- gfx::Point cursor_pos(gfx::Screen::GetScreen()->GetCursorScreenPoint());
+ gfx::Point cursor_pos(display::Screen::GetScreen()->GetCursorScreenPoint());
ConvertPointFromScreen(this, &cursor_pos);
return HitTestPoint(cursor_pos);
}
@@ -1066,9 +1066,9 @@ const ui::InputMethod* View::GetInputMethod() const {
: nullptr;
}
-scoped_ptr<ViewTargeter>
-View::SetEventTargeter(scoped_ptr<ViewTargeter> targeter) {
- scoped_ptr<ViewTargeter> old_targeter = std::move(targeter_);
+std::unique_ptr<ViewTargeter> View::SetEventTargeter(
+ std::unique_ptr<ViewTargeter> targeter) {
+ std::unique_ptr<ViewTargeter> old_targeter = std::move(targeter_);
targeter_ = std::move(targeter);
return old_targeter;
}
@@ -1090,8 +1090,8 @@ ui::EventTarget* View::GetParentTarget() {
return parent_;
}
-scoped_ptr<ui::EventTargetIterator> View::GetChildIterator() const {
- return make_scoped_ptr(new ui::EventTargetIteratorImpl<View>(children_));
+std::unique_ptr<ui::EventTargetIterator> View::GetChildIterator() const {
+ return base::WrapUnique(new ui::EventTargetIteratorImpl<View>(children_));
}
ui::EventTargeter* View::GetEventTargeter() {
@@ -1198,28 +1198,20 @@ void View::SetNextFocusableView(View* view) {
next_focusable_view_ = view;
}
-void View::SetFocusable(bool focusable) {
- if (focusable_ == focusable)
+void View::SetFocusBehavior(FocusBehavior focus_behavior) {
+ if (focus_behavior_ == focus_behavior)
return;
- focusable_ = focusable;
+ focus_behavior_ = focus_behavior;
AdvanceFocusIfNecessary();
}
bool View::IsFocusable() const {
- return focusable_ && enabled_ && IsDrawn();
+ return focus_behavior_ == FocusBehavior::ALWAYS && enabled_ && IsDrawn();
}
bool View::IsAccessibilityFocusable() const {
- return (focusable_ || accessibility_focusable_) && enabled_ && IsDrawn();
-}
-
-void View::SetAccessibilityFocusable(bool accessibility_focusable) {
- if (accessibility_focusable_ == accessibility_focusable)
- return;
-
- accessibility_focusable_ = accessibility_focusable;
- AdvanceFocusIfNecessary();
+ return focus_behavior_ != FocusBehavior::NEVER && enabled_ && IsDrawn();
}
FocusManager* View::GetFocusManager() {
@@ -1234,8 +1226,13 @@ const FocusManager* View::GetFocusManager() const {
void View::RequestFocus() {
FocusManager* focus_manager = GetFocusManager();
- if (focus_manager && IsFocusable())
- focus_manager->SetFocusedView(this);
+ if (focus_manager) {
+ bool focusable = focus_manager->keyboard_accessible()
+ ? IsAccessibilityFocusable()
+ : IsFocusable();
+ if (focusable)
+ focus_manager->SetFocusedView(this);
+ }
}
bool View::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
@@ -1808,7 +1805,7 @@ void View::DoRemoveChildView(View* view,
if (i == children_.end())
return;
- scoped_ptr<View> view_to_be_deleted;
+ std::unique_ptr<View> view_to_be_deleted;
if (update_focus_cycle) {
View* next_focusable = view->next_focusable_view_;
View* prev_focusable = view->previous_focusable_view_;
@@ -2086,9 +2083,7 @@ void View::CreateLayer() {
SetLayer(new ui::Layer());
layer()->set_delegate(this);
-#if !defined(NDEBUG)
layer()->set_name(GetClassName());
-#endif
UpdateParentLayers();
UpdateLayerVisibility();
diff --git a/chromium/ui/views/view.h b/chromium/ui/views/view.h
index a85ef3dfa00..6b45c6313ba 100644
--- a/chromium/ui/views/view.h
+++ b/chromium/ui/views/view.h
@@ -9,6 +9,7 @@
#include <algorithm>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -17,7 +18,6 @@
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_enums.h"
#include "ui/base/accelerators/accelerator.h"
@@ -116,6 +116,18 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
public:
typedef std::vector<View*> Views;
+ enum class FocusBehavior {
+ // Use when the View is never focusable. Default.
+ NEVER,
+
+ // Use when the View is to be focusable both in regular and accessibility
+ // mode.
+ ALWAYS,
+
+ // Use when the View is focusable only during accessibility mode.
+ ACCESSIBLE_ONLY,
+ };
+
struct ViewHierarchyChangedDetails {
ViewHierarchyChangedDetails()
: is_add(false),
@@ -314,7 +326,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
void SetPaintToLayer(bool paint_to_layer);
// Overridden from ui::LayerOwner:
- scoped_ptr<ui::Layer> RecreateLayer() override;
+ std::unique_ptr<ui::Layer> RecreateLayer() override;
// RTL positioning -----------------------------------------------------------
@@ -504,7 +516,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
Background* background() { return background_.get(); }
// The border object is owned by this object and may be NULL.
- virtual void SetBorder(scoped_ptr<Border> b);
+ virtual void SetBorder(std::unique_ptr<Border> b);
const Border* border() const { return border_.get(); }
Border* border() { return border_.get(); }
@@ -700,7 +712,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Sets a new ViewTargeter for the view, and returns the previous
// ViewTargeter.
- scoped_ptr<ViewTargeter> SetEventTargeter(scoped_ptr<ViewTargeter> targeter);
+ std::unique_ptr<ViewTargeter> SetEventTargeter(
+ std::unique_ptr<ViewTargeter> targeter);
// Returns the ViewTargeter installed on |this| if one exists,
// otherwise returns the ViewTargeter installed on our root view.
@@ -712,7 +725,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Overridden from ui::EventTarget:
bool CanAcceptEvent(const ui::Event& event) override;
ui::EventTarget* GetParentTarget() override;
- scoped_ptr<ui::EventTargetIterator> GetChildIterator() const override;
+ std::unique_ptr<ui::EventTargetIterator> GetChildIterator() const override;
ui::EventTargeter* GetEventTargeter() override;
void ConvertEventToTarget(ui::EventTarget* target,
ui::LocatedEvent* event) override;
@@ -766,25 +779,16 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// IMPORTANT NOTE: loops in the focus hierarchy are not supported.
void SetNextFocusableView(View* view);
- // Sets whether this view is capable of taking focus. It will clear focus if
- // the focused view is set to be non-focusable.
- // Note that this is false by default so that a view used as a container does
- // not get the focus.
- void SetFocusable(bool focusable);
+ // Sets |focus_behavior| and advances focus if necessary.
+ void SetFocusBehavior(FocusBehavior focus_behavior);
- // Returns true if this view is |focusable_|, |enabled_| and drawn.
+ // Returns true if this view is focusable, |enabled_| and drawn.
bool IsFocusable() const;
// Return whether this view is focusable when the user requires full keyboard
// access, even though it may not be normally focusable.
bool IsAccessibilityFocusable() const;
- // Set whether this view can be made focusable if the user requires
- // full keyboard access, even though it's not normally focusable. It will
- // clear focus if the focused view is set to be non-focusable.
- // Note that this is false by default.
- void SetAccessibilityFocusable(bool accessibility_focusable);
-
// Convenience method to retrieve the FocusManager associated with the
// Widget that contains this view. This can return NULL if this view is not
// part of a view hierarchy with a Widget.
@@ -1140,9 +1144,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Focus ---------------------------------------------------------------------
- // Returns last value passed to SetFocusable(). Use IsFocusable() to determine
- // if a view can take focus right now.
- bool focusable() const { return focusable_; }
+ // Returns last set focus behavior.
+ FocusBehavior focus_behavior() const { return focus_behavior_; }
// Override to be notified when focus has changed either to or from this View.
virtual void OnFocus();
@@ -1191,7 +1194,9 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// NativeTheme ---------------------------------------------------------------
- // Invoked when the NativeTheme associated with this View changes.
+ // Invoked when the NativeTheme associated with this View changes, including
+ // when one first becomes available (after the view is added to a widget
+ // hierarchy).
virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) {}
// Debugging -----------------------------------------------------------------
@@ -1482,7 +1487,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
bool registered_for_visible_bounds_notification_;
// List of descendants wanting notification when their visible bounds change.
- scoped_ptr<Views> descendants_to_notify_;
+ std::unique_ptr<Views> descendants_to_notify_;
// Transformations -----------------------------------------------------------
@@ -1497,7 +1502,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// The View's LayoutManager defines the sizing heuristics applied to child
// Views. The default is absolute positioning according to bounds_.
- scoped_ptr<LayoutManager> layout_manager_;
+ std::unique_ptr<LayoutManager> layout_manager_;
// Whether this View's layer should be snapped to the pixel boundary.
bool snap_layer_to_pixel_boundary_;
@@ -1505,10 +1510,10 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Painting ------------------------------------------------------------------
// Background
- scoped_ptr<Background> background_;
+ std::unique_ptr<Background> background_;
// Border.
- scoped_ptr<Border> border_;
+ std::unique_ptr<Border> border_;
// Cached output of painting to be reused in future frames until invalidated.
ui::PaintCache paint_cache_;
@@ -1532,7 +1537,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// The list of accelerators. List elements in the range
// [0, registered_accelerator_count_) are already registered to FocusManager,
// and the rest are not yet.
- scoped_ptr<std::vector<ui::Accelerator> > accelerators_;
+ std::unique_ptr<std::vector<ui::Accelerator>> accelerators_;
size_t registered_accelerator_count_;
// Focus ---------------------------------------------------------------------
@@ -1543,12 +1548,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Next view to be focused when the Shift-Tab key combination is pressed.
View* previous_focusable_view_;
- // Whether this view can be focused.
- bool focusable_;
-
- // Whether this view is focusable if the user requires full keyboard access,
- // even though it may not be normally focusable.
- bool accessibility_focusable_;
+ // The focus behavior of the view in regular and accessibility mode.
+ FocusBehavior focus_behavior_;
// Context menus -------------------------------------------------------------
@@ -1561,7 +1562,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Input --------------------------------------------------------------------
- scoped_ptr<ViewTargeter> targeter_;
+ std::unique_ptr<ViewTargeter> targeter_;
// Accessibility -------------------------------------------------------------
diff --git a/chromium/ui/views/view_targeter_unittest.cc b/chromium/ui/views/view_targeter_unittest.cc
index 33a23729662..ea579d59f93 100644
--- a/chromium/ui/views/view_targeter_unittest.cc
+++ b/chromium/ui/views/view_targeter_unittest.cc
@@ -5,6 +5,7 @@
#include "ui/views/view_targeter.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "ui/events/event_targeter.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/path.h"
@@ -133,7 +134,7 @@ TEST_F(ViewTargeterTest, ViewTargeterForKeyEvents) {
content->AddChildView(child);
child->AddChildView(grandchild);
- grandchild->SetFocusable(true);
+ grandchild->SetFocusBehavior(View::FocusBehavior::ALWAYS);
grandchild->RequestFocus();
internal::RootView* root_view =
@@ -617,7 +618,7 @@ TEST_F(ViewTargeterTest, HitTestCallsOnView) {
v2->SetBoundsRect(v2_bounds);
root_view->AddChildView(v2);
ViewTargeter* view_targeter = new ViewTargeter(v2);
- v2->SetEventTargeter(make_scoped_ptr(view_targeter));
+ v2->SetEventTargeter(base::WrapUnique(view_targeter));
gfx::Point v1_centerpoint = v1_bounds.CenterPoint();
gfx::Point v2_centerpoint = v2_bounds.CenterPoint();
diff --git a/chromium/ui/views/view_unittest.cc b/chromium/ui/views/view_unittest.cc
index 4b50b319ad2..89e3c1bb94d 100644
--- a/chromium/ui/views/view_unittest.cc
+++ b/chromium/ui/views/view_unittest.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "ui/views/view.h"
+
#include <stddef.h>
#include <map>
+#include <memory>
#include "base/i18n/rtl.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/rand_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -39,7 +41,6 @@
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/focus/view_storage.h"
#include "ui/views/test/views_test_base.h"
-#include "ui/views/view.h"
#include "ui/views/widget/native_widget.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/window/dialog_client_view.h"
@@ -238,7 +239,7 @@ class TestView : public View {
views::View::Blur();
}
- bool focusable() const { return View::focusable(); }
+ FocusBehavior focus_behavior() const { return View::focus_behavior(); }
void set_can_process_events_within_subtree(bool can_process) {
can_process_events_within_subtree_ = can_process;
@@ -385,7 +386,7 @@ TEST_F(ViewTest, MouseEvent) {
TestView* v2 = new TestView();
v2->SetBoundsRect(gfx::Rect(100, 100, 100, 100));
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
@@ -448,7 +449,7 @@ TEST_F(ViewTest, DeleteOnPressed) {
v1->Reset();
v2->Reset();
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
@@ -2113,7 +2114,7 @@ TEST_F(ViewTest, HandleAccelerator) {
EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
// Create a window and add the view as its child.
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(0, 0, 100, 100);
@@ -2192,7 +2193,7 @@ TEST_F(ViewTest, ActivateAccelerator) {
EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
// Create a window and add the view as its child.
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(0, 0, 100, 100);
@@ -2255,7 +2256,7 @@ TEST_F(ViewTest, HiddenViewWithAccelerator) {
view->AddAccelerator(return_accelerator);
EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(0, 0, 100, 100);
@@ -2283,7 +2284,7 @@ TEST_F(ViewTest, ViewInHiddenWidgetWithAccelerator) {
view->AddAccelerator(return_accelerator);
EXPECT_EQ(view->accelerator_count_map_[return_accelerator], 0);
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(0, 0, 100, 100);
@@ -2429,13 +2430,13 @@ class ToplevelWidgetObserverView : public View {
// Test that a view can track the current top level widget by overriding
// View::ViewHierarchyChanged() and View::NativeViewHierarchyChanged().
TEST_F(ViewTest, MAYBE_NativeViewHierarchyChanged) {
- scoped_ptr<Widget> toplevel1(new Widget);
+ std::unique_ptr<Widget> toplevel1(new Widget);
Widget::InitParams toplevel1_params =
CreateParams(Widget::InitParams::TYPE_POPUP);
toplevel1_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
toplevel1->Init(toplevel1_params);
- scoped_ptr<Widget> toplevel2(new Widget);
+ std::unique_ptr<Widget> toplevel2(new Widget);
Widget::InitParams toplevel2_params =
CreateParams(Widget::InitParams::TYPE_POPUP);
toplevel2_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -2676,7 +2677,7 @@ TEST_F(ViewTest, TransformEvent) {
TEST_F(ViewTest, TransformVisibleBound) {
gfx::Rect viewport_bounds(0, 0, 100, 100);
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = viewport_bounds;
@@ -2733,7 +2734,7 @@ class VisibleBoundsView : public View {
TEST_F(ViewTest, OnVisibleBoundsChanged) {
gfx::Rect viewport_bounds(0, 0, 100, 100);
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = viewport_bounds;
@@ -2835,7 +2836,7 @@ TEST_F(ViewTest, AddAndRemoveSchedulePaints) {
// We have to put the View hierarchy into a Widget or no paints will be
// scheduled.
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = viewport_bounds;
@@ -2855,7 +2856,7 @@ TEST_F(ViewTest, AddAndRemoveSchedulePaints) {
parent_view->scheduled_paint_rects_.clear();
parent_view->RemoveChildView(child_view);
- scoped_ptr<View> child_deleter(child_view);
+ std::unique_ptr<View> child_deleter(child_view);
ASSERT_EQ(1U, parent_view->scheduled_paint_rects_.size());
EXPECT_EQ(child_view->bounds(), parent_view->scheduled_paint_rects_.front());
@@ -3051,7 +3052,7 @@ TEST_F(ViewTest, ConversionsWithTransform) {
// Tests conversion methods to and from screen coordinates.
TEST_F(ViewTest, ConversionsToFromScreen) {
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
@@ -3077,7 +3078,7 @@ TEST_F(ViewTest, ConversionsToFromScreen) {
// Tests conversion methods for rectangles.
TEST_F(ViewTest, ConvertRectWithTransform) {
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 650, 650);
@@ -3192,7 +3193,7 @@ TEST_F(ViewTest, ViewHierarchyChanged) {
ObserverView* v3 = new ObserverView();
// Add |v3| to |v2|.
- scoped_ptr<ObserverView> v2(new ObserverView());
+ std::unique_ptr<ObserverView> v2(new ObserverView());
v2->AddChildView(v3);
// Make sure both |v2| and |v3| receive the ViewHierarchyChanged()
@@ -3425,9 +3426,9 @@ TEST_F(ViewTest, ReorderChildren) {
child->AddChildView(foo2);
View* foo3 = new View();
child->AddChildView(foo3);
- foo1->SetFocusable(true);
- foo2->SetFocusable(true);
- foo3->SetFocusable(true);
+ foo1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ foo2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ foo3->SetFocusBehavior(View::FocusBehavior::ALWAYS);
ASSERT_EQ(0, child->GetIndexOf(foo1));
ASSERT_EQ(1, child->GetIndexOf(foo2));
@@ -3572,10 +3573,11 @@ TEST_F(ViewTest, AdvanceFocusIfNecessaryForUnfocusableView) {
widget.Init(params);
View* view1 = new View();
- view1->SetFocusable(true);
+ view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+
widget.GetRootView()->AddChildView(view1);
View* view2 = new View();
- view2->SetFocusable(true);
+ view2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget.GetRootView()->AddChildView(view2);
FocusManager* focus_manager = widget.GetFocusManager();
@@ -3604,7 +3606,7 @@ TEST_F(ViewTest, AdvanceFocusIfNecessaryForUnfocusableView) {
// Set the focused view as not focusable and check if the next view gets
// focused.
- view1->SetFocusable(false);
+ view1->SetFocusBehavior(View::FocusBehavior::NEVER);
EXPECT_EQ(view2, focus_manager->GetFocusedView());
}
@@ -4207,15 +4209,15 @@ TEST_F(ViewLayerTest, ReorderUnderWidget) {
TEST_F(ViewLayerTest, AcquireLayer) {
View* content = new View;
widget()->SetContentsView(content);
- scoped_ptr<View> c1(new View);
+ std::unique_ptr<View> c1(new View);
c1->SetPaintToLayer(true);
EXPECT_TRUE(c1->layer());
content->AddChildView(c1.get());
- scoped_ptr<ui::Layer> layer(c1->AcquireLayer());
+ std::unique_ptr<ui::Layer> layer(c1->AcquireLayer());
EXPECT_EQ(layer.get(), c1->layer());
- scoped_ptr<ui::Layer> layer2(c1->RecreateLayer());
+ std::unique_ptr<ui::Layer> layer2(c1->RecreateLayer());
EXPECT_NE(c1->layer(), layer2.get());
// Destroy view before destroying layer.
@@ -4224,7 +4226,7 @@ TEST_F(ViewLayerTest, AcquireLayer) {
// Verify the z-order of the layers as a result of calling RecreateLayer().
TEST_F(ViewLayerTest, RecreateLayerZOrder) {
- scoped_ptr<View> v(new View());
+ std::unique_ptr<View> v(new View());
v->SetPaintToLayer(true);
View* v1 = new View();
@@ -4240,7 +4242,7 @@ TEST_F(ViewLayerTest, RecreateLayerZOrder) {
EXPECT_EQ(v1->layer(), child_layers_pre[0]);
EXPECT_EQ(v2->layer(), child_layers_pre[1]);
- scoped_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
+ std::unique_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
// Test the new layer order. We expect: |v1| |v1_old_layer| |v2|.
// for |v1| and |v2|.
@@ -4272,7 +4274,7 @@ TEST_F(ViewLayerTest, RecreateLayerZOrderWidgetParent) {
EXPECT_EQ(v1->layer(), child_layers_pre[0]);
EXPECT_EQ(v2->layer(), child_layers_pre[1]);
- scoped_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
+ std::unique_ptr<ui::Layer> v1_old_layer(v1->RecreateLayer());
// Test the new layer order. We expect: |v1| |v1_old_layer| |v2|.
const std::vector<ui::Layer*>& child_layers_post = root_layer->children();
@@ -4298,7 +4300,7 @@ TEST_F(ViewLayerTest, RecreateLayerMovesNonViewChildren) {
v.layer()->Add(&layer);
v.layer()->StackAtBottom(&layer);
- scoped_ptr<ui::Layer> old_layer(v.RecreateLayer());
+ std::unique_ptr<ui::Layer> old_layer(v.RecreateLayer());
// All children should be moved from old layer to new layer.
ASSERT_TRUE(old_layer.get() != NULL);
@@ -4362,17 +4364,19 @@ TEST_F(ViewLayerTest, SnapLayerToPixel) {
TEST_F(ViewTest, FocusableAssertions) {
// View subclasses may change insets based on whether they are focusable,
// which effects the preferred size. To avoid preferred size changing around
- // these Views need to key off the last value set to SetFocusable(), not
+ // these Views need to key off the last value set to SetFocusBehavior(), not
// whether the View is focusable right now. For this reason it's important
- // that focusable() return the last value passed to SetFocusable and not
- // whether the View is focusable right now.
+ // that the return value of focus_behavior() depends on the last value passed
+ // to SetFocusBehavior and not whether the View is focusable right now.
TestView view;
- view.SetFocusable(true);
- EXPECT_TRUE(view.focusable());
+ view.SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ EXPECT_EQ(View::FocusBehavior::ALWAYS, view.focus_behavior());
view.SetEnabled(false);
- EXPECT_TRUE(view.focusable());
- view.SetFocusable(false);
- EXPECT_FALSE(view.focusable());
+ EXPECT_EQ(View::FocusBehavior::ALWAYS, view.focus_behavior());
+ view.SetFocusBehavior(View::FocusBehavior::NEVER);
+ EXPECT_EQ(View::FocusBehavior::NEVER, view.focus_behavior());
+ view.SetFocusBehavior(View::FocusBehavior::ACCESSIBLE_ONLY);
+ EXPECT_EQ(View::FocusBehavior::ACCESSIBLE_ONLY, view.focus_behavior());
}
// Verifies when a view is deleted it is removed from ViewStorage.
@@ -4404,7 +4408,7 @@ TEST_F(ViewTest, OnNativeThemeChanged) {
// new native theme notification.
test_view->AddChildView(test_view_child);
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(params);
@@ -4444,7 +4448,7 @@ TEST_F(ViewTest, ScopedTargetHandlerReceivesEvents) {
TestView* v = new TestView();
v->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 350, 350);
diff --git a/chromium/ui/views/view_unittest_aura.cc b/chromium/ui/views/view_unittest_aura.cc
index 568a29cf264..b1e7b2fee60 100644
--- a/chromium/ui/views/view_unittest_aura.cc
+++ b/chromium/ui/views/view_unittest_aura.cc
@@ -4,7 +4,8 @@
#include "ui/views/view.h"
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_tree_owner.h"
@@ -120,8 +121,8 @@ TEST_F(ViewAuraTest, RecreateLayersWithWindows) {
EXPECT_EQ(v7_layer, old_w1_root_sublayers[2]);
{
- scoped_ptr<ui::LayerTreeOwner> cloned_owner(
- wm::RecreateLayers(w1->GetNativeView()));
+ std::unique_ptr<ui::LayerTreeOwner> cloned_owner(
+ wm::RecreateLayers(w1->GetNativeView(), nullptr));
EXPECT_EQ(w1_layer, cloned_owner->root());
EXPECT_NE(w1_layer, w1->GetNativeView()->layer());
diff --git a/chromium/ui/views/views.gyp b/chromium/ui/views/views.gyp
index 6f2243320b9..b57a8158d63 100644
--- a/chromium/ui/views/views.gyp
+++ b/chromium/ui/views/views.gyp
@@ -16,16 +16,16 @@
'animation/bounds_animator.h',
'animation/button_ink_drop_delegate.cc',
'animation/button_ink_drop_delegate.h',
- 'animation/ink_drop_animation.cc',
- 'animation/ink_drop_animation.h',
- 'animation/ink_drop_animation_controller.h',
- 'animation/ink_drop_animation_controller_factory.cc',
- 'animation/ink_drop_animation_controller_factory.h',
- 'animation/ink_drop_animation_controller_impl.cc',
- 'animation/ink_drop_animation_controller_impl.h',
+ 'animation/ink_drop_ripple.cc',
+ 'animation/ink_drop_ripple.h',
+ 'animation/ink_drop.h',
+ 'animation/ink_drop_factory.cc',
+ 'animation/ink_drop_factory.h',
+ 'animation/ink_drop_impl.cc',
+ 'animation/ink_drop_impl.h',
'animation/ink_drop_animation_ended_reason.cc',
'animation/ink_drop_animation_ended_reason.h',
- 'animation/ink_drop_animation_observer.h',
+ 'animation/ink_drop_ripple_observer.h',
'animation/ink_drop_delegate.h',
'animation/ink_drop_host.h',
'animation/ink_drop_host_view.cc',
@@ -39,18 +39,16 @@
'animation/ink_drop_state.h',
'animation/scroll_animator.cc',
'animation/scroll_animator.h',
- 'animation/flood_fill_ink_drop_animation.cc',
- 'animation/flood_fill_ink_drop_animation.h',
- 'animation/square_ink_drop_animation.cc',
- 'animation/square_ink_drop_animation.h',
+ 'animation/flood_fill_ink_drop_ripple.cc',
+ 'animation/flood_fill_ink_drop_ripple.h',
+ 'animation/square_ink_drop_ripple.cc',
+ 'animation/square_ink_drop_ripple.h',
'background.cc',
'background.h',
'border.cc',
'border.h',
'bubble/bubble_border.cc',
'bubble/bubble_border.h',
- 'bubble/bubble_delegate.cc',
- 'bubble/bubble_delegate.h',
'bubble/bubble_dialog_delegate.cc',
'bubble/bubble_dialog_delegate.h',
'bubble/bubble_frame_view.cc',
@@ -284,6 +282,7 @@
'native_theme_delegate.h',
'painter.cc',
'painter.h',
+ 'pointer_watcher.h',
'rect_based_targeting_utils.cc',
'rect_based_targeting_utils.h',
'repeat_controller.cc',
@@ -313,6 +312,8 @@
'view_targeter_delegate.h',
'views_delegate.cc',
'views_delegate.h',
+ 'views_export.h',
+ 'views_exports.cc',
'views_switches.cc',
'views_switches.h',
'views_touch_selection_controller_factory.h',
@@ -490,18 +491,19 @@
'widget/desktop_aura/desktop_window_tree_host_ozone.cc',
],
'views_test_support_sources': [
- 'animation/test/flood_fill_ink_drop_animation_test_api.cc',
- 'animation/test/flood_fill_ink_drop_animation_test_api.h',
- 'animation/test/ink_drop_animation_test_api.cc',
- 'animation/test/ink_drop_animation_test_api.h',
- 'animation/test/ink_drop_animation_controller_impl_test_api.cc',
- 'animation/test/ink_drop_animation_controller_impl_test_api.h',
+ 'animation/test/flood_fill_ink_drop_ripple_test_api.cc',
+ 'animation/test/flood_fill_ink_drop_ripple_test_api.h',
+ 'animation/test/ink_drop_ripple_test_api.cc',
+ 'animation/test/ink_drop_ripple_test_api.h',
+ 'animation/test/ink_drop_impl_test_api.cc',
+ 'animation/test/ink_drop_impl_test_api.h',
'animation/test/ink_drop_hover_test_api.cc',
'animation/test/ink_drop_hover_test_api.h',
- 'animation/test/square_ink_drop_animation_test_api.cc',
- 'animation/test/square_ink_drop_animation_test_api.h',
- 'animation/test/test_ink_drop_animation_observer.cc',
- 'animation/test/test_ink_drop_animation_observer.h',
+ 'animation/test/ink_drop_utils.cc',
+ 'animation/test/square_ink_drop_ripple_test_api.cc',
+ 'animation/test/square_ink_drop_ripple_test_api.h',
+ 'animation/test/test_ink_drop_ripple_observer.cc',
+ 'animation/test/test_ink_drop_ripple_observer.h',
'animation/test/test_ink_drop_animation_observer_helper.h',
'animation/test/test_ink_drop_host.cc',
'animation/test/test_ink_drop_host.h',
@@ -523,6 +525,8 @@
'test/focus_manager_test.h',
'test/menu_runner_test_api.cc',
'test/menu_runner_test_api.h',
+ 'test/menu_test_utils.cc',
+ 'test/menu_test_utils.h',
'test/native_widget_factory.cc',
'test/native_widget_factory.h',
'test/scoped_views_test_helper.cc',
@@ -557,8 +561,8 @@
'test/widget_test_aura.cc',
],
'views_test_support_desktop_aura_x11_sources': [
- 'test/desktop_screen_x11_test_api.h',
'test/desktop_screen_x11_test_api.cc',
+ 'test/desktop_screen_x11_test_api.h',
'test/ui_controls_factory_desktop_aurax11.cc',
'test/ui_controls_factory_desktop_aurax11.h',
],
@@ -567,13 +571,12 @@
'accessibility/native_view_accessibility_win_unittest.cc',
'accessible_pane_view_unittest.cc',
'animation/bounds_animator_unittest.cc',
- 'animation/ink_drop_animation_controller_factory_unittest.cc',
- 'animation/ink_drop_animation_controller_impl_unittest.cc',
- 'animation/ink_drop_animation_unittest.cc',
+ 'animation/ink_drop_factory_unittest.cc',
+ 'animation/ink_drop_impl_unittest.cc',
+ 'animation/ink_drop_ripple_unittest.cc',
'animation/ink_drop_hover_unittest.cc',
- 'animation/square_ink_drop_animation_unittest.cc',
+ 'animation/square_ink_drop_ripple_unittest.cc',
'bubble/bubble_border_unittest.cc',
- 'bubble/bubble_delegate_unittest.cc',
'bubble/bubble_dialog_delegate_unittest.cc',
'bubble/bubble_frame_view_unittest.cc',
'bubble/bubble_window_targeter_unittest.cc',
@@ -616,14 +619,14 @@
'layout/box_layout_unittest.cc',
'layout/grid_layout_unittest.cc',
'rect_based_targeting_utils_unittest.cc',
- 'run_all_unittests.cc',
- 'run_all_unittests.h',
'run_all_unittests_main.cc',
'style/mac/dialog_button_border_mac_unittest.cc',
'view_model_unittest.cc',
'view_model_utils_unittest.cc',
'view_targeter_unittest.cc',
'view_unittest.cc',
+ 'views_test_suite.cc',
+ 'views_test_suite.h',
'widget/native_widget_mac_unittest.mm',
'widget/native_widget_unittest.cc',
'widget/root_view_unittest.cc',
@@ -679,6 +682,7 @@
'../events/platform/events_platform.gyp:events_platform',
'../gfx/gfx.gyp:gfx',
'../gfx/gfx.gyp:gfx_geometry',
+ '../gfx/gfx.gyp:gfx_range',
'../gfx/gfx.gyp:gfx_vector_icons',
'../native_theme/native_theme.gyp:native_theme',
'../resources/ui_resources.gyp:ui_resources',
@@ -770,6 +774,8 @@
'../../build/linux/system.gyp:x11',
'../../build/linux/system.gyp:xrandr',
'../events/devices/events_devices.gyp:events_devices',
+ '../events/devices/x11/events_devices_x11.gyp:events_devices_x11',
+ '../events/keycodes/events_keycodes.gyp:keycodes_x11',
'../events/platform/x11/x11_events_platform.gyp:x11_events_platform',
'../gfx/x/gfx_x11.gyp:gfx_x11',
],
@@ -794,6 +800,7 @@
'sources': [ '<@(views_desktop_aura_x11_sources)' ],
'dependencies': [
'../../build/linux/system.gyp:xext',
+ '../../ui/base/x/ui_base_x.gyp:ui_base_x',
],
}],
['OS == "win"', {
@@ -836,6 +843,7 @@
'../events/platform/events_platform.gyp:events_platform',
'../gfx/gfx.gyp:gfx',
'../gfx/gfx.gyp:gfx_geometry',
+ '../gfx/gfx.gyp:gfx_range',
'resources/views_resources.gyp:views_resources',
'views',
],
@@ -846,8 +854,8 @@
'<@(views_test_support_sources)',
# These are not listed in views_test_support_sources as they are not
# used by the gn target that pulls in views_test_support_sources.
- 'test/default_platform_test_helper.cc',
'test/native_widget_factory_desktop.cc',
+ 'test/platform_test_helper.cc',
'test/platform_test_helper.h',
],
'conditions': [
@@ -887,6 +895,7 @@
'../events/events.gyp:events_test_support',
'../gfx/gfx.gyp:gfx',
'../gfx/gfx.gyp:gfx_geometry',
+ '../gfx/gfx.gyp:gfx_range',
'../native_theme/native_theme.gyp:native_theme',
'../resources/ui_resources.gyp:ui_resources',
'../resources/ui_resources.gyp:ui_test_pak',
@@ -1019,9 +1028,9 @@
],
'sources': [
'cocoa/bridged_native_widget_interactive_uitest.mm',
- 'run_all_unittests.cc',
- 'run_all_unittests.h',
'run_all_unittests_main.cc',
+ 'views_test_suite.cc',
+ 'views_test_suite.h',
'widget/native_widget_mac_interactive_uitest.mm',
],
'conditions': [
diff --git a/chromium/ui/views/views_delegate.h b/chromium/ui/views/views_delegate.h
index c0e24cfe86c..54b5c4383e8 100644
--- a/chromium/ui/views/views_delegate.h
+++ b/chromium/ui/views/views_delegate.h
@@ -197,10 +197,10 @@ class VIEWS_EXPORT ViewsDelegate {
ViewsDelegate();
private:
- scoped_ptr<ViewsTouchEditingControllerFactory> views_tsc_factory_;
+ std::unique_ptr<ViewsTouchEditingControllerFactory> views_tsc_factory_;
#if defined(USE_AURA)
- scoped_ptr<TouchSelectionMenuRunnerViews> touch_selection_menu_runner_;
+ std::unique_ptr<TouchSelectionMenuRunnerViews> touch_selection_menu_runner_;
#endif
NativeWidgetFactory native_widget_factory_;
diff --git a/chromium/ui/views/views_exports.cc b/chromium/ui/views/views_exports.cc
new file mode 100644
index 00000000000..f1ba3f5336e
--- /dev/null
+++ b/chromium/ui/views/views_exports.cc
@@ -0,0 +1,10 @@
+// Copyright 2016 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.
+
+// This file is for including headers that are not included in any other .cc
+// files contained within the ui/views module. We need to include these here so
+// that linker will know to include the symbols, defined by these headers, in
+// the resulting dynamic library.
+
+#include "ui/views/pointer_watcher.h"
diff --git a/chromium/ui/views/views_test_suite.cc b/chromium/ui/views/views_test_suite.cc
new file mode 100644
index 00000000000..a7e7c13db09
--- /dev/null
+++ b/chromium/ui/views/views_test_suite.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2012 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.
+
+#include "ui/views/views_test_suite.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/path_service.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "base/test/test_suite.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/ui_base_paths.h"
+#include "ui/gl/test/gl_surface_test_support.h"
+
+#if defined(USE_AURA)
+#include <memory>
+
+#include "ui/aura/env.h"
+#endif
+
+namespace views {
+
+ViewsTestSuite::ViewsTestSuite(int argc, char** argv)
+ : base::TestSuite(argc, argv), argc_(argc), argv_(argv) {}
+
+ViewsTestSuite::~ViewsTestSuite() {}
+
+int ViewsTestSuite::RunTests() {
+ return base::LaunchUnitTests(
+ argc_, argv_, base::Bind(&ViewsTestSuite::Run, base::Unretained(this)));
+}
+
+int ViewsTestSuite::RunTestsSerially() {
+ return base::LaunchUnitTestsSerially(
+ argc_, argv_, base::Bind(&ViewsTestSuite::Run, base::Unretained(this)));
+}
+
+void ViewsTestSuite::Initialize() {
+ base::TestSuite::Initialize();
+ gfx::GLSurfaceTestSupport::InitializeOneOff();
+ ui::RegisterPathProvider();
+
+ base::FilePath ui_test_pak_path;
+ ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
+ ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+#if defined(USE_AURA)
+ env_ = aura::Env::CreateInstance();
+#endif
+}
+
+void ViewsTestSuite::Shutdown() {
+#if defined(USE_AURA)
+ env_.reset();
+#endif
+ ui::ResourceBundle::CleanupSharedInstance();
+ base::TestSuite::Shutdown();
+}
+
+} // namespace views
diff --git a/chromium/ui/views/views_test_suite.h b/chromium/ui/views/views_test_suite.h
new file mode 100644
index 00000000000..7a03f29e714
--- /dev/null
+++ b/chromium/ui/views/views_test_suite.h
@@ -0,0 +1,45 @@
+// Copyright 2016 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_VIEWS_VIEWS_TEST_SUITE_H_
+#define UI_VIEWS_VIEWS_TEST_SUITE_H_
+
+#include "base/test/test_suite.h"
+
+#if defined(USE_AURA)
+#include <memory>
+#endif
+
+namespace aura {
+class Env;
+}
+
+namespace views {
+
+class ViewsTestSuite : public base::TestSuite {
+ public:
+ ViewsTestSuite(int argc, char** argv);
+ ~ViewsTestSuite() override;
+
+ int RunTests();
+ int RunTestsSerially();
+
+ protected:
+ // base::TestSuite:
+ void Initialize() override;
+ void Shutdown() override;
+
+ private:
+#if defined(USE_AURA)
+ std::unique_ptr<aura::Env> env_;
+#endif
+ int argc_;
+ char** argv_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewsTestSuite);
+};
+
+} // namespace
+
+#endif // UI_VIEWS_VIEWS_TEST_SUITE_H_
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h
index ff116bc81a0..3e30e133bf6 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h
@@ -5,14 +5,15 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_CURSOR_LOADER_UPDATER_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_CURSOR_LOADER_UPDATER_H_
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "ui/views/views_export.h"
namespace aura {
class RootWindow;
}
-namespace gfx {
+namespace display {
class Display;
}
@@ -30,7 +31,7 @@ class VIEWS_EXPORT DesktopCursorLoaderUpdater {
// Creates a new DesktopCursorLoaderUpdater, or NULL if the platform doesn't
// support one.
- static scoped_ptr<DesktopCursorLoaderUpdater> Create();
+ static std::unique_ptr<DesktopCursorLoaderUpdater> Create();
// Called when a CursorLoader is created.
virtual void OnCreate(float device_scale_factor,
@@ -38,7 +39,7 @@ class VIEWS_EXPORT DesktopCursorLoaderUpdater {
// Called when the display has changed (as we may need to reload the cursor
// assets in response to a device scale factor or rotation change).
- virtual void OnDisplayUpdated(const gfx::Display& display,
+ virtual void OnDisplayUpdated(const display::Display& display,
ui::CursorLoader* loader) = 0;
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc
index 11fc3f1e1cc..2d0063b6944 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.cc
@@ -7,10 +7,11 @@
#include <stddef.h>
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/cursor/cursor_loader.h"
#include "ui/base/cursor/cursors_aura.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
namespace views {
namespace {
@@ -62,14 +63,15 @@ void DesktopCursorLoaderUpdaterAuraLinux::OnCreate(
}
void DesktopCursorLoaderUpdaterAuraLinux::OnDisplayUpdated(
- const gfx::Display& display,
+ const display::Display& display,
ui::CursorLoader* loader) {
LoadImageCursors(display.device_scale_factor(), loader);
}
// static
-scoped_ptr<DesktopCursorLoaderUpdater> DesktopCursorLoaderUpdater::Create() {
- return make_scoped_ptr(new DesktopCursorLoaderUpdaterAuraLinux);
+std::unique_ptr<DesktopCursorLoaderUpdater>
+DesktopCursorLoaderUpdater::Create() {
+ return base::WrapUnique(new DesktopCursorLoaderUpdaterAuraLinux);
}
} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h
index d0be0944fab..65490dd8c6c 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_auralinux.h
@@ -18,7 +18,7 @@ class DesktopCursorLoaderUpdaterAuraLinux : public DesktopCursorLoaderUpdater {
// Overridden from DesktopCursorLoaderUpdater:
void OnCreate(float device_scale_factor, ui::CursorLoader* loader) override;
- void OnDisplayUpdated(const gfx::Display& display,
+ void OnDisplayUpdated(const display::Display& display,
ui::CursorLoader* loader) override;
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurawin.cc b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurawin.cc
index eadc1ca49e1..249bb08aa3b 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurawin.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurawin.cc
@@ -7,7 +7,8 @@
namespace views {
// static
-scoped_ptr<DesktopCursorLoaderUpdater> DesktopCursorLoaderUpdater::Create() {
+std::unique_ptr<DesktopCursorLoaderUpdater>
+DesktopCursorLoaderUpdater::Create() {
return nullptr;
}
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index e9907e2a275..c133595c123 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -4,13 +4,14 @@
#include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
+#include <X11/Xatom.h>
#include <stddef.h>
#include <stdint.h>
-#include <X11/Xatom.h>
#include "base/event_types.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -24,11 +25,11 @@
#include "ui/base/x/selection_utils.h"
#include "ui/base/x/x11_foreign_window_manager.h"
#include "ui/base/x/x11_util.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
@@ -838,9 +839,9 @@ void DesktopDragDropClientAuraX11::OnMoveLoopEnded() {
end_move_loop_timer_.Stop();
}
-scoped_ptr<X11MoveLoop> DesktopDragDropClientAuraX11::CreateMoveLoop(
+std::unique_ptr<X11MoveLoop> DesktopDragDropClientAuraX11::CreateMoveLoop(
X11MoveLoopDelegate* delegate) {
- return make_scoped_ptr(new X11WholeScreenMoveLoop(this));
+ return base::WrapUnique(new X11WholeScreenMoveLoop(this));
}
XID DesktopDragDropClientAuraX11::FindWindowFor(
@@ -952,8 +953,8 @@ void DesktopDragDropClientAuraX11::EndMoveLoop() {
void DesktopDragDropClientAuraX11::DragTranslate(
const gfx::Point& root_window_location,
- scoped_ptr<ui::OSExchangeData>* data,
- scoped_ptr<ui::DropTargetEvent>* event,
+ std::unique_ptr<ui::OSExchangeData>* data,
+ std::unique_ptr<ui::DropTargetEvent>* event,
aura::client::DragDropDelegate** delegate) {
gfx::Point root_location = root_window_location;
root_window_->GetHost()->ConvertPointFromNativeScreen(&root_location);
@@ -1065,8 +1066,8 @@ void DesktopDragDropClientAuraX11::CompleteXdndPosition(
::Window source_window,
const gfx::Point& screen_point) {
int drag_operation = ui::DragDropTypes::DRAG_NONE;
- scoped_ptr<ui::OSExchangeData> data;
- scoped_ptr<ui::DropTargetEvent> drop_target_event;
+ std::unique_ptr<ui::OSExchangeData> data;
+ std::unique_ptr<ui::DropTargetEvent> drop_target_event;
DragDropDelegate* delegate = NULL;
DragTranslate(screen_point, &data, &drop_target_event, &delegate);
if (delegate)
@@ -1186,8 +1187,8 @@ void DesktopDragDropClientAuraX11::CreateDragWidget(
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.accept_events = false;
- gfx::Point location =
- gfx::Screen::GetScreen()->GetCursorScreenPoint() - drag_widget_offset_;
+ gfx::Point location = display::Screen::GetScreen()->GetCursorScreenPoint() -
+ drag_widget_offset_;
params.bounds = gfx::Rect(location, image.size());
widget->set_focus_on_creation(false);
widget->set_frame_type(Widget::FRAME_TYPE_FORCE_NATIVE);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
index 65dc403ddf2..9fec7bbe020 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h
@@ -6,12 +6,13 @@
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_DRAG_DROP_CLIENT_AURAX11_H_
#include <X11/Xlib.h>
+
+#include <memory>
#include <set>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "ui/aura/window_observer.h"
@@ -106,7 +107,7 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
// The following methods are virtual for the sake of testing.
// Creates a move loop.
- virtual scoped_ptr<X11MoveLoop> CreateMoveLoop(
+ virtual std::unique_ptr<X11MoveLoop> CreateMoveLoop(
X11MoveLoopDelegate* delegate);
// Finds the topmost X11 window at |screen_point| and returns it if it is
@@ -148,8 +149,8 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
// the underlying aura::Window representation, as moves internal to the X11
// window can cause internal drag leave and enter messages.
void DragTranslate(const gfx::Point& root_window_location,
- scoped_ptr<ui::OSExchangeData>* data,
- scoped_ptr<ui::DropTargetEvent>* event,
+ std::unique_ptr<ui::OSExchangeData>* data,
+ std::unique_ptr<ui::DropTargetEvent>* event,
aura::client::DragDropDelegate** delegate);
// Called when we need to notify the current aura::Window that we're no
@@ -201,7 +202,7 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
// A nested message loop that notifies this object of events through the
// X11MoveLoopDelegate interface.
- scoped_ptr<X11MoveLoop> move_loop_;
+ std::unique_ptr<X11MoveLoop> move_loop_;
aura::Window* root_window_;
@@ -214,7 +215,7 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
// Target side information.
class X11DragContext;
- scoped_ptr<X11DragContext> target_current_context_;
+ std::unique_ptr<X11DragContext> target_current_context_;
// The modifier state for the most recent mouse move.
int current_modifier_state_;
@@ -238,7 +239,7 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
// If we would send an XdndPosition message while we're waiting for an
// XdndStatus response, we need to cache the latest details we'd send.
- scoped_ptr<std::pair<gfx::Point, unsigned long> > next_position_message_;
+ std::unique_ptr<std::pair<gfx::Point, unsigned long>> next_position_message_;
// Reprocesses the most recent mouse move event if the mouse has not moved
// in a while in case the window stacking order has changed and
@@ -275,7 +276,7 @@ class VIEWS_EXPORT DesktopDragDropClientAuraX11
base::OneShotTimer end_move_loop_timer_;
// Widget that the user drags around. May be NULL.
- scoped_ptr<Widget> drag_widget_;
+ std::unique_ptr<Widget> drag_widget_;
// The offset of |drag_widget_| relative to the mouse position.
gfx::Vector2d drag_widget_offset_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
index 29105c2c366..55e1b03726b 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <map>
+#include <memory>
#include <vector>
// Include views_test_base.h first because the definition of None in X.h
@@ -10,7 +11,7 @@
#include "ui/views/test/views_test_base.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
+#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/window.h"
@@ -119,7 +120,7 @@ class SimpleTestDragDropClient : public DesktopDragDropClientAuraX11 {
private:
// DesktopDragDropClientAuraX11:
- scoped_ptr<X11MoveLoop> CreateMoveLoop(
+ std::unique_ptr<X11MoveLoop> CreateMoveLoop(
X11MoveLoopDelegate* delegate) override;
XID FindWindowFor(const gfx::Point& screen_point) override;
@@ -281,10 +282,10 @@ bool SimpleTestDragDropClient::IsMoveLoopRunning() {
return loop_->IsRunning();
}
-scoped_ptr<X11MoveLoop> SimpleTestDragDropClient::CreateMoveLoop(
+std::unique_ptr<X11MoveLoop> SimpleTestDragDropClient::CreateMoveLoop(
X11MoveLoopDelegate* delegate) {
loop_ = new TestMoveLoop(delegate);
- return make_scoped_ptr(loop_);
+ return base::WrapUnique(loop_);
}
XID SimpleTestDragDropClient::FindWindowFor(const gfx::Point& screen_point) {
@@ -427,11 +428,11 @@ class DesktopDragDropClientAuraX11Test : public ViewsTestBase {
}
private:
- scoped_ptr<TestDragDropClient> client_;
- scoped_ptr<DesktopNativeCursorManager> cursor_manager_;
+ std::unique_ptr<TestDragDropClient> client_;
+ std::unique_ptr<DesktopNativeCursorManager> cursor_manager_;
// The widget used to initiate drags.
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientAuraX11Test);
};
@@ -869,11 +870,11 @@ class DesktopDragDropClientAuraX11ChromeSourceTargetTest
}
private:
- scoped_ptr<SimpleTestDragDropClient> client_;
- scoped_ptr<DesktopNativeCursorManager> cursor_manager_;
+ std::unique_ptr<SimpleTestDragDropClient> client_;
+ std::unique_ptr<DesktopNativeCursorManager> cursor_manager_;
// The widget used to initiate drags.
- scoped_ptr<Widget> widget_;
+ std::unique_ptr<Widget> widget_;
DISALLOW_COPY_AND_ASSIGN(DesktopDragDropClientAuraX11ChromeSourceTargetTest);
};
@@ -884,7 +885,7 @@ void ChromeSourceTargetStep2(SimpleTestDragDropClient* client,
int modifier_flags) {
EXPECT_TRUE(client->IsMoveLoopRunning());
- scoped_ptr<Widget> target_widget(new Widget);
+ std::unique_ptr<Widget> target_widget(new Widget);
Widget::InitParams target_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
target_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
target_params.native_widget =
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
index 6931bd51863..875763dad35 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.cc
@@ -62,8 +62,8 @@ DWORD DesktopDropTargetWin::OnDragEnter(IDataObject* data_object,
DWORD key_state,
POINT position,
DWORD effect) {
- scoped_ptr<OSExchangeData> data;
- scoped_ptr<ui::DropTargetEvent> event;
+ std::unique_ptr<OSExchangeData> data;
+ std::unique_ptr<ui::DropTargetEvent> event;
DragDropDelegate* delegate;
// Translate will call OnDragEntered.
Translate(data_object, key_state, position, effect, &data, &event, &delegate);
@@ -76,8 +76,8 @@ DWORD DesktopDropTargetWin::OnDragOver(IDataObject* data_object,
POINT position,
DWORD effect) {
int drag_operation = ui::DragDropTypes::DRAG_NONE;
- scoped_ptr<OSExchangeData> data;
- scoped_ptr<ui::DropTargetEvent> event;
+ std::unique_ptr<OSExchangeData> data;
+ std::unique_ptr<ui::DropTargetEvent> event;
DragDropDelegate* delegate;
Translate(data_object, key_state, position, effect, &data, &event, &delegate);
if (delegate)
@@ -94,8 +94,8 @@ DWORD DesktopDropTargetWin::OnDrop(IDataObject* data_object,
POINT position,
DWORD effect) {
int drag_operation = ui::DragDropTypes::DRAG_NONE;
- scoped_ptr<OSExchangeData> data;
- scoped_ptr<ui::DropTargetEvent> event;
+ std::unique_ptr<OSExchangeData> data;
+ std::unique_ptr<ui::DropTargetEvent> event;
DragDropDelegate* delegate;
Translate(data_object, key_state, position, effect, &data, &event, &delegate);
if (delegate) {
@@ -123,8 +123,8 @@ void DesktopDropTargetWin::Translate(
DWORD key_state,
POINT position,
DWORD effect,
- scoped_ptr<OSExchangeData>* data,
- scoped_ptr<ui::DropTargetEvent>* event,
+ std::unique_ptr<OSExchangeData>* data,
+ std::unique_ptr<ui::DropTargetEvent>* event,
DragDropDelegate** delegate) {
gfx::Point location(position.x, position.y);
gfx::Point root_location = location;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h
index 24059b6f64c..b7fcf6c8a78 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_drop_target_win.h
@@ -5,8 +5,9 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTIOP_DROP_TARGET_WIN_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTIOP_DROP_TARGET_WIN_H_
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/aura/window_observer.h"
#include "ui/base/dragdrop/drop_target_win.h"
@@ -57,8 +58,8 @@ class DesktopDropTargetWin : public ui::DropTargetWin,
DWORD key_state,
POINT cursor_position,
DWORD effect,
- scoped_ptr<ui::OSExchangeData>* data,
- scoped_ptr<ui::DropTargetEvent>* event,
+ std::unique_ptr<ui::OSExchangeData>* data,
+ std::unique_ptr<ui::DropTargetEvent>* event,
aura::client::DragDropDelegate** delegate);
void NotifyDragLeave();
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_factory_ozone.h b/chromium/ui/views/widget/desktop_aura/desktop_factory_ozone.h
index 2af191b445f..bb6cbd2d5f5 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_factory_ozone.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_factory_ozone.h
@@ -7,9 +7,12 @@
#include "ui/views/views_export.h"
+namespace display {
+class Screen;
+}
+
namespace gfx {
class Rect;
-class Screen;
}
namespace views {
@@ -39,7 +42,7 @@ class VIEWS_EXPORT DesktopFactoryOzone {
// Delegates implementation of DesktopScreen externally to
// Ozone implementation.
- virtual gfx::Screen* CreateDesktopScreen() = 0;
+ virtual display::Screen* CreateDesktopScreen() = 0;
private:
static DesktopFactoryOzone* impl_; // not owned
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_focus_rules_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_focus_rules_unittest.cc
index 35cce8d5354..8b306f5e5ef 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_focus_rules_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_focus_rules_unittest.cc
@@ -17,8 +17,8 @@ namespace views {
namespace {
-scoped_ptr<Widget> CreateDesktopWidget() {
- scoped_ptr<Widget> widget(new Widget);
+std::unique_ptr<Widget> CreateDesktopWidget() {
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = Widget::InitParams(
Widget::InitParams::TYPE_WINDOW);
params.bounds = gfx::Rect(0, 0, 200, 200);
@@ -37,8 +37,8 @@ TEST_F(DesktopFocusRulesTest, DontFocusWindowsInOtherHierarchies) {
// Two widgets (each with a DesktopNativeWidgetAura). |w2| has a child Window
// |w2_child| that is not focusable. |w2_child|'s has a transient parent in
// |w1|.
- scoped_ptr<views::Widget> w1(CreateDesktopWidget());
- scoped_ptr<views::Widget> w2(CreateDesktopWidget());
+ std::unique_ptr<views::Widget> w1(CreateDesktopWidget());
+ std::unique_ptr<views::Widget> w2(CreateDesktopWidget());
aura::test::TestWindowDelegate w2_child_delegate;
w2_child_delegate.set_can_focus(false);
aura::Window* w2_child = new aura::Window(&w2_child_delegate);
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
index 2f9dc0d4be4..ea8df16d00d 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
@@ -14,7 +14,7 @@
namespace views {
DesktopNativeCursorManager::DesktopNativeCursorManager(
- scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater)
+ std::unique_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater)
: cursor_loader_updater_(std::move(cursor_loader_updater)),
cursor_loader_(ui::CursorLoader::Create()) {
if (cursor_loader_updater_.get())
@@ -39,7 +39,7 @@ void DesktopNativeCursorManager::RemoveHost(aura::WindowTreeHost* host) {
}
void DesktopNativeCursorManager::SetDisplay(
- const gfx::Display& display,
+ const display::Display& display,
wm::NativeCursorManagerDelegate* delegate) {
cursor_loader_->UnloadAll();
cursor_loader_->set_rotation(display.rotation());
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
index 552a1b8f114..d059c87453b 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_cursor_manager.h
@@ -5,11 +5,11 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_CURSOR_MANAGER_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_CURSOR_MANAGER_H_
+#include <memory>
#include <set>
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/views/views_export.h"
#include "ui/wm/core/native_cursor_manager.h"
@@ -35,7 +35,7 @@ class VIEWS_EXPORT DesktopNativeCursorManager
: public wm::NativeCursorManager {
public:
DesktopNativeCursorManager(
- scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater);
+ std::unique_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater);
~DesktopNativeCursorManager() override;
// Builds a cursor and sets the internal platform representation. The return
@@ -50,7 +50,7 @@ class VIEWS_EXPORT DesktopNativeCursorManager
private:
// Overridden from wm::NativeCursorManager:
- void SetDisplay(const gfx::Display& display,
+ void SetDisplay(const display::Display& display,
wm::NativeCursorManagerDelegate* delegate) override;
void SetCursor(gfx::NativeCursor cursor,
wm::NativeCursorManagerDelegate* delegate) override;
@@ -66,8 +66,8 @@ class VIEWS_EXPORT DesktopNativeCursorManager
typedef std::set<aura::WindowTreeHost*> Hosts;
Hosts hosts_;
- scoped_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater_;
- scoped_ptr<ui::CursorLoader> cursor_loader_;
+ std::unique_ptr<DesktopCursorLoaderUpdater> cursor_loader_updater_;
+ std::unique_ptr<ui::CursorLoader> cursor_loader_;
DISALLOW_COPY_AND_ASSIGN(DesktopNativeCursorManager);
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index f69b839d73a..99809d17f38 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -19,12 +19,11 @@
#include "ui/base/hit_test.h"
#include "ui/base/ime/input_method.h"
#include "ui/compositor/layer.h"
+#include "ui/display/screen.h"
#include "ui/gfx/canvas.h"
-#include "ui/gfx/display.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_conversions.h"
-#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/corewm/tooltip.h"
#include "ui/views/corewm/tooltip_controller.h"
@@ -401,6 +400,7 @@ void DesktopNativeWidgetAura::InitNativeWidget(
const Widget::InitParams& params) {
ownership_ = params.ownership;
widget_type_ = params.type;
+ name_ = params.name;
NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_window_);
// Animations on TYPE_WINDOW are handled by the OS. Additionally if we animate
@@ -458,7 +458,7 @@ void DesktopNativeWidgetAura::InitNativeWidget(
}
if (!cursor_manager_) {
cursor_manager_ = new wm::CursorManager(
- scoped_ptr<wm::NativeCursorManager>(native_cursor_manager_));
+ std::unique_ptr<wm::NativeCursorManager>(native_cursor_manager_));
}
native_cursor_manager_->AddHost(host());
aura::client::SetCursorClient(host_->window(), cursor_manager_);
@@ -675,11 +675,16 @@ gfx::Rect DesktopNativeWidgetAura::GetRestoredBounds() const {
desktop_window_tree_host_->GetRestoredBounds() : gfx::Rect();
}
+std::string DesktopNativeWidgetAura::GetWorkspace() const {
+ return content_window_ ?
+ desktop_window_tree_host_->GetWorkspace() : std::string();
+}
+
void DesktopNativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
if (!content_window_)
return;
aura::Window* root = host_->window();
- gfx::Screen* screen = gfx::Screen::GetScreen();
+ display::Screen* screen = display::Screen::GetScreen();
gfx::Rect bounds_in_pixels = screen->DIPToScreenRectInWindow(root, bounds);
desktop_window_tree_host_->AsWindowTreeHost()->SetBounds(bounds_in_pixels);
}
@@ -946,6 +951,10 @@ void DesktopNativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event) {
OnEvent(native_event);
}
+std::string DesktopNativeWidgetAura::GetName() const {
+ return name_;
+}
+
////////////////////////////////////////////////////////////////////////////////
// DesktopNativeWidgetAura, aura::WindowDelegate implementation:
@@ -1152,6 +1161,11 @@ void DesktopNativeWidgetAura::OnHostResized(const aura::WindowTreeHost* host) {
native_widget_delegate_->OnNativeWidgetSizeChanged(new_bounds.size());
}
+void DesktopNativeWidgetAura::OnHostWorkspaceChanged(
+ const aura::WindowTreeHost* host) {
+ native_widget_delegate_->OnNativeWidgetWorkspaceChanged();
+}
+
void DesktopNativeWidgetAura::OnHostMoved(const aura::WindowTreeHost* host,
const gfx::Point& new_origin) {
TRACE_EVENT1("views", "DesktopNativeWidgetAura::OnHostMoved",
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
index 47f514924bf..61adcdd5730 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.h
@@ -5,6 +5,8 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_WIDGET_AURA_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_NATIVE_WIDGET_AURA_H_
+#include <string>
+
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "ui/aura/client/focus_change_observer.h"
@@ -121,6 +123,7 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
gfx::Rect GetWindowBoundsInScreen() const override;
gfx::Rect GetClientAreaBoundsInScreen() const override;
gfx::Rect GetRestoredBounds() const override;
+ std::string GetWorkspace() const override;
void SetBounds(const gfx::Rect& bounds) override;
void SetSize(const gfx::Size& size) override;
void StackAbove(gfx::NativeView native_view) override;
@@ -173,6 +176,7 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
bool IsTranslucentWindowOpacitySupported() const override;
void OnSizeConstraintsChanged() override;
void RepostNativeEvent(gfx::NativeEvent native_event) override;
+ std::string GetName() const override;
// Overridden from aura::WindowDelegate:
gfx::Size GetMinimumSize() const override;
@@ -222,6 +226,7 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
// Overridden from aura::WindowTreeHostObserver:
void OnHostCloseRequested(const aura::WindowTreeHost* host) override;
void OnHostResized(const aura::WindowTreeHost* host) override;
+ void OnHostWorkspaceChanged(const aura::WindowTreeHost* host) override;
void OnHostMoved(const aura::WindowTreeHost* host,
const gfx::Point& new_origin) override;
@@ -235,13 +240,16 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
void RootWindowDestroyed();
- scoped_ptr<aura::WindowTreeHost> host_;
+ std::unique_ptr<aura::WindowTreeHost> host_;
DesktopWindowTreeHost* desktop_window_tree_host_;
// See class documentation for Widget in widget.h for a note about ownership.
Widget::InitParams::Ownership ownership_;
- scoped_ptr<DesktopCaptureClient> capture_client_;
+ // Internal name.
+ std::string name_;
+
+ std::unique_ptr<DesktopCaptureClient> capture_client_;
// Child of the root, contains |content_window_|.
aura::Window* content_window_container_;
@@ -253,26 +261,25 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
internal::NativeWidgetDelegate* native_widget_delegate_;
- scoped_ptr<wm::FocusController> focus_client_;
- scoped_ptr<aura::client::ScreenPositionClient> position_client_;
- scoped_ptr<aura::client::DragDropClient> drag_drop_client_;
- scoped_ptr<aura::client::WindowTreeClient> window_tree_client_;
- scoped_ptr<DesktopEventClient> event_client_;
- scoped_ptr<FocusManagerEventHandler> focus_manager_event_handler_;
+ std::unique_ptr<wm::FocusController> focus_client_;
+ std::unique_ptr<aura::client::ScreenPositionClient> position_client_;
+ std::unique_ptr<aura::client::DragDropClient> drag_drop_client_;
+ std::unique_ptr<aura::client::WindowTreeClient> window_tree_client_;
+ std::unique_ptr<DesktopEventClient> event_client_;
+ std::unique_ptr<FocusManagerEventHandler> focus_manager_event_handler_;
// Toplevel event filter which dispatches to other event filters.
- scoped_ptr<wm::CompoundEventFilter> root_window_event_filter_;
+ std::unique_ptr<wm::CompoundEventFilter> root_window_event_filter_;
- scoped_ptr<DropHelper> drop_helper_;
+ std::unique_ptr<DropHelper> drop_helper_;
int last_drop_operation_;
- scoped_ptr<corewm::TooltipController> tooltip_controller_;
- scoped_ptr<TooltipManagerAura> tooltip_manager_;
+ std::unique_ptr<corewm::TooltipController> tooltip_controller_;
+ std::unique_ptr<TooltipManagerAura> tooltip_manager_;
- scoped_ptr<wm::VisibilityController> visibility_controller_;
+ std::unique_ptr<wm::VisibilityController> visibility_controller_;
- scoped_ptr<wm::WindowModalityController>
- window_modality_controller_;
+ std::unique_ptr<wm::WindowModalityController> window_modality_controller_;
bool restore_focus_on_activate_;
@@ -287,11 +294,11 @@ class VIEWS_EXPORT DesktopNativeWidgetAura
static wm::CursorManager* cursor_manager_;
static views::DesktopNativeCursorManager* native_cursor_manager_;
- scoped_ptr<wm::ShadowController> shadow_controller_;
+ std::unique_ptr<wm::ShadowController> shadow_controller_;
// Reorders child windows of |window_| associated with a view based on the
// order of the associated views in the widget's view hierarchy.
- scoped_ptr<WindowReorderer> window_reorderer_;
+ std::unique_ptr<WindowReorderer> window_reorderer_;
// See class documentation for Widget in widget.h for a note about type.
Widget::InitParams::Type widget_type_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
index 86e60d31fc8..997b4e1071e 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura_unittest.cc
@@ -14,10 +14,10 @@
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
+#include "ui/display/screen.h"
#include "ui/events/event_processor.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
-#include "ui/gfx/screen.h"
#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/test_views.h"
#include "ui/views/test/test_views_delegate.h"
@@ -40,7 +40,7 @@ typedef ViewsTestBase DesktopNativeWidgetAuraTest;
// Verifies creating a Widget with a parent that is not in a RootWindow doesn't
// crash.
TEST_F(DesktopNativeWidgetAuraTest, CreateWithParentNotInRootWindow) {
- scoped_ptr<aura::Window> window(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> window(new aura::Window(NULL));
window->Init(ui::LAYER_NOT_DRAWN);
Widget widget;
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
@@ -219,14 +219,14 @@ TEST_F(DesktopNativeWidgetAuraTest, DontAccessContentWindowDuringDestruction) {
}
}
-void QuitNestedLoopAndCloseWidget(scoped_ptr<Widget> widget,
+void QuitNestedLoopAndCloseWidget(std::unique_ptr<Widget> widget,
base::Closure* quit_runloop) {
quit_runloop->Run();
}
// Verifies that a widget can be destroyed when running a nested message-loop.
TEST_F(DesktopNativeWidgetAuraTest, WidgetCanBeDestroyedFromNestedLoop) {
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.bounds = gfx::Rect(0, 0, 200, 200);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -432,7 +432,8 @@ TEST_F(DesktopAuraWidgetTest, TopLevelOwnedPopupRepositionTest) {
gfx::Rect new_pos(10, 10, 400, 400);
popup_window.owned_window()->SetBoundsInScreen(
- new_pos, gfx::Screen::GetScreen()->GetDisplayNearestPoint(gfx::Point()));
+ new_pos,
+ display::Screen::GetScreen()->GetDisplayNearestPoint(gfx::Point()));
EXPECT_EQ(new_pos,
popup_window.top_level_widget()->GetWindowBoundsInScreen());
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen.h b/chromium/ui/views/widget/desktop_aura/desktop_screen.h
index 2db961d2d95..88d2ffee2d7 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen.h
@@ -7,7 +7,7 @@
#include "ui/views/views_export.h"
-namespace gfx {
+namespace display {
class Screen;
}
@@ -15,7 +15,7 @@ namespace views {
// Creates a Screen that represents the screen of the environment that hosts
// a WindowTreeHost. Caller owns the result.
-VIEWS_EXPORT gfx::Screen* CreateDesktopScreen();
+VIEWS_EXPORT display::Screen* CreateDesktopScreen();
} // namespace views
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_ozone.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_ozone.cc
index 9708ad88bfc..870413f84f8 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_ozone.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_ozone.cc
@@ -8,7 +8,7 @@
namespace views {
-gfx::Screen* CreateDesktopScreen() {
+display::Screen* CreateDesktopScreen() {
return DesktopFactoryOzone::GetInstance()->CreateDesktopScreen();
}
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc
index cf49c96fca4..6096b4e1079 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.cc
@@ -34,7 +34,7 @@ DesktopScreenPositionClient::~DesktopScreenPositionClient() {
void DesktopScreenPositionClient::SetBounds(aura::Window* window,
const gfx::Rect& bounds,
- const gfx::Display& display) {
+ const display::Display& display) {
// TODO(jam): Use the 3rd parameter, |display|.
aura::Window* root = window->GetRootWindow();
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h
index 2e7bb1b9b2d..33fbdc2ef8d 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_position_client.h
@@ -22,7 +22,7 @@ class VIEWS_EXPORT DesktopScreenPositionClient
// aura::client::DefaultScreenPositionClient:
void SetBounds(aura::Window* window,
const gfx::Rect& bounds,
- const gfx::Display& display) override;
+ const display::Display& display) override;
private:
aura::Window* root_window_;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc
index 4df7b7ffae5..f772f64d656 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.cc
@@ -8,7 +8,7 @@
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
-#include "ui/gfx/display.h"
+#include "ui/display/display.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
@@ -26,7 +26,7 @@ DesktopScreenWin::~DesktopScreenWin() {
////////////////////////////////////////////////////////////////////////////////
// DesktopScreenWin, display::win::ScreenWin implementation:
-gfx::Display DesktopScreenWin::GetDisplayMatching(
+display::Display DesktopScreenWin::GetDisplayMatching(
const gfx::Rect& match_rect) const {
return GetDisplayNearestPoint(match_rect.CenterPoint());
}
@@ -43,7 +43,7 @@ gfx::NativeWindow DesktopScreenWin::GetNativeWindowFromHWND(HWND hwnd) const {
////////////////////////////////////////////////////////////////////////////////
-gfx::Screen* CreateDesktopScreen() {
+display::Screen* CreateDesktopScreen() {
return new DesktopScreenWin;
}
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
index 085ba321da1..87299feba93 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_win.h
@@ -18,7 +18,8 @@ public:
private:
// Overridden from display::win::ScreenWin:
- gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
+ display::Display GetDisplayMatching(
+ const gfx::Rect& match_rect) const override;
HWND GetHWNDFromNativeView(gfx::NativeView window) const override;
gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index 6ffd94a3c89..57d5f13bc9b 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -16,15 +16,15 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/layout.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/display/util/display_util.h"
#include "ui/display/util/x11/edid_parser_x11.h"
#include "ui/events/platform/platform_event_source.h"
-#include "ui/gfx/display.h"
#include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/linux_ui/linux_ui.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
@@ -33,6 +33,11 @@
namespace {
+const char* const kAtomsToCache[] = {
+ "_NET_WORKAREA",
+ nullptr
+};
+
// The delay to perform configuration after RRNotify. See the comment
// in |Dispatch()|.
const int64_t kConfigureDelayMs = 500;
@@ -42,8 +47,8 @@ double GetDeviceScaleFactor() {
if (views::LinuxUI::instance()) {
device_scale_factor =
views::LinuxUI::instance()->GetDeviceScaleFactor();
- } else if (gfx::Display::HasForceDeviceScaleFactor()) {
- device_scale_factor = gfx::Display::GetForcedDeviceScaleFactor();
+ } else if (display::Display::HasForceDeviceScaleFactor()) {
+ device_scale_factor = display::Display::GetForcedDeviceScaleFactor();
}
return device_scale_factor;
}
@@ -56,7 +61,7 @@ gfx::Point DIPToPixelPoint(const gfx::Point& dip_point) {
return gfx::ScaleToFlooredPoint(dip_point, GetDeviceScaleFactor());
}
-std::vector<gfx::Display> GetFallbackDisplayList() {
+std::vector<display::Display> GetFallbackDisplayList() {
::XDisplay* display = gfx::GetXDisplay();
::Screen* screen = DefaultScreenOfDisplay(display);
int width = WidthOfScreen(screen);
@@ -64,15 +69,15 @@ std::vector<gfx::Display> GetFallbackDisplayList() {
gfx::Size physical_size(WidthMMOfScreen(screen), HeightMMOfScreen(screen));
gfx::Rect bounds_in_pixels(0, 0, width, height);
- gfx::Display gfx_display(0, bounds_in_pixels);
- if (!gfx::Display::HasForceDeviceScaleFactor() &&
+ display::Display gfx_display(0, bounds_in_pixels);
+ if (!display::Display::HasForceDeviceScaleFactor() &&
!ui::IsDisplaySizeBlackListed(physical_size)) {
const float device_scale_factor = GetDeviceScaleFactor();
DCHECK_LE(1.0f, device_scale_factor);
gfx_display.SetScaleAndBounds(device_scale_factor, bounds_in_pixels);
}
- return std::vector<gfx::Display>(1, gfx_display);
+ return std::vector<display::Display>(1, gfx_display);
}
} // namespace
@@ -86,7 +91,9 @@ DesktopScreenX11::DesktopScreenX11()
: xdisplay_(gfx::GetXDisplay()),
x_root_window_(DefaultRootWindow(xdisplay_)),
has_xrandr_(false),
- xrandr_event_base_(0) {
+ xrandr_event_base_(0),
+ primary_display_index_(0),
+ atom_cache_(xdisplay_, kAtomsToCache) {
// We only support 1.3+. There were library changes before this and we should
// use the new interface instead of the 1.2 one.
int randr_version_major = 0;
@@ -120,7 +127,7 @@ DesktopScreenX11::~DesktopScreenX11() {
}
////////////////////////////////////////////////////////////////////////////////
-// DesktopScreenX11, gfx::Screen implementation:
+// DesktopScreenX11, display::Screen implementation:
gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
TRACE_EVENT0("views", "DesktopScreenX11::GetCursorScreenPoint()");
@@ -143,8 +150,8 @@ gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
return PixelToDIPPoint(gfx::Point(root_x, root_y));
}
-gfx::NativeWindow DesktopScreenX11::GetWindowUnderCursor() {
- return GetWindowAtScreenPoint(GetCursorScreenPoint());
+bool DesktopScreenX11::IsWindowUnderCursor(gfx::NativeWindow window) {
+ return GetWindowAtScreenPoint(GetCursorScreenPoint()) == window;
}
gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint(
@@ -158,11 +165,11 @@ int DesktopScreenX11::GetNumDisplays() const {
return displays_.size();
}
-std::vector<gfx::Display> DesktopScreenX11::GetAllDisplays() const {
+std::vector<display::Display> DesktopScreenX11::GetAllDisplays() const {
return displays_;
}
-gfx::Display DesktopScreenX11::GetDisplayNearestWindow(
+display::Display DesktopScreenX11::GetDisplayNearestWindow(
gfx::NativeView window) const {
if (!window)
return GetPrimaryDisplay();
@@ -187,9 +194,9 @@ gfx::Display DesktopScreenX11::GetDisplayNearestWindow(
return GetPrimaryDisplay();
}
-gfx::Display DesktopScreenX11::GetDisplayNearestPoint(
+display::Display DesktopScreenX11::GetDisplayNearestPoint(
const gfx::Point& point) const {
- for (std::vector<gfx::Display>::const_iterator it = displays_.begin();
+ for (std::vector<display::Display>::const_iterator it = displays_.begin();
it != displays_.end(); ++it) {
if (it->bounds().Contains(point))
return *it;
@@ -198,11 +205,11 @@ gfx::Display DesktopScreenX11::GetDisplayNearestPoint(
return GetPrimaryDisplay();
}
-gfx::Display DesktopScreenX11::GetDisplayMatching(
+display::Display DesktopScreenX11::GetDisplayMatching(
const gfx::Rect& match_rect) const {
int max_area = 0;
- const gfx::Display* matching = NULL;
- for (std::vector<gfx::Display>::const_iterator it = displays_.begin();
+ const display::Display* matching = NULL;
+ for (std::vector<display::Display>::const_iterator it = displays_.begin();
it != displays_.end(); ++it) {
gfx::Rect intersect = gfx::IntersectRects(it->bounds(), match_rect);
int area = intersect.width() * intersect.height();
@@ -215,28 +222,34 @@ gfx::Display DesktopScreenX11::GetDisplayMatching(
return matching ? *matching : GetPrimaryDisplay();
}
-gfx::Display DesktopScreenX11::GetPrimaryDisplay() const {
- return displays_.front();
+display::Display DesktopScreenX11::GetPrimaryDisplay() const {
+ DCHECK(!displays_.empty());
+ return displays_[primary_display_index_];
}
-void DesktopScreenX11::AddObserver(gfx::DisplayObserver* observer) {
+void DesktopScreenX11::AddObserver(display::DisplayObserver* observer) {
change_notifier_.AddObserver(observer);
}
-void DesktopScreenX11::RemoveObserver(gfx::DisplayObserver* observer) {
+void DesktopScreenX11::RemoveObserver(display::DisplayObserver* observer) {
change_notifier_.RemoveObserver(observer);
}
bool DesktopScreenX11::CanDispatchEvent(const ui::PlatformEvent& event) {
return event->type - xrandr_event_base_ == RRScreenChangeNotify ||
- event->type - xrandr_event_base_ == RRNotify;
+ event->type - xrandr_event_base_ == RRNotify ||
+ (event->type == PropertyNotify &&
+ event->xproperty.window == x_root_window_ &&
+ event->xproperty.atom == atom_cache_.GetAtom("_NET_WORKAREA"));
}
uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
// Pass the event through to xlib.
XRRUpdateConfiguration(event);
- } else if (event->type - xrandr_event_base_ == RRNotify) {
+ } else if (event->type - xrandr_event_base_ == RRNotify ||
+ (event->type == PropertyNotify &&
+ event->xproperty.atom == atom_cache_.GetAtom("_NET_WORKAREA"))) {
// There's some sort of observer dispatch going on here, but I don't think
// it's the screen's?
if (configure_timer_.get() && configure_timer_->IsRunning()) {
@@ -259,7 +272,7 @@ uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
// static
void DesktopScreenX11::UpdateDeviceScaleFactorForTest() {
DesktopScreenX11* screen =
- static_cast<DesktopScreenX11*>(gfx::Screen::GetScreen());
+ static_cast<DesktopScreenX11*>(display::Screen::GetScreen());
screen->ConfigureTimerFired();
}
@@ -267,16 +280,17 @@ void DesktopScreenX11::UpdateDeviceScaleFactorForTest() {
// DesktopScreenX11, private:
DesktopScreenX11::DesktopScreenX11(
- const std::vector<gfx::Display>& test_displays)
+ const std::vector<display::Display>& test_displays)
: xdisplay_(gfx::GetXDisplay()),
x_root_window_(DefaultRootWindow(xdisplay_)),
has_xrandr_(false),
xrandr_event_base_(0),
- displays_(test_displays) {
-}
+ displays_(test_displays),
+ primary_display_index_(0),
+ atom_cache_(xdisplay_, kAtomsToCache) {}
-std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
- std::vector<gfx::Display> displays;
+std::vector<display::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
+ std::vector<display::Display> displays;
gfx::XScopedPtr<
XRRScreenResources,
gfx::XObjectDeleter<XRRScreenResources, void, XRRFreeScreenResources>>
@@ -286,6 +300,9 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
return GetFallbackDisplayList();
}
+ primary_display_index_ = 0;
+ RROutput primary_display_id = XRRGetOutputPrimary(xdisplay_, x_root_window_);
+
bool has_work_area = false;
gfx::Rect work_area_in_pixels;
std::vector<int> value;
@@ -322,9 +339,9 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
}
gfx::Rect crtc_bounds(crtc->x, crtc->y, crtc->width, crtc->height);
- gfx::Display display(display_id, crtc_bounds);
+ display::Display display(display_id, crtc_bounds);
- if (!gfx::Display::HasForceDeviceScaleFactor()) {
+ if (!display::Display::HasForceDeviceScaleFactor()) {
display.SetScaleAndBounds(device_scale_factor, crtc_bounds);
}
@@ -342,19 +359,22 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
switch (crtc->rotation) {
case RR_Rotate_0:
- display.set_rotation(gfx::Display::ROTATE_0);
+ display.set_rotation(display::Display::ROTATE_0);
break;
case RR_Rotate_90:
- display.set_rotation(gfx::Display::ROTATE_90);
+ display.set_rotation(display::Display::ROTATE_90);
break;
case RR_Rotate_180:
- display.set_rotation(gfx::Display::ROTATE_180);
+ display.set_rotation(display::Display::ROTATE_180);
break;
case RR_Rotate_270:
- display.set_rotation(gfx::Display::ROTATE_270);
+ display.set_rotation(display::Display::ROTATE_270);
break;
}
+ if (output_id == primary_display_id)
+ primary_display_index_ = displays.size();
+
displays.push_back(display);
}
}
@@ -366,13 +386,13 @@ std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
}
void DesktopScreenX11::ConfigureTimerFired() {
- std::vector<gfx::Display> old_displays = displays_;
+ std::vector<display::Display> old_displays = displays_;
SetDisplaysInternal(BuildDisplaysFromXRandRInfo());
change_notifier_.NotifyDisplaysChanged(old_displays, displays_);
}
void DesktopScreenX11::SetDisplaysInternal(
- const std::vector<gfx::Display>& displays) {
+ const std::vector<display::Display>& displays) {
displays_ = displays;
gfx::SetFontRenderParamsDeviceScaleFactor(
GetPrimaryDisplay().device_scale_factor());
@@ -380,7 +400,7 @@ void DesktopScreenX11::SetDisplaysInternal(
////////////////////////////////////////////////////////////////////////////////
-gfx::Screen* CreateDesktopScreen() {
+display::Screen* CreateDesktopScreen() {
return new DesktopScreenX11;
}
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
index e96d983ccb2..03f5c6255b0 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11.h
@@ -7,18 +7,16 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/timer/timer.h"
+#include "ui/display/display_change_notifier.h"
+#include "ui/display/screen.h"
#include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/gfx/display_change_notifier.h"
-#include "ui/gfx/screen.h"
+#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/views/views_export.h"
-namespace gfx {
-class Display;
-}
-
typedef unsigned long XID;
typedef XID Window;
typedef struct _XDisplay Display;
@@ -31,25 +29,28 @@ class DesktopScreenX11TestApi;
}
// Our singleton screen implementation that talks to xrandr.
-class VIEWS_EXPORT DesktopScreenX11 : public gfx::Screen,
+class VIEWS_EXPORT DesktopScreenX11 : public display::Screen,
public ui::PlatformEventDispatcher {
public:
DesktopScreenX11();
~DesktopScreenX11() override;
- // Overridden from gfx::Screen:
+ // Overridden from display::Screen:
gfx::Point GetCursorScreenPoint() override;
- gfx::NativeWindow GetWindowUnderCursor() override;
+ bool IsWindowUnderCursor(gfx::NativeWindow window) override;
gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
int GetNumDisplays() const override;
- std::vector<gfx::Display> GetAllDisplays() const override;
- gfx::Display GetDisplayNearestWindow(gfx::NativeView window) const override;
- gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const override;
- gfx::Display GetDisplayMatching(const gfx::Rect& match_rect) const override;
- gfx::Display GetPrimaryDisplay() const override;
- void AddObserver(gfx::DisplayObserver* observer) override;
- void RemoveObserver(gfx::DisplayObserver* observer) override;
+ std::vector<display::Display> GetAllDisplays() const override;
+ display::Display GetDisplayNearestWindow(
+ gfx::NativeView window) const override;
+ display::Display GetDisplayNearestPoint(
+ const gfx::Point& point) const override;
+ display::Display GetDisplayMatching(
+ const gfx::Rect& match_rect) const override;
+ display::Display GetPrimaryDisplay() const override;
+ void AddObserver(display::DisplayObserver* observer) override;
+ void RemoveObserver(display::DisplayObserver* observer) override;
// ui::PlatformEventDispatcher:
bool CanDispatchEvent(const ui::PlatformEvent& event) override;
@@ -62,17 +63,17 @@ class VIEWS_EXPORT DesktopScreenX11 : public gfx::Screen,
friend class test::DesktopScreenX11TestApi;
// Constructor used in tests.
- DesktopScreenX11(const std::vector<gfx::Display>& test_displays);
+ DesktopScreenX11(const std::vector<display::Display>& test_displays);
// Builds a list of displays from the current screen information offered by
// the X server.
- std::vector<gfx::Display> BuildDisplaysFromXRandRInfo();
+ std::vector<display::Display> BuildDisplaysFromXRandRInfo();
// We delay updating the display so we can coalesce events.
void ConfigureTimerFired();
// Updates |displays_| and sets FontRenderParams's scale factor.
- void SetDisplaysInternal(const std::vector<gfx::Display>& displays);
+ void SetDisplaysInternal(const std::vector<display::Display>& displays);
Display* xdisplay_;
::Window x_root_window_;
@@ -85,13 +86,18 @@ class VIEWS_EXPORT DesktopScreenX11 : public gfx::Screen,
int xrandr_event_base_;
// The display objects we present to chrome.
- std::vector<gfx::Display> displays_;
+ std::vector<display::Display> displays_;
+
+ // The index into displays_ that represents the primary display.
+ size_t primary_display_index_;
// The timer to delay configuring outputs. See also the comments in
// Dispatch().
- scoped_ptr<base::OneShotTimer> configure_timer_;
+ std::unique_ptr<base::OneShotTimer> configure_timer_;
+
+ display::DisplayChangeNotifier change_notifier_;
- gfx::DisplayChangeNotifier change_notifier_;
+ ui::X11AtomCache atom_cache_;
DISALLOW_COPY_AND_ASSIGN(DesktopScreenX11);
};
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
index a2e2d2aed7e..82f81bad69c 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
@@ -6,16 +6,17 @@
#include <stdint.h>
+#include <memory>
+
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/hit_test.h"
#include "ui/base/x/x11_util.h"
+#include "ui/display/display_observer.h"
#include "ui/events/test/event_generator.h"
-#include "ui/gfx/display_observer.h"
#include "ui/gfx/font_render_params.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/test/views_test_base.h"
@@ -56,7 +57,7 @@ const int64_t kFirstDisplay = 5321829;
const int64_t kSecondDisplay = 928310;
class DesktopScreenX11Test : public views::ViewsTestBase,
- public gfx::DisplayObserver {
+ public display::DisplayObserver {
public:
DesktopScreenX11Test() {}
~DesktopScreenX11Test() override {}
@@ -65,8 +66,9 @@ class DesktopScreenX11Test : public views::ViewsTestBase,
void SetUp() override {
ViewsTestBase::SetUp();
// Initialize the world to the single monitor case.
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
screen_.reset(new DesktopScreenX11(displays));
screen_->AddObserver(this);
}
@@ -77,14 +79,14 @@ class DesktopScreenX11Test : public views::ViewsTestBase,
}
protected:
- std::vector<gfx::Display> changed_display_;
- std::vector<gfx::Display> added_display_;
- std::vector<gfx::Display> removed_display_;
+ std::vector<display::Display> changed_display_;
+ std::vector<display::Display> added_display_;
+ std::vector<display::Display> removed_display_;
DesktopScreenX11* screen() { return screen_.get(); }
- void NotifyDisplaysChanged(const std::vector<gfx::Display>& displays) {
- std::vector<gfx::Display> old_displays = screen_->displays_;
+ void NotifyDisplaysChanged(const std::vector<display::Display>& displays) {
+ std::vector<display::Display> old_displays = screen_->displays_;
screen_->SetDisplaysInternal(displays);
screen_->change_notifier_.NotifyDisplaysChanged(old_displays,
screen_->displays_);
@@ -115,28 +117,29 @@ class DesktopScreenX11Test : public views::ViewsTestBase,
}
private:
- // Overridden from gfx::DisplayObserver:
- void OnDisplayAdded(const gfx::Display& new_display) override {
+ // Overridden from display::DisplayObserver:
+ void OnDisplayAdded(const display::Display& new_display) override {
added_display_.push_back(new_display);
}
- void OnDisplayRemoved(const gfx::Display& old_display) override {
+ void OnDisplayRemoved(const display::Display& old_display) override {
removed_display_.push_back(old_display);
}
- void OnDisplayMetricsChanged(const gfx::Display& display,
+ void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override {
changed_display_.push_back(display);
}
- scoped_ptr<DesktopScreenX11> screen_;
+ std::unique_ptr<DesktopScreenX11> screen_;
DISALLOW_COPY_AND_ASSIGN(DesktopScreenX11Test);
};
TEST_F(DesktopScreenX11Test, BoundsChangeSingleMonitor) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(1u, changed_display_.size());
@@ -145,10 +148,11 @@ TEST_F(DesktopScreenX11Test, BoundsChangeSingleMonitor) {
}
TEST_F(DesktopScreenX11Test, AddMonitorToTheRight) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(0u, changed_display_.size());
@@ -157,9 +161,11 @@ TEST_F(DesktopScreenX11Test, AddMonitorToTheRight) {
}
TEST_F(DesktopScreenX11Test, AddMonitorToTheLeft) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768)));
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(1024, 0, 640, 480)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768)));
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(1024, 0, 640, 480)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(1u, changed_display_.size());
@@ -168,16 +174,18 @@ TEST_F(DesktopScreenX11Test, AddMonitorToTheLeft) {
}
TEST_F(DesktopScreenX11Test, RemoveMonitorOnRight) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
ResetDisplayChanges();
displays.clear();
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(0u, changed_display_.size());
@@ -186,16 +194,18 @@ TEST_F(DesktopScreenX11Test, RemoveMonitorOnRight) {
}
TEST_F(DesktopScreenX11Test, RemoveMonitorOnLeft) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
ResetDisplayChanges();
displays.clear();
- displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(0, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(1u, changed_display_.size());
@@ -204,10 +214,11 @@ TEST_F(DesktopScreenX11Test, RemoveMonitorOnLeft) {
}
TEST_F(DesktopScreenX11Test, GetDisplayNearestPoint) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(kFirstDisplay,
@@ -221,10 +232,11 @@ TEST_F(DesktopScreenX11Test, GetDisplayNearestPoint) {
}
TEST_F(DesktopScreenX11Test, GetDisplayMatchingBasic) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(kSecondDisplay,
@@ -232,10 +244,11 @@ TEST_F(DesktopScreenX11Test, GetDisplayMatchingBasic) {
}
TEST_F(DesktopScreenX11Test, GetDisplayMatchingOverlap) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
EXPECT_EQ(kSecondDisplay,
@@ -243,10 +256,11 @@ TEST_F(DesktopScreenX11Test, GetDisplayMatchingOverlap) {
}
TEST_F(DesktopScreenX11Test, GetPrimaryDisplay) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay,
- gfx::Rect(640, 0, 1024, 768)));
- displays.push_back(gfx::Display(kSecondDisplay, gfx::Rect(0, 0, 640, 480)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(640, 0, 1024, 768)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(0, 0, 640, 480)));
NotifyDisplaysChanged(displays);
// The first display in the list is always the primary, even if other
@@ -256,10 +270,11 @@ TEST_F(DesktopScreenX11Test, GetPrimaryDisplay) {
TEST_F(DesktopScreenX11Test, GetDisplayNearestWindow) {
// Set up a two monitor situation.
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
- displays.push_back(gfx::Display(kSecondDisplay,
- gfx::Rect(640, 0, 1024, 768)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
Widget* window_one = BuildTopLevelDesktopWidget(gfx::Rect(10, 10, 10, 10),
@@ -369,41 +384,43 @@ TEST_F(DesktopScreenX11Test, RightClickDuringDoubleClickDoesntMaximize) {
// Test that rotating the displays notifies the DisplayObservers.
TEST_F(DesktopScreenX11Test, RotationChange) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ std::vector<display::Display> displays;
displays.push_back(
- gfx::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ displays.push_back(
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
ResetDisplayChanges();
- displays[0].set_rotation(gfx::Display::ROTATE_90);
+ displays[0].set_rotation(display::Display::ROTATE_90);
NotifyDisplaysChanged(displays);
EXPECT_EQ(1u, changed_display_.size());
- displays[1].set_rotation(gfx::Display::ROTATE_90);
+ displays[1].set_rotation(display::Display::ROTATE_90);
NotifyDisplaysChanged(displays);
EXPECT_EQ(2u, changed_display_.size());
- displays[0].set_rotation(gfx::Display::ROTATE_270);
+ displays[0].set_rotation(display::Display::ROTATE_270);
NotifyDisplaysChanged(displays);
EXPECT_EQ(3u, changed_display_.size());
- displays[0].set_rotation(gfx::Display::ROTATE_270);
+ displays[0].set_rotation(display::Display::ROTATE_270);
NotifyDisplaysChanged(displays);
EXPECT_EQ(3u, changed_display_.size());
- displays[0].set_rotation(gfx::Display::ROTATE_0);
- displays[1].set_rotation(gfx::Display::ROTATE_0);
+ displays[0].set_rotation(display::Display::ROTATE_0);
+ displays[1].set_rotation(display::Display::ROTATE_0);
NotifyDisplaysChanged(displays);
EXPECT_EQ(5u, changed_display_.size());
}
// Test that changing the displays workarea notifies the DisplayObservers.
TEST_F(DesktopScreenX11Test, WorkareaChange) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
displays.push_back(
- gfx::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
ResetDisplayChanges();
@@ -431,10 +448,11 @@ TEST_F(DesktopScreenX11Test, WorkareaChange) {
// Test that changing the device scale factor notifies the DisplayObservers.
TEST_F(DesktopScreenX11Test, DeviceScaleFactorChange) {
- std::vector<gfx::Display> displays;
- displays.push_back(gfx::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
+ std::vector<display::Display> displays;
+ displays.push_back(
+ display::Display(kFirstDisplay, gfx::Rect(0, 0, 640, 480)));
displays.push_back(
- gfx::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
+ display::Display(kSecondDisplay, gfx::Rect(640, 0, 1024, 768)));
NotifyDisplaysChanged(displays);
ResetDisplayChanges();
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h
index 831557d4f66..7eee095edf7 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host.h
@@ -5,7 +5,8 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_H_
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/ui_base_types.h"
#include "ui/views/views_export.h"
@@ -62,12 +63,12 @@ class VIEWS_EXPORT DesktopWindowTreeHost {
// Creates and returns the Tooltip implementation to use. Return value is
// owned by DesktopNativeWidgetAura and lives as long as
// DesktopWindowTreeHost.
- virtual scoped_ptr<corewm::Tooltip> CreateTooltip() = 0;
+ virtual std::unique_ptr<corewm::Tooltip> CreateTooltip() = 0;
// Creates and returns the DragDropClient implementation to use. Return value
// is owned by DesktopNativeWidgetAura and lives as long as
// DesktopWindowTreeHost.
- virtual scoped_ptr<aura::client::DragDropClient> CreateDragDropClient(
+ virtual std::unique_ptr<aura::client::DragDropClient> CreateDragDropClient(
DesktopNativeCursorManager* cursor_manager) = 0;
virtual void Close() = 0;
@@ -89,6 +90,7 @@ class VIEWS_EXPORT DesktopWindowTreeHost {
virtual gfx::Rect GetWindowBoundsInScreen() const = 0;
virtual gfx::Rect GetClientAreaBoundsInScreen() const = 0;
virtual gfx::Rect GetRestoredBounds() const = 0;
+ virtual std::string GetWorkspace() const = 0;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const = 0;
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index fa9ea48b500..7591042b3c5 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -4,6 +4,7 @@
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
+#include "base/memory/ptr_util.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/aura/client/aura_constants.h"
@@ -16,12 +17,13 @@
#include "ui/base/win/shell.h"
#include "ui/compositor/compositor_constants.h"
#include "ui/compositor/paint_context.h"
+#include "ui/display/win/dpi.h"
+#include "ui/display/win/screen_win.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/path.h"
#include "ui/gfx/path_win.h"
-#include "ui/gfx/win/dpi.h"
#include "ui/native_theme/native_theme_aura.h"
#include "ui/native_theme/native_theme_win.h"
#include "ui/views/corewm/tooltip_win.h"
@@ -140,7 +142,9 @@ void DesktopWindowTreeHostWin::Init(aura::Window* content_window,
remove_standard_frame_ = params.remove_standard_frame;
has_non_client_view_ = Widget::RequiresNonClientView(params.type);
- gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(params.bounds);
+ // We don't have an HWND yet, so scale relative to the nearest screen.
+ gfx::Rect pixel_bounds =
+ display::win::ScreenWin::DIPToScreenRect(nullptr, params.bounds);
message_handler_->Init(parent_hwnd, pixel_bounds);
if (params.force_software_compositing) {
::SetProp(GetAcceleratedWidget(),
@@ -170,17 +174,17 @@ void DesktopWindowTreeHostWin::OnNativeWidgetCreated(
SetWindowTransparency();
}
-scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
+std::unique_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
DCHECK(!tooltip_);
tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
- return make_scoped_ptr(tooltip_);
+ return base::WrapUnique(tooltip_);
}
-scoped_ptr<aura::client::DragDropClient>
+std::unique_ptr<aura::client::DragDropClient>
DesktopWindowTreeHostWin::CreateDragDropClient(
DesktopNativeCursorManager* cursor_manager) {
drag_drop_client_ = new DesktopDragDropClientWin(window(), GetHWND());
- return make_scoped_ptr(drag_drop_client_);
+ return base::WrapUnique(drag_drop_client_);
}
void DesktopWindowTreeHostWin::Close() {
@@ -218,7 +222,8 @@ void DesktopWindowTreeHostWin::ShowMaximizedWithBounds(
const gfx::Rect& restored_bounds) {
if (compositor())
compositor()->SetVisible(true);
- gfx::Rect pixel_bounds = gfx::win::DIPToScreenRect(restored_bounds);
+ gfx::Rect pixel_bounds =
+ display::win::ScreenWin::DIPToScreenRect(GetHWND(), restored_bounds);
message_handler_->ShowMaximizedWithBounds(pixel_bounds);
}
@@ -227,7 +232,8 @@ bool DesktopWindowTreeHostWin::IsVisible() const {
}
void DesktopWindowTreeHostWin::SetSize(const gfx::Size& size) {
- gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
+ gfx::Size size_in_pixels = display::win::ScreenWin::DIPToScreenSize(GetHWND(),
+ size);
gfx::Size expanded = GetExpandedWindowSize(
message_handler_->window_ex_style(), size_in_pixels);
window_enlargement_ =
@@ -247,7 +253,8 @@ void DesktopWindowTreeHostWin::StackAtTop() {
}
void DesktopWindowTreeHostWin::CenterWindow(const gfx::Size& size) {
- gfx::Size size_in_pixels = gfx::win::DIPToScreenSize(size);
+ gfx::Size size_in_pixels = display::win::ScreenWin::DIPToScreenSize(GetHWND(),
+ size);
gfx::Size expanded_size;
expanded_size = GetExpandedWindowSize(message_handler_->window_ex_style(),
size_in_pixels);
@@ -262,25 +269,29 @@ void DesktopWindowTreeHostWin::GetWindowPlacement(
ui::WindowShowState* show_state) const {
message_handler_->GetWindowPlacement(bounds, show_state);
InsetBottomRight(bounds, window_enlargement_);
- *bounds = gfx::win::ScreenToDIPRect(*bounds);
+ *bounds = display::win::ScreenWin::ScreenToDIPRect(GetHWND(), *bounds);
}
gfx::Rect DesktopWindowTreeHostWin::GetWindowBoundsInScreen() const {
gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
InsetBottomRight(&pixel_bounds, window_enlargement_);
- return gfx::win::ScreenToDIPRect(pixel_bounds);
+ return display::win::ScreenWin::ScreenToDIPRect(GetHWND(), pixel_bounds);
}
gfx::Rect DesktopWindowTreeHostWin::GetClientAreaBoundsInScreen() const {
gfx::Rect pixel_bounds = message_handler_->GetClientAreaBoundsInScreen();
InsetBottomRight(&pixel_bounds, window_enlargement_);
- return gfx::win::ScreenToDIPRect(pixel_bounds);
+ return display::win::ScreenWin::ScreenToDIPRect(GetHWND(), pixel_bounds);
}
gfx::Rect DesktopWindowTreeHostWin::GetRestoredBounds() const {
gfx::Rect pixel_bounds = message_handler_->GetRestoredBounds();
InsetBottomRight(&pixel_bounds, window_enlargement_);
- return gfx::win::ScreenToDIPRect(pixel_bounds);
+ return display::win::ScreenWin::ScreenToDIPRect(GetHWND(), pixel_bounds);
+}
+
+std::string DesktopWindowTreeHostWin::GetWorkspace() const {
+ return std::string();
}
gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
@@ -290,7 +301,7 @@ gfx::Rect DesktopWindowTreeHostWin::GetWorkAreaBoundsInScreen() const {
MONITOR_DEFAULTTONEAREST),
&monitor_info);
gfx::Rect pixel_bounds = gfx::Rect(monitor_info.rcWork);
- return gfx::win::ScreenToDIPRect(pixel_bounds);
+ return display::win::ScreenWin::ScreenToDIPRect(GetHWND(), pixel_bounds);
}
void DesktopWindowTreeHostWin::SetShape(SkRegion* native_region) {
@@ -299,9 +310,9 @@ void DesktopWindowTreeHostWin::SetShape(SkRegion* native_region) {
// See crbug.com/410593.
SkRegion* shape = native_region;
SkRegion device_region;
- if (gfx::GetDPIScale() > 1.0) {
+ if (display::win::GetDPIScale() > 1.0) {
shape = &device_region;
- const float& scale = gfx::GetDPIScale();
+ const float& scale = display::win::GetDPIScale();
std::vector<SkIRect> rects;
for (SkRegion::Iterator it(*native_region); !it.done(); it.next()) {
const SkIRect& rect = it.rect();
@@ -654,7 +665,8 @@ bool DesktopWindowTreeHostWin::WillProcessWorkAreaChange() const {
int DesktopWindowTreeHostWin::GetNonClientComponent(
const gfx::Point& point) const {
- gfx::Point dip_position = gfx::win::ScreenToDIPPoint(point);
+ gfx::Point dip_position = display::win::ScreenWin::ClientToDIPPoint(GetHWND(),
+ point);
return native_widget_delegate_->GetNonClientComponent(dip_position);
}
@@ -685,6 +697,11 @@ gfx::Size DesktopWindowTreeHostWin::GetRootViewSize() const {
return GetWidget()->GetRootView()->size();
}
+gfx::Size DesktopWindowTreeHostWin::DIPToScreenSize(
+ const gfx::Size& dip_size) const {
+ return display::win::ScreenWin::DIPToScreenSize(GetHWND(), dip_size);
+}
+
void DesktopWindowTreeHostWin::ResetWindowControls() {
GetWidget()->non_client_view()->ResetWindowControls();
}
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 3465112eac0..f357a5c9895 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -48,8 +48,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
void Init(aura::Window* content_window,
const Widget::InitParams& params) override;
void OnNativeWidgetCreated(const Widget::InitParams& params) override;
- scoped_ptr<corewm::Tooltip> CreateTooltip() override;
- scoped_ptr<aura::client::DragDropClient> CreateDragDropClient(
+ std::unique_ptr<corewm::Tooltip> CreateTooltip() override;
+ std::unique_ptr<aura::client::DragDropClient> CreateDragDropClient(
DesktopNativeCursorManager* cursor_manager) override;
void Close() override;
void CloseNow() override;
@@ -66,6 +66,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
gfx::Rect GetWindowBoundsInScreen() const override;
gfx::Rect GetClientAreaBoundsInScreen() const override;
gfx::Rect GetRestoredBounds() const override;
+ std::string GetWorkspace() const override;
gfx::Rect GetWorkAreaBoundsInScreen() const override;
void SetShape(SkRegion* native_region) override;
void Activate() override;
@@ -146,6 +147,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
bool GetClientAreaInsets(gfx::Insets* insets) const override;
void GetMinMaxSize(gfx::Size* min_size, gfx::Size* max_size) const override;
gfx::Size GetRootViewSize() const override;
+ gfx::Size DIPToScreenSize(const gfx::Size& dip_size) const override;
void ResetWindowControls() override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
bool ShouldHandleSystemCommands() const override;
@@ -205,8 +207,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
// Returns true if a modal window is active in the current root window chain.
bool IsModalWindowActive() const;
- scoped_ptr<HWNDMessageHandler> message_handler_;
- scoped_ptr<aura::client::FocusClient> focus_client_;
+ std::unique_ptr<HWNDMessageHandler> message_handler_;
+ std::unique_ptr<aura::client::FocusClient> focus_client_;
// TODO(beng): Consider providing an interface to DesktopNativeWidgetAura
// instead of providing this route back to Widget.
@@ -258,7 +260,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
// whenever the cursor visibility state changes.
static bool is_cursor_visible_;
- scoped_ptr<aura::client::ScopedTooltipDisabler> tooltip_disabler_;
+ std::unique_ptr<aura::client::ScopedTooltipDisabler> tooltip_disabler_;
// Indicates if current window will receive mouse events when should not
// become activated.
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index cecae1ee81d..f792797e855 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -9,9 +9,12 @@
#include <X11/Xutil.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/shape.h>
+
#include <utility>
#include "base/command_line.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
@@ -26,20 +29,20 @@
#include "ui/base/ime/input_method.h"
#include "ui/base/x/x11_util.h"
#include "ui/base/x/x11_util_internal.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/events/devices/x11/device_data_manager_x11.h"
#include "ui/events/devices/x11/device_list_cache_x11.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/event_utils.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/gfx/display.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/path.h"
#include "ui/gfx/path_x11.h"
-#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/native_theme_aura.h"
#include "ui/views/corewm/tooltip_aura.h"
@@ -250,7 +253,7 @@ void DesktopWindowTreeHostX11::RemoveObserver(
}
void DesktopWindowTreeHostX11::SwapNonClientEventHandler(
- scoped_ptr<ui::EventHandler> handler) {
+ std::unique_ptr<ui::EventHandler> handler) {
wm::CompoundEventFilter* compound_event_filter =
desktop_native_widget_aura_->root_window_event_filter();
if (x11_non_client_event_filter_)
@@ -307,7 +310,7 @@ void DesktopWindowTreeHostX11::OnNativeWidgetCreated(
// TODO(erg): Unify this code once the other consumer goes away.
SwapNonClientEventHandler(
- scoped_ptr<ui::EventHandler>(new X11WindowEventFilter(this)));
+ std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this)));
SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW &&
!params.remove_standard_frame);
@@ -319,17 +322,17 @@ void DesktopWindowTreeHostX11::OnNativeWidgetCreated(
native_widget_delegate_->OnNativeWidgetCreated(true);
}
-scoped_ptr<corewm::Tooltip> DesktopWindowTreeHostX11::CreateTooltip() {
- return make_scoped_ptr(new corewm::TooltipAura);
+std::unique_ptr<corewm::Tooltip> DesktopWindowTreeHostX11::CreateTooltip() {
+ return base::WrapUnique(new corewm::TooltipAura);
}
-scoped_ptr<aura::client::DragDropClient>
+std::unique_ptr<aura::client::DragDropClient>
DesktopWindowTreeHostX11::CreateDragDropClient(
DesktopNativeCursorManager* cursor_manager) {
drag_drop_client_ = new DesktopDragDropClientAuraX11(
window(), cursor_manager, xdisplay_, xwindow_);
drag_drop_client_->Init();
- return make_scoped_ptr(drag_drop_client_);
+ return base::WrapUnique(drag_drop_client_);
}
void DesktopWindowTreeHostX11::Close() {
@@ -561,6 +564,13 @@ gfx::Rect DesktopWindowTreeHostX11::GetRestoredBounds() const {
return GetWindowBoundsInScreen();
}
+std::string DesktopWindowTreeHostX11::GetWorkspace() const {
+ int workspace_id;
+ if (ui::GetIntProperty(xwindow_, "_NET_WM_DESKTOP", &workspace_id))
+ return base::IntToString(workspace_id);
+ return std::string();
+}
+
gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const {
return ToDIPRect(GetWorkAreaBoundsInPixels());
}
@@ -819,8 +829,8 @@ void DesktopWindowTreeHostX11::SetFullscreen(bool fullscreen) {
// See https://crbug.com/361408
if (fullscreen) {
restored_bounds_in_pixels_ = bounds_in_pixels_;
- const gfx::Display display =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(window());
+ const display::Display display =
+ display::Screen::GetScreen()->GetDisplayNearestWindow(window());
bounds_in_pixels_ = ToPixelRect(display.bounds());
} else {
bounds_in_pixels_ = restored_bounds_in_pixels_;
@@ -938,10 +948,10 @@ void DesktopWindowTreeHostX11::SizeConstraintsChanged() {
// DesktopWindowTreeHostX11, aura::WindowTreeHost implementation:
gfx::Transform DesktopWindowTreeHostX11::GetRootTransform() const {
- gfx::Display display = gfx::Screen::GetScreen()->GetPrimaryDisplay();
+ display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
if (window_mapped_) {
aura::Window* win = const_cast<aura::Window*>(window());
- display = gfx::Screen::GetScreen()->GetDisplayNearestWindow(win);
+ display = display::Screen::GetScreen()->GetDisplayNearestWindow(win);
}
float scale = display.device_scale_factor();
@@ -1216,6 +1226,10 @@ void DesktopWindowTreeHostX11::InitX11Window(
if (params.visible_on_all_workspaces) {
state_atom_list.push_back(atom_cache_.GetAtom("_NET_WM_STATE_STICKY"));
ui::SetIntProperty(xwindow_, "_NET_WM_DESKTOP", "CARDINAL", kAllDesktops);
+ } else if (!params.workspace.empty()) {
+ int workspace;
+ if (base::StringToInt(params.workspace, &workspace))
+ ui::SetIntProperty(xwindow_, "_NET_WM_DESKTOP", "CARDINAL", workspace);
}
// Setting _NET_WM_STATE by sending a message to the root_window (with
@@ -1286,8 +1300,8 @@ void DesktopWindowTreeHostX11::InitX11Window(
gfx::Size DesktopWindowTreeHostX11::AdjustSize(
const gfx::Size& requested_size_in_pixels) {
- std::vector<gfx::Display> displays =
- gfx::Screen::GetScreen()->GetAllDisplays();
+ std::vector<display::Display> displays =
+ display::Screen::GetScreen()->GetAllDisplays();
// Compare against all monitor sizes. The window manager can move the window
// to whichever monitor it wants.
for (size_t i = 0; i < displays.size(); ++i) {
@@ -1532,10 +1546,10 @@ void DesktopWindowTreeHostX11::ConvertEventToDifferentHost(
ui::LocatedEvent* located_event,
DesktopWindowTreeHostX11* host) {
DCHECK_NE(this, host);
- const gfx::Display display_src =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(window());
- const gfx::Display display_dest =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(host->window());
+ const display::Display display_src =
+ display::Screen::GetScreen()->GetDisplayNearestWindow(window());
+ const display::Display display_dest =
+ display::Screen::GetScreen()->GetDisplayNearestWindow(host->window());
DCHECK_EQ(display_src.device_scale_factor(),
display_dest.device_scale_factor());
gfx::Vector2d offset = GetLocationOnNativeScreen() -
@@ -1658,16 +1672,6 @@ void DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState show_state) {
// asynchronous.
if (ui::X11EventSource::GetInstance())
ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_);
- window_mapped_ = true;
-
- UpdateMinAndMaxSize();
-
- // Some WMs only respect maximize hints after the window has been mapped.
- // Check whether we need to re-do a maximization.
- if (should_maximize_after_map_) {
- Maximize();
- should_maximize_after_map_ = false;
- }
}
void DesktopWindowTreeHostX11::SetWindowTransparency() {
@@ -1881,9 +1885,21 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
break;
}
case MapNotify: {
+ window_mapped_ = true;
+
FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11,
observer_list_,
OnWindowMapped(xwindow_));
+
+ UpdateMinAndMaxSize();
+
+ // Some WMs only respect maximize hints after the window has been mapped.
+ // Check whether we need to re-do a maximization.
+ if (should_maximize_after_map_) {
+ Maximize();
+ should_maximize_after_map_ = false;
+ }
+
break;
}
case UnmapNotify: {
@@ -1967,6 +1983,8 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
OnWMStateUpdated();
else if (changed_atom == atom_cache_.GetAtom("_NET_FRAME_EXTENTS"))
OnFrameExtentsUpdated();
+ else if (changed_atom == atom_cache_.GetAtom("_NET_WM_DESKTOP"))
+ OnHostWorkspaceChanged();
break;
}
case SelectionNotify: {
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 7e842fed086..6a963f8456e 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -80,7 +80,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
void RemoveObserver(views::DesktopWindowTreeHostObserverX11* observer);
// Swaps the current handler for events in the non client view with |handler|.
- void SwapNonClientEventHandler(scoped_ptr<ui::EventHandler> handler);
+ void SwapNonClientEventHandler(std::unique_ptr<ui::EventHandler> handler);
// Runs the |func| callback for each content-window, and deallocates the
// internal list of open windows.
@@ -91,8 +91,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
void Init(aura::Window* content_window,
const Widget::InitParams& params) override;
void OnNativeWidgetCreated(const Widget::InitParams& params) override;
- scoped_ptr<corewm::Tooltip> CreateTooltip() override;
- scoped_ptr<aura::client::DragDropClient> CreateDragDropClient(
+ std::unique_ptr<corewm::Tooltip> CreateTooltip() override;
+ std::unique_ptr<aura::client::DragDropClient> CreateDragDropClient(
DesktopNativeCursorManager* cursor_manager) override;
void Close() override;
void CloseNow() override;
@@ -109,6 +109,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
gfx::Rect GetWindowBoundsInScreen() const override;
gfx::Rect GetClientAreaBoundsInScreen() const override;
gfx::Rect GetRestoredBounds() const override;
+ std::string GetWorkspace() const override;
gfx::Rect GetWorkAreaBoundsInScreen() const override;
void SetShape(SkRegion* native_region) override;
void Activate() override;
@@ -300,8 +301,8 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
DesktopDragDropClientAuraX11* drag_drop_client_;
- scoped_ptr<ui::EventHandler> x11_non_client_event_filter_;
- scoped_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
+ std::unique_ptr<ui::EventHandler> x11_non_client_event_filter_;
+ std::unique_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
// TODO(beng): Consider providing an interface to DesktopNativeWidgetAura
// instead of providing this route back to Widget.
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
index 7ea716cfe0e..1ac18b5b7cd 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_interactive_uitest.cc
@@ -6,12 +6,13 @@
#include <X11/Xlib.h>
+#include <memory>
+
// Get rid of X11 macros which conflict with gtest.
#undef Bool
#undef None
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
@@ -81,8 +82,8 @@ class MouseMoveCounterHandler : public ui::EventHandler {
};
// Creates a widget with the given bounds.
-scoped_ptr<Widget> CreateWidget(const gfx::Rect& bounds) {
- scoped_ptr<Widget> widget(new Widget);
+std::unique_ptr<Widget> CreateWidget(const gfx::Rect& bounds) {
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.remove_standard_frame = true;
@@ -156,7 +157,7 @@ class DesktopWindowTreeHostX11Test : public ViewsTestBase {
// Chrome even if it not possible to deactivate the window wrt to the x server.
// This behavior is required by several interactive_ui_tests.
TEST_F(DesktopWindowTreeHostX11Test, Deactivate) {
- scoped_ptr<Widget> widget(CreateWidget(gfx::Rect(100, 100, 100, 100)));
+ std::unique_ptr<Widget> widget(CreateWidget(gfx::Rect(100, 100, 100, 100)));
ActivationWaiter waiter(
widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget());
@@ -181,13 +182,13 @@ TEST_F(DesktopWindowTreeHostX11Test, Deactivate) {
// Chrome synchronously switches the window that mouse events are forwarded to
// when capture is changed.
TEST_F(DesktopWindowTreeHostX11Test, CaptureEventForwarding) {
- scoped_ptr<Widget> widget1(CreateWidget(gfx::Rect(100, 100, 100, 100)));
+ std::unique_ptr<Widget> widget1(CreateWidget(gfx::Rect(100, 100, 100, 100)));
aura::Window* window1 = widget1->GetNativeWindow();
DesktopWindowTreeHostX11* host1 =
static_cast<DesktopWindowTreeHostX11*>(window1->GetHost());
widget1->Show();
- scoped_ptr<Widget> widget2(CreateWidget(gfx::Rect(200, 100, 100, 100)));
+ std::unique_ptr<Widget> widget2(CreateWidget(gfx::Rect(200, 100, 100, 100)));
aura::Window* window2 = widget2->GetNativeWindow();
DesktopWindowTreeHostX11* host2 =
static_cast<DesktopWindowTreeHostX11*>(window2->GetHost());
@@ -255,8 +256,8 @@ TEST_F(DesktopWindowTreeHostX11Test, CaptureEventForwarding) {
}
TEST_F(DesktopWindowTreeHostX11Test, InputMethodFocus) {
- scoped_ptr<Widget> widget(CreateWidget(gfx::Rect(100, 100, 100, 100)));
- scoped_ptr<Textfield> textfield(new Textfield);
+ std::unique_ptr<Widget> widget(CreateWidget(gfx::Rect(100, 100, 100, 100)));
+ std::unique_ptr<Textfield> textfield(new Textfield);
textfield->SetBounds(0, 0, 200, 20);
widget->GetRootView()->AddChildView(textfield.get());
widget->ShowInactive();
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index 7c2253493ac..52a3827f2bc 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <vector>
-
#include <stddef.h>
#include <X11/extensions/shape.h>
#include <X11/Xlib.h>
+#include <memory>
+#include <vector>
+
// Get rid of X11 macros which conflict with gtest.
// It is necessary to include this header before the rest so that Bool can be
// undefined.
@@ -17,19 +18,18 @@
#include "base/command_line.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
#include "ui/base/x/x11_util.h"
+#include "ui/display/display_switches.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/platform/x11/x11_event_source_glib.h"
#include "ui/events/test/platform_event_source_test_api.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/path.h"
-#include "ui/gfx/switches.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/x11_property_change_waiter.h"
@@ -76,7 +76,7 @@ class WMStateWaiter : public X11PropertyChangeWaiter {
return true;
}
- scoped_ptr<ui::X11AtomCache> atom_cache_;
+ std::unique_ptr<ui::X11AtomCache> atom_cache_;
// The name of the hint to wait to get set or unset.
const char* hint_;
@@ -140,8 +140,8 @@ class ShapedWidgetDelegate : public WidgetDelegateView {
};
// Creates a widget of size 100x100.
-scoped_ptr<Widget> CreateWidget(WidgetDelegate* delegate) {
- scoped_ptr<Widget> widget(new Widget);
+std::unique_ptr<Widget> CreateWidget(WidgetDelegate* delegate) {
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.delegate = delegate;
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -219,7 +219,7 @@ TEST_F(DesktopWindowTreeHostX11Test, Shape) {
// 1) Test setting the window shape via the NonClientFrameView. This technique
// is used to get rounded corners on Chrome windows when not using the native
// window frame.
- scoped_ptr<Widget> widget1 = CreateWidget(new ShapedWidgetDelegate());
+ std::unique_ptr<Widget> widget1 = CreateWidget(new ShapedWidgetDelegate());
widget1->Show();
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -290,7 +290,7 @@ TEST_F(DesktopWindowTreeHostX11Test, Shape) {
SkRegion* shape_region = new SkRegion;
shape_region->setPath(shape2, SkRegion(shape2.getBounds().round()));
- scoped_ptr<Widget> widget2(CreateWidget(NULL));
+ std::unique_ptr<Widget> widget2(CreateWidget(NULL));
widget2->Show();
widget2->SetShape(shape_region);
ui::X11EventSource::GetInstance()->DispatchXEvents();
@@ -330,7 +330,7 @@ TEST_F(DesktopWindowTreeHostX11Test, WindowManagerTogglesFullscreen) {
if (!ui::WmSupportsHint(ui::GetAtom("_NET_WM_STATE_FULLSCREEN")))
return;
- scoped_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate());
+ std::unique_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate());
XID xid = widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
widget->Show();
ui::X11EventSource::GetInstance()->DispatchXEvents();
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
index 5ab84f9928e..8ec4b1e7b9a 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
@@ -43,7 +43,7 @@ X11DesktopHandler::X11DesktopHandler()
: xdisplay_(gfx::GetXDisplay()),
x_root_window_(DefaultRootWindow(xdisplay_)),
x_active_window_(None),
- wm_user_time_ms_(0),
+ wm_user_time_ms_(CurrentTime),
current_window_(None),
current_window_active_state_(NOT_ACTIVE),
atom_cache_(xdisplay_, kAtomsToCache),
@@ -91,6 +91,10 @@ void X11DesktopHandler::ActivateWindow(::Window window) {
// If the window is not already active, send a hint to activate it
if (x_active_window_ != window) {
+ if (wm_user_time_ms_ == CurrentTime) {
+ set_wm_user_time_ms(
+ ui::X11EventSource::GetInstance()->UpdateLastSeenServerTime());
+ }
XEvent xclient;
memset(&xclient, 0, sizeof(xclient));
xclient.type = ClientMessage;
@@ -120,6 +124,18 @@ void X11DesktopHandler::ActivateWindow(::Window window) {
}
}
+void X11DesktopHandler::set_wm_user_time_ms(Time time_ms) {
+ if (time_ms != CurrentTime) {
+ int64_t event_time_64 = time_ms;
+ int64_t time_difference = wm_user_time_ms_ - event_time_64;
+ // Ignore timestamps that go backwards. However, X server time is a 32-bit
+ // millisecond counter, so if the time goes backwards by more than half the
+ // range of the 32-bit counter, treat it as a rollover.
+ if (time_difference < 0 || time_difference > (UINT32_MAX >> 1))
+ wm_user_time_ms_ = time_ms;
+ }
+}
+
void X11DesktopHandler::DeactivateWindow(::Window window) {
if (!IsActiveWindow(window))
return;
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h
index 947040e4393..47a1ff1a7ff 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h
+++ b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.h
@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "ui/aura/env_observer.h"
#include "ui/events/platform/platform_event_dispatcher.h"
+#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/views_export.h"
@@ -36,12 +37,8 @@ class VIEWS_EXPORT X11DesktopHandler : public ui::PlatformEventDispatcher,
// Gets/sets the X11 server time of the most recent mouse click, touch or
// key press on a Chrome window.
- int wm_user_time_ms() const {
- return wm_user_time_ms_;
- }
- void set_wm_user_time_ms(unsigned long time_ms) {
- wm_user_time_ms_ = time_ms;
- }
+ int wm_user_time_ms() const { return wm_user_time_ms_; }
+ void set_wm_user_time_ms(Time time_ms);
// Sends a request to the window manager to activate |window|.
// This method should only be called if the window is already mapped.
@@ -95,7 +92,7 @@ class VIEWS_EXPORT X11DesktopHandler : public ui::PlatformEventDispatcher,
// The X11 server time of the most recent mouse click, touch, or key press
// on a Chrome window.
- unsigned long wm_user_time_ms_;
+ Time wm_user_time_ms_;
// The active window according to X11 server.
::Window current_window_;
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc b/chromium/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc
index 35403700d7d..c6bcbb3e8e6 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_desktop_window_move_client.cc
@@ -14,7 +14,6 @@
#include "ui/aura/window_tree_host.h"
#include "ui/base/x/x11_util.h"
#include "ui/events/event.h"
-#include "ui/gfx/screen.h"
namespace views {
diff --git a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
index 46357f60f00..2bb919bb4df 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
@@ -4,11 +4,13 @@
#include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
-#include <stddef.h>
-#include <X11/extensions/shape.h>
#include <X11/Xlib.h>
#include <X11/Xregion.h>
+#include <X11/extensions/shape.h>
+#include <stddef.h>
+
#include <algorithm>
+#include <memory>
#include <vector>
// Get rid of X11 macros which conflict with gtest.
@@ -16,7 +18,6 @@
#undef None
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRegion.h"
@@ -62,7 +63,7 @@ class MinimizeWaiter : public X11PropertyChangeWaiter {
return true;
}
- scoped_ptr<ui::X11AtomCache> atom_cache_;
+ std::unique_ptr<ui::X11AtomCache> atom_cache_;
DISALLOW_COPY_AND_ASSIGN(MinimizeWaiter);
};
@@ -118,8 +119,8 @@ class X11TopmostWindowFinderTest : public ViewsTestBase {
// Creates and shows a Widget with |bounds|. The caller takes ownership of
// the returned widget.
- scoped_ptr<Widget> CreateAndShowWidget(const gfx::Rect& bounds) {
- scoped_ptr<Widget> toplevel(new Widget);
+ std::unique_ptr<Widget> CreateAndShowWidget(const gfx::Rect& bounds) {
+ std::unique_ptr<Widget> toplevel(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.native_widget = new DesktopNativeWidgetAura(toplevel.get());
@@ -226,14 +227,14 @@ TEST_F(X11TopmostWindowFinderTest, Basic) {
// Avoid positioning test windows at 0x0 because window managers often have a
// panel/launcher along one of the screen edges and do not allow windows to
// position themselves to overlap the panel/launcher.
- scoped_ptr<Widget> widget1(
+ std::unique_ptr<Widget> widget1(
CreateAndShowWidget(gfx::Rect(100, 100, 200, 100)));
aura::Window* window1 = widget1->GetNativeWindow();
XID xid1 = window1->GetHost()->GetAcceleratedWidget();
XID xid2 = CreateAndShowXWindow(gfx::Rect(200, 100, 100, 200));
- scoped_ptr<Widget> widget3(
+ std::unique_ptr<Widget> widget3(
CreateAndShowWidget(gfx::Rect(100, 190, 200, 110)));
aura::Window* window3 = widget3->GetNativeWindow();
XID xid3 = window3->GetHost()->GetAcceleratedWidget();
@@ -277,7 +278,7 @@ TEST_F(X11TopmostWindowFinderTest, Basic) {
// Test that the minimized state is properly handled.
TEST_F(X11TopmostWindowFinderTest, Minimized) {
- scoped_ptr<Widget> widget1(
+ std::unique_ptr<Widget> widget1(
CreateAndShowWidget(gfx::Rect(100, 100, 100, 100)));
aura::Window* window1 = widget1->GetNativeWindow();
XID xid1 = window1->GetHost()->GetAcceleratedWidget();
@@ -316,7 +317,7 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangular) {
if (!ui::IsShapeExtensionAvailable())
return;
- scoped_ptr<Widget> widget1(
+ std::unique_ptr<Widget> widget1(
CreateAndShowWidget(gfx::Rect(100, 100, 100, 100)));
XID xid1 = widget1->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
SkRegion* skregion1 = new SkRegion;
@@ -356,7 +357,7 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangularEmptyShape) {
if (!ui::IsShapeExtensionAvailable())
return;
- scoped_ptr<Widget> widget1(
+ std::unique_ptr<Widget> widget1(
CreateAndShowWidget(gfx::Rect(100, 100, 100, 100)));
XID xid1 = widget1->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
SkRegion* skregion1 = new SkRegion;
@@ -377,7 +378,7 @@ TEST_F(X11TopmostWindowFinderTest, NonRectangularNullShape) {
if (!ui::IsShapeExtensionAvailable())
return;
- scoped_ptr<Widget> widget1(
+ std::unique_ptr<Widget> widget1(
CreateAndShowWidget(gfx::Rect(100, 100, 100, 100)));
XID xid1 = widget1->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
SkRegion* skregion1 = new SkRegion;
diff --git a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index eca9951d2da..cbf3f35638c 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -159,7 +159,7 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source,
GrabEscKey();
- scoped_ptr<ui::ScopedEventDispatcher> old_dispatcher =
+ std::unique_ptr<ui::ScopedEventDispatcher> old_dispatcher =
std::move(nested_dispatcher_);
nested_dispatcher_ =
ui::PlatformEventSource::GetInstance()->OverrideDispatcher(this);
diff --git a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
index 24a909911c1..c1eb5515ef8 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
+++ b/chromium/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h
@@ -67,7 +67,7 @@ class X11WholeScreenMoveLoop : public X11MoveLoop,
// Are we running a nested message loop from RunMoveLoop()?
bool in_move_loop_;
- scoped_ptr<ui::ScopedEventDispatcher> nested_dispatcher_;
+ std::unique_ptr<ui::ScopedEventDispatcher> nested_dispatcher_;
// Cursor in use prior to the move loop starting. Restored when the move loop
// quits.
@@ -88,7 +88,7 @@ class X11WholeScreenMoveLoop : public X11MoveLoop,
// pressing escape).
bool canceled_;
- scoped_ptr<ui::MouseEvent> last_motion_in_screen_;
+ std::unique_ptr<ui::MouseEvent> last_motion_in_screen_;
base::WeakPtrFactory<X11WholeScreenMoveLoop> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(X11WholeScreenMoveLoop);
diff --git a/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc b/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc
index c0ead5563fd..b8a4c388be2 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_window_event_filter.cc
@@ -14,10 +14,10 @@
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/hit_test.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/views/linux_ui/linux_ui.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
@@ -152,7 +152,7 @@ void X11WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) {
return;
gfx::Rect display_work_area =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area();
+ display::Screen::GetScreen()->GetDisplayNearestWindow(target).work_area();
gfx::Rect bounds = widget->GetWindowBoundsInScreen();
if (event->IsMiddleMouseButton()) {
bounds.set_y(display_work_area.y());
diff --git a/chromium/ui/views/widget/native_widget_aura.cc b/chromium/ui/views/widget/native_widget_aura.cc
index 4f24e5caced..cbdf38294d4 100644
--- a/chromium/ui/views/widget/native_widget_aura.cc
+++ b/chromium/ui/views/widget/native_widget_aura.cc
@@ -5,10 +5,12 @@
#include "ui/views/widget/native_widget_aura.h"
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/screen_position_client.h"
@@ -21,10 +23,11 @@
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/ui_base_types.h"
#include "ui/compositor/layer.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h"
-#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme_aura.h"
#include "ui/views/drag_utils.h"
#include "ui/views/views_delegate.h"
@@ -109,6 +112,8 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
window_->SetTransparent(
params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW);
window_->Init(params.layer_type);
+ // Set name after layer init so it propagates to layer.
+ window_->SetName(params.name);
if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_NONE)
SetShadowType(window_, wm::SHADOW_TYPE_NONE);
else if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP)
@@ -137,8 +142,9 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
// If a parent is specified but no bounds are given,
// use the origin of the parent's display so that the widget
// will be added to the same display as the parent.
- gfx::Rect bounds =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(parent).bounds();
+ gfx::Rect bounds = display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(parent)
+ .bounds();
window_bounds.set_origin(bounds.origin());
}
}
@@ -283,8 +289,9 @@ void NativeWidgetAura::CenterWindow(const gfx::Size& size) {
// When centering window, we take the intersection of the host and
// the parent. We assume the root window represents the visible
// rect of a single screen.
- gfx::Rect work_area =
- gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_).work_area();
+ gfx::Rect work_area = display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(window_)
+ .work_area();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(window_->GetRootWindow());
@@ -394,6 +401,10 @@ gfx::Rect NativeWidgetAura::GetRestoredBounds() const {
return bounds;
}
+std::string NativeWidgetAura::GetWorkspace() const {
+ return std::string();
+}
+
void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
if (!window_)
return;
@@ -403,8 +414,8 @@ void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) {
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root);
if (screen_position_client) {
- gfx::Display dst_display =
- gfx::Screen::GetScreen()->GetDisplayMatching(bounds);
+ display::Display dst_display =
+ display::Screen::GetScreen()->GetDisplayMatching(bounds);
screen_position_client->SetBounds(window_, bounds, dst_display);
return;
}
@@ -436,7 +447,7 @@ void NativeWidgetAura::StackBelow(gfx::NativeView native_view) {
void NativeWidgetAura::SetShape(SkRegion* region) {
if (window_)
- window_->layer()->SetAlphaShape(make_scoped_ptr(region));
+ window_->layer()->SetAlphaShape(base::WrapUnique(region));
else
delete region;
}
@@ -642,7 +653,9 @@ void NativeWidgetAura::ClearNativeFocus() {
gfx::Rect NativeWidgetAura::GetWorkAreaBoundsInScreen() const {
if (!window_)
return gfx::Rect();
- return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_).work_area();
+ return display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(window_)
+ .work_area();
}
Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop(
@@ -737,6 +750,10 @@ void NativeWidgetAura::RepostNativeEvent(gfx::NativeEvent native_event) {
OnEvent(native_event);
}
+std::string NativeWidgetAura::GetName() const {
+ return window_ ? window_->name() : std::string();
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetAura, aura::WindowDelegate implementation:
@@ -1170,5 +1187,15 @@ gfx::FontList NativeWidgetPrivate::GetWindowTitleFontList() {
#endif
}
+// static
+gfx::NativeView NativeWidgetPrivate::GetGlobalCapture(
+ gfx::NativeView native_view) {
+ aura::client::CaptureClient* capture_client =
+ aura::client::GetCaptureClient(native_view->GetRootWindow());
+ if (!capture_client)
+ return nullptr;
+ return capture_client->GetGlobalCaptureWindow();
+}
+
} // namespace internal
} // namespace views
diff --git a/chromium/ui/views/widget/native_widget_aura.h b/chromium/ui/views/widget/native_widget_aura.h
index 9e27cca806b..65585834a64 100644
--- a/chromium/ui/views/widget/native_widget_aura.h
+++ b/chromium/ui/views/widget/native_widget_aura.h
@@ -5,6 +5,8 @@
#ifndef UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_
#define UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_
+#include <string>
+
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "ui/aura/client/focus_change_observer.h"
@@ -81,6 +83,7 @@ class VIEWS_EXPORT NativeWidgetAura
gfx::Rect GetWindowBoundsInScreen() const override;
gfx::Rect GetClientAreaBoundsInScreen() const override;
gfx::Rect GetRestoredBounds() const override;
+ std::string GetWorkspace() const override;
void SetBounds(const gfx::Rect& bounds) override;
void SetSize(const gfx::Size& size) override;
void StackAbove(gfx::NativeView native_view) override;
@@ -133,6 +136,7 @@ class VIEWS_EXPORT NativeWidgetAura
bool IsTranslucentWindowOpacitySupported() const override;
void OnSizeConstraintsChanged() override;
void RepostNativeEvent(gfx::NativeEvent native_event) override;
+ std::string GetName() const override;
// Overridden from aura::WindowDelegate:
gfx::Size GetMinimumSize() const override;
@@ -213,13 +217,13 @@ class VIEWS_EXPORT NativeWidgetAura
// The saved window state for exiting full screen state.
ui::WindowShowState saved_window_state_;
- scoped_ptr<TooltipManagerAura> tooltip_manager_;
+ std::unique_ptr<TooltipManagerAura> tooltip_manager_;
// Reorders child windows of |window_| associated with a view based on the
// order of the associated views in the widget's view hierarchy.
- scoped_ptr<WindowReorderer> window_reorderer_;
+ std::unique_ptr<WindowReorderer> window_reorderer_;
- scoped_ptr<DropHelper> drop_helper_;
+ std::unique_ptr<DropHelper> drop_helper_;
int last_drop_operation_;
// The following factory is used for calls to close the NativeWidgetAura
diff --git a/chromium/ui/views/widget/native_widget_aura_unittest.cc b/chromium/ui/views/widget/native_widget_aura_unittest.cc
index 0a626ae45a1..3d2f1c3b97e 100644
--- a/chromium/ui/views/widget/native_widget_aura_unittest.cc
+++ b/chromium/ui/views/widget/native_widget_aura_unittest.cc
@@ -4,9 +4,10 @@
#include "ui/views/widget/native_widget_aura.h"
+#include <memory>
+
#include "base/command_line.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
@@ -14,10 +15,10 @@
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
-#include "ui/gfx/screen.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/root_view.h"
@@ -78,7 +79,7 @@ class NativeWidgetAuraTest : public aura::test::AuraTestBase {
}
private:
- scoped_ptr<wm::FocusController> focus_controller_;
+ std::unique_ptr<wm::FocusController> focus_controller_;
TestFocusRules* test_focus_rules_;
DISALLOW_COPY_AND_ASSIGN(NativeWidgetAuraTest);
@@ -87,10 +88,10 @@ class NativeWidgetAuraTest : public aura::test::AuraTestBase {
TEST_F(NativeWidgetAuraTest, CenterWindowLargeParent) {
// Make a parent window larger than the host represented by
// WindowEventDispatcher.
- scoped_ptr<aura::Window> parent(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> parent(new aura::Window(nullptr));
parent->Init(ui::LAYER_NOT_DRAWN);
parent->SetBounds(gfx::Rect(0, 0, 1024, 800));
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
NativeWidgetAura* window = Init(parent.get(), widget.get());
window->CenterWindow(gfx::Size(100, 100));
@@ -104,10 +105,10 @@ TEST_F(NativeWidgetAuraTest, CenterWindowLargeParent) {
TEST_F(NativeWidgetAuraTest, CenterWindowSmallParent) {
// Make a parent window smaller than the host represented by
// WindowEventDispatcher.
- scoped_ptr<aura::Window> parent(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> parent(new aura::Window(nullptr));
parent->Init(ui::LAYER_NOT_DRAWN);
parent->SetBounds(gfx::Rect(0, 0, 480, 320));
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
NativeWidgetAura* window = Init(parent.get(), widget.get());
window->CenterWindow(gfx::Size(100, 100));
@@ -122,10 +123,10 @@ TEST_F(NativeWidgetAuraTest, CenterWindowSmallParent) {
TEST_F(NativeWidgetAuraTest, CenterWindowSmallParentNotAtOrigin) {
// Make a parent window smaller than the host represented by
// WindowEventDispatcher and offset it slightly from the origin.
- scoped_ptr<aura::Window> parent(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> parent(new aura::Window(nullptr));
parent->Init(ui::LAYER_NOT_DRAWN);
parent->SetBounds(gfx::Rect(20, 40, 480, 320));
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
NativeWidgetAura* window = Init(parent.get(), widget.get());
window->CenterWindow(gfx::Size(500, 600));
@@ -137,11 +138,11 @@ TEST_F(NativeWidgetAuraTest, CenterWindowSmallParentNotAtOrigin) {
TEST_F(NativeWidgetAuraTest, CreateMinimized) {
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.parent = NULL;
+ params.parent = nullptr;
params.context = root_window();
params.show_state = ui::SHOW_STATE_MINIMIZED;
params.bounds.SetRect(0, 0, 1024, 800);
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
widget->Init(params);
widget->Show();
@@ -149,6 +150,72 @@ TEST_F(NativeWidgetAuraTest, CreateMinimized) {
widget->CloseNow();
}
+// A WindowObserver that counts kShowStateKey property changes.
+class TestWindowObserver : public aura::WindowObserver {
+ public:
+ explicit TestWindowObserver(gfx::NativeWindow window) : window_(window) {
+ window_->AddObserver(this);
+ }
+ ~TestWindowObserver() override {
+ window_->RemoveObserver(this);
+ }
+
+ // aura::WindowObserver:
+ void OnWindowPropertyChanged(aura::Window* window,
+ const void* key,
+ intptr_t old) override {
+ if (key != aura::client::kShowStateKey)
+ return;
+ count_++;
+ state_ = window_->GetProperty(aura::client::kShowStateKey);
+ }
+
+ int count() const { return count_; }
+ ui::WindowShowState state() const { return state_; }
+ void Reset() { count_ = 0; }
+
+ private:
+ gfx::NativeWindow window_;
+ int count_ = 0;
+ ui::WindowShowState state_ = ui::WindowShowState::SHOW_STATE_DEFAULT;
+
+ DISALLOW_COPY_AND_ASSIGN(TestWindowObserver);
+};
+
+// Tests that window transitions from normal to minimized and back do not
+// involve extra show state transitions.
+TEST_F(NativeWidgetAuraTest, ToggleState) {
+ Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.parent = nullptr;
+ params.context = root_window();
+ params.show_state = ui::SHOW_STATE_NORMAL;
+ params.bounds.SetRect(0, 0, 1024, 800);
+ Widget widget;
+ widget.Init(params);
+ std::unique_ptr<TestWindowObserver> observer(
+ new TestWindowObserver(widget.GetNativeWindow()));
+ widget.Show();
+ EXPECT_FALSE(widget.IsMinimized());
+ EXPECT_EQ(0, observer->count());
+ EXPECT_EQ(ui::WindowShowState::SHOW_STATE_DEFAULT, observer->state());
+
+ widget.Minimize();
+ EXPECT_TRUE(widget.IsMinimized());
+ EXPECT_EQ(1, observer->count());
+ EXPECT_EQ(ui::WindowShowState::SHOW_STATE_MINIMIZED, observer->state());
+ observer->Reset();
+
+ widget.Show();
+ widget.Restore();
+ EXPECT_EQ(1, observer->count());
+ EXPECT_EQ(ui::WindowShowState::SHOW_STATE_NORMAL, observer->state());
+
+ observer.reset();
+ EXPECT_FALSE(widget.IsMinimized());
+ widget.CloseNow();
+}
+
class TestLayoutManagerBase : public aura::LayoutManager {
public:
TestLayoutManagerBase() {}
@@ -219,10 +286,10 @@ class TestWidget : public views::Widget {
TEST_F(NativeWidgetAuraTest, ShowMaximizedDoesntBounceAround) {
root_window()->SetBounds(gfx::Rect(0, 0, 640, 480));
root_window()->SetLayoutManager(new MaximizeLayoutManager);
- scoped_ptr<TestWidget> widget(new TestWidget());
+ std::unique_ptr<TestWidget> widget(new TestWidget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
- params.parent = NULL;
+ params.parent = nullptr;
params.context = root_window();
params.show_state = ui::SHOW_STATE_MAXIMIZED;
params.bounds = gfx::Rect(10, 10, 100, 200);
@@ -276,11 +343,11 @@ TEST_F(NativeWidgetAuraTest, TestPropertiesWhenAddedToLayout) {
root_window()->SetBounds(gfx::Rect(0, 0, 640, 480));
PropertyTestLayoutManager* layout_manager = new PropertyTestLayoutManager();
root_window()->SetLayoutManager(layout_manager);
- scoped_ptr<TestWidget> widget(new TestWidget());
+ std::unique_ptr<TestWidget> widget(new TestWidget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.delegate = new PropertyTestWidgetDelegate(widget.get());
- params.parent = NULL;
+ params.parent = nullptr;
params.context = root_window();
widget->Init(params);
EXPECT_TRUE(layout_manager->added());
@@ -293,7 +360,7 @@ TEST_F(NativeWidgetAuraTest, GetClientAreaScreenBounds) {
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.context = root_window();
params.bounds.SetRect(10, 20, 300, 400);
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
widget->Init(params);
// For Aura, client area bounds match window bounds.
@@ -349,7 +416,7 @@ TEST_F(NativeWidgetAuraTest, DontCaptureOnGesture) {
child->set_consume_gesture_event(false);
view->SetLayoutManager(new FillLayout);
view->AddChildView(child);
- scoped_ptr<TestWidget> widget(new TestWidget());
+ std::unique_ptr<TestWidget> widget(new TestWidget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.context = root_window();
@@ -390,7 +457,7 @@ TEST_F(NativeWidgetAuraTest, DontCaptureOnGesture) {
TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
// Create two widgets: |parent| and |child|. |child| is a child of |parent|.
views::View* parent_root = new views::View;
- scoped_ptr<Widget> parent(new Widget());
+ std::unique_ptr<Widget> parent(new Widget());
Widget::InitParams parent_params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
parent_params.ownership =
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -400,7 +467,7 @@ TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
parent->SetBounds(gfx::Rect(0, 0, 400, 400));
parent->Show();
- scoped_ptr<Widget> child(new Widget());
+ std::unique_ptr<Widget> child(new Widget());
Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
child_params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
child_params.parent = parent->GetNativeWindow();
@@ -438,7 +505,7 @@ TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
gfx::Point(70, 70)));
delete view_with_layer;
- view_with_layer = NULL;
+ view_with_layer = nullptr;
EXPECT_EQ(child->GetNativeWindow(),
parent->GetNativeWindow()->GetEventHandlerForPoint(
@@ -452,7 +519,7 @@ TEST_F(NativeWidgetAuraTest, PreferViewLayersToChildWindows) {
// Verifies that widget->FlashFrame() sets aura::client::kDrawAttentionKey,
// and activating the window clears it.
TEST_F(NativeWidgetAuraTest, FlashFrame) {
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
Widget::InitParams params(Widget::InitParams::TYPE_WINDOW);
params.context = root_window();
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
@@ -470,10 +537,10 @@ TEST_F(NativeWidgetAuraTest, FlashFrame) {
}
TEST_F(NativeWidgetAuraTest, NoCrashOnThemeAfterClose) {
- scoped_ptr<aura::Window> parent(new aura::Window(NULL));
+ std::unique_ptr<aura::Window> parent(new aura::Window(nullptr));
parent->Init(ui::LAYER_NOT_DRAWN);
parent->SetBounds(gfx::Rect(0, 0, 480, 320));
- scoped_ptr<Widget> widget(new Widget());
+ std::unique_ptr<Widget> widget(new Widget());
Init(parent.get(), widget.get());
widget->Show();
widget->Close();
diff --git a/chromium/ui/views/widget/native_widget_delegate.h b/chromium/ui/views/widget/native_widget_delegate.h
index 033db2bf107..e6c3b84ea04 100644
--- a/chromium/ui/views/widget/native_widget_delegate.h
+++ b/chromium/ui/views/widget/native_widget_delegate.h
@@ -97,6 +97,9 @@ class VIEWS_EXPORT NativeWidgetDelegate {
// e.g. maximize.
virtual void OnNativeWidgetSizeChanged(const gfx::Size& new_size) = 0;
+ // Called when NativeWidget changed workspaces.
+ virtual void OnNativeWidgetWorkspaceChanged() = 0;
+
// Called when the NativeWidget changes its window state.
// This may happen at the same time as OnNativeWidgetSizeChanged, e.g.
// maximize.
diff --git a/chromium/ui/views/widget/native_widget_mac.h b/chromium/ui/views/widget/native_widget_mac.h
index 1b7deb2c801..93402a18470 100644
--- a/chromium/ui/views/widget/native_widget_mac.h
+++ b/chromium/ui/views/widget/native_widget_mac.h
@@ -80,6 +80,7 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
gfx::Rect GetWindowBoundsInScreen() const override;
gfx::Rect GetClientAreaBoundsInScreen() const override;
gfx::Rect GetRestoredBounds() const override;
+ std::string GetWorkspace() const override;
void SetBounds(const gfx::Rect& bounds) override;
void SetSize(const gfx::Size& size) override;
void StackAbove(gfx::NativeView native_view) override;
@@ -132,6 +133,7 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
bool IsTranslucentWindowOpacitySupported() const override;
void OnSizeConstraintsChanged() override;
void RepostNativeEvent(gfx::NativeEvent native_event) override;
+ std::string GetName() const override;
protected:
// Creates the NSWindow that will be passed to the BridgedNativeWidget.
@@ -146,10 +148,13 @@ class VIEWS_EXPORT NativeWidgetMac : public internal::NativeWidgetPrivate {
friend class test::HitTestNativeWidgetMac;
internal::NativeWidgetDelegate* delegate_;
- scoped_ptr<BridgedNativeWidget> bridge_;
+ std::unique_ptr<BridgedNativeWidget> bridge_;
Widget::InitParams::Ownership ownership_;
+ // Internal name.
+ std::string name_;
+
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMac);
};
diff --git a/chromium/ui/views/widget/native_widget_mac.mm b/chromium/ui/views/widget/native_widget_mac.mm
index 126623ff0e7..fb7fef45007 100644
--- a/chromium/ui/views/widget/native_widget_mac.mm
+++ b/chromium/ui/views/widget/native_widget_mac.mm
@@ -119,6 +119,7 @@ int NativeWidgetMac::SheetPositionY() {
void NativeWidgetMac::InitNativeWidget(const Widget::InitParams& params) {
ownership_ = params.ownership;
+ name_ = params.name;
base::scoped_nsobject<NSWindow> window([CreateNSWindow(params) retain]);
[window setReleasedWhenClosed:NO]; // Owned by scoped_nsobject.
bridge_->Init(window, params);
@@ -305,6 +306,10 @@ gfx::Rect NativeWidgetMac::GetRestoredBounds() const {
return bridge_ ? bridge_->GetRestoredBounds() : gfx::Rect();
}
+std::string NativeWidgetMac::GetWorkspace() const {
+ return std::string();
+}
+
void NativeWidgetMac::SetBounds(const gfx::Rect& bounds) {
if (bridge_)
bridge_->SetBounds(bounds);
@@ -371,7 +376,7 @@ void NativeWidgetMac::CloseNow() {
// Notify observers while |bridged_| is still valid.
delegate_->OnNativeWidgetDestroying();
// Reset |bridge_| to NULL before destroying it.
- scoped_ptr<BridgedNativeWidget> bridge(std::move(bridge_));
+ std::unique_ptr<BridgedNativeWidget> bridge(std::move(bridge_));
}
void NativeWidgetMac::Show() {
@@ -590,6 +595,10 @@ void NativeWidgetMac::RepostNativeEvent(gfx::NativeEvent native_event) {
NOTIMPLEMENTED();
}
+std::string NativeWidgetMac::GetName() const {
+ return name_;
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetMac, protected:
@@ -710,6 +719,13 @@ gfx::FontList NativeWidgetPrivate::GetWindowTitleFontList() {
return gfx::FontList();
}
+// static
+gfx::NativeView NativeWidgetPrivate::GetGlobalCapture(
+ gfx::NativeView native_view) {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
} // namespace internal
} // namespace views
diff --git a/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm b/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
index 528f67d42a7..c29fe0464ff 100644
--- a/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_interactive_uitest.mm
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "ui/base/test/ui_controls.h"
#import "ui/base/test/windowed_nsnotification_observer.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/widget_test.h"
@@ -38,7 +39,7 @@ class NativeWidgetMacInteractiveUITest
}
protected:
- scoped_ptr<Observer> observer_;
+ std::unique_ptr<Observer> observer_;
int activationCount_;
int deactivationCount_;
@@ -159,6 +160,16 @@ NSData* ViewAsTIFF(NSView* view) {
return [bitmap TIFFRepresentation];
}
+class TestBubbleView : public BubbleDialogDelegateView {
+ public:
+ explicit TestBubbleView(Widget* parent) {
+ SetAnchorView(parent->GetContentsView());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestBubbleView);
+};
+
} // namespace
// Test that parent windows keep their traffic lights enabled when showing
@@ -176,15 +187,11 @@ TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
NSData* active_button_image = ViewAsTIFF(button);
EXPECT_TRUE(active_button_image);
- // Create an activatable frameless child. Frameless so that it doesn't have
- // traffic lights of its own, and activatable so that it can take key status.
- Widget* child_widget = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
- params.native_widget = new NativeWidgetMac(child_widget);
- params.bounds = gfx::Rect(130, 130, 100, 100);
- params.parent = parent_widget->GetNativeView();
- child_widget->Init(params);
- ShowKeyWindow(child_widget);
+ // Pop open a bubble on the parent Widget. When the visibility of Bubbles with
+ // an anchor View changes, BubbleDialogDelegateView::HandleVisibilityChanged()
+ // updates Widget::SetAlwaysRenderAsActive(..) accordingly.
+ ShowKeyWindow(BubbleDialogDelegateView::CreateBubble(
+ new TestBubbleView(parent_widget)));
// Ensure the button instance is still valid.
EXPECT_EQ(button, [parent standardWindowButton:NSWindowCloseButton]);
@@ -199,6 +206,8 @@ TEST_F(NativeWidgetMacInteractiveUITest, ParentWindowTrafficLights) {
EXPECT_TRUE([active_button_image isEqualToData:button_image_with_child]);
// Verify that activating some other random window does change the button.
+ // When the bubble loses activation, it will dismiss itself and update
+ // Widget::SetAlwaysRenderAsActive().
Widget* other_widget = CreateTopLevelPlatformWidget();
other_widget->SetBounds(gfx::Rect(200, 200, 100, 100));
ShowKeyWindow(other_widget);
diff --git a/chromium/ui/views/widget/native_widget_mac_unittest.mm b/chromium/ui/views/widget/native_widget_mac_unittest.mm
index ba095dfbeeb..ac0740d53ed 100644
--- a/chromium/ui/views/widget/native_widget_mac_unittest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_unittest.mm
@@ -8,6 +8,7 @@
#import "base/mac/foundation_util.h"
#import "base/mac/scoped_nsobject.h"
+#import "base/mac/scoped_nsautorelease_pool.h"
#import "base/mac/scoped_objc_class_swizzler.h"
#include "base/macros.h"
#include "base/run_loop.h"
@@ -19,10 +20,12 @@
#include "third_party/skia/include/core/SkCanvas.h"
#import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
#import "ui/base/cocoa/window_size_constants.h"
+#import "ui/base/test/scoped_fake_full_keyboard_access.h"
#import "ui/events/test/cocoa_test_event_utils.h"
#include "ui/events/test/event_generator.h"
#import "ui/gfx/mac/coordinate_conversion.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
+#import "ui/views/cocoa/bridged_content_view.h"
#import "ui/views/cocoa/bridged_native_widget.h"
#import "ui/views/cocoa/native_widget_mac_nswindow.h"
#include "ui/views/controls/button/label_button.h"
@@ -53,8 +56,10 @@
@interface NativeWidgetMacTestWindow : NativeWidgetMacNSWindow {
@private
int invalidateShadowCount_;
+ bool* deallocFlag_;
}
@property(readonly, nonatomic) int invalidateShadowCount;
+@property(assign, nonatomic) bool* deallocFlag;
@end
// Used to mock BridgedContentView so that calls to drawRect: can be
@@ -75,6 +80,10 @@
@interface FocusableTestNSView : NSView
@end
+@interface TestNativeParentWindow : NSWindow
+@property(assign, nonatomic) bool* deallocFlag;
+@end
+
namespace views {
namespace test {
@@ -89,7 +98,7 @@ class BridgedNativeWidgetTestApi {
void SimulateFrameSwap(const gfx::Size& size) {
const float kScaleFactor = 1.0f;
bridge_->compositor_widget_->GotFrame(
- 0, base::ScopedCFTypeRef<IOSurfaceRef>(), size, kScaleFactor);
+ 0, false, 0, base::ScopedCFTypeRef<IOSurfaceRef>(), size, kScaleFactor);
bridge_->AcceleratedWidgetSwapCompleted();
}
@@ -136,8 +145,8 @@ class NativeWidgetMacTest : public WidgetTest {
NSRect ParentRect() const { return NSMakeRect(100, 100, 300, 200); }
// Make a native NSWindow with the given |style_mask| to use as a parent.
- NSWindow* MakeNativeParentWithStyle(int style_mask) {
- native_parent_.reset([[NSWindow alloc]
+ TestNativeParentWindow* MakeNativeParentWithStyle(int style_mask) {
+ native_parent_.reset([[TestNativeParentWindow alloc]
initWithContentRect:ParentRect()
styleMask:style_mask
backing:NSBackingStoreBuffered
@@ -148,7 +157,7 @@ class NativeWidgetMacTest : public WidgetTest {
}
// Make a borderless, native NSWindow to use as a parent.
- NSWindow* MakeNativeParent() {
+ TestNativeParentWindow* MakeNativeParent() {
return MakeNativeParentWithStyle(NSBorderlessWindowMask);
}
@@ -165,9 +174,10 @@ class NativeWidgetMacTest : public WidgetTest {
return widget;
}
- private:
- base::scoped_nsobject<NSWindow> native_parent_;
+ protected:
+ base::scoped_nsobject<TestNativeParentWindow> native_parent_;
+ private:
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMacTest);
};
@@ -231,11 +241,22 @@ class NativeHostHolder {
private:
base::scoped_nsobject<NSView> view_;
- scoped_ptr<NativeViewHost> host_;
+ std::unique_ptr<NativeViewHost> host_;
DISALLOW_COPY_AND_ASSIGN(NativeHostHolder);
};
+// This class gives public access to the protected ctor of
+// BubbleDialogDelegateView.
+class SimpleBubbleView : public BubbleDialogDelegateView {
+ public:
+ SimpleBubbleView() {}
+ ~SimpleBubbleView() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleBubbleView);
+};
+
// Test visibility states triggered externally.
TEST_F(NativeWidgetMacTest, HideAndShowExternally) {
Widget* widget = CreateTopLevelPlatformWidget();
@@ -633,6 +654,37 @@ TEST_F(NativeWidgetMacTest, NonWidgetParent) {
EXPECT_EQ(0u, [[native_parent childWindows] count]);
}
+// Tests closing the last remaining NSWindow reference via -windowWillClose:.
+// This is a regression test for http://crbug.com/616701.
+TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) {
+ bool child_dealloced = false;
+ bool native_parent_dealloced = false;
+ {
+ base::mac::ScopedNSAutoreleasePool pool;
+ TestNativeParentWindow* native_parent = MakeNativeParent();
+ [native_parent setDeallocFlag:&native_parent_dealloced];
+
+ NativeWidgetMacTestWindow* window;
+ Widget::InitParams init_params =
+ CreateParams(Widget::InitParams::TYPE_POPUP);
+ init_params.parent = [native_parent_ contentView];
+ init_params.bounds = gfx::Rect(0, 0, 100, 200);
+ CreateWidgetWithTestWindow(init_params, &window);
+ [window setDeallocFlag:&child_dealloced];
+ }
+ {
+ // On 10.11, closing a weak reference on the parent window works, but older
+ // versions of AppKit get upset if things are released inside -[NSWindow
+ // close]. This test tries to establish a situation where the last reference
+ // to the child window is released inside WidgetOwnerNSWindowAdapter::
+ // OnWindowWillClose().
+ base::mac::ScopedNSAutoreleasePool pool;
+ [native_parent_.autorelease() close];
+ EXPECT_TRUE(child_dealloced);
+ }
+ EXPECT_TRUE(native_parent_dealloced);
+}
+
// Use Native APIs to query the tooltip text that would be shown once the
// tooltip delay had elapsed.
base::string16 TooltipTextForWidget(Widget* widget) {
@@ -1041,7 +1093,7 @@ TEST_F(NativeWidgetMacTest, NoParentDelegateDuringTeardown) {
// Test the WIDGET_OWNS_NATIVE_WIDGET flow.
{
- scoped_ptr<Widget> parent(new Widget);
+ std::unique_ptr<Widget> parent(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(100, 100, 300, 200);
@@ -1075,15 +1127,15 @@ TEST_F(NativeWidgetMacTest, NativeProperties) {
EXPECT_FALSE([dialog_widget->GetNativeWindow() canBecomeMainWindow]);
// Create a bubble widget with a parent: also shouldn't get main.
- BubbleDelegateView* bubble_view = new BubbleDelegateView();
+ BubbleDialogDelegateView* bubble_view = new SimpleBubbleView();
bubble_view->set_parent_window(regular_widget->GetNativeView());
- Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_view);
+ Widget* bubble_widget = BubbleDialogDelegateView::CreateBubble(bubble_view);
EXPECT_TRUE([bubble_widget->GetNativeWindow() canBecomeKeyWindow]);
EXPECT_FALSE([bubble_widget->GetNativeWindow() canBecomeMainWindow]);
// But a bubble without a parent should still be able to become main.
Widget* toplevel_bubble_widget =
- BubbleDelegateView::CreateBubble(new BubbleDelegateView());
+ BubbleDialogDelegateView::CreateBubble(new SimpleBubbleView());
EXPECT_TRUE([toplevel_bubble_widget->GetNativeWindow() canBecomeKeyWindow]);
EXPECT_TRUE([toplevel_bubble_widget->GetNativeWindow() canBecomeMainWindow]);
@@ -1340,7 +1392,7 @@ TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Borderless) {
// Ensure traversing NSView focus correctly updates the views::FocusManager.
TEST_F(NativeWidgetMacTest, ChangeFocusOnChangeFirstResponder) {
Widget* widget = CreateTopLevelPlatformWidget();
- widget->GetRootView()->SetFocusable(true);
+ widget->GetRootView()->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget->Show();
base::scoped_nsobject<NSView> child_view([[FocusableTestNSView alloc]
@@ -1362,6 +1414,79 @@ TEST_F(NativeWidgetMacTest, ChangeFocusOnChangeFirstResponder) {
widget->CloseNow();
}
+// Test class for Full Keyboard Access related tests.
+class NativeWidgetMacFullKeyboardAccessTest : public NativeWidgetMacTest {
+ public:
+ NativeWidgetMacFullKeyboardAccessTest() {}
+
+ protected:
+ // testing::Test:
+ void SetUp() override {
+ NativeWidgetMacTest::SetUp();
+
+ widget_ = CreateTopLevelPlatformWidget();
+ bridge_ =
+ NativeWidgetMac::GetBridgeForNativeWindow(widget_->GetNativeWindow());
+ fake_full_keyboard_access_ =
+ ui::test::ScopedFakeFullKeyboardAccess::GetInstance();
+ DCHECK(fake_full_keyboard_access_);
+ widget_->Show();
+ }
+
+ void TearDown() override {
+ widget_->CloseNow();
+ NativeWidgetMacTest::TearDown();
+ }
+
+ Widget* widget_ = nullptr;
+ BridgedNativeWidget* bridge_ = nullptr;
+ ui::test::ScopedFakeFullKeyboardAccess* fake_full_keyboard_access_ = nullptr;
+};
+
+// Test that updateFullKeyboardAccess method on BridgedContentView correctly
+// sets the keyboard accessibility mode on the associated focus manager.
+TEST_F(NativeWidgetMacFullKeyboardAccessTest, FullKeyboardToggle) {
+ EXPECT_TRUE(widget_->GetFocusManager()->keyboard_accessible());
+ fake_full_keyboard_access_->set_full_keyboard_access_state(false);
+ [bridge_->ns_view() updateFullKeyboardAccess];
+ EXPECT_FALSE(widget_->GetFocusManager()->keyboard_accessible());
+ fake_full_keyboard_access_->set_full_keyboard_access_state(true);
+ [bridge_->ns_view() updateFullKeyboardAccess];
+ EXPECT_TRUE(widget_->GetFocusManager()->keyboard_accessible());
+}
+
+// Test that a Widget's associated FocusManager is initialized with the correct
+// keyboard accessibility value.
+TEST_F(NativeWidgetMacFullKeyboardAccessTest, Initialization) {
+ EXPECT_TRUE(widget_->GetFocusManager()->keyboard_accessible());
+
+ fake_full_keyboard_access_->set_full_keyboard_access_state(false);
+ Widget* widget2 = CreateTopLevelPlatformWidget();
+ EXPECT_FALSE(widget2->GetFocusManager()->keyboard_accessible());
+ widget2->CloseNow();
+}
+
+// Test that the correct keyboard accessibility mode is set when the window
+// becomes active.
+TEST_F(NativeWidgetMacFullKeyboardAccessTest, Activation) {
+ EXPECT_TRUE(widget_->GetFocusManager()->keyboard_accessible());
+
+ widget_->Hide();
+ fake_full_keyboard_access_->set_full_keyboard_access_state(false);
+ // [bridge_->ns_view() updateFullKeyboardAccess] is not explicitly called
+ // since we may not receive full keyboard access toggle notifications when our
+ // application is inactive.
+
+ widget_->Show();
+ EXPECT_FALSE(widget_->GetFocusManager()->keyboard_accessible());
+
+ widget_->Hide();
+ fake_full_keyboard_access_->set_full_keyboard_access_state(true);
+
+ widget_->Show();
+ EXPECT_TRUE(widget_->GetFocusManager()->keyboard_accessible());
+}
+
class NativeWidgetMacViewsOrderTest : public WidgetTest {
public:
NativeWidgetMacViewsOrderTest() {}
@@ -1381,7 +1506,7 @@ class NativeWidgetMacViewsOrderTest : public WidgetTest {
const int kNativeViewCount = 3;
for (int i = 0; i < kNativeViewCount; ++i) {
- scoped_ptr<NativeHostHolder> holder(new NativeHostHolder());
+ std::unique_ptr<NativeHostHolder> holder(new NativeHostHolder());
native_host_parent_->AddChildView(holder->host());
holder->AttachNativeView();
hosts_.push_back(std::move(holder));
@@ -1402,7 +1527,7 @@ class NativeWidgetMacViewsOrderTest : public WidgetTest {
Widget* widget_ = nullptr;
View* native_host_parent_ = nullptr;
NSView* compositor_view_ = nil;
- std::vector<scoped_ptr<NativeHostHolder>> hosts_;
+ std::vector<std::unique_ptr<NativeHostHolder>> hosts_;
private:
DISALLOW_COPY_AND_ASSIGN(NativeWidgetMacViewsOrderTest);
@@ -1481,6 +1606,15 @@ TEST_F(NativeWidgetMacViewsOrderTest, UnassociatedViewsIsAbove) {
@implementation NativeWidgetMacTestWindow
@synthesize invalidateShadowCount = invalidateShadowCount_;
+@synthesize deallocFlag = deallocFlag_;
+
+- (void)dealloc {
+ if (deallocFlag_) {
+ DCHECK(!*deallocFlag_);
+ *deallocFlag_ = true;
+ }
+ [super dealloc];
+}
- (void)invalidateShadow {
++invalidateShadowCount_;
@@ -1506,3 +1640,19 @@ TEST_F(NativeWidgetMacViewsOrderTest, UnassociatedViewsIsAbove) {
return YES;
}
@end
+
+@implementation TestNativeParentWindow {
+ bool* deallocFlag_;
+}
+
+@synthesize deallocFlag = deallocFlag_;
+
+- (void)dealloc {
+ if (deallocFlag_) {
+ DCHECK(!*deallocFlag_);
+ *deallocFlag_ = true;
+ }
+ [super dealloc];
+}
+
+@end
diff --git a/chromium/ui/views/widget/native_widget_private.h b/chromium/ui/views/widget/native_widget_private.h
index 777eaa226a4..d52aee63249 100644
--- a/chromium/ui/views/widget/native_widget_private.h
+++ b/chromium/ui/views/widget/native_widget_private.h
@@ -5,6 +5,8 @@
#ifndef UI_VIEWS_WIDGET_NATIVE_WIDGET_PRIVATE_H_
#define UI_VIEWS_WIDGET_NATIVE_WIDGET_PRIVATE_H_
+#include <string>
+
#include "base/strings/string16.h"
#include "ui/base/ui_base_types.h"
#include "ui/gfx/native_widget_types.h"
@@ -71,6 +73,10 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
static gfx::FontList GetWindowTitleFontList();
+ // Returns the NativeView with capture, otherwise NULL if there is no current
+ // capture set, or if |native_view| has no root.
+ static gfx::NativeView GetGlobalCapture(gfx::NativeView native_view);
+
// Initializes the NativeWidget.
virtual void InitNativeWidget(const Widget::InitParams& params) = 0;
@@ -165,6 +171,7 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
virtual gfx::Rect GetWindowBoundsInScreen() const = 0;
virtual gfx::Rect GetClientAreaBoundsInScreen() const = 0;
virtual gfx::Rect GetRestoredBounds() const = 0;
+ virtual std::string GetWorkspace() const = 0;
virtual void SetBounds(const gfx::Rect& bounds) = 0;
virtual void SetSize(const gfx::Size& size) = 0;
virtual void StackAbove(gfx::NativeView native_view) = 0;
@@ -223,6 +230,9 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget {
// Repost an unhandled event to the native widget for default OS processing.
virtual void RepostNativeEvent(gfx::NativeEvent native_event) = 0;
+ // Returns an internal name that matches the name of the associated Widget.
+ virtual std::string GetName() const = 0;
+
// Overridden from NativeWidget:
internal::NativeWidgetPrivate* AsNativeWidgetPrivate() override;
};
diff --git a/chromium/ui/views/widget/root_view.cc b/chromium/ui/views/widget/root_view.cc
index ff1294ae9f7..cbfb8c4a95d 100644
--- a/chromium/ui/views/widget/root_view.cc
+++ b/chromium/ui/views/widget/root_view.cc
@@ -171,7 +171,8 @@ RootView::RootView(Widget* widget)
old_dispatch_target_(NULL) {
AddPreTargetHandler(pre_dispatch_handler_.get());
AddPostTargetHandler(post_dispatch_handler_.get());
- SetEventTargeter(scoped_ptr<ViewTargeter>(new RootViewTargeter(this, this)));
+ SetEventTargeter(
+ std::unique_ptr<ViewTargeter>(new RootViewTargeter(this, this)));
}
RootView::~RootView() {
diff --git a/chromium/ui/views/widget/root_view.h b/chromium/ui/views/widget/root_view.h
index 58c647fccef..dea38d2be73 100644
--- a/chromium/ui/views/widget/root_view.h
+++ b/chromium/ui/views/widget/root_view.h
@@ -207,8 +207,8 @@ class VIEWS_EXPORT RootView : public View,
// its place.
bool gesture_handler_set_before_processing_;
- scoped_ptr<internal::PreEventDispatchHandler> pre_dispatch_handler_;
- scoped_ptr<internal::PostEventDispatchHandler> post_dispatch_handler_;
+ std::unique_ptr<internal::PreEventDispatchHandler> pre_dispatch_handler_;
+ std::unique_ptr<internal::PostEventDispatchHandler> post_dispatch_handler_;
// Focus ---------------------------------------------------------------------
diff --git a/chromium/ui/views/widget/root_view_unittest.cc b/chromium/ui/views/widget/root_view_unittest.cc
index 03f672d302e..26a9b3d9495 100644
--- a/chromium/ui/views/widget/root_view_unittest.cc
+++ b/chromium/ui/views/widget/root_view_unittest.cc
@@ -5,6 +5,7 @@
#include "ui/views/widget/root_view.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "ui/events/event_utils.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/test/views_test_base.h"
@@ -53,13 +54,13 @@ TEST_F(RootViewTest, DeleteViewDuringKeyEventDispatch) {
content->AddChildView(child);
// Give focus to |child| so that it will be the target of the key event.
- child->SetFocusable(true);
+ child->SetFocusBehavior(View::FocusBehavior::ALWAYS);
child->RequestFocus();
internal::RootView* root_view =
static_cast<internal::RootView*>(widget.GetRootView());
ViewTargeter* view_targeter = new ViewTargeter(root_view);
- root_view->SetEventTargeter(make_scoped_ptr(view_targeter));
+ root_view->SetEventTargeter(base::WrapUnique(view_targeter));
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE);
ui::EventDispatchDetails details = root_view->OnEventFromSource(&key_event);
@@ -120,7 +121,7 @@ TEST_F(RootViewTest, ContextMenuFromKeyEvent) {
View* focused_view = new View;
focused_view->set_context_menu_controller(&controller);
widget.SetContentsView(focused_view);
- focused_view->SetFocusable(true);
+ focused_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
focused_view->RequestFocus();
// No context menu should be shown for a keypress of 'A'.
diff --git a/chromium/ui/views/widget/tooltip_manager.h b/chromium/ui/views/widget/tooltip_manager.h
index e8074047340..4c27c361cee 100644
--- a/chromium/ui/views/widget/tooltip_manager.h
+++ b/chromium/ui/views/widget/tooltip_manager.h
@@ -11,7 +11,6 @@
#include "ui/views/views_export.h"
namespace gfx {
-class Display;
class FontList;
class Point;
} // namespace gfx
diff --git a/chromium/ui/views/widget/tooltip_manager_aura.cc b/chromium/ui/views/widget/tooltip_manager_aura.cc
index c4bf40ea856..90b6e063933 100644
--- a/chromium/ui/views/widget/tooltip_manager_aura.cc
+++ b/chromium/ui/views/widget/tooltip_manager_aura.cc
@@ -9,8 +9,8 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/display/screen.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/screen.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/public/tooltip_client.h"
@@ -49,7 +49,7 @@ void TooltipManagerAura::UpdateTooltipManagerForCapture(Widget* source) {
if (!screen_position_client)
return;
screen_position_client->ConvertPointToScreen(root_window, &screen_loc);
- gfx::Screen* screen = gfx::Screen::GetScreen();
+ display::Screen* screen = display::Screen::GetScreen();
aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc);
if (!target)
return;
diff --git a/chromium/ui/views/widget/widget.cc b/chromium/ui/views/widget/widget.cc
index ffafd0d2bbb..a86fe4859ee 100644
--- a/chromium/ui/views/widget/widget.cc
+++ b/chromium/ui/views/widget/widget.cc
@@ -18,10 +18,10 @@
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
+#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/screen.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/event_monitor.h"
#include "ui/views/focus/focus_manager.h"
@@ -134,8 +134,7 @@ Widget::InitParams::InitParams(Type type)
layer_type(ui::LAYER_TEXTURED),
context(nullptr),
force_show_in_taskbar(false),
- force_software_compositing(false) {
-}
+ force_software_compositing(false) {}
Widget::InitParams::InitParams(const InitParams& other) = default;
@@ -290,6 +289,12 @@ void Widget::Init(const InitParams& in_params) {
TRACE_EVENT0("views", "Widget::Init");
InitParams params = in_params;
+ // If an internal name was not provided the class name of the contents view
+ // is a reasonable default.
+ if (params.name.empty() && params.delegate &&
+ params.delegate->GetContentsView())
+ params.name = params.delegate->GetContentsView()->GetClassName();
+
params.child |= (params.type == InitParams::TYPE_CONTROL);
is_top_level_ = !params.child;
@@ -347,10 +352,12 @@ void Widget::Init(const InitParams& in_params) {
UpdateWindowTitle();
non_client_view_->ResetWindowControls();
SetInitialBounds(params.bounds);
- if (params.show_state == ui::SHOW_STATE_MAXIMIZED)
+ if (params.show_state == ui::SHOW_STATE_MAXIMIZED) {
Maximize();
- else if (params.show_state == ui::SHOW_STATE_MINIMIZED)
+ } else if (params.show_state == ui::SHOW_STATE_MINIMIZED) {
Minimize();
+ saved_show_state_ = ui::SHOW_STATE_MINIMIZED;
+ }
} else if (params.delegate) {
SetContentsView(params.delegate->GetContentsView());
SetInitialBoundsForFramelessWindow(params.bounds);
@@ -481,6 +488,10 @@ gfx::Rect Widget::GetRestoredBounds() const {
return native_widget_->GetRestoredBounds();
}
+std::string Widget::GetWorkspace() const {
+ return native_widget_->GetWorkspace();
+}
+
void Widget::SetBounds(const gfx::Rect& bounds) {
native_widget_->SetBounds(bounds);
}
@@ -494,7 +505,7 @@ void Widget::CenterWindow(const gfx::Size& size) {
}
void Widget::SetBoundsConstrained(const gfx::Rect& bounds) {
- gfx::Rect work_area = gfx::Screen::GetScreen()
+ gfx::Rect work_area = display::Screen::GetScreen()
->GetDisplayNearestPoint(bounds.origin())
.work_area();
if (work_area.IsEmpty()) {
@@ -600,10 +611,8 @@ void Widget::Show() {
!IsFullscreen()) {
native_widget_->ShowMaximizedWithBounds(initial_restored_bounds_);
} else {
- ui::WindowShowState show_state =
- IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN :
- IsMinimized() ? ui::SHOW_STATE_MINIMIZED : saved_show_state_;
- native_widget_->ShowWithWindowState(show_state);
+ native_widget_->ShowWithWindowState(
+ IsFullscreen() ? ui::SHOW_STATE_FULLSCREEN : saved_show_state_);
}
// |saved_show_state_| only applies the first time the window is shown.
// If we don't reset the value the window may be shown maximized every time
@@ -987,6 +996,10 @@ void Widget::OnSizeConstraintsChanged() {
void Widget::OnOwnerClosing() {}
+std::string Widget::GetName() const {
+ return native_widget_->GetName();
+}
+
////////////////////////////////////////////////////////////////////////////////
// Widget, NativeWidgetDelegate implementation:
@@ -1100,6 +1113,8 @@ void Widget::OnNativeWidgetSizeChanged(const gfx::Size& new_size) {
GetWindowBoundsInScreen()));
}
+void Widget::OnNativeWidgetWorkspaceChanged() {}
+
void Widget::OnNativeWidgetWindowShowStateChanged() {
SaveWindowPlacementIfInitialized();
}
@@ -1156,19 +1171,23 @@ void Widget::OnMouseEvent(ui::MouseEvent* event) {
// use an observer to make sure we are still alive.
WidgetDeletionObserver widget_deletion_observer(this);
+ gfx::NativeView current_capture =
+ internal::NativeWidgetPrivate::GetGlobalCapture(
+ native_widget_->GetNativeView());
// Make sure we're still visible before we attempt capture as the mouse
// press processing may have made the window hide (as happens with menus).
-
- // It is possible for a View to show a context menu on mouse-press. Since
- // the menu does a capture and starts a nested message-loop, the release
- // would go to the menu. The next click (i.e. both mouse-press and release
- // events) also go to the menu. The menu (and the nested message-loop)
- // gets closed after this second release event. The code then resumes from
- // here. So make sure that the mouse-button is still down before doing a
- // capture.
+ //
+ // It is possible that capture has changed as a result of a mouse-press.
+ // In these cases do not update internal state.
+ //
+ // A mouse-press may trigger a nested message-loop, and absorb the paired
+ // release. If so the code returns here. So make sure that that
+ // mouse-button is still down before attempting to do a capture.
if (root_view && root_view->OnMousePressed(*event) &&
widget_deletion_observer.IsWidgetAlive() && IsVisible() &&
- internal::NativeWidgetPrivate::IsMouseButtonDown()) {
+ internal::NativeWidgetPrivate::IsMouseButtonDown() &&
+ current_capture == internal::NativeWidgetPrivate::GetGlobalCapture(
+ native_widget_->GetNativeView())) {
is_mouse_button_pressed_ = true;
if (!native_widget_->HasCapture())
native_widget_->SetCapture();
diff --git a/chromium/ui/views/widget/widget.h b/chromium/ui/views/widget/widget.h
index 0ceaf825ffb..e52c7fff2ed 100644
--- a/chromium/ui/views/widget/widget.h
+++ b/chromium/ui/views/widget/widget.h
@@ -5,12 +5,14 @@
#ifndef UI_VIEWS_WIDGET_WIDGET_H_
#define UI_VIEWS_WIDGET_WIDGET_H_
+#include <map>
+#include <memory>
#include <set>
#include <stack>
+#include <string>
#include <vector>
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observer.h"
#include "build/build_config.h"
@@ -47,6 +49,10 @@ class Point;
class Rect;
}
+namespace mus {
+class Window;
+}
+
namespace ui {
class Accelerator;
class Compositor;
@@ -97,8 +103,8 @@ class RootView;
// The Widget instance owns its NativeWidget. This state implies someone
// else wants to control the lifetime of this object. When they destroy
// the Widget it is responsible for destroying the NativeWidget (from its
-// destructor). This is often used to place a Widget in a scoped_ptr<> or
-// on the stack in a test.
+// destructor). This is often used to place a Widget in a std::unique_ptr<>
+// or on the stack in a test.
class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
public ui::EventSource,
public FocusTraversable,
@@ -209,6 +215,8 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// If null, a default implementation will be constructed. The default
// implementation deletes itself when the Widget closes.
WidgetDelegate* delegate;
+ // Internal name. Propagated to the NativeWidget. Useful for debugging.
+ std::string name;
bool child;
// If TRANSLUCENT_WINDOW, the widget may be fully or partially transparent.
// If OPAQUE_WINDOW, we can perform optimizations based on the widget being
@@ -236,11 +244,16 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Whether the widget should be maximized or minimized.
ui::WindowShowState show_state;
gfx::NativeView parent;
+ // Used only by mus and is necessitated by mus not being a NativeView.
+ mus::Window* parent_mus = nullptr;
// Specifies the initial bounds of the Widget. Default is empty, which means
// the NativeWidget may specify a default size. If the parent is specified,
// |bounds| is in the parent's coordinate system. If the parent is not
// specified, it's in screen's global coordinate system.
gfx::Rect bounds;
+ // The initial workspace of the Widget. Default is "", which means the
+ // current workspace.
+ std::string workspace;
// When set, this value is used as the Widget's NativeWidget implementation.
// The Widget will not construct a default one. Default is NULL.
NativeWidget* native_widget;
@@ -277,6 +290,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Used if widget is not activatable to do determine if mouse events should
// be sent to the widget.
bool wants_mouse_events_when_inactive = false;
+
+ // A map of properties applied to windows when running in mus.
+ std::map<std::string, std::vector<uint8_t>> mus_properties;
};
Widget();
@@ -416,6 +432,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// Retrieves the restored bounds for the window.
gfx::Rect GetRestoredBounds() const;
+ // Retrieves the current workspace for the window.
+ std::string GetWorkspace() const;
+
// Sizes and/or places the widget to the specified bounds, size or position.
void SetBounds(const gfx::Rect& bounds);
void SetSize(const gfx::Size& size);
@@ -758,6 +777,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// closes.
virtual void OnOwnerClosing();
+ // Returns the internal name for this Widget and NativeWidget.
+ std::string GetName() const;
+
// Overridden from NativeWidgetDelegate:
bool IsModal() const override;
bool IsDialogBox() const override;
@@ -776,6 +798,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
gfx::Size GetMaximumSize() const override;
void OnNativeWidgetMove() override;
void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override;
+ void OnNativeWidgetWorkspaceChanged() override;
void OnNativeWidgetWindowShowStateChanged() override;
void OnNativeWidgetBeginUserBoundsChange() override;
void OnNativeWidgetEndUserBoundsChange() override;
@@ -861,7 +884,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// The root of the View hierarchy attached to this window.
// WARNING: see warning in tooltip_manager_ for ordering dependencies with
// this and tooltip_manager_.
- scoped_ptr<internal::RootView> root_view_;
+ std::unique_ptr<internal::RootView> root_view_;
// The View that provides the non-client area of the window (title bar,
// window controls, sizing borders etc). To use an implementation other than
@@ -873,10 +896,10 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// children. NULL for non top-level widgets.
// WARNING: RootView's destructor calls into the FocusManager. As such, this
// must be destroyed AFTER root_view_. This is enforced in DestroyRootView().
- scoped_ptr<FocusManager> focus_manager_;
+ std::unique_ptr<FocusManager> focus_manager_;
// A theme provider to use when no other theme provider is specified.
- scoped_ptr<ui::DefaultThemeProvider> default_theme_provider_;
+ std::unique_ptr<ui::DefaultThemeProvider> default_theme_provider_;
// Valid for the lifetime of RunShellDrag(), indicates the view the drag
// started from.
diff --git a/chromium/ui/views/widget/widget_delegate.cc b/chromium/ui/views/widget/widget_delegate.cc
index ced90b6f392..c5f9d97490c 100644
--- a/chromium/ui/views/widget/widget_delegate.cc
+++ b/chromium/ui/views/widget/widget_delegate.cc
@@ -6,7 +6,6 @@
#include "base/strings/utf_string_conversions.h"
#include "ui/gfx/image/image_skia.h"
-#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/view.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/widget.h"
@@ -35,10 +34,6 @@ View* WidgetDelegate::GetInitiallyFocusedView() {
return nullptr;
}
-BubbleDelegateView* WidgetDelegate::AsBubbleDelegate() {
- return nullptr;
-}
-
BubbleDialogDelegateView* WidgetDelegate::AsBubbleDialogDelegate() {
return nullptr;
}
diff --git a/chromium/ui/views/widget/widget_delegate.h b/chromium/ui/views/widget/widget_delegate.h
index 0ec021505b6..8a344c55623 100644
--- a/chromium/ui/views/widget/widget_delegate.h
+++ b/chromium/ui/views/widget/widget_delegate.h
@@ -20,7 +20,6 @@ class Rect;
namespace views {
class BubbleDialogDelegateView;
-class BubbleDelegateView;
class ClientView;
class DialogDelegate;
class NonClientFrameView;
@@ -51,7 +50,6 @@ class VIEWS_EXPORT WidgetDelegate {
// NULL no view is focused.
virtual View* GetInitiallyFocusedView();
- virtual BubbleDelegateView* AsBubbleDelegate();
virtual BubbleDialogDelegateView* AsBubbleDialogDelegate();
virtual DialogDelegate* AsDialogDelegate();
diff --git a/chromium/ui/views/widget/widget_hwnd_utils.cc b/chromium/ui/views/widget/widget_hwnd_utils.cc
index ca561b6d6dc..b843416dac5 100644
--- a/chromium/ui/views/widget/widget_hwnd_utils.cc
+++ b/chromium/ui/views/widget/widget_hwnd_utils.cc
@@ -7,7 +7,6 @@
#include <dwmapi.h>
#include "base/command_line.h"
-#include "base/win/windows_version.h"
#include "build/build_config.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/base/ui_base_switches.h"
@@ -66,14 +65,12 @@ void CalculateWindowStylesFromInitParams(
// We also set the WS_EX_COMPOSITED style for software composited translucent
// windows, which ensures that they are updated via the layered window code
// path in the software compositor.
- if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW) {
- if (ui::win::IsAeroGlassEnabled() || params.force_software_compositing)
+ if (params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW &&
+ (ui::win::IsAeroGlassEnabled() || params.force_software_compositing))
*ex_style |= WS_EX_COMPOSITED;
- }
- if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP) {
- *class_style |= (base::win::GetVersion() < base::win::VERSION_XP) ?
- 0 : CS_DROPSHADOW;
- }
+
+ if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP)
+ *class_style |= CS_DROPSHADOW;
// Set type-dependent style attributes.
switch (params.type) {
diff --git a/chromium/ui/views/widget/widget_interactive_uitest.cc b/chromium/ui/views/widget/widget_interactive_uitest.cc
index e9f9397c01b..a64a3faba98 100644
--- a/chromium/ui/views/widget/widget_interactive_uitest.cc
+++ b/chromium/ui/views/widget/widget_interactive_uitest.cc
@@ -278,11 +278,15 @@ class WidgetTestInteractive : public WidgetTest {
~WidgetTestInteractive() override {}
void SetUp() override {
- gfx::GLSurfaceTestSupport::InitializeOneOff();
- ui::RegisterPathProvider();
- base::FilePath ui_test_pak_path;
- ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
- ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+ // On mus these tests run as part of views::ViewsTestSuite which already
+ // does this initialization.
+ if (!IsMus()) {
+ gfx::GLSurfaceTestSupport::InitializeOneOff();
+ ui::RegisterPathProvider();
+ base::FilePath ui_test_pak_path;
+ ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
+ ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+ }
WidgetTest::SetUp();
}
@@ -318,7 +322,7 @@ class WidgetTestInteractive : public WidgetTest {
TEST_F(WidgetTestInteractive, DesktopNativeWidgetAuraActivationAndFocusTest) {
// Create widget 1 and expect the active window to be its window.
View* focusable_view1 = new View;
- focusable_view1->SetFocusable(true);
+ focusable_view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
Widget* widget1 = CreateWidget();
widget1->GetContentsView()->AddChildView(focusable_view1);
widget1->Show();
@@ -602,14 +606,14 @@ TEST_F(WidgetTestInteractive, CheckResizeControllerEvents) {
TEST_F(WidgetTestInteractive, ViewFocusOnWidgetActivationChanges) {
Widget* widget1 = CreateTopLevelPlatformWidget();
View* view1 = new View;
- view1->SetFocusable(true);
+ view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget1->GetContentsView()->AddChildView(view1);
Widget* widget2 = CreateTopLevelPlatformWidget();
View* view2a = new View;
View* view2b = new View;
- view2a->SetFocusable(true);
- view2b->SetFocusable(true);
+ view2a->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ view2b->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget2->GetContentsView()->AddChildView(view2a);
widget2->GetContentsView()->AddChildView(view2b);
@@ -649,9 +653,10 @@ TEST_F(WidgetTestInteractive, ViewFocusOnWidgetActivationChanges) {
TEST_F(WidgetTestInteractive, ViewFocusOnHWNDEnabledChanges) {
Widget* widget = CreateTopLevelFramelessPlatformWidget();
widget->SetContentsView(new View);
- for (size_t i = 0; i < 2; ++i) {
+ for (int i = 0; i < 2; ++i) {
widget->GetContentsView()->AddChildView(new View);
- widget->GetContentsView()->child_at(i)->SetFocusable(true);
+ widget->GetContentsView()->child_at(i)->SetFocusBehavior(
+ View::FocusBehavior::ALWAYS);
}
widget->Show();
@@ -805,6 +810,56 @@ TEST_F(WidgetTestInteractive, FullscreenBoundsReducedOnActivationLoss) {
widget1.CloseNow();
widget2.CloseNow();
}
+
+// Ensure the window rect and client rects are correct with a window that was
+// maximized.
+TEST_F(WidgetTestInteractive, FullscreenMaximizedWindowBounds) {
+ Widget widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.native_widget = new DesktopNativeWidgetAura(&widget);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.set_frame_type(Widget::FRAME_TYPE_FORCE_CUSTOM);
+ widget.Init(params);
+ widget.SetBounds(gfx::Rect(0, 0, 200, 200));
+ widget.Show();
+
+ widget.Maximize();
+ EXPECT_TRUE(widget.IsMaximized());
+
+ widget.SetFullscreen(true);
+ EXPECT_TRUE(widget.IsFullscreen());
+ EXPECT_FALSE(widget.IsMaximized());
+ // Ensure that the StopIgnoringPosChanges task in HWNDMessageHandler runs.
+ // This task is queued when a widget becomes fullscreen.
+ RunPendingMessages();
+
+ aura::WindowTreeHost* host = widget.GetNativeWindow()->GetHost();
+ HWND hwnd = host->GetAcceleratedWidget();
+
+ HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+ ASSERT_TRUE(!!monitor);
+ MONITORINFO monitor_info;
+ monitor_info.cbSize = sizeof(monitor_info);
+ ASSERT_TRUE(::GetMonitorInfo(monitor, &monitor_info));
+
+ gfx::Rect monitor_bounds(monitor_info.rcMonitor);
+ gfx::Rect window_bounds = widget.GetWindowBoundsInScreen();
+ gfx::Rect client_area_bounds = host->GetBounds();
+
+ EXPECT_EQ(window_bounds, monitor_bounds);
+ EXPECT_EQ(monitor_bounds, client_area_bounds);
+
+ // Setting not fullscreen should return it to maximized.
+ widget.SetFullscreen(false);
+ EXPECT_FALSE(widget.IsFullscreen());
+ EXPECT_TRUE(widget.IsMaximized());
+
+ client_area_bounds = host->GetBounds();
+ EXPECT_TRUE(monitor_bounds.Contains(client_area_bounds));
+ EXPECT_NE(monitor_bounds, client_area_bounds);
+
+ widget.CloseNow();
+}
#endif // defined(OS_WIN)
#if !defined(OS_CHROMEOS)
@@ -826,6 +881,10 @@ class ModalDialogDelegate : public DialogDelegateView {
// Tests whether the focused window is set correctly when a modal window is
// created and destroyed. When it is destroyed it should focus the owner window.
TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
+ // Fails on mus due to focus issues. http://crbug.com/611601
+ if (IsMus())
+ return;
+
TestWidgetFocusChangeListener focus_listener;
WidgetFocusManager::GetInstance()->AddFocusChangeListener(&focus_listener);
const std::vector<gfx::NativeView>& focus_changes =
@@ -863,7 +922,7 @@ TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
modal_dialog_widget->Show();
gfx::NativeView modal_native_view = modal_dialog_widget->GetNativeView();
- EXPECT_EQ(3u, focus_changes.size());
+ ASSERT_EQ(3u, focus_changes.size());
EXPECT_EQ(nullptr, focus_changes[1]);
EXPECT_EQ(modal_native_view, focus_changes[2]);
@@ -877,7 +936,7 @@ TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
modal_dialog_widget->CloseNow();
#endif
- EXPECT_EQ(5u, focus_changes.size());
+ ASSERT_EQ(5u, focus_changes.size());
EXPECT_EQ(nullptr, focus_changes[3]);
EXPECT_EQ(top_level_native_view, focus_changes[4]);
@@ -897,6 +956,10 @@ TEST_F(WidgetTestInteractive, WindowModalWindowDestroyedActivationTest) {
// Test that when opening a system-modal window, capture is released.
TEST_F(WidgetTestInteractive, MAYBE_SystemModalWindowReleasesCapture) {
+ // Crashes on mus due to capture issue. http://crbug.com/611764
+ if (IsMus())
+ return;
+
TestWidgetFocusChangeListener focus_listener;
WidgetFocusManager::GetInstance()->AddFocusChangeListener(&focus_listener);
@@ -988,6 +1051,10 @@ TEST_F(WidgetTestInteractive, TouchSelectionQuickMenuIsNotActivated) {
#endif // defined(USE_AURA)
TEST_F(WidgetTestInteractive, DisableViewDoesNotActivateWidget) {
+ // Times out on mus. See http://crbug.com/612193
+ if (IsMus())
+ return;
+
#if defined(OS_WIN)
views_delegate()->set_use_desktop_native_widgets(true);
#endif // !defined(OS_WIN)
@@ -1000,7 +1067,7 @@ TEST_F(WidgetTestInteractive, DisableViewDoesNotActivateWidget) {
widget1.Init(params1);
View* view1 = new View();
- view1->SetFocusable(true);
+ view1->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget1.GetRootView()->AddChildView(view1);
ActivateSync(&widget1);
@@ -1018,7 +1085,7 @@ TEST_F(WidgetTestInteractive, DisableViewDoesNotActivateWidget) {
widget2.Init(params2);
View* view2 = new View();
- view2->SetFocusable(true);
+ view2->SetFocusBehavior(View::FocusBehavior::ALWAYS);
widget2.GetRootView()->AddChildView(view2);
ActivateSync(&widget2);
@@ -1179,7 +1246,7 @@ TEST_F(WidgetTestInteractive, InitialFocus) {
// focusable subview).
Widget* toplevel(CreateTopLevelPlatformWidget());
View* view = new View;
- view->SetFocusable(true);
+ view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
toplevel->GetContentsView()->AddChildView(view);
ShowSync(toplevel);
@@ -1234,11 +1301,15 @@ class WidgetCaptureTest : public ViewsTestBase {
~WidgetCaptureTest() override {}
void SetUp() override {
- gfx::GLSurfaceTestSupport::InitializeOneOff();
- ui::RegisterPathProvider();
- base::FilePath ui_test_pak_path;
- ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
- ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+ // On mus these tests run as part of views::ViewsTestSuite which already
+ // does this initialization.
+ if (!IsMus()) {
+ gfx::GLSurfaceTestSupport::InitializeOneOff();
+ ui::RegisterPathProvider();
+ base::FilePath ui_test_pak_path;
+ ASSERT_TRUE(PathService::Get(ui::UI_TEST_PAK, &ui_test_pak_path));
+ ui::ResourceBundle::InitSharedInstanceWithPakPath(ui_test_pak_path);
+ }
ViewsTestBase::SetUp();
}
@@ -1305,12 +1376,20 @@ TEST_F(WidgetCaptureTest, Capture) {
#if !defined(OS_CHROMEOS)
// See description in TestCapture(). Creates DesktopNativeWidget.
TEST_F(WidgetCaptureTest, CaptureDesktopNativeWidget) {
+ // Fails on mus. http://crbug.com/611764
+ if (IsMus())
+ return;
+
TestCapture(true);
}
#endif
// Test that no state is set if capture fails.
TEST_F(WidgetCaptureTest, FailedCaptureRequestIsNoop) {
+ // Fails on mus. http://crbug.com/611764
+ if (IsMus())
+ return;
+
Widget widget;
Widget::InitParams params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -1353,6 +1432,10 @@ TEST_F(WidgetCaptureTest, FailedCaptureRequestIsNoop) {
// Test that a synthetic mouse exit is sent to the widget which was handling
// mouse events when a different widget grabs capture.
TEST_F(WidgetCaptureTest, MAYBE_MouseExitOnCaptureGrab) {
+ // Fails on mus. http://crbug.com/611764
+ if (IsMus())
+ return;
+
Widget widget1;
Widget::InitParams params1 =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -1608,6 +1691,10 @@ TEST_F(WidgetInputMethodInteractiveTest, OneWindow) {
// Test input method focus changes affected by focus changes cross 2 windows
// which shares the same top window.
TEST_F(WidgetInputMethodInteractiveTest, TwoWindows) {
+ // Fails on mus. http://crbug.com/611766
+ if (IsMus())
+ return;
+
Widget* parent = CreateWidget();
parent->SetBounds(gfx::Rect(100, 100, 100, 100));
diff --git a/chromium/ui/views/widget/widget_unittest.cc b/chromium/ui/views/widget/widget_unittest.cc
index 12dec089cc9..3dfd3572eb1 100644
--- a/chromium/ui/views/widget/widget_unittest.cc
+++ b/chromium/ui/views/widget/widget_unittest.cc
@@ -3,11 +3,11 @@
// found in the LICENSE file.
#include <algorithm>
+#include <memory>
#include <set>
#include "base/bind.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -21,7 +21,7 @@
#include "ui/events/test/event_generator.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_widget_types.h"
-#include "ui/views/bubble/bubble_delegate.h"
+#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/test/native_widget_factory.h"
#include "ui/views/test/test_views.h"
@@ -61,13 +61,28 @@ gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) {
return tmp;
}
-// This class can be used as a deleter for scoped_ptr<Widget>
+// This class can be used as a deleter for std::unique_ptr<Widget>
// to call function Widget::CloseNow automatically.
struct WidgetCloser {
inline void operator()(Widget* widget) const { widget->CloseNow(); }
};
-using WidgetAutoclosePtr = scoped_ptr<Widget, WidgetCloser>;
+class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {
+ public:
+ TestBubbleDialogDelegateView(View* anchor)
+ : BubbleDialogDelegateView(anchor, BubbleBorder::NONE),
+ reset_controls_called_(false) {}
+ ~TestBubbleDialogDelegateView() override {}
+
+ bool ShouldShowCloseButton() const override {
+ reset_controls_called_ = true;
+ return true;
+ }
+
+ mutable bool reset_controls_called_;
+};
+
+using WidgetAutoclosePtr = std::unique_ptr<Widget, WidgetCloser>;
} // namespace
@@ -154,6 +169,19 @@ TEST_F(WidgetTest, WidgetInitParams) {
EXPECT_EQ(Widget::InitParams::INFER_OPACITY, init1.opacity);
}
+// Tests that the internal name is propagated through widget initialization to
+// the native widget and back.
+TEST_F(WidgetTest, GetName) {
+ Widget widget;
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.name = "MyWidget";
+ widget.Init(params);
+
+ EXPECT_EQ("MyWidget", widget.native_widget_private()->GetName());
+ EXPECT_EQ("MyWidget", widget.GetName());
+}
+
TEST_F(WidgetTest, NativeWindowProperty) {
const char* key = "foo";
int value = 3;
@@ -379,7 +407,7 @@ class OwnershipTestWidget : public Widget {
TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
OwnershipTestState state;
- scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
+ std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
@@ -400,7 +428,7 @@ TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsPlatformNativeWidget) {
TEST_F(WidgetOwnershipTest, Ownership_WidgetOwnsViewsNativeWidget) {
OwnershipTestState state;
- scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
+ std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
@@ -425,7 +453,7 @@ TEST_F(WidgetOwnershipTest,
Widget* toplevel = CreateTopLevelPlatformWidget();
- scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
+ std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.parent = toplevel->GetNativeView();
params.native_widget = CreatePlatformNativeWidgetImpl(
@@ -571,7 +599,7 @@ TEST_F(WidgetOwnershipTest,
WidgetDelegateView* delegate_view = new WidgetDelegateView;
- scoped_ptr<Widget> widget(new OwnershipTestWidget(&state));
+ std::unique_ptr<Widget> widget(new OwnershipTestWidget(&state));
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.native_widget = CreatePlatformNativeWidgetImpl(
params, widget.get(), kStubCapture, &state.native_widget_deleted);
@@ -822,11 +850,11 @@ TEST_F(WidgetObserverTest, DestroyBubble) {
WidgetAutoclosePtr anchor(CreateTopLevelPlatformWidget());
anchor->Show();
- BubbleDelegateView* bubble_delegate =
- new BubbleDelegateView(anchor->client_view(), BubbleBorder::NONE);
+ BubbleDialogDelegateView* bubble_delegate =
+ new TestBubbleDialogDelegateView(anchor->client_view());
{
WidgetAutoclosePtr bubble_widget(
- BubbleDelegateView::CreateBubble(bubble_delegate));
+ BubbleDialogDelegateView::CreateBubble(bubble_delegate));
bubble_widget->Show();
}
@@ -1189,7 +1217,7 @@ TEST_F(WidgetTest, KeyboardInputEvent) {
TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
// Create a widget, show and activate it and focus the contents view.
View* contents_view = new View;
- contents_view->SetFocusable(true);
+ contents_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
Widget widget;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -1207,10 +1235,10 @@ TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
EXPECT_TRUE(contents_view->HasFocus());
// Show a bubble.
- BubbleDelegateView* bubble_delegate_view =
- new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT);
- bubble_delegate_view->SetFocusable(true);
- BubbleDelegateView::CreateBubble(bubble_delegate_view)->Show();
+ BubbleDialogDelegateView* bubble_delegate_view =
+ new TestBubbleDialogDelegateView(contents_view);
+ bubble_delegate_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ BubbleDialogDelegateView::CreateBubble(bubble_delegate_view)->Show();
bubble_delegate_view->RequestFocus();
// |contents_view_| should no longer have focus.
@@ -1223,30 +1251,15 @@ TEST_F(WidgetTest, DISABLED_FocusChangesOnBubble) {
EXPECT_TRUE(contents_view->HasFocus());
}
-class TestBubbleDelegateView : public BubbleDelegateView {
- public:
- TestBubbleDelegateView(View* anchor)
- : BubbleDelegateView(anchor, BubbleBorder::NONE),
- reset_controls_called_(false) {}
- ~TestBubbleDelegateView() override {}
-
- bool ShouldShowCloseButton() const override {
- reset_controls_called_ = true;
- return true;
- }
-
- mutable bool reset_controls_called_;
-};
-
TEST_F(WidgetTest, BubbleControlsResetOnInit) {
WidgetAutoclosePtr anchor(CreateTopLevelPlatformWidget());
anchor->Show();
{
- TestBubbleDelegateView* bubble_delegate =
- new TestBubbleDelegateView(anchor->client_view());
+ TestBubbleDialogDelegateView* bubble_delegate =
+ new TestBubbleDialogDelegateView(anchor->client_view());
WidgetAutoclosePtr bubble_widget(
- BubbleDelegateView::CreateBubble(bubble_delegate));
+ BubbleDialogDelegateView::CreateBubble(bubble_delegate));
EXPECT_TRUE(bubble_delegate->reset_controls_called_);
bubble_widget->Show();
}
@@ -1351,7 +1364,7 @@ void DesktopAuraTestValidPaintWidget::InitForTest(InitParams init_params) {
Init(init_params);
View* contents_view = new View;
- contents_view->SetFocusable(true);
+ contents_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
SetContentsView(contents_view);
Show();
@@ -1534,7 +1547,7 @@ TEST_F(WidgetTest, EventHandlersOnRootView) {
WidgetAutoclosePtr widget(CreateTopLevelNativeWidget());
View* root_view = widget->GetRootView();
- scoped_ptr<EventCountView> view(new EventCountView());
+ std::unique_ptr<EventCountView> view(new EventCountView());
view->set_owned_by_client();
view->SetBounds(0, 0, 20, 20);
root_view->AddChildView(view.get());
@@ -1688,9 +1701,6 @@ TEST_F(WidgetTest, SynthesizeMouseMoveEvent) {
EXPECT_EQ(1, v2->GetEventCount(ui::ET_MOUSE_MOVED));
}
-// No touch on desktop Mac. Tracked in http://crbug.com/445520.
-#if !defined(OS_MACOSX) || defined(USE_AURA)
-
namespace {
// ui::EventHandler which handles all mouse press events.
@@ -1710,6 +1720,9 @@ class MousePressEventConsumer : public ui::EventHandler {
} // namespace
+// No touch on desktop Mac. Tracked in http://crbug.com/445520.
+#if !defined(OS_MACOSX) || defined(USE_AURA)
+
// Test that mouse presses and mouse releases are dispatched normally when a
// touch is down.
TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
@@ -1724,9 +1737,10 @@ TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
MousePressEventConsumer consumer;
event_count_view->AddPostTargetHandler(&consumer);
- scoped_ptr<ui::test::EventGenerator> generator(new ui::test::EventGenerator(
- IsMus() ? widget->GetNativeWindow() : GetContext(),
- widget->GetNativeWindow()));
+ std::unique_ptr<ui::test::EventGenerator> generator(
+ new ui::test::EventGenerator(
+ IsMus() ? widget->GetNativeWindow() : GetContext(),
+ widget->GetNativeWindow()));
generator->PressTouch();
generator->ClickLeftButton();
@@ -1739,6 +1753,107 @@ TEST_F(WidgetTest, MouseEventDispatchWhileTouchIsDown) {
#endif // !defined(OS_MACOSX) || defined(USE_AURA)
+// Tests that when there is no active capture, that a mouse press causes capture
+// to be set.
+TEST_F(WidgetTest, MousePressCausesCapture) {
+ Widget* widget = CreateTopLevelNativeWidget();
+ widget->Show();
+ widget->SetSize(gfx::Size(300, 300));
+
+ EventCountView* event_count_view = new EventCountView();
+ event_count_view->SetBounds(0, 0, 300, 300);
+ widget->GetRootView()->AddChildView(event_count_view);
+
+ // No capture has been set.
+ EXPECT_EQ(nullptr, internal::NativeWidgetPrivate::GetGlobalCapture(
+ widget->GetNativeView()));
+
+ MousePressEventConsumer consumer;
+ event_count_view->AddPostTargetHandler(&consumer);
+ std::unique_ptr<ui::test::EventGenerator> generator(
+ new ui::test::EventGenerator(
+ IsMus() ? widget->GetNativeWindow() : GetContext(),
+ widget->GetNativeWindow()));
+ generator->PressLeftButton();
+
+ EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_EQ(
+ widget->GetNativeView(),
+ internal::NativeWidgetPrivate::GetGlobalCapture(widget->GetNativeView()));
+
+ // For mus it's important we destroy the widget before the EventGenerator.
+ widget->CloseNow();
+}
+
+namespace {
+
+// An EventHandler which shows a Wiget upon receiving a mouse event. The Widget
+// proceeds to take capture.
+class CaptureEventConsumer : public ui::EventHandler {
+ public:
+ CaptureEventConsumer(Widget* widget)
+ : event_count_view_(new EventCountView()), widget_(widget) {}
+ ~CaptureEventConsumer() override { widget_->CloseNow(); }
+
+ private:
+ // ui::EventHandler:
+ void OnMouseEvent(ui::MouseEvent* event) override {
+ if (event->type() == ui::ET_MOUSE_PRESSED) {
+ event->SetHandled();
+ widget_->Show();
+ widget_->SetSize(gfx::Size(200, 200));
+
+ event_count_view_->SetBounds(0, 0, 200, 200);
+ widget_->GetRootView()->AddChildView(event_count_view_);
+ widget_->SetCapture(event_count_view_);
+ }
+ }
+
+ EventCountView* event_count_view_;
+ Widget* widget_;
+ DISALLOW_COPY_AND_ASSIGN(CaptureEventConsumer);
+};
+
+} // namespace
+
+// Tests that if explicit capture occurs during a mouse press, that implicit
+// capture is not applied.
+TEST_F(WidgetTest, CaptureDuringMousePressNotOverridden) {
+ Widget* widget = CreateTopLevelNativeWidget();
+ widget->Show();
+ widget->SetSize(gfx::Size(300, 300));
+
+ EventCountView* event_count_view = new EventCountView();
+ event_count_view->SetBounds(0, 0, 300, 300);
+ widget->GetRootView()->AddChildView(event_count_view);
+
+ EXPECT_EQ(nullptr, internal::NativeWidgetPrivate::GetGlobalCapture(
+ widget->GetNativeView()));
+
+ Widget* widget2 = CreateTopLevelNativeWidget();
+ // Gives explicit capture to |widget2|
+ CaptureEventConsumer consumer(widget2);
+ event_count_view->AddPostTargetHandler(&consumer);
+ std::unique_ptr<ui::test::EventGenerator> generator(
+ new ui::test::EventGenerator(
+ IsMus() ? widget->GetNativeWindow() : GetContext(),
+ widget->GetNativeWindow()));
+ // This event should implicitly give capture to |widget|, except that
+ // |consumer| will explicitly set capture on |widget2|.
+ generator->PressLeftButton();
+
+ EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSE_PRESSED));
+ EXPECT_NE(
+ widget->GetNativeView(),
+ internal::NativeWidgetPrivate::GetGlobalCapture(widget->GetNativeView()));
+ EXPECT_EQ(
+ widget2->GetNativeView(),
+ internal::NativeWidgetPrivate::GetGlobalCapture(widget->GetNativeView()));
+
+ // For mus it's important we destroy the widget before the EventGenerator.
+ widget->CloseNow();
+}
+
// Verifies WindowClosing() is invoked correctly on the delegate when a Widget
// is closed.
TEST_F(WidgetTest, SingleWindowClosing) {
@@ -1837,8 +1952,9 @@ TEST_F(WidgetTest, WidgetDeleted_InOnMousePressed) {
#if !defined(OS_MACOSX) || defined(USE_AURA)
TEST_F(WidgetTest, WidgetDeleted_InDispatchGestureEvent) {
- // This test doesn't make sense for mus. Force NativeWidgetAura to be used.
- DisableNativeWidgetMus();
+ // This test doesn't make sense for mus.
+ if (IsMus())
+ return;
Widget* widget = new Widget;
Widget::InitParams params =
@@ -1996,7 +2112,7 @@ TEST_F(WidgetTest, CloseDestroys) {
// Tests that killing a widget while animating it does not crash.
TEST_F(WidgetTest, CloseWidgetWhileAnimating) {
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(50, 50, 250, 250);
@@ -2058,7 +2174,7 @@ TEST_F(WidgetTest, ValidDuringOnNativeWidgetDestroyingFromClose) {
// Tests that we do not crash when a Widget is destroyed by going out of
// scope (as opposed to being explicitly deleted by its NativeWidget).
TEST_F(WidgetTest, NoCrashOnWidgetDelete) {
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
widget->Init(params);
@@ -2067,7 +2183,7 @@ TEST_F(WidgetTest, NoCrashOnWidgetDelete) {
// Tests that we do not crash when a Widget is destroyed before it finishes
// processing of pending input events in the message loop.
TEST_F(WidgetTest, NoCrashOnWidgetDeleteWithPendingEvents) {
- scoped_ptr<Widget> widget(new Widget);
+ std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
params.bounds = gfx::Rect(0, 0, 200, 200);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
diff --git a/chromium/ui/views/widget/window_reorderer.h b/chromium/ui/views/widget/window_reorderer.h
index 7b9db7ccad4..1d8d253e80f 100644
--- a/chromium/ui/views/widget/window_reorderer.h
+++ b/chromium/ui/views/widget/window_reorderer.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_WIDGET_WINDOW_REORDERER_H_
#define UI_VIEWS_WIDGET_WINDOW_REORDERER_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/aura/window_observer.h"
namespace aura {
@@ -50,7 +51,7 @@ class WindowReorderer : public aura::WindowObserver {
// Reorders windows as a result of the kHostViewKey being set on a child of
// |parent_window_|.
class AssociationObserver;
- scoped_ptr<AssociationObserver> association_observer_;
+ std::unique_ptr<AssociationObserver> association_observer_;
DISALLOW_COPY_AND_ASSIGN(WindowReorderer);
};
diff --git a/chromium/ui/views/widget/window_reorderer_unittest.cc b/chromium/ui/views/widget/window_reorderer_unittest.cc
index 67cf246e73a..08be48b904f 100644
--- a/chromium/ui/views/widget/window_reorderer_unittest.cc
+++ b/chromium/ui/views/widget/window_reorderer_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
@@ -52,8 +54,8 @@ typedef aura::test::AuraTestBase WindowReordererTest;
// Test that views with layers and views with associated windows are reordered
// according to the view hierarchy.
TEST_F(WindowReordererTest, Basic) {
- scoped_ptr<Widget> parent(CreateControlWidget(root_window(),
- gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent(
+ CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
@@ -68,12 +70,12 @@ TEST_F(WindowReordererTest, Basic) {
v->layer()->set_name("v");
contents_view->AddChildView(v);
- scoped_ptr<Widget> w1(CreateControlWidget(parent_window,
- gfx::Rect(0, 1, 100, 101)));
+ std::unique_ptr<Widget> w1(
+ CreateControlWidget(parent_window, gfx::Rect(0, 1, 100, 101)));
SetWindowAndLayerName(w1->GetNativeView(), "w1");
w1->Show();
- scoped_ptr<Widget> w2(CreateControlWidget(parent_window,
- gfx::Rect(0, 2, 100, 102)));
+ std::unique_ptr<Widget> w2(
+ CreateControlWidget(parent_window, gfx::Rect(0, 2, 100, 102)));
SetWindowAndLayerName(w2->GetNativeView(), "w2");
w2->Show();
@@ -130,8 +132,8 @@ TEST_F(WindowReordererTest, Basic) {
// - associating the "host" view and window
// all correctly reorder the child windows and layers.
TEST_F(WindowReordererTest, Association) {
- scoped_ptr<Widget> parent(CreateControlWidget(root_window(),
- gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent(
+ CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
@@ -191,8 +193,8 @@ TEST_F(WindowReordererTest, Association) {
// view and the parent layer of the associated window are different. Test that
// the layers and windows are properly reordered in this case.
TEST_F(WindowReordererTest, HostViewParentHasLayer) {
- scoped_ptr<Widget> parent(CreateControlWidget(root_window(),
- gfx::Rect(0, 0, 100, 100)));
+ std::unique_ptr<Widget> parent(
+ CreateControlWidget(root_window(), gfx::Rect(0, 0, 100, 100)));
parent->Show();
aura::Window* parent_window = parent->GetNativeWindow();
@@ -217,8 +219,8 @@ TEST_F(WindowReordererTest, HostViewParentHasLayer) {
v11->layer()->set_name("v11");
v1->AddChildView(v11);
- scoped_ptr<Widget> w(CreateControlWidget(parent_window,
- gfx::Rect(0, 1, 100, 101)));
+ std::unique_ptr<Widget> w(
+ CreateControlWidget(parent_window, gfx::Rect(0, 1, 100, 101)));
SetWindowAndLayerName(w->GetNativeView(), "w");
w->Show();
diff --git a/chromium/ui/views/win/fullscreen_handler.cc b/chromium/ui/views/win/fullscreen_handler.cc
index 0529f6e37d8..89581d79d06 100644
--- a/chromium/ui/views/win/fullscreen_handler.cc
+++ b/chromium/ui/views/win/fullscreen_handler.cc
@@ -4,8 +4,9 @@
#include "ui/views/win/fullscreen_handler.h"
+#include <memory>
+
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
#include "base/win/win_util.h"
#include "ui/base/win/shell.h"
#include "ui/gfx/geometry/rect.h"
@@ -36,7 +37,7 @@ gfx::Rect FullscreenHandler::GetRestoreBounds() const {
// FullscreenHandler, private:
void FullscreenHandler::SetFullscreenImpl(bool fullscreen) {
- scoped_ptr<ScopedFullscreenVisibility> visibility;
+ std::unique_ptr<ScopedFullscreenVisibility> visibility;
// With Aero enabled disabling the visibility causes the window to disappear
// for several frames, which looks worse than doing other updates
@@ -46,12 +47,6 @@ void FullscreenHandler::SetFullscreenImpl(bool fullscreen) {
// Save current window state if not already fullscreen.
if (!fullscreen_) {
- // Save current window information. We force the window into restored mode
- // before going fullscreen because Windows doesn't seem to hide the
- // taskbar if the window is in the maximized state.
- saved_window_info_.maximized = !!::IsZoomed(hwnd_);
- if (saved_window_info_.maximized)
- ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_RESTORE, 0);
saved_window_info_.style = GetWindowLong(hwnd_, GWL_STYLE);
saved_window_info_.ex_style = GetWindowLong(hwnd_, GWL_EXSTYLE);
GetWindowRect(hwnd_, &saved_window_info_.window_rect);
@@ -89,8 +84,6 @@ void FullscreenHandler::SetFullscreenImpl(bool fullscreen) {
SetWindowPos(hwnd_, NULL, new_rect.x(), new_rect.y(), new_rect.width(),
new_rect.height(),
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
- if (saved_window_info_.maximized)
- ::SendMessage(hwnd_, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
}
}
diff --git a/chromium/ui/views/win/fullscreen_handler.h b/chromium/ui/views/win/fullscreen_handler.h
index b23b1421374..9714057ed86 100644
--- a/chromium/ui/views/win/fullscreen_handler.h
+++ b/chromium/ui/views/win/fullscreen_handler.h
@@ -34,7 +34,6 @@ class FullscreenHandler {
// Information saved before going into fullscreen mode, used to restore the
// window afterwards.
struct SavedWindowInfo {
- bool maximized;
LONG style;
LONG ex_style;
RECT window_rect;
diff --git a/chromium/ui/views/win/hwnd_message_handler.cc b/chromium/ui/views/win/hwnd_message_handler.cc
index 7555abd0f26..3d77ea47a79 100644
--- a/chromium/ui/views/win/hwnd_message_handler.cc
+++ b/chromium/ui/views/win/hwnd_message_handler.cc
@@ -34,9 +34,7 @@
#include "ui/gfx/icon_util.h"
#include "ui/gfx/path.h"
#include "ui/gfx/path_win.h"
-#include "ui/gfx/screen.h"
#include "ui/gfx/win/direct_manipulation.h"
-#include "ui/gfx/win/dpi.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/gfx/win/rendering_window_manager.h"
#include "ui/native_theme/native_theme_win.h"
@@ -302,6 +300,10 @@ class HWNDMessageHandler::ScopedRedrawLock {
DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock);
};
+// static HWNDMessageHandler member initialization.
+base::LazyInstance<HWNDMessageHandler::FullscreenWindowMonitorMap>
+ HWNDMessageHandler::fullscreen_monitor_map_ = LAZY_INSTANCE_INITIALIZER;
+
////////////////////////////////////////////////////////////////////////////////
// HWNDMessageHandler, public:
@@ -683,7 +685,7 @@ bool HWNDMessageHandler::IsMinimized() const {
}
bool HWNDMessageHandler::IsMaximized() const {
- return !!::IsZoomed(hwnd());
+ return !!::IsZoomed(hwnd()) && !IsFullscreen();
}
bool HWNDMessageHandler::IsFullscreen() const {
@@ -815,6 +817,18 @@ void HWNDMessageHandler::SetFullscreen(bool fullscreen) {
// window, then go ahead and do it now.
if (!fullscreen && dwm_transition_desired_)
PerformDwmTransition();
+
+ // Add the fullscreen window to the fullscreen window map which is used to
+ // handle window activations.
+ HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY);
+ if (fullscreen) {
+ (fullscreen_monitor_map_.Get())[monitor] = this;
+ } else {
+ FullscreenWindowMonitorMap::iterator iter =
+ fullscreen_monitor_map_.Get().find(monitor);
+ if (iter != fullscreen_monitor_map_.Get().end())
+ fullscreen_monitor_map_.Get().erase(iter);
+ }
}
void HWNDMessageHandler::SizeConstraintsChanged() {
@@ -1025,18 +1039,18 @@ void HWNDMessageHandler::PostProcessActivateMessage(
// By reducing the size of the fullscreen window by 1px, we ensure that the
// taskbar no longer treats the window and in turn the thread as a fullscreen
// thread. This in turn ensures that maximized windows on the same thread
- /// don't obscure the taskbar, etc.
+ // don't obscure the taskbar, etc.
+ // Please note that this taskbar behavior only occurs if the window becoming
+ // active is on the same monitor as the fullscreen window.
if (!active) {
if (IsFullscreen() && ::IsWindow(window_gaining_or_losing_activation)) {
- // Reduce the bounds of the window by 1px to ensure that Windows does
- // not treat this like a fullscreen window.
- MONITORINFO monitor_info = {sizeof(monitor_info)};
- GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
- &monitor_info);
- gfx::Rect shrunk_rect(monitor_info.rcMonitor);
- shrunk_rect.set_height(shrunk_rect.height() - 1);
- background_fullscreen_hack_ = true;
- SetBoundsInternal(shrunk_rect, false);
+ HMONITOR active_window_monitor = MonitorFromWindow(
+ window_gaining_or_losing_activation, MONITOR_DEFAULTTOPRIMARY);
+ HMONITOR fullscreen_window_monitor =
+ MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY);
+
+ if (active_window_monitor == fullscreen_window_monitor)
+ OnBackgroundFullscreen();
}
} else if (background_fullscreen_hack_) {
// Restore the bounds of the window to fullscreen.
@@ -1046,6 +1060,13 @@ void HWNDMessageHandler::PostProcessActivateMessage(
&monitor_info);
SetBoundsInternal(gfx::Rect(monitor_info.rcMonitor), false);
background_fullscreen_hack_ = false;
+ } else {
+ // If the window becoming active has a fullscreen window on the same
+ // monitor then we need to reduce the size of the fullscreen window by
+ // 1 px. Please refer to the comments above for the reasoning behind
+ // this.
+ CheckAndHandleBackgroundFullscreenOnMonitor(
+ window_gaining_or_losing_activation);
}
}
@@ -1093,7 +1114,7 @@ void HWNDMessageHandler::TrackMouseEvents(DWORD mouse_tracking_flags) {
void HWNDMessageHandler::ClientAreaSizeChanged() {
// Ignore size changes due to fullscreen windows losing activation.
- if (background_fullscreen_hack_)
+ if (background_fullscreen_hack_ && !sent_window_size_changing_)
return;
gfx::Size s = GetClientAreaBounds().size();
delegate_->HandleClientSizeChanged(s);
@@ -1341,6 +1362,16 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
void HWNDMessageHandler::OnDestroy() {
windows_session_change_observer_.reset(nullptr);
delegate_->HandleDestroying();
+ // If the window going away is a fullscreen window then remove its references
+ // from the full screen window map.
+ for (auto iter = fullscreen_monitor_map_.Get().begin();
+ iter != fullscreen_monitor_map_.Get().end();
+ iter++) {
+ if (iter->second == this) {
+ fullscreen_monitor_map_.Get().erase(iter);
+ break;
+ }
+ }
}
void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel,
@@ -1401,14 +1432,17 @@ void HWNDMessageHandler::OnExitSizeMove() {
// trackpoint drivers.
if (in_size_loop_ && needs_scroll_styles_)
AddScrollStylesToWindow(hwnd());
+ // If the window was moved to a monitor which has a fullscreen window active,
+ // we need to reduce the size of the fullscreen window by 1px.
+ CheckAndHandleBackgroundFullscreenOnMonitor(hwnd());
}
void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
gfx::Size min_window_size;
gfx::Size max_window_size;
delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
- min_window_size = gfx::win::DIPToScreenSize(min_window_size);
- max_window_size = gfx::win::DIPToScreenSize(max_window_size);
+ min_window_size = delegate_->DIPToScreenSize(min_window_size);
+ max_window_size = delegate_->DIPToScreenSize(max_window_size);
// Add the native frame border size to the minimum and maximum size if the
@@ -1562,6 +1596,29 @@ LRESULT HWNDMessageHandler::OnMouseRange(UINT message,
return HandleMouseEventInternal(message, w_param, l_param, true);
}
+// On some systems with a high-resolution track pad and running Windows 10,
+// using the scrolling gesture (two-finger scroll) on the track pad
+// causes it to also generate a WM_POINTERDOWN message if the window
+// isn't focused. This leads to a WM_POINTERACTIVATE message and the window
+// gaining focus and coming to the front. This code detects a
+// WM_POINTERACTIVATE coming from the track pad and kills the activation
+// of the window. NOTE: most other trackpad messages come in as mouse
+// messages, including WM_MOUSEWHEEL instead of WM_POINTERWHEEL.
+LRESULT HWNDMessageHandler::OnPointerActivate(UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ using GetPointerTypeFn = BOOL(WINAPI*)(UINT32, POINTER_INPUT_TYPE*);
+ UINT32 pointer_id = GET_POINTERID_WPARAM(w_param);
+ POINTER_INPUT_TYPE pointer_type;
+ static GetPointerTypeFn get_pointer_type = reinterpret_cast<GetPointerTypeFn>(
+ GetProcAddress(GetModuleHandleA("user32.dll"), "GetPointerType"));
+ if (get_pointer_type && get_pointer_type(pointer_id, &pointer_type) &&
+ pointer_type == PT_TOUCHPAD)
+ return PA_NOACTIVATE;
+ SetMsgHandled(FALSE);
+ return -1;
+}
+
void HWNDMessageHandler::OnMove(const gfx::Point& point) {
delegate_->HandleMove();
SetMsgHandled(FALSE);
@@ -1725,6 +1782,21 @@ LRESULT HWNDMessageHandler::OnNCHitTest(const gfx::Point& point) {
return 0;
}
+ // Some views may overlap the non client area of the window.
+ // This means that we should look for these views before handing the
+ // hittest message off to DWM or DefWindowProc.
+ // If the hittest returned from the search for a view returns HTCLIENT
+ // then it means that we have a view overlapping the non client area.
+ // In all other cases we can fallback to the system default handling.
+
+ // Allow the NonClientView to handle the hittest to see if we have a view
+ // overlapping the non client area of the window.
+ POINT temp = { point.x(), point.y() };
+ MapWindowPoints(HWND_DESKTOP, hwnd(), &temp, 1);
+ int component = delegate_->GetNonClientComponent(gfx::Point(temp));
+ if (component == HTCLIENT)
+ return component;
+
// If the DWM is rendering the window controls, we need to give the DWM's
// default window procedure first chance to handle hit testing.
if (HasSystemFrame()) {
@@ -1735,11 +1807,7 @@ LRESULT HWNDMessageHandler::OnNCHitTest(const gfx::Point& point) {
}
}
- // First, give the NonClientView a chance to test the point to see if it
- // provides any of the non-client area.
- POINT temp = { point.x(), point.y() };
- MapWindowPoints(HWND_DESKTOP, hwnd(), &temp, 1);
- int component = delegate_->GetNonClientComponent(gfx::Point(temp));
+ // If the point is specified as custom or system nonclient item, return it.
if (component != HTNOWHERE)
return component;
@@ -2123,7 +2191,7 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message,
LPARAM l_param) {
// Handle touch events only on Aura for now.
int num_points = LOWORD(w_param);
- scoped_ptr<TOUCHINPUT[]> input(new TOUCHINPUT[num_points]);
+ std::unique_ptr<TOUCHINPUT[]> input(new TOUCHINPUT[num_points]);
if (ui::GetTouchInputInfoWrapper(reinterpret_cast<HTOUCHINPUT>(l_param),
num_points, input.get(),
sizeof(TOUCHINPUT))) {
@@ -2653,5 +2721,29 @@ void HWNDMessageHandler::SetBoundsInternal(const gfx::Rect& bounds_in_pixels,
direct_manipulation_helper_->SetBounds(bounds_in_pixels);
}
+void HWNDMessageHandler::CheckAndHandleBackgroundFullscreenOnMonitor(
+ HWND window) {
+ HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
+
+ FullscreenWindowMonitorMap::iterator iter =
+ fullscreen_monitor_map_.Get().find(monitor);
+ if (iter != fullscreen_monitor_map_.Get().end()) {
+ DCHECK(iter->second);
+ if (window != iter->second->hwnd())
+ iter->second->OnBackgroundFullscreen();
+ }
+}
+
+void HWNDMessageHandler::OnBackgroundFullscreen() {
+ // Reduce the bounds of the window by 1px to ensure that Windows does
+ // not treat this like a fullscreen window.
+ MONITORINFO monitor_info = {sizeof(monitor_info)};
+ GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
+ &monitor_info);
+ gfx::Rect shrunk_rect(monitor_info.rcMonitor);
+ shrunk_rect.set_height(shrunk_rect.height() - 1);
+ background_fullscreen_hack_ = true;
+ SetBoundsInternal(shrunk_rect, false);
+}
} // namespace views
diff --git a/chromium/ui/views/win/hwnd_message_handler.h b/chromium/ui/views/win/hwnd_message_handler.h
index 143b1c61fec..f011864177c 100644
--- a/chromium/ui/views/win/hwnd_message_handler.h
+++ b/chromium/ui/views/win/hwnd_message_handler.h
@@ -6,14 +6,16 @@
#define UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_H_
#include <windows.h>
-#include <stddef.h>
+#include <stddef.h>
+#include <map>
+#include <memory>
#include <set>
#include <vector>
#include "base/compiler_specific.h"
+#include "base/lazy_instance.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/win/scoped_gdi_object.h"
@@ -337,6 +339,9 @@ class VIEWS_EXPORT HWNDMessageHandler :
CR_MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseRange)
CR_MESSAGE_HANDLER_EX(WM_SETCURSOR, OnSetCursor);
+ // Pointer events.
+ CR_MESSAGE_HANDLER_EX(WM_POINTERACTIVATE, OnPointerActivate)
+
// Key events.
CR_MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent)
CR_MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent)
@@ -432,6 +437,7 @@ class VIEWS_EXPORT HWNDMessageHandler :
void OnKillFocus(HWND focused_window);
LRESULT OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param);
+ LRESULT OnPointerActivate(UINT message, WPARAM w_param, LPARAM l_param);
void OnMove(const gfx::Point& point);
void OnMoving(UINT param, const RECT* new_bounds);
LRESULT OnNCActivate(UINT message, WPARAM w_param, LPARAM l_param);
@@ -513,9 +519,19 @@ class VIEWS_EXPORT HWNDMessageHandler :
void SetBoundsInternal(const gfx::Rect& bounds_in_pixels,
bool force_size_changed);
+ // Checks if there is a full screen window on the same monitor as the
+ // |window| which is becoming active. If yes then we reduce the size of the
+ // fullscreen window by 1 px to ensure that maximized windows on the same
+ // monitor don't draw over the taskbar.
+ void CheckAndHandleBackgroundFullscreenOnMonitor(HWND window);
+
+ // Provides functionality to reduce the bounds of the fullscreen window by 1
+ // px on activation loss to a window on the same monitor.
+ void OnBackgroundFullscreen();
+
HWNDMessageHandlerDelegate* delegate_;
- scoped_ptr<FullscreenHandler> fullscreen_handler_;
+ std::unique_ptr<FullscreenHandler> fullscreen_handler_;
// Set to true in Close() and false is CloseNow().
bool waiting_for_close_now_;
@@ -591,7 +607,7 @@ class VIEWS_EXPORT HWNDMessageHandler :
// Stores a pointer to the WindowEventTarget interface implemented by this
// class. Allows callers to retrieve the interface pointer.
- scoped_ptr<ui::ViewProp> prop_window_target_;
+ std::unique_ptr<ui::ViewProp> prop_window_target_;
// Number of active touch down contexts. This is incremented on touch down
// events and decremented later using a delayed task.
@@ -623,12 +639,14 @@ class VIEWS_EXPORT HWNDMessageHandler :
bool sent_window_size_changing_;
// Manages observation of Windows Session Change messages.
- scoped_ptr<WindowsSessionChangeObserver> windows_session_change_observer_;
+ std::unique_ptr<WindowsSessionChangeObserver>
+ windows_session_change_observer_;
// This class provides functionality to register the legacy window as a
// Direct Manipulation consumer. This allows us to support smooth scroll
// in Chrome on Windows 10.
- scoped_ptr<gfx::win::DirectManipulationHelper> direct_manipulation_helper_;
+ std::unique_ptr<gfx::win::DirectManipulationHelper>
+ direct_manipulation_helper_;
// The location where the user clicked on the caption. We cache this when we
// receive the WM_NCLBUTTONDOWN message. We use this in the subsequent
@@ -645,6 +663,12 @@ class VIEWS_EXPORT HWNDMessageHandler :
// fullscreen window which lost activation. Defaults to false.
bool background_fullscreen_hack_;
+ // This is a map of the HMONITOR to full screeen window instance. It is safe
+ // to keep a raw pointer to the HWNDMessageHandler instance as we track the
+ // window destruction and ensure that the map is cleaned up.
+ using FullscreenWindowMonitorMap = std::map<HMONITOR, HWNDMessageHandler*>;
+ static base::LazyInstance<FullscreenWindowMonitorMap> fullscreen_monitor_map_;
+
// The WeakPtrFactories below must occur last in the class definition so they
// get destroyed last.
diff --git a/chromium/ui/views/win/hwnd_message_handler_delegate.h b/chromium/ui/views/win/hwnd_message_handler_delegate.h
index 007157aefe8..631f3592b8c 100644
--- a/chromium/ui/views/win/hwnd_message_handler_delegate.h
+++ b/chromium/ui/views/win/hwnd_message_handler_delegate.h
@@ -89,6 +89,8 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
// Returns the current size of the RootView.
virtual gfx::Size GetRootViewSize() const = 0;
+ virtual gfx::Size DIPToScreenSize(const gfx::Size& dip_size) const = 0;
+
virtual void ResetWindowControls() = 0;
virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0;
diff --git a/chromium/ui/views/win/windows_session_change_observer.cc b/chromium/ui/views/win/windows_session_change_observer.cc
index 6d230d6edd0..ddbb3191ae3 100644
--- a/chromium/ui/views/win/windows_session_change_observer.cc
+++ b/chromium/ui/views/win/windows_session_change_observer.cc
@@ -6,13 +6,14 @@
#include <wtsapi32.h>
+#include <memory>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "base/task_runner.h"
@@ -101,7 +102,7 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
}
base::ObserverList<WindowsSessionChangeObserver, true> observer_list_;
- scoped_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_;
+ std::unique_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_;
DISALLOW_COPY_AND_ASSIGN(WtsRegistrationNotificationManager);
};
diff --git a/chromium/ui/views/window/custom_frame_view.h b/chromium/ui/views/window/custom_frame_view.h
index db77648a273..8869bef4aa3 100644
--- a/chromium/ui/views/window/custom_frame_view.h
+++ b/chromium/ui/views/window/custom_frame_view.h
@@ -5,9 +5,10 @@
#ifndef UI_VIEWS_WINDOW_CUSTOM_FRAME_VIEW_H_
#define UI_VIEWS_WINDOW_CUSTOM_FRAME_VIEW_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/window/frame_buttons.h"
@@ -144,7 +145,7 @@ class VIEWS_EXPORT CustomFrameView : public NonClientFrameView,
ImageButton* close_button_;
// Background painter for the window frame.
- scoped_ptr<FrameBackground> frame_background_;
+ std::unique_ptr<FrameBackground> frame_background_;
// The horizontal boundaries for the title bar to layout within. Restricted
// by the space used by the leading and trailing buttons.
diff --git a/chromium/ui/views/window/dialog_client_view.cc b/chromium/ui/views/window/dialog_client_view.cc
index 1d5c1f25205..55bf0047508 100644
--- a/chromium/ui/views/window/dialog_client_view.cc
+++ b/chromium/ui/views/window/dialog_client_view.cc
@@ -7,10 +7,12 @@
#include <algorithm>
#include "build/build_config.h"
+#include "ui/base/material_design/material_design_controller.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/blue_button.h"
#include "ui/views/controls/button/label_button.h"
+#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/layout/layout_constants.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"
@@ -58,9 +60,9 @@ DialogClientView::DialogClientView(Widget* owner, View* contents_view)
kButtonHEdgeMarginNew,
kButtonVEdgeMarginNew,
kButtonHEdgeMarginNew),
- ok_button_(NULL),
- cancel_button_(NULL),
- extra_view_(NULL),
+ ok_button_(nullptr),
+ cancel_button_(nullptr),
+ extra_view_(nullptr),
delegate_allowed_close_(false) {
// Doing this now ensures this accelerator will have lower priority than
// one set by the contents view.
@@ -98,7 +100,7 @@ void DialogClientView::UpdateDialogButtons() {
GetDialogDelegate()->UpdateButton(ok_button_, ui::DIALOG_BUTTON_OK);
} else if (ok_button_) {
delete ok_button_;
- ok_button_ = NULL;
+ ok_button_ = nullptr;
}
if (buttons & ui::DIALOG_BUTTON_CANCEL) {
@@ -110,7 +112,7 @@ void DialogClientView::UpdateDialogButtons() {
GetDialogDelegate()->UpdateButton(cancel_button_, ui::DIALOG_BUTTON_CANCEL);
} else if (cancel_button_) {
delete cancel_button_;
- cancel_button_ = NULL;
+ cancel_button_ = nullptr;
}
SetupFocusChain();
@@ -238,7 +240,7 @@ void DialogClientView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
// dialog style simply inherits the bubble's frame view color.
const DialogDelegate* dialog = GetDialogDelegate();
- if (dialog && !dialog->UseNewStyleForThisDialog()) {
+ if (dialog && !dialog->ShouldUseCustomFrame()) {
set_background(views::Background::CreateSolidBackground(GetNativeTheme()->
GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)));
}
@@ -264,10 +266,10 @@ void DialogClientView::ButtonPressed(Button* sender, const ui::Event& event) {
// DialogClientView, protected:
DialogClientView::DialogClientView(View* contents_view)
- : ClientView(NULL, contents_view),
- ok_button_(NULL),
- cancel_button_(NULL),
- extra_view_(NULL),
+ : ClientView(nullptr, contents_view),
+ ok_button_(nullptr),
+ cancel_button_(nullptr),
+ extra_view_(nullptr),
delegate_allowed_close_(false) {}
DialogDelegate* DialogClientView::GetDialogDelegate() const {
@@ -300,16 +302,13 @@ void DialogClientView::ChildVisibilityChanged(View* child) {
LabelButton* DialogClientView::CreateDialogButton(ui::DialogButton type) {
const base::string16 title = GetDialogDelegate()->GetDialogButtonLabel(type);
- LabelButton* button = NULL;
- if (GetDialogDelegate()->UseNewStyleForThisDialog() &&
- GetDialogDelegate()->GetDefaultDialogButton() == type &&
+ LabelButton* button = nullptr;
+ if (GetDialogDelegate()->GetDefaultDialogButton() == type &&
GetDialogDelegate()->ShouldDefaultButtonBeBlue()) {
- button = new BlueButton(this, title);
+ return MdTextButton::CreateSecondaryUiBlueButton(this, title);
} else {
- button = new LabelButton(this, title);
- button->SetStyle(Button::STYLE_BUTTON);
+ button = MdTextButton::CreateSecondaryUiButton(this, title);
}
- button->SetFocusable(true);
const int kDialogMinButtonWidth = 75;
button->SetMinSize(gfx::Size(kDialogMinButtonWidth, 0));
diff --git a/chromium/ui/views/window/dialog_client_view_unittest.cc b/chromium/ui/views/window/dialog_client_view_unittest.cc
index 9078aba9f17..c483d254af3 100644
--- a/chromium/ui/views/window/dialog_client_view_unittest.cc
+++ b/chromium/ui/views/window/dialog_client_view_unittest.cc
@@ -110,11 +110,11 @@ class DialogClientViewTest : public ViewsTestBase,
private:
// The DialogClientView that's being tested.
- scoped_ptr<TestDialogClientView> client_view_;
+ std::unique_ptr<TestDialogClientView> client_view_;
// The bitmask of buttons to show in the dialog.
int dialog_buttons_;
View* extra_view_; // weak
- scoped_ptr<int> extra_view_padding_; // Null by default.
+ std::unique_ptr<int> extra_view_padding_; // Null by default.
DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest);
};
diff --git a/chromium/ui/views/window/dialog_delegate.cc b/chromium/ui/views/window/dialog_delegate.cc
index 84ed6b9fc2e..d2271142430 100644
--- a/chromium/ui/views/window/dialog_delegate.cc
+++ b/chromium/ui/views/window/dialog_delegate.cc
@@ -29,7 +29,7 @@ namespace views {
////////////////////////////////////////////////////////////////////////////////
// DialogDelegate:
-DialogDelegate::DialogDelegate() : supports_new_style_(true) {}
+DialogDelegate::DialogDelegate() : supports_custom_frame_(true) {}
DialogDelegate::~DialogDelegate() {}
@@ -54,14 +54,14 @@ Widget* DialogDelegate::CreateDialogWidgetWithBounds(WidgetDelegate* delegate,
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// The new style doesn't support unparented dialogs on Linux desktop.
if (dialog)
- dialog->supports_new_style_ &= parent != NULL;
+ dialog->supports_custom_frame_ &= parent != NULL;
#elif defined(OS_WIN)
// The new style doesn't support unparented dialogs on Windows Classic themes.
if (dialog && !ui::win::IsAeroGlassEnabled())
- dialog->supports_new_style_ &= parent != NULL;
+ dialog->supports_custom_frame_ &= parent != NULL;
#endif
- if (!dialog || dialog->UseNewStyleForThisDialog()) {
+ if (!dialog || dialog->ShouldUseCustomFrame()) {
params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
params.remove_standard_frame = true;
#if !defined(OS_MACOSX)
@@ -181,7 +181,7 @@ ClientView* DialogDelegate::CreateClientView(Widget* widget) {
}
NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) {
- if (UseNewStyleForThisDialog())
+ if (ShouldUseCustomFrame())
return CreateDialogFrameView(widget);
return WidgetDelegate::CreateNonClientFrameView(widget);
}
@@ -193,7 +193,7 @@ NonClientFrameView* DialogDelegate::CreateDialogFrameView(Widget* widget) {
0, kButtonHEdgeMarginNew),
gfx::Insets());
const BubbleBorder::Shadow kShadow = BubbleBorder::SMALL_SHADOW;
- scoped_ptr<BubbleBorder> border(
+ std::unique_ptr<BubbleBorder> border(
new BubbleBorder(BubbleBorder::FLOAT, kShadow, gfx::kPlaceholderColor));
border->set_use_theme_background_color(true);
frame->SetBubbleBorder(std::move(border));
@@ -203,8 +203,8 @@ NonClientFrameView* DialogDelegate::CreateDialogFrameView(Widget* widget) {
return frame;
}
-bool DialogDelegate::UseNewStyleForThisDialog() const {
- return supports_new_style_;
+bool DialogDelegate::ShouldUseCustomFrame() const {
+ return supports_custom_frame_;
}
const DialogClientView* DialogDelegate::GetDialogClientView() const {
diff --git a/chromium/ui/views/window/dialog_delegate.h b/chromium/ui/views/window/dialog_delegate.h
index 06c9bbe6b93..b6532dc44bc 100644
--- a/chromium/ui/views/window/dialog_delegate.h
+++ b/chromium/ui/views/window/dialog_delegate.h
@@ -102,8 +102,10 @@ class VIEWS_EXPORT DialogDelegate : public ui::DialogModel,
// Create a frame view using the new dialog style.
static NonClientFrameView* CreateDialogFrameView(Widget* widget);
- // Returns whether this particular dialog should use the new dialog style.
- virtual bool UseNewStyleForThisDialog() const;
+ // Returns true if this particular dialog should use a Chrome-styled frame
+ // like the one used for bubbles. The alternative is a more platform-native
+ // frame.
+ virtual bool ShouldUseCustomFrame() const;
// A helper for accessing the DialogClientView object contained by this
// delegate's Window.
@@ -115,8 +117,9 @@ class VIEWS_EXPORT DialogDelegate : public ui::DialogModel,
ui::AXRole GetAccessibleWindowRole() const override;
private:
- // A flag indicating whether this dialog supports the new style.
- bool supports_new_style_;
+ // A flag indicating whether this dialog is able to use the custom frame
+ // style for dialogs.
+ bool supports_custom_frame_;
};
// A DialogDelegate implementation that is-a View. Used to override GetWidget()
diff --git a/chromium/ui/views/window/dialog_delegate_unittest.cc b/chromium/ui/views/window/dialog_delegate_unittest.cc
index 8dd6e231cf0..648175d8d23 100644
--- a/chromium/ui/views/window/dialog_delegate_unittest.cc
+++ b/chromium/ui/views/window/dialog_delegate_unittest.cc
@@ -70,7 +70,7 @@ class TestDialog : public DialogDelegateView, public ButtonListener {
}
base::string16 GetWindowTitle() const override { return title_; }
View* GetInitiallyFocusedView() override { return input_; }
- bool UseNewStyleForThisDialog() const override { return true; }
+ bool ShouldUseCustomFrame() const override { return true; }
// ButtonListener override:
void ButtonPressed(Button* sender, const ui::Event& event) override {
diff --git a/chromium/ui/views/window/non_client_view.cc b/chromium/ui/views/window/non_client_view.cc
index a6d38a24f4c..1cb6bc374c0 100644
--- a/chromium/ui/views/window/non_client_view.cc
+++ b/chromium/ui/views/window/non_client_view.cc
@@ -43,9 +43,10 @@ bool NonClientFrameView::GetClientMask(const gfx::Size& size,
NonClientView::NonClientView()
: client_view_(nullptr),
+ mirror_client_in_rtl_(true),
overlay_view_(nullptr) {
SetEventTargeter(
- scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
+ std::unique_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
}
NonClientView::~NonClientView() {
@@ -165,7 +166,14 @@ void NonClientView::Layout() {
LayoutFrameView();
// Then layout the ClientView, using those bounds.
- client_view_->SetBoundsRect(frame_view_->GetBoundsForClientView());
+ gfx::Rect client_bounds = frame_view_->GetBoundsForClientView();
+
+ // RTL code will mirror the ClientView in the frame by default. If this isn't
+ // desired, do a second mirror here to get the standard LTR position.
+ if (base::i18n::IsRTL() && !mirror_client_in_rtl_)
+ client_bounds.set_x(GetMirroredXForRect(client_bounds));
+
+ client_view_->SetBoundsRect(client_bounds);
gfx::Path client_clip;
if (frame_view_->GetClientMask(client_view_->size(), &client_clip))
@@ -324,7 +332,7 @@ const char* NonClientFrameView::GetClassName() const {
NonClientFrameView::NonClientFrameView()
: active_state_override_(nullptr) {
SetEventTargeter(
- scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
+ std::unique_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
}
// ViewTargeterDelegate:
diff --git a/chromium/ui/views/window/non_client_view.h b/chromium/ui/views/window/non_client_view.h
index 40000243b30..74209869f26 100644
--- a/chromium/ui/views/window/non_client_view.h
+++ b/chromium/ui/views/window/non_client_view.h
@@ -220,6 +220,8 @@ class VIEWS_EXPORT NonClientView : public View, public ViewTargeterDelegate {
client_view_ = client_view;
}
+ void set_mirror_client_in_rtl(bool mirror) { mirror_client_in_rtl_ = mirror; }
+
// Layout just the frame view. This is necessary on Windows when non-client
// metrics such as the position of the window controls changes independently
// of a window resize message.
@@ -252,10 +254,13 @@ class VIEWS_EXPORT NonClientView : public View, public ViewTargeterDelegate {
// implementation.
ClientView* client_view_;
+ // Set to false if client_view_ position shouldn't be mirrored in RTL.
+ bool mirror_client_in_rtl_;
+
// The NonClientFrameView that renders the non-client portions of the window.
// This object is not owned by the view hierarchy because it can be replaced
// dynamically as the system settings change.
- scoped_ptr<NonClientFrameView> frame_view_;
+ std::unique_ptr<NonClientFrameView> frame_view_;
// The overlay view, when non-NULL and visible, takes up the entire widget and
// is placed on top of the ClientView and NonClientFrameView.