diff options
author | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 22:59:14 +0000 |
---|---|---|
committer | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-14 22:59:14 +0000 |
commit | 627a62fd16973c166e6b3039eccda92a7253bd77 (patch) | |
tree | ce56d6682469c3c0e710f675b8f9a254f9c49f37 | |
parent | 1243f0537d891f9ee5d803ffac94045c9b591f49 (diff) | |
download | chromium_src-627a62fd16973c166e6b3039eccda92a7253bd77.zip chromium_src-627a62fd16973c166e6b3039eccda92a7253bd77.tar.gz chromium_src-627a62fd16973c166e6b3039eccda92a7253bd77.tar.bz2 |
aura: Hide cursor during and after shutdown.
This updates the semantics of aura::RootWindow::ShowCursor()
so that after the cursor is hidden, it remains hidden during
subsequent calls to SetCursor().
It also makes us not show the cursor on mouse movement if
we're in the process of shutting down.
Finally, it makes us set an invisible cursor on the root
window when running on a Chrome OS device so that the cursor
will remain hidden after Chrome has exited during shutdown.
BUG=111884
TEST=manual: can't see cursor while shutting down now
Review URL: http://codereview.chromium.org/9388030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121960 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/shell.cc | 7 | ||||
-rw-r--r-- | ash/shell.h | 6 | ||||
-rw-r--r-- | ash/wm/power_button_controller.cc | 2 | ||||
-rw-r--r-- | ash/wm/root_window_event_filter.cc | 12 | ||||
-rw-r--r-- | ash/wm/root_window_event_filter.h | 8 | ||||
-rw-r--r-- | ash/wm/root_window_event_filter_unittest.cc | 34 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_main_extra_parts_aura.cc | 1 | ||||
-rw-r--r-- | chrome/browser/chromeos/chrome_browser_main_chromeos.cc | 8 | ||||
-rw-r--r-- | ui/aura/root_window.cc | 3 | ||||
-rw-r--r-- | ui/aura/root_window.h | 23 | ||||
-rw-r--r-- | ui/aura/root_window_host.h | 10 | ||||
-rw-r--r-- | ui/aura/root_window_host_linux.cc | 54 |
12 files changed, 121 insertions, 47 deletions
diff --git a/ash/shell.cc b/ash/shell.cc index 4cd6ed9..c1db664 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -198,7 +198,8 @@ Shell* Shell::instance_ = NULL; // Shell, public: Shell::Shell(ShellDelegate* delegate) - : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), + : root_filter_(new internal::RootWindowEventFilter), + ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), #if !defined(OS_MACOSX) nested_dispatcher_controller_(new NestedDispatcherController), accelerator_controller_(new AcceleratorController), @@ -209,8 +210,8 @@ Shell::Shell(ShellDelegate* delegate) window_mode_(MODE_OVERLAPPING), root_window_layout_(NULL), status_widget_(NULL) { - aura::RootWindow::GetInstance()->SetEventFilter( - new internal::RootWindowEventFilter); + // Pass ownership of the filter to the root window. + aura::RootWindow::GetInstance()->SetEventFilter(root_filter_); } Shell::~Shell() { diff --git a/ash/shell.h b/ash/shell.h index 67c4fc6..ca21b9f 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -50,6 +50,7 @@ class AppList; class DragDropController; class FocusCycler; class InputMethodEventFilter; +class RootWindowEventFilter; class RootWindowLayoutManager; class ShadowController; class ShelfLayoutManager; @@ -148,6 +149,9 @@ class ASH_EXPORT Shell { } #endif // !defined(OS_MACOSX) + internal::RootWindowEventFilter* root_filter() { + return root_filter_; + } internal::TooltipController* tooltip_controller() { return tooltip_controller_.get(); } @@ -199,6 +203,8 @@ class ASH_EXPORT Shell { static Shell* instance_; + internal::RootWindowEventFilter* root_filter_; // not owned + std::vector<WindowAndBoundsPair> to_restore_; base::WeakPtrFactory<Shell> method_factory_; diff --git a/ash/wm/power_button_controller.cc b/ash/wm/power_button_controller.cc index f41d9c4..c057b20 100644 --- a/ash/wm/power_button_controller.cc +++ b/ash/wm/power_button_controller.cc @@ -7,6 +7,7 @@ #include "ash/ash_switches.h" #include "ash/shell.h" #include "ash/shell_window_ids.h" +#include "ash/wm/root_window_event_filter.h" #include "base/command_line.h" #include "base/logging.h" #include "base/time.h" @@ -473,6 +474,7 @@ void PowerButtonController::OnLockToShutdownTimeout() { void PowerButtonController::OnShutdownTimeout() { DCHECK(!shutting_down_); shutting_down_ = true; + ash::Shell::GetInstance()->root_filter()->set_update_cursor_visibility(false); aura::RootWindow::GetInstance()->ShowCursor(false); StartAnimation(ALL_CONTAINERS, ANIMATION_FAST_CLOSE); real_shutdown_timer_.Start( diff --git a/ash/wm/root_window_event_filter.cc b/ash/wm/root_window_event_filter.cc index 6739e8c..a48fc7f 100644 --- a/ash/wm/root_window_event_filter.cc +++ b/ash/wm/root_window_event_filter.cc @@ -6,6 +6,7 @@ #include "ash/shell.h" #include "ash/wm/activation_controller.h" +#include "ash/wm/power_button_controller.h" #include "ash/wm/window_util.h" #include "ui/aura/event.h" #include "ui/aura/focus_manager.h" @@ -43,7 +44,8 @@ gfx::NativeCursor CursorForWindowComponent(int window_component) { //////////////////////////////////////////////////////////////////////////////// // RootWindowEventFilter, public: -RootWindowEventFilter::RootWindowEventFilter() { +RootWindowEventFilter::RootWindowEventFilter() + : update_cursor_visibility_(true) { } RootWindowEventFilter::~RootWindowEventFilter() { @@ -77,8 +79,8 @@ bool RootWindowEventFilter::PreHandleMouseEvent(aura::Window* target, // We must always update the cursor, otherwise the cursor can get stuck if an // event filter registered with us consumes the event. if (event->type() == ui::ET_MOUSE_MOVED) { - // Shows the cursor when mouse moved. - SetCursorVisible(target, event, true); + if (update_cursor_visibility_) + SetCursorVisible(target, event, true); UpdateCursor(target, event); } @@ -100,8 +102,8 @@ ui::TouchStatus RootWindowEventFilter::PreHandleTouchEvent( return status; if (event->type() == ui::ET_TOUCH_PRESSED) { - // Hides the cursor when touch pressed. - SetCursorVisible(target, event, false); + if (update_cursor_visibility_) + SetCursorVisible(target, event, false); target->GetFocusManager()->SetFocusedWindow(target); } diff --git a/ash/wm/root_window_event_filter.h b/ash/wm/root_window_event_filter.h index 0eb552c..8801f3d 100644 --- a/ash/wm/root_window_event_filter.h +++ b/ash/wm/root_window_event_filter.h @@ -28,6 +28,10 @@ class ASH_EXPORT RootWindowEventFilter : public aura::EventFilter { RootWindowEventFilter(); virtual ~RootWindowEventFilter(); + void set_update_cursor_visibility(bool update) { + update_cursor_visibility_ = update; + } + // Adds/removes additional event filters. void AddFilter(aura::EventFilter* filter); void RemoveFilter(aura::EventFilter* filter); @@ -64,6 +68,10 @@ class ASH_EXPORT RootWindowEventFilter : public aura::EventFilter { // Additional event filters that pre-handles events. ObserverList<aura::EventFilter, true> filters_; + // Should we show the mouse cursor when we see mouse movement and hide it when + // we see a touch event? + bool update_cursor_visibility_; + DISALLOW_COPY_AND_ASSIGN(RootWindowEventFilter); }; diff --git a/ash/wm/root_window_event_filter_unittest.cc b/ash/wm/root_window_event_filter_unittest.cc index 25e0a17..9cd2829 100644 --- a/ash/wm/root_window_event_filter_unittest.cc +++ b/ash/wm/root_window_event_filter_unittest.cc @@ -464,5 +464,39 @@ TEST_F(RootWindowEventFilterTest, AdditionalFilters) { root_window_filter->RemoveFilter(f2.get()); } +// We should show and hide the cursor in response to mouse and touch events as +// requested. +TEST_F(RootWindowEventFilterTest, UpdateCursorVisibility) { + aura::RootWindow* root_window = aura::RootWindow::GetInstance(); + root_window->SetBounds(gfx::Rect(0, 0, 500, 500)); + scoped_ptr<aura::Window> window(aura::test::CreateTestWindow( + SK_ColorWHITE, -1, gfx::Rect(0, 0, 500, 500), NULL)); + + internal::RootWindowEventFilter* root_window_filter = + static_cast<internal::RootWindowEventFilter*>( + root_window->event_filter()); + + aura::MouseEvent mouse_moved( + ui::ET_MOUSE_MOVED, gfx::Point(0, 0), gfx::Point(0, 0), 0x0); + aura::TouchEvent touch_pressed( + ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0); + + root_window_filter->set_update_cursor_visibility(true); + root_window->DispatchMouseEvent(&mouse_moved); + EXPECT_TRUE(root_window->cursor_shown()); + root_window->DispatchTouchEvent(&touch_pressed); + EXPECT_FALSE(root_window->cursor_shown()); + root_window->DispatchMouseEvent(&mouse_moved); + EXPECT_TRUE(root_window->cursor_shown()); + + root_window_filter->set_update_cursor_visibility(false); + root_window->ShowCursor(false); + root_window->DispatchMouseEvent(&mouse_moved); + EXPECT_FALSE(root_window->cursor_shown()); + root_window->ShowCursor(true); + root_window->DispatchTouchEvent(&touch_pressed); + EXPECT_TRUE(root_window->cursor_shown()); +} + } // namespace test } // namespace ash diff --git a/chrome/browser/chrome_browser_main_extra_parts_aura.cc b/chrome/browser/chrome_browser_main_extra_parts_aura.cc index 4c32941..8bc4192 100644 --- a/chrome/browser/chrome_browser_main_extra_parts_aura.cc +++ b/chrome/browser/chrome_browser_main_extra_parts_aura.cc @@ -36,6 +36,7 @@ void ChromeBrowserMainExtraPartsAura::PreProfileInit() { #if defined(OS_CHROMEOS) if (chromeos::system::runtime_environment::IsRunningOnChromeOS()) aura::RootWindow::set_use_fullscreen_host_window(true); + aura::RootWindow::set_hide_host_cursor(true); #endif // Shell takes ownership of ChromeShellDelegate. diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 74a7ff7..d1cf8b2 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -310,13 +310,13 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() { // with a small keyboard, u, i, o, p, ... keys might be repurposed as // cursor keys when Num Lock is on). #if defined(GOOGLE_CHROME_BUILD) - chromeos::input_method::InputMethodManager::GetInstance()-> - GetXKeyboard()->SetNumLockEnabled(true); + chromeos::input_method::InputMethodManager::GetInstance()-> + GetXKeyboard()->SetNumLockEnabled(true); #endif #if defined(USE_AURA) - initial_browser_window_observer_.reset( - new chromeos::InitialBrowserWindowObserver); + initial_browser_window_observer_.reset( + new chromeos::InitialBrowserWindowObserver); #endif } diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc index bd545ad..5182e4c 100644 --- a/ui/aura/root_window.cc +++ b/ui/aura/root_window.cc @@ -65,6 +65,7 @@ void GetEventFiltersToNotify(Window* target, EventFilters* filters) { RootWindow* RootWindow::instance_ = NULL; bool RootWindow::use_fullscreen_host_window_ = false; +bool RootWindow::hide_host_cursor_ = false; //////////////////////////////////////////////////////////////////////////////// // RootWindow, public: @@ -109,6 +110,7 @@ void RootWindow::SetCursor(gfx::NativeCursor cursor) { } void RootWindow::ShowCursor(bool show) { + cursor_shown_ = show; host_->ShowCursor(show); } @@ -456,6 +458,7 @@ RootWindow::RootWindow() ALLOW_THIS_IN_INITIALIZER_LIST(event_factory_(this)), mouse_button_flags_(0), last_cursor_(kCursorNull), + cursor_shown_(true), screen_(new ScreenAura), capture_window_(NULL), mouse_pressed_handler_(NULL), diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h index 3cfec4e..7396059 100644 --- a/ui/aura/root_window.h +++ b/ui/aura/root_window.h @@ -58,9 +58,17 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, return use_fullscreen_host_window_; } + static void set_hide_host_cursor(bool hide) { + hide_host_cursor_ = hide; + } + static bool hide_host_cursor() { + return hide_host_cursor_; + } + ui::Compositor* compositor() { return compositor_.get(); } gfx::Point last_mouse_location() const { return last_mouse_location_; } gfx::NativeCursor last_cursor() const { return last_cursor_; } + bool cursor_shown() const { return cursor_shown_; } Window* mouse_pressed_handler() { return mouse_pressed_handler_; } Window* capture_window() { return capture_window_; } ScreenAura* screen() { return screen_; } @@ -72,10 +80,13 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, void SetHostSize(const gfx::Size& size); gfx::Size GetHostSize() const; - // Shows the specified cursor. + // Sets the currently-displayed cursor. If the cursor was previously hidden + // via ShowCursor(false), it will remain hidden until ShowCursor(true) is + // called, at which point the cursor that was last set via SetCursor() will be + // used. void SetCursor(gfx::NativeCursor cursor); - // Sets current cursor visibility to |show|. + // Shows or hides the cursor. void ShowCursor(bool show); // Moves the cursor to the specified location relative to the root window. @@ -260,6 +271,11 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, // switches::kAuraHostWindowSize flag. static bool use_fullscreen_host_window_; + // If set before the RootWindow is created, the cursor will be drawn within + // the Aura root window but hidden outside of it, and it'll remain hidden + // after the Aura window is closed. + static bool hide_host_cursor_; + // Used to schedule painting. base::WeakPtrFactory<RootWindow> schedule_paint_factory_; @@ -275,6 +291,9 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate, // Last cursor set. Used for testing. gfx::NativeCursor last_cursor_; + // Is the cursor currently shown? Used for testing. + bool cursor_shown_; + ObserverList<RootWindowObserver> observers_; ScreenAura* screen_; diff --git a/ui/aura/root_window_host.h b/ui/aura/root_window_host.h index 551aaf9..a6c7c53 100644 --- a/ui/aura/root_window_host.h +++ b/ui/aura/root_window_host.h @@ -58,18 +58,16 @@ class RootWindowHost : public MessageLoop::Dispatcher { // Returns the location of the RootWindow on native screen. virtual gfx::Point GetLocationOnNativeScreen() const = 0; - // Set the OS capture to the root window. + // Sets the OS capture to the root window. virtual void SetCapture() = 0; - // Release OS capture of the root window. + // Releases OS capture of the root window. virtual void ReleaseCapture() = 0; - // Sets the currently displayed cursor. Shows the cursor by default. - // If you want to update hidden cursor, should call ShowCursor(false) - // after this function. + // Sets the currently displayed cursor. virtual void SetCursor(gfx::NativeCursor cursor) = 0; - // Sets current cursor visibility to |show|. + // Shows or hides the cursor. virtual void ShowCursor(bool show) = 0; // Queries the mouse's current position relative to the host window. diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc index 67655fe..cf5d762 100644 --- a/ui/aura/root_window_host_linux.cc +++ b/ui/aura/root_window_host_linux.cc @@ -309,6 +309,10 @@ class RootWindowHostLinux : public RootWindowHost, // detect that they're there. bool IsWindowManagerPresent(); + // Sets the cursor on |xwindow_| to |cursor|. Does not check or update + // |current_cursor_|. + void SetCursorInternal(gfx::NativeCursor cursor); + RootWindow* root_window_; // The display and the native X window hosting the root window. @@ -321,9 +325,8 @@ class RootWindowHostLinux : public RootWindowHost, // Current Aura cursor. gfx::NativeCursor current_cursor_; - // The default cursor is showed after startup, and hidden when touch pressed. - // Once mouse moved, the cursor is immediately displayed. - bool is_cursor_visible_; + // Is the cursor currently shown? + bool cursor_shown_; // The invisible cursor. ::Cursor invisible_cursor_; @@ -340,7 +343,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) xwindow_(0), x_root_window_(DefaultRootWindow(xdisplay_)), current_cursor_(aura::kCursorNull), - is_cursor_visible_(true), + cursor_shown_(true), bounds_(bounds) { XSetWindowAttributes swa; memset(&swa, 0, sizeof(swa)); @@ -371,7 +374,7 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) base::MessagePumpX::SetDefaultDispatcher(this); MessageLoopForUI::current()->AddDestructionObserver(this); - // Initializes invisiable cursor. + // Initialize invisible cursor. char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; XColor black; black.red = black.green = black.blue = 0; @@ -379,6 +382,8 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) nodata, 8, 8); invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, &black, &black, 0, 0); + if (RootWindow::hide_host_cursor()) + XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_); } RootWindowHostLinux::~RootWindowHostLinux() { @@ -603,36 +608,23 @@ void RootWindowHostLinux::ReleaseCapture() { } void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { - if (cursor == kCursorNone && is_cursor_visible_) { - current_cursor_ = cursor; - ShowCursor(false); - return; - } - - if (current_cursor_ == cursor) + if (cursor == current_cursor_) return; current_cursor_ = cursor; + // Custom web cursors are handled directly. if (cursor == kCursorCustom) return; - int cursor_shape = CursorShapeFromNative(cursor); - ::Cursor xcursor = ui::GetXCursor(cursor_shape); - XDefineCursor(xdisplay_, xwindow_, xcursor); + + if (cursor_shown_) + SetCursorInternal(cursor); } void RootWindowHostLinux::ShowCursor(bool show) { - if (show == is_cursor_visible_) - return; - - is_cursor_visible_ = show; - - if (show) { - int cursor_shape = CursorShapeFromNative(current_cursor_); - ::Cursor xcursor = ui::GetXCursor(cursor_shape); - XDefineCursor(xdisplay_, xwindow_, xcursor); - } else { - XDefineCursor(xdisplay_, xwindow_, invisible_cursor_); - } + if (show == cursor_shown_) + return; + cursor_shown_ = show; + SetCursorInternal(show ? current_cursor_ : kCursorNone); } gfx::Point RootWindowHostLinux::QueryMouseLocation() { @@ -715,6 +707,14 @@ bool RootWindowHostLinux::IsWindowManagerPresent() { return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None; } +void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { + ::Cursor xcursor = + cursor == kCursorNone ? + invisible_cursor_ : + ui::GetXCursor(CursorShapeFromNative(cursor)); + XDefineCursor(xdisplay_, xwindow_, xcursor); +} + } // namespace // static |