diff options
-rw-r--r-- | chrome/browser/chrome_browser_main_extra_parts_ash.cc | 6 | ||||
-rw-r--r-- | chrome/browser/chrome_browser_main_extra_parts_ash.h | 5 | ||||
-rw-r--r-- | chrome/browser/ui/views/ash/user_gesture_handler.cc | 60 | ||||
-rw-r--r-- | chrome/browser/ui/views/ash/user_gesture_handler.h | 26 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | ui/aura/aura.gyp | 2 | ||||
-rw-r--r-- | ui/aura/client/user_gesture_client.cc | 27 | ||||
-rw-r--r-- | ui/aura/client/user_gesture_client.h | 39 | ||||
-rw-r--r-- | ui/aura/root_window_host_linux.cc | 55 | ||||
-rw-r--r-- | ui/base/events.h | 8 | ||||
-rw-r--r-- | ui/base/win/events_win.cc | 12 | ||||
-rw-r--r-- | ui/base/x/events_x.cc | 50 | ||||
-rw-r--r-- | ui/base/x/events_x_unittest.cc | 18 |
13 files changed, 255 insertions, 55 deletions
diff --git a/chrome/browser/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/chrome_browser_main_extra_parts_ash.cc index 6554502..76a7c83 100644 --- a/chrome/browser/chrome_browser_main_extra_parts_ash.cc +++ b/chrome/browser/chrome_browser_main_extra_parts_ash.cc @@ -17,8 +17,10 @@ #include "chrome/browser/ui/views/ash/key_rewriter.h" #include "chrome/browser/ui/views/ash/screen_orientation_listener.h" #include "chrome/browser/ui/views/ash/screenshot_taker.h" +#include "chrome/browser/ui/views/ash/user_gesture_handler.h" #include "ui/aura/env.h" #include "ui/aura/aura_switches.h" +#include "ui/aura/client/user_gesture_client.h" #include "ui/aura/monitor_manager.h" #include "ui/aura/root_window.h" #include "ui/gfx/compositor/compositor_setup.h" @@ -79,6 +81,10 @@ void ChromeBrowserMainExtraPartsAsh::PreProfileInit() { // Make sure the singleton ScreenOrientationListener object is created. ScreenOrientationListener::GetInstance(); + + gesture_handler_.reset(new UserGestureHandler); + aura::client::SetUserGestureClient( + ash::Shell::GetRootWindow(), gesture_handler_.get()); } void ChromeBrowserMainExtraPartsAsh::PostProfileInit() { diff --git a/chrome/browser/chrome_browser_main_extra_parts_ash.h b/chrome/browser/chrome_browser_main_extra_parts_ash.h index 9cde453..f661d4c 100644 --- a/chrome/browser/chrome_browser_main_extra_parts_ash.h +++ b/chrome/browser/chrome_browser_main_extra_parts_ash.h @@ -7,8 +7,11 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "chrome/browser/chrome_browser_main_extra_parts.h" +class UserGestureHandler; + class ChromeBrowserMainExtraPartsAsh : public ChromeBrowserMainExtraParts { public: ChromeBrowserMainExtraPartsAsh(); @@ -18,6 +21,8 @@ class ChromeBrowserMainExtraPartsAsh : public ChromeBrowserMainExtraParts { virtual void PostMainMessageLoopRun() OVERRIDE; private: + scoped_ptr<UserGestureHandler> gesture_handler_; + DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsAsh); }; diff --git a/chrome/browser/ui/views/ash/user_gesture_handler.cc b/chrome/browser/ui/views/ash/user_gesture_handler.cc new file mode 100644 index 0000000..1cdabab --- /dev/null +++ b/chrome/browser/ui/views/ash/user_gesture_handler.cc @@ -0,0 +1,60 @@ +// 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 "chrome/browser/ui/views/ash/user_gesture_handler.h" + +#include "ash/wm/window_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "content/public/browser/web_contents.h" + +namespace { + +// Returns the currently-active WebContents belonging to the active browser, or +// NULL if there's no currently-active browser. +content::WebContents* GetActiveWebContents() { + Browser* browser = BrowserList::GetLastActive(); + if (!browser) + return NULL; + if (!ash::wm::IsActiveWindow(browser->window()->GetNativeHandle())) + return NULL; + + TabContentsWrapper* wrapper = browser->GetSelectedTabContentsWrapper(); + if (!wrapper) + return NULL; + return wrapper->web_contents(); +} + +} // namespace + +UserGestureHandler::UserGestureHandler() {} + +UserGestureHandler::~UserGestureHandler() {} + +bool UserGestureHandler::OnUserGesture( + aura::client::UserGestureClient::Gesture gesture) { + switch (gesture) { + case aura::client::UserGestureClient::GESTURE_BACK: { + content::WebContents* contents = GetActiveWebContents(); + if (contents && contents->GetController().CanGoBack()) { + contents->GetController().GoBack(); + return true; + } + break; + } + case aura::client::UserGestureClient::GESTURE_FORWARD: { + content::WebContents* contents = GetActiveWebContents(); + if (contents && contents->GetController().CanGoForward()) { + contents->GetController().GoForward(); + return true; + } + break; + } + default: + break; + } + return false; +} diff --git a/chrome/browser/ui/views/ash/user_gesture_handler.h b/chrome/browser/ui/views/ash/user_gesture_handler.h new file mode 100644 index 0000000..c8ff514 --- /dev/null +++ b/chrome/browser/ui/views/ash/user_gesture_handler.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 CHROME_BROWSER_UI_VIEWS_ASH_USER_GESTURE_HANDLER_H_ +#define CHROME_BROWSER_UI_VIEWS_ASH_USER_GESTURE_HANDLER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/aura/client/user_gesture_client.h" + +class UserGestureHandler : public aura::client::UserGestureClient { + public: + UserGestureHandler(); + virtual ~UserGestureHandler(); + + // aura::client::UserGestureClient overrides: + virtual bool OnUserGesture( + aura::client::UserGestureClient::Gesture gesture) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(UserGestureHandler); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_ASH_USER_GESTURE_HANDLER_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 438c396..ef7c712 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3222,6 +3222,8 @@ 'browser/ui/views/ash/screen_orientation_listener.h', 'browser/ui/views/ash/screenshot_taker.cc', 'browser/ui/views/ash/screenshot_taker.h', + 'browser/ui/views/ash/user_gesture_handler.cc', + 'browser/ui/views/ash/user_gesture_handler.h', 'browser/ui/views/ash/volume_controller_chromeos.cc', 'browser/ui/views/ash/volume_controller_chromeos.h', 'browser/ui/views/ash/window_positioner.cc', diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp index 6bea410..aa46a9f 100644 --- a/ui/aura/aura.gyp +++ b/ui/aura/aura.gyp @@ -44,6 +44,8 @@ 'client/stacking_client.h', 'client/tooltip_client.cc', 'client/tooltip_client.h', + 'client/user_gesture_client.cc', + 'client/user_gesture_client.h', 'client/visibility_client.cc', 'client/visibility_client.h', 'client/window_move_client.cc', diff --git a/ui/aura/client/user_gesture_client.cc b/ui/aura/client/user_gesture_client.cc new file mode 100644 index 0000000..78b4311 --- /dev/null +++ b/ui/aura/client/user_gesture_client.cc @@ -0,0 +1,27 @@ +// 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/aura/client/user_gesture_client.h" + +#include "ui/aura/root_window.h" +#include "ui/aura/window_property.h" + +namespace aura { +namespace client { + +DEFINE_WINDOW_PROPERTY_KEY(UserGestureClient*, + kRootWindowUserGestureClientKey, + NULL); + +void SetUserGestureClient(RootWindow* root_window, UserGestureClient* client) { + root_window->SetProperty(kRootWindowUserGestureClientKey, client); +} + +UserGestureClient* GetUserGestureClient(RootWindow* root_window) { + return root_window ? + root_window->GetProperty(kRootWindowUserGestureClientKey) : NULL; +} + +} // namespace client +} // namespace aura diff --git a/ui/aura/client/user_gesture_client.h b/ui/aura/client/user_gesture_client.h new file mode 100644 index 0000000..b82edbe --- /dev/null +++ b/ui/aura/client/user_gesture_client.h @@ -0,0 +1,39 @@ +// 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_AURA_CLIENT_USER_GESTURE_CLIENT_H_ +#define UI_AURA_CLIENT_USER_GESTURE_CLIENT_H_ +#pragma once + +#include "ui/aura/aura_export.h" + +namespace aura { +class RootWindow; +namespace client { + +// An interface for handling user gestures that aren't handled by the standard +// event path. +class AURA_EXPORT UserGestureClient { + public: + enum Gesture { + GESTURE_BACK = 0, + GESTURE_FORWARD, + }; + + // Returns true if the gesture was handled and false otherwise. + virtual bool OnUserGesture(Gesture gesture) = 0; + + protected: + virtual ~UserGestureClient() {} +}; + +// Sets/gets the client for handling gestures on the specified root window. +AURA_EXPORT void SetUserGestureClient(RootWindow* root_window, + UserGestureClient* client); +AURA_EXPORT UserGestureClient* GetUserGestureClient(RootWindow* root_window); + +} // namespace client +} // namespace aura + +#endif // UI_AURA_CLIENT_USER_GESTURE_CLIENT_H_ diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc index f0d17bc..21bdd06 100644 --- a/ui/aura/root_window_host_linux.cc +++ b/ui/aura/root_window_host_linux.cc @@ -14,6 +14,7 @@ #include "base/message_pump_x.h" #include "base/stl_util.h" #include "base/stringprintf.h" +#include "ui/aura/client/user_gesture_client.h" #include "ui/aura/dispatcher_linux.h" #include "ui/aura/env.h" #include "ui/aura/event.h" @@ -33,6 +34,10 @@ namespace aura { namespace { +// Standard Linux mouse buttons for going back and forward. +const int kBackMouseButton = 8; +const int kForwardMouseButton = 9; + // The events reported for slave devices can have incorrect information for some // fields. This utility function is used to check for such inconsistencies. void CheckXEventForConsistency(XEvent* xevent) { @@ -406,7 +411,20 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { root_window_->DispatchKeyEvent(&keyup_event); break; } - case ButtonPress: + case ButtonPress: { + if (static_cast<int>(xev->xbutton.button) == kBackMouseButton || + static_cast<int>(xev->xbutton.button) == kForwardMouseButton) { + client::UserGestureClient* gesture_client = + client::GetUserGestureClient(root_window_); + if (gesture_client) { + gesture_client->OnUserGesture( + static_cast<int>(xev->xbutton.button) == kBackMouseButton ? + client::UserGestureClient::GESTURE_BACK : + client::UserGestureClient::GESTURE_FORWARD); + } + break; + } + } // fallthrough case ButtonRelease: { MouseEvent mouseev(xev); root_window_->DispatchMouseEvent(&mouseev); @@ -444,8 +462,6 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { break; ui::EventType type = ui::EventTypeFromNative(xev); - // If this is a motion event we want to coalesce all pending motion - // events that are at the top of the queue. XEvent last_event; int num_coalesced = 0; @@ -458,18 +474,37 @@ bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { break; } case ui::ET_MOUSE_MOVED: - case ui::ET_MOUSE_DRAGGED: { - // If this is a motion event we want to coalesce all pending motion - // events that are at the top of the queue. - num_coalesced = CoalescePendingXIMotionEvents(xev, &last_event); - if (num_coalesced > 0) - xev = &last_event; - } + case ui::ET_MOUSE_DRAGGED: case ui::ET_MOUSE_PRESSED: case ui::ET_MOUSE_RELEASED: case ui::ET_MOUSEWHEEL: case ui::ET_MOUSE_ENTERED: case ui::ET_MOUSE_EXITED: { + if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { + // If this is a motion event, we want to coalesce all pending motion + // events that are at the top of the queue. + num_coalesced = CoalescePendingXIMotionEvents(xev, &last_event); + if (num_coalesced > 0) + xev = &last_event; + } else if (type == ui::ET_MOUSE_PRESSED) { + XIDeviceEvent* xievent = + static_cast<XIDeviceEvent*>(xev->xcookie.data); + int button = xievent->detail; + if (button == kBackMouseButton || button == kForwardMouseButton) { + client::UserGestureClient* gesture_client = + client::GetUserGestureClient(root_window_); + if (gesture_client) { + bool reverse_direction = + ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); + gesture_client->OnUserGesture( + (button == kBackMouseButton && !reverse_direction) || + (button == kForwardMouseButton && reverse_direction) ? + client::UserGestureClient::GESTURE_BACK : + client::UserGestureClient::GESTURE_FORWARD); + } + break; + } + } MouseEvent mouseev(xev); root_window_->DispatchMouseEvent(&mouseev); break; diff --git a/ui/base/events.h b/ui/base/events.h index 33fb77f..ef443be 100644 --- a/ui/base/events.h +++ b/ui/base/events.h @@ -189,6 +189,14 @@ UI_EXPORT bool GetGestureTimes(const base::NativeEvent& native_event, // Enable/disable natural scrolling for touchpads. UI_EXPORT void SetNaturalScroll(bool enabled); +// In natural scrolling enabled for touchpads? +UI_EXPORT bool IsNaturalScrollEnabled(); + +// Was this event generated by a touchpad device? +// The caller is responsible for ensuring that this is a mouse/touchpad event +// before calling this function. +UI_EXPORT bool IsTouchpadEvent(const base::NativeEvent& event); + // Returns true if event is noop. UI_EXPORT bool IsNoopEvent(const base::NativeEvent& event); diff --git a/ui/base/win/events_win.cc b/ui/base/win/events_win.cc index b650e1d..9f75b6f 100644 --- a/ui/base/win/events_win.cc +++ b/ui/base/win/events_win.cc @@ -127,6 +127,10 @@ int MouseStateFlagsFromNative(const base::NativeEvent& native_event) { namespace ui { +void UpdateDeviceList() { + NOTIMPLEMENTED(); +} + EventType EventTypeFromNative(const base::NativeEvent& native_event) { switch (native_event.message) { case WM_KEYDOWN: @@ -276,8 +280,14 @@ void SetNaturalScroll(bool enabled) { NOTIMPLEMENTED(); } -void UpdateDeviceList() { +bool IsNaturalScrollEnabled() { NOTIMPLEMENTED(); + return false; +} + +bool IsTouchpadEvent(const base::NativeEvent& event) { + NOTIMPLEMENTED(); + return false; } bool IsNoopEvent(const base::NativeEvent& event) { diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc index 8bb5aebd4..c914599 100644 --- a/ui/base/x/events_x.cc +++ b/ui/base/x/events_x.cc @@ -34,18 +34,8 @@ namespace { // Scroll amount for each wheelscroll event. 53 is also the value used for GTK+. const int kWheelScrollAmount = 53; -const int kMinWheelButton = 4; -#if defined(OS_CHROMEOS) -// TODO(davemoore) For now use the button to decide how much to scroll by. -// When we go to XI2 scroll events this won't be necessary. If this doesn't -// happen for some reason we can better detect which devices are touchpads. -const int kTouchpadScrollAmount = 3; - -// Chrome OS also uses buttons 8 and 9 for scrolling. -const int kMaxWheelButton = 9; -#else -const int kMaxWheelButton = 7; -#endif +static const int kMinWheelButton = 4; +static const int kMaxWheelButton = 7; // A class to support the detection of scroll events, using X11 valuators. class UI_EXPORT CMTEventData { @@ -133,10 +123,20 @@ class UI_EXPORT CMTEventData { XIFreeDeviceInfo(info_list); } + bool natural_scroll_enabled() const { return natural_scroll_enabled_; } void set_natural_scroll_enabled(bool enabled) { natural_scroll_enabled_ = enabled; } + bool IsTouchpadXInputEvent(const base::NativeEvent& native_event) { + if (native_event->type != GenericEvent) + return false; + + XIDeviceEvent* xievent = + static_cast<XIDeviceEvent*>(native_event->xcookie.data); + return touchpads_[xievent->sourceid]; + } + float GetNaturalScrollFactor(int deviceid) { // Natural scroll is touchpad-only. if (!touchpads_[deviceid]) @@ -515,6 +515,12 @@ Atom GetNoopEventAtom() { namespace ui { +void UpdateDeviceList() { + Display* display = GetXDisplay(); + CMTEventData::GetInstance()->UpdateDeviceList(display); + TouchFactory::GetInstance()->UpdateDeviceList(display); +} + EventType EventTypeFromNative(const base::NativeEvent& native_event) { switch (native_event->type) { case KeyPress: @@ -748,19 +754,9 @@ int GetMouseWheelOffset(const base::NativeEvent& native_event) { switch (button) { case 4: -#if defined(OS_CHROMEOS) - return kTouchpadScrollAmount; - case 8: -#endif return kWheelScrollAmount; - case 5: -#if defined(OS_CHROMEOS) - return -kTouchpadScrollAmount; - case 9: -#endif return -kWheelScrollAmount; - default: // TODO(derat): Do something for horizontal scrolls (buttons 6 and 7)? return 0; @@ -852,10 +848,12 @@ void SetNaturalScroll(bool enabled) { CMTEventData::GetInstance()->set_natural_scroll_enabled(enabled); } -void UpdateDeviceList() { - Display* display = GetXDisplay(); - CMTEventData::GetInstance()->UpdateDeviceList(display); - TouchFactory::GetInstance()->UpdateDeviceList(display); +bool IsNaturalScrollEnabled() { + return CMTEventData::GetInstance()->natural_scroll_enabled(); +} + +bool IsTouchpadEvent(const base::NativeEvent& event) { + return CMTEventData::GetInstance()->IsTouchpadXInputEvent(event); } bool IsNoopEvent(const base::NativeEvent& event) { diff --git a/ui/base/x/events_x_unittest.cc b/ui/base/x/events_x_unittest.cc index 65b46aa..18010a3 100644 --- a/ui/base/x/events_x_unittest.cc +++ b/ui/base/x/events_x_unittest.cc @@ -94,24 +94,6 @@ TEST(EventsXTest, ButtonEvents) { EXPECT_TRUE(ui::IsMouseEvent(&event)); EXPECT_EQ(0, ui::GetMouseWheelOffset(&event)); -#if defined(OS_CHROMEOS) - // Scroll up. - InitButtonEvent(&event, true, location, 8, 0); - EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event)); - EXPECT_EQ(0, ui::EventFlagsFromNative(&event)); - EXPECT_EQ(location, ui::EventLocationFromNative(&event)); - EXPECT_TRUE(ui::IsMouseEvent(&event)); - EXPECT_GT(ui::GetMouseWheelOffset(&event), 0); - - // Scroll down. - InitButtonEvent(&event, true, location, 9, 0); - EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(&event)); - EXPECT_EQ(0, ui::EventFlagsFromNative(&event)); - EXPECT_EQ(location, ui::EventLocationFromNative(&event)); - EXPECT_TRUE(ui::IsMouseEvent(&event)); - EXPECT_LT(ui::GetMouseWheelOffset(&event), 0); -#endif - // TODO(derat): Test XInput code. } |