diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-06 14:33:57 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-06 14:33:57 +0000 |
commit | 5e6ae79b96d96b38bad9d20fcf0987399bded674 (patch) | |
tree | b996a6cad2dfe99e32d38a80724085a818ddeee5 /ui | |
parent | 595b6cbe2df8248644ff7119a871bd1ed1991392 (diff) | |
download | chromium_src-5e6ae79b96d96b38bad9d20fcf0987399bded674.zip chromium_src-5e6ae79b96d96b38bad9d20fcf0987399bded674.tar.gz chromium_src-5e6ae79b96d96b38bad9d20fcf0987399bded674.tar.bz2 |
Makes MouseWatcher work while in metro mode
I'm changing the aura implementation to use
Env::AddPreTargetListener. This way I don't need MessageLoop specific
code and it'll work correctly for win on both metro and non-metro.
BUG=315155
TEST=none
R=ben@chromium.org
Review URL: https://codereview.chromium.org/60443003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233270 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/views/mouse_watcher.cc | 92 | ||||
-rw-r--r-- | ui/views/views.gyp | 2 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_event_client.cc | 26 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_event_client.h | 31 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_native_widget_aura.cc | 7 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/desktop_native_widget_aura.h | 2 |
6 files changed, 142 insertions, 18 deletions
diff --git a/ui/views/mouse_watcher.cc b/ui/views/mouse_watcher.cc index 5a2b4bd..bee5984 100644 --- a/ui/views/mouse_watcher.cc +++ b/ui/views/mouse_watcher.cc @@ -13,12 +13,20 @@ #include "ui/events/event_utils.h" #include "ui/gfx/screen.h" +#if defined(USE_AURA) +#include "ui/aura/env.h" +#include "ui/aura/window.h" +#include "ui/events/event.h" +#include "ui/events/event_handler.h" +#endif + namespace views { // Amount of time between when the mouse moves outside the Host's zone and when // the listener is notified. const int kNotifyListenerTimeMs = 300; +#if defined(OS_WIN) && !defined(USE_AURA) class MouseWatcher::Observer : public base::MessageLoopForUI::Observer { public: explicit Observer(MouseWatcher* mouse_watcher) @@ -32,7 +40,6 @@ class MouseWatcher::Observer : public base::MessageLoopForUI::Observer { } // MessageLoop::Observer implementation: -#if defined(OS_WIN) virtual base::EventStatus WillProcessEvent( const base::NativeEvent& event) OVERRIDE { return base::EVENT_CONTINUE; @@ -60,37 +67,85 @@ class MouseWatcher::Observer : public base::MessageLoopForUI::Observer { break; } } -#elif defined(USE_AURA) - virtual base::EventStatus WillProcessEvent( - const base::NativeEvent& event) OVERRIDE { - return base::EVENT_CONTINUE; + + private: + MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); } + + // Called from the message loop observer when a mouse movement has occurred. + void HandleGlobalMouseMoveEvent(MouseWatcherHost::MouseEventType event_type) { + bool contained = host()->Contains( + // TODO(scottmg): Native is wrong http://crbug.com/133312 + gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(), + event_type); + if (!contained) { + // Mouse moved outside the host's zone, start a timer to notify the + // listener. + if (!notify_listener_factory_.HasWeakPtrs()) { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&Observer::NotifyListener, + notify_listener_factory_.GetWeakPtr()), + event_type == MouseWatcherHost::MOUSE_MOVE + ? base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs) + : mouse_watcher_->notify_on_exit_time_); + } + } else { + // Mouse moved quickly out of the host and then into it again, so cancel + // the timer. + notify_listener_factory_.InvalidateWeakPtrs(); + } } - virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE { - switch (ui::EventTypeFromNative(event)) { + + void NotifyListener() { + mouse_watcher_->NotifyListener(); + // WARNING: we've been deleted. + } + + private: + MouseWatcher* mouse_watcher_; + + // A factory that is used to construct a delayed callback to the listener. + base::WeakPtrFactory<Observer> notify_listener_factory_; + + DISALLOW_COPY_AND_ASSIGN(Observer); +}; +#else +class MouseWatcher::Observer : public ui::EventHandler { + public: + explicit Observer(MouseWatcher* mouse_watcher) + : mouse_watcher_(mouse_watcher), + notify_listener_factory_(this) { + aura::Env::GetInstance()->AddPreTargetHandler(this); + } + + virtual ~Observer() { + aura::Env::GetInstance()->RemovePreTargetHandler(this); + } + + // ui::EventHandler implementation: + virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { + switch (event->type()) { case ui::ET_MOUSE_MOVED: case ui::ET_MOUSE_DRAGGED: - // DRAGGED is a special case of MOVED. See events_win.cc/events_x.cc. - HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE); + HandleMouseEvent(MouseWatcherHost::MOUSE_MOVE); break; case ui::ET_MOUSE_EXITED: - HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT); + HandleMouseEvent(MouseWatcherHost::MOUSE_EXIT); break; default: break; } } -#endif private: MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); } - // Called from the message loop observer when a mouse movement has occurred. - void HandleGlobalMouseMoveEvent(MouseWatcherHost::MouseEventType event_type) { - bool contained = host()->Contains( - // TODO(scottmg): Native is wrong http://crbug.com/133312 - gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(), - event_type); - if (!contained) { + // Called when a mouse event we're interested is seen. + void HandleMouseEvent(MouseWatcherHost::MouseEventType event_type) { + // It's safe to use last_mouse_location() here as this function is invoked + // during event dispatching. + if (!host()->Contains(aura::Env::GetInstance()->last_mouse_location(), + event_type)) { // Mouse moved outside the host's zone, start a timer to notify the // listener. if (!notify_listener_factory_.HasWeakPtrs()) { @@ -122,6 +177,7 @@ class MouseWatcher::Observer : public base::MessageLoopForUI::Observer { DISALLOW_COPY_AND_ASSIGN(Observer); }; +#endif MouseWatcherListener::~MouseWatcherListener() { } diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 7815cf9..23d3768 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -379,6 +379,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_event_client.cc', + 'widget/desktop_aura/desktop_event_client.h', 'widget/desktop_aura/desktop_factory_ozone.cc', 'widget/desktop_aura/desktop_factory_ozone.h', 'widget/desktop_aura/desktop_focus_rules.cc', diff --git a/ui/views/widget/desktop_aura/desktop_event_client.cc b/ui/views/widget/desktop_aura/desktop_event_client.cc new file mode 100644 index 0000000..fe85a72 --- /dev/null +++ b/ui/views/widget/desktop_aura/desktop_event_client.cc @@ -0,0 +1,26 @@ +// Copyright 2013 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_event_client.h" + +#include "ui/aura/env.h" + +namespace views { + +DesktopEventClient::DesktopEventClient() { +} + +DesktopEventClient::~DesktopEventClient() { +} + +bool DesktopEventClient::CanProcessEventsWithinSubtree( + const aura::Window* window) const { + return true; +} + +ui::EventTarget* DesktopEventClient::GetToplevelEventTarget() { + return aura::Env::GetInstance(); +} + +} // namespace views diff --git a/ui/views/widget/desktop_aura/desktop_event_client.h b/ui/views/widget/desktop_aura/desktop_event_client.h new file mode 100644 index 0000000..d16b5c9 --- /dev/null +++ b/ui/views/widget/desktop_aura/desktop_event_client.h @@ -0,0 +1,31 @@ +// Copyright 2013 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_AURA_DESKTOP_EVENT_CLIENT_H_ +#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_EVENT_CLIENT_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/aura/client/event_client.h" +#include "ui/views/views_export.h" + +namespace views { + +class VIEWS_EXPORT DesktopEventClient : public aura::client::EventClient { + public: + DesktopEventClient(); + virtual ~DesktopEventClient(); + + // Overridden from aura::client::EventClient: + virtual bool CanProcessEventsWithinSubtree( + const aura::Window* window) const OVERRIDE; + virtual ui::EventTarget* GetToplevelEventTarget() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(DesktopEventClient); +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_EVENT_CLIENT_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 6262c19..0a74b98 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc @@ -43,6 +43,7 @@ #include "ui/views/widget/desktop_aura/desktop_capture_client.h" #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater.h" #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" +#include "ui/views/widget/desktop_aura/desktop_event_client.h" #include "ui/views/widget/desktop_aura/desktop_focus_rules.h" #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" #include "ui/views/widget/desktop_aura/desktop_root_window_host.h" @@ -277,6 +278,9 @@ void DesktopNativeWidgetAura::OnDesktopRootWindowHostDestroyed( aura::client::SetDragDropClient(root, NULL); drag_drop_client_.reset(); + + aura::client::SetEventClient(root, NULL); + event_client_.reset(); } void DesktopNativeWidgetAura::HandleActivationChanged(bool active) { @@ -435,6 +439,9 @@ void DesktopNativeWidgetAura::InitNativeWidget( root_window_->AddPreTargetHandler(focus_manager->GetEventHandler()); } + event_client_.reset(new DesktopEventClient); + aura::client::SetEventClient(root_window_.get(), event_client_.get()); + aura::client::GetFocusClient(content_window_)->FocusWindow(content_window_); aura::client::SetActivationDelegate(content_window_, this); diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h index 6fc4b35..3cf6979 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.h +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.h @@ -40,6 +40,7 @@ class WindowModalityController; class DesktopCaptureClient; class DesktopDispatcherClient; +class DesktopEventClient; class DesktopRootWindowHost; class DropHelper; class TooltipManagerAura; @@ -265,6 +266,7 @@ class VIEWS_EXPORT DesktopNativeWidgetAura 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_; // Toplevel event filter which dispatches to other event filters. corewm::CompoundEventFilter* root_window_event_filter_; |