summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chrome_browser_main_extra_parts_ash.cc6
-rw-r--r--chrome/browser/chrome_browser_main_extra_parts_ash.h5
-rw-r--r--chrome/browser/ui/views/ash/user_gesture_handler.cc60
-rw-r--r--chrome/browser/ui/views/ash/user_gesture_handler.h26
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--ui/aura/aura.gyp2
-rw-r--r--ui/aura/client/user_gesture_client.cc27
-rw-r--r--ui/aura/client/user_gesture_client.h39
-rw-r--r--ui/aura/root_window_host_linux.cc55
-rw-r--r--ui/base/events.h8
-rw-r--r--ui/base/win/events_win.cc12
-rw-r--r--ui/base/x/events_x.cc50
-rw-r--r--ui/base/x/events_x_unittest.cc18
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.
}