Index: ash/wm/system_gesture_event_filter.cc |
diff --git a/ash/wm/system_gesture_event_filter.cc b/ash/wm/system_gesture_event_filter.cc |
index 1568052561a3f6187925387d067338ee27bb48b6..1de41ca7600443f6f7622fc2b69f1ffc53550387 100644 |
--- a/ash/wm/system_gesture_event_filter.cc |
+++ b/ash/wm/system_gesture_event_filter.cc |
@@ -5,14 +5,23 @@ |
#include "ash/wm/system_gesture_event_filter.h" |
#include "ash/shell.h" |
+#include "ash/accelerators/accelerator_controller.h" |
+#include "ash/system/brightness/brightness_control_delegate.h" |
+#include "ash/volume_control_delegate.h" |
#include "ui/aura/event.h" |
#include "ui/aura/root_window.h" |
+#include "ui/gfx/screen.h" |
namespace ash { |
namespace internal { |
SystemGestureEventFilter::SystemGestureEventFilter() |
- : aura::EventFilter() { |
+ : aura::EventFilter(), |
+ kOverlapPercent(5), |
+ start_location_(bezel_start_unset), |
+ orientation_(scroll_orientation_unset), |
+ is_scrubbing_(false), |
+ touch_id_(0) { |
} |
SystemGestureEventFilter::~SystemGestureEventFilter() { |
@@ -39,10 +48,126 @@ ui::GestureStatus SystemGestureEventFilter::PreHandleGestureEvent( |
// TODO(tdresser) handle system level gesture events |
if (event->type() == ui::ET_GESTURE_THREE_FINGER_SWIPE) |
return ui::GESTURE_STATUS_CONSUMED; |
- if (target == Shell::GetRootWindow()) |
+ if (!target || target == Shell::GetRootWindow()) { |
+ switch (event->type()) { |
+ case ui::ET_GESTURE_SCROLL_BEGIN: |
+ if (start_location_ == bezel_start_unset) { |
+ gfx::Rect screen = |
+ gfx::Screen::GetPrimaryMonitor().bounds_in_pixel(); |
+ int overlap_area = screen.width() * kOverlapPercent / 100; |
+ |
+ if (event->x() <= screen.x() + overlap_area) { |
+ start_location_ = bezel_start_left; |
+ } else if (event->x() >= screen.right() - overlap_area) { |
+ start_location_ = bezel_start_right; |
+ } else if (event->y() >= screen.bottom()) { |
+ start_location_ = bezel_start_bottom; |
+ } else { |
+ break; |
+ } |
+ orientation_ = scroll_orientation_unset; |
+ touch_id_ = event->GetLowestTouchId(); |
+ } |
+ break; |
+ case ui::ET_GESTURE_SCROLL_UPDATE: |
+ if (start_location_ == bezel_start_unset || |
+ touch_id_ != event->GetLowestTouchId()) |
+ break; |
+ if (orientation_ == scroll_orientation_unset) { |
+ if (!event->delta_x() && !event->delta_y()) |
+ break; |
+ // For left and right the scroll angle needs to be much steeper to |
+ // be accepted for a 'device configuration' gesture. |
+ if (start_location_ == bezel_start_left || |
+ start_location_ == bezel_start_right) |
+ orientation_ = abs(event->delta_y()) > abs(event->delta_x()) * 3 ? |
+ scroll_orientation_vertical : scroll_orientation_horizontal; |
+ else |
+ orientation_ = abs(event->delta_y()) > abs(event->delta_x()) ? |
+ scroll_orientation_vertical : scroll_orientation_horizontal; |
+ } |
+ if (orientation_ == scroll_orientation_horizontal) { |
+ if (HandleApplicationControl(event)) |
+ start_location_ = bezel_start_unset; |
+ } else { |
+ if (start_location_ == bezel_start_bottom) { |
+ if (HandleLauncherControl(event)) |
+ start_location_ = bezel_start_unset; |
+ } else { |
+ if (HandleDeviceControl(event)) |
+ start_location_ = bezel_start_unset; |
+ } |
+ } |
+ break; |
+ case ui::ET_GESTURE_SCROLL_END: |
+ if (touch_id_ == event->GetLowestTouchId()) |
+ start_location_ = bezel_start_unset; |
+ break; |
+ default: |
+ break; |
+ } |
return ui::GESTURE_STATUS_CONSUMED; |
+ } |
return ui::GESTURE_STATUS_UNKNOWN; |
} |
+bool SystemGestureEventFilter::HandleDeviceControl(aura::GestureEvent* event) { |
+ gfx::Rect screen = gfx::Screen::GetPrimaryMonitor().bounds_in_pixel(); |
+ double percent = 100.0 * (event->y() - screen.y()) / screen.height(); |
+ if (percent > 100.0) |
+ percent = 100.0; |
+ if (percent < 0.0) |
+ percent = 0.0; |
+ ash::AcceleratorController* accelerator = |
+ ash::Shell::GetInstance()->accelerator_controller(); |
+ if (start_location_ == bezel_start_left) { |
+ ash::BrightnessControlDelegate* delegate = |
+ accelerator->brightness_control_delegate(); |
+ if (delegate) |
+ delegate->SetBrightnessPercent(100.0 - percent, true); |
+ } else if (start_location_ == bezel_start_right) { |
+ ash::VolumeControlDelegate* delegate = |
+ accelerator->volume_control_delegate(); |
+ if (delegate) |
+ delegate->SetVolumePercent(100.0 - percent); |
+ } else { |
+ return true; |
+ } |
+ // More notifications can be send. |
+ return false; |
+} |
+ |
+bool SystemGestureEventFilter::HandleLauncherControl( |
+ aura::GestureEvent* event) { |
+ ash::AcceleratorController* accelerator = |
+ ash::Shell::GetInstance()->accelerator_controller(); |
+ if (start_location_ == bezel_start_bottom && event->delta_y() < 0) |
+ // We leave the work to switch to the next window to our accelerators. |
+ accelerator->AcceleratorPressed( |
+ ui::Accelerator(ui::VKEY_LWIN, false, true, false)); |
+ else |
+ return false; |
+ // No further notifications for this gesture. |
+ return true; |
+} |
+ |
+bool SystemGestureEventFilter::HandleApplicationControl( |
+ aura::GestureEvent* event) { |
+ ash::AcceleratorController* accelerator = |
+ ash::Shell::GetInstance()->accelerator_controller(); |
+ if (start_location_ == bezel_start_left && event->delta_x() > 0) |
+ // We leave the work to switch to the next window to our accelerators. |
+ accelerator->AcceleratorPressed( |
+ ui::Accelerator(ui::VKEY_F5, true, false, false)); |
+ else if (start_location_ == bezel_start_right && event->delta_x() < 0) |
+ // We leave the work to switch to the previous window to our accelerators. |
+ accelerator->AcceleratorPressed( |
+ ui::Accelerator(ui::VKEY_F5, false, false, false)); |
+ else |
+ return false; |
+ // No further notifications for this gesture. |
+ return true; |
+} |
+ |
} // namespace internal |
} // namespace ash |