diff options
-rw-r--r-- | ui/views/corewm/corewm_switches.cc | 9 | ||||
-rw-r--r-- | ui/views/corewm/corewm_switches.h | 3 | ||||
-rw-r--r-- | ui/views/views.gyp | 2 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_focus_rules.cc | 20 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_focus_rules.h | 26 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_native_widget_aura.cc | 36 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc | 23 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_root_window_host_win.cc | 23 | ||||
-rw-r--r-- | ui/views/widget/widget_unittest.cc | 2 |
9 files changed, 120 insertions, 24 deletions
diff --git a/ui/views/corewm/corewm_switches.cc b/ui/views/corewm/corewm_switches.cc index 02c526f..fdeb126 100644 --- a/ui/views/corewm/corewm_switches.cc +++ b/ui/views/corewm/corewm_switches.cc @@ -14,6 +14,10 @@ namespace switches { // CoreWM FocusController. const char kDisableFocusController[] = "disable-focus-controller"; +// When set uses the FocusController in desktop mode. +const char kEnableFocusControllerOnDesktop[] = + "enable-focus-controller-on-desktop"; + // If present animations are disabled. const char kWindowAnimationsDisabled[] = "views-corewm-window-animations-disabled"; @@ -25,5 +29,10 @@ bool UseFocusController() { switches::kDisableFocusController); } +bool UseFocusControllerOnDesktop() { + return CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableFocusControllerOnDesktop); +} + } // namespace corewm } // namespace views diff --git a/ui/views/corewm/corewm_switches.h b/ui/views/corewm/corewm_switches.h index 5eed9f8..a9f452d 100644 --- a/ui/views/corewm/corewm_switches.h +++ b/ui/views/corewm/corewm_switches.h @@ -25,6 +25,9 @@ VIEWS_EXPORT extern const char kWindowAnimationsDisabled[]; // Activation/FocusClient. VIEWS_EXPORT bool UseFocusController(); +// Same as above but for Desktop mode. +VIEWS_EXPORT bool UseFocusControllerOnDesktop(); + } // namespace corewm } // namespace views diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 00d6297..1d027b2 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -351,6 +351,8 @@ 'widget/desktop_aura/desktop_drag_drop_client_win.h', 'widget/desktop_aura/desktop_drop_target_win.cc', 'widget/desktop_aura/desktop_drop_target_win.h', + 'widget/desktop_aura/desktop_focus_rules.cc', + 'widget/desktop_aura/desktop_focus_rules.h', 'widget/desktop_aura/desktop_layout_manager.cc', 'widget/desktop_aura/desktop_layout_manager.h', 'widget/desktop_aura/desktop_native_widget_aura.cc', diff --git a/ui/views/widget/desktop_aura/desktop_focus_rules.cc b/ui/views/widget/desktop_aura/desktop_focus_rules.cc new file mode 100644 index 0000000..54894f8 --- /dev/null +++ b/ui/views/widget/desktop_aura/desktop_focus_rules.cc @@ -0,0 +1,20 @@ +// 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/widget/desktop_aura/desktop_focus_rules.h" + +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" + +namespace views { + +DesktopFocusRules::DesktopFocusRules() {} +DesktopFocusRules::~DesktopFocusRules() {} + +bool DesktopFocusRules::SupportsChildActivation(aura::Window* window) const { + // In Desktop-Aura, only children of the RootWindow are activatable. + return window->GetRootWindow() == window; +} + +} // namespace views diff --git a/ui/views/widget/desktop_aura/desktop_focus_rules.h b/ui/views/widget/desktop_aura/desktop_focus_rules.h new file mode 100644 index 0000000..a7db8c2 --- /dev/null +++ b/ui/views/widget/desktop_aura/desktop_focus_rules.h @@ -0,0 +1,26 @@ +// 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_WIDGET_DESKTOP_FOCUS_RULES_H_ +#define UI_VIEWS_WIDGET_DESKTOP_FOCUS_RULES_H_ + +#include "ui/views/corewm/base_focus_rules.h" + +namespace views { + +class DesktopFocusRules : public corewm::BaseFocusRules { + public: + DesktopFocusRules(); + virtual ~DesktopFocusRules(); + + private: + // Overridden from corewm::BaseFocusRules: + virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(DesktopFocusRules); +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_DESKTOP_FOCUS_RULES_H_ diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index baa3dbe..bc4b1a4 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc @@ -16,6 +16,7 @@ #include "ui/gfx/canvas.h" #include "ui/native_theme/native_theme.h" #include "ui/views/corewm/compound_event_filter.h" +#include "ui/views/corewm/corewm_switches.h" #include "ui/views/corewm/input_method_event_filter.h" #include "ui/views/drag_utils.h" #include "ui/views/ime/input_method.h" @@ -437,7 +438,7 @@ void DesktopNativeWidgetAura::SetCursor(gfx::NativeCursor cursor) { void DesktopNativeWidgetAura::ClearNativeFocus() { desktop_root_window_host_->ClearNativeFocus(); - aura::client::GetFocusClient(window_)->FocusWindow(window_); + aura::client::GetFocusClient(window_)->ResetFocusWithinActiveWindow(window_); } gfx::Rect DesktopNativeWidgetAura::GetWorkAreaBoundsInScreen() const { @@ -632,23 +633,28 @@ void DesktopNativeWidgetAura::OnWindowActivated(aura::Window* gained_active, restore_focus_on_activate_ = false; GetWidget()->GetFocusManager()->RestoreFocusedView(); } else if (lost_active == window_ && GetWidget()->HasFocusManager()) { - // If we're losing focus to a window that is a top level (such as a bubble) - // store the focus. Such a window shares the same RootWindowHost, so that - // such a change won't trigger an activation change (which calls - // StoreFocusedView()). Without this the focused view is never told it lost - // focus. - aura::Window* focused_window = + bool store_focused_view = corewm::UseFocusControllerOnDesktop(); + if (!store_focused_view) { + // If we're losing focus to a window that is a top level (such as a + // bubble) store the focus. Such a window shares the same + // RootWindowHost, so that such a change won't trigger an activation + // change (which calls StoreFocusedView()). Without this the focused + // view is never told it lost focus. + aura::Window* focused_window = aura::client::GetFocusClient(window_)->GetFocusedWindow(); - if (focused_window && focused_window != window_) { - Widget* focused_widget = Widget::GetWidgetForNativeWindow(focused_window); - if (focused_widget && focused_widget != GetWidget() && - focused_widget->is_top_level()) { - DCHECK(!restore_focus_on_activate_); - restore_focus_on_activate_ = true; - // Pass in false so that ClearNativeFocus() isn't invoked. - GetWidget()->GetFocusManager()->StoreFocusedView(false); + if (focused_window && focused_window != window_) { + Widget* focused_widget = + Widget::GetWidgetForNativeWindow(focused_window); + store_focused_view = focused_widget && focused_widget != GetWidget() && + focused_widget->is_top_level(); } } + if (store_focused_view) { + DCHECK(!restore_focus_on_activate_); + restore_focus_on_activate_ = true; + // Pass in false so that ClearNativeFocus() isn't invoked. + GetWidget()->GetFocusManager()->StoreFocusedView(false); + } } } diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc index e487e47..3df42ec9 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc @@ -23,10 +23,13 @@ #include "ui/base/x/x11_util.h" #include "ui/native_theme/native_theme.h" #include "ui/views/corewm/compound_event_filter.h" +#include "ui/views/corewm/corewm_switches.h" +#include "ui/views/corewm/focus_controller.h" #include "ui/views/ime/input_method.h" #include "ui/views/widget/desktop_aura/desktop_activation_client.h" #include "ui/views/widget/desktop_aura/desktop_cursor_client.h" #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" +#include "ui/views/widget/desktop_aura/desktop_focus_rules.h" #include "ui/views/widget/desktop_aura/desktop_layout_manager.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" @@ -91,6 +94,10 @@ DesktopRootWindowHostLinux::DesktopRootWindowHostLinux( DesktopRootWindowHostLinux::~DesktopRootWindowHostLinux() { root_window_->ClearProperty(kHostForRootWindow); + if (corewm::UseFocusControllerOnDesktop()) { + aura::client::SetFocusClient(root_window_, NULL); + aura::client::SetActivationClient(root_window_, NULL); + } } // static @@ -214,10 +221,18 @@ aura::RootWindow* DesktopRootWindowHostLinux::InitRootWindow( // messages to us. X11DesktopHandler::get(); - focus_client_.reset(new aura::FocusManager); - aura::client::SetFocusClient(root_window_, focus_client_.get()); - - activation_client_.reset(new DesktopActivationClient(root_window_)); + if (corewm::UseFocusControllerOnDesktop()) { + corewm::FocusController* focus_controller = + new corewm::FocusController(new DesktopFocusRules); + focus_client_.reset(focus_controller); + aura::client::SetFocusClient(root_window_, focus_controller); + aura::client::SetActivationClient(root_window_, focus_controller); + root_window_->AddPreTargetHandler(focus_controller); + } else { + focus_client_.reset(new aura::FocusManager); + aura::client::SetFocusClient(root_window_, focus_client_.get()); + activation_client_.reset(new DesktopActivationClient(root_window_)); + } dispatcher_client_.reset(new DesktopDispatcherClient); aura::client::SetDispatcherClient(root_window_, diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc index e9fc62f..c422d13 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc @@ -19,12 +19,15 @@ #include "ui/native_theme/native_theme_aura.h" #include "ui/native_theme/native_theme_win.h" #include "ui/views/corewm/compound_event_filter.h" +#include "ui/views/corewm/corewm_switches.h" +#include "ui/views/corewm/focus_controller.h" #include "ui/views/corewm/input_method_event_filter.h" #include "ui/views/ime/input_method_bridge.h" #include "ui/views/widget/desktop_aura/desktop_activation_client.h" #include "ui/views/widget/desktop_aura/desktop_cursor_client.h" #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_win.h" +#include "ui/views/widget/desktop_aura/desktop_focus_rules.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" #include "ui/views/widget/root_view.h" @@ -54,6 +57,10 @@ DesktopRootWindowHostWin::DesktopRootWindowHostWin( } DesktopRootWindowHostWin::~DesktopRootWindowHostWin() { + if (corewm::UseFocusControllerOnDesktop()) { + aura::client::SetFocusClient(root_window_, NULL); + aura::client::SetActivationClient(root_window_, NULL); + } } // static @@ -118,10 +125,18 @@ aura::RootWindow* DesktopRootWindowHostWin::Init( capture_client_.reset(new aura::client::DefaultCaptureClient(root_window_)); aura::client::SetCaptureClient(root_window_, capture_client_.get()); - focus_client_.reset(new aura::FocusManager); - aura::client::SetFocusClient(root_window_, focus_client_.get()); - - activation_client_.reset(new DesktopActivationClient(root_window_)); + if (corewm::UseFocusControllerOnDesktop()) { + corewm::FocusController* focus_controller = + new corewm::FocusController(new DesktopFocusRules); + focus_client_.reset(focus_controller); + aura::client::SetFocusClient(root_window_, focus_controller); + aura::client::SetActivationClient(root_window_, focus_controller); + root_window_->AddPreTargetHandler(focus_controller); + } else { + focus_client_.reset(new aura::FocusManager); + aura::client::SetFocusClient(root_window_, focus_client_.get()); + activation_client_.reset(new DesktopActivationClient(root_window_)); + } dispatcher_client_.reset(new DesktopDispatcherClient); aura::client::SetDispatcherClient(root_window_, diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index 6e6ed07..b72984b 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc @@ -1184,7 +1184,7 @@ TEST_F(WidgetTest, FocusChangesOnBubble) { contents_view->RequestFocus(); EXPECT_TRUE(contents_view->HasFocus()); - // Show a buble. + // Show a bubble. BubbleDelegateView* bubble_delegate_view = new BubbleDelegateView(contents_view, BubbleBorder::TOP_LEFT); bubble_delegate_view->set_focusable(true); |