workspace_event_handler.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/wm/workspace/workspace_event_handler.h"
  5. #include "ash/shell.h"
  6. #include "ash/wm/overview/overview_controller.h"
  7. #include "ash/wm/overview/overview_session.h"
  8. #include "ash/wm/splitview/split_view_controller.h"
  9. #include "ash/wm/window_state.h"
  10. #include "ash/wm/window_util.h"
  11. #include "ash/wm/wm_event.h"
  12. #include "base/metrics/user_metrics.h"
  13. #include "ui/aura/window.h"
  14. #include "ui/aura/window_delegate.h"
  15. #include "ui/base/hit_test.h"
  16. #include "ui/events/event.h"
  17. namespace ash {
  18. WorkspaceEventHandler::WorkspaceEventHandler(aura::Window* workspace_window)
  19. : workspace_window_(workspace_window), click_component_(HTNOWHERE) {
  20. workspace_window_->AddPreTargetHandler(this);
  21. }
  22. WorkspaceEventHandler::~WorkspaceEventHandler() {
  23. workspace_window_->RemovePreTargetHandler(this);
  24. }
  25. void WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) {
  26. aura::Window* target = static_cast<aura::Window*>(event->target());
  27. if (event->type() == ui::ET_MOUSE_PRESSED && event->IsOnlyLeftMouseButton() &&
  28. ((event->flags() & (ui::EF_IS_DOUBLE_CLICK | ui::EF_IS_TRIPLE_CLICK)) ==
  29. 0)) {
  30. click_component_ =
  31. window_util::GetNonClientComponent(target, event->location());
  32. }
  33. if (event->handled())
  34. return;
  35. switch (event->type()) {
  36. case ui::ET_MOUSE_MOVED: {
  37. int component =
  38. window_util::GetNonClientComponent(target, event->location());
  39. multi_window_resize_controller_.Show(target, component,
  40. event->location());
  41. break;
  42. }
  43. case ui::ET_MOUSE_ENTERED:
  44. break;
  45. case ui::ET_MOUSE_CAPTURE_CHANGED:
  46. case ui::ET_MOUSE_EXITED:
  47. break;
  48. case ui::ET_MOUSE_PRESSED: {
  49. WindowState* target_state = WindowState::Get(target);
  50. // No action for windows that aren't managed by WindowState.
  51. if (!target_state)
  52. return;
  53. if (event->IsOnlyLeftMouseButton()) {
  54. if (event->flags() & ui::EF_IS_DOUBLE_CLICK) {
  55. int component =
  56. window_util::GetNonClientComponent(target, event->location());
  57. if (component == HTCAPTION && component == click_component_) {
  58. base::RecordAction(
  59. base::UserMetricsAction("Caption_ClickTogglesMaximize"));
  60. const WMEvent wm_event(WM_EVENT_TOGGLE_MAXIMIZE_CAPTION);
  61. target_state->OnWMEvent(&wm_event);
  62. event->StopPropagation();
  63. }
  64. click_component_ = HTNOWHERE;
  65. }
  66. } else {
  67. click_component_ = HTNOWHERE;
  68. }
  69. HandleResizeDoubleClick(target_state, event);
  70. break;
  71. }
  72. default:
  73. break;
  74. }
  75. }
  76. void WorkspaceEventHandler::OnGestureEvent(ui::GestureEvent* event) {
  77. if (event->handled() || event->type() != ui::ET_GESTURE_TAP)
  78. return;
  79. aura::Window* target = static_cast<aura::Window*>(event->target());
  80. int previous_target_component = click_component_;
  81. click_component_ =
  82. window_util::GetNonClientComponent(target, event->location());
  83. if (click_component_ != HTCAPTION)
  84. return;
  85. if (event->details().tap_count() != 2)
  86. return;
  87. if (click_component_ == previous_target_component) {
  88. base::RecordAction(
  89. base::UserMetricsAction("Caption_GestureTogglesMaximize"));
  90. const WMEvent wm_event(WM_EVENT_TOGGLE_MAXIMIZE_CAPTION);
  91. WindowState::Get(target)->OnWMEvent(&wm_event);
  92. event->StopPropagation();
  93. }
  94. click_component_ = HTNOWHERE;
  95. }
  96. void WorkspaceEventHandler::HandleResizeDoubleClick(WindowState* target_state,
  97. ui::MouseEvent* event) {
  98. aura::Window* target = target_state->window();
  99. if ((event->flags() & ui::EF_IS_DOUBLE_CLICK) != 0 && target->delegate()) {
  100. const int component =
  101. window_util::GetNonClientComponent(target, event->location());
  102. if (component == HTBOTTOM || component == HTTOP) {
  103. base::RecordAction(base::UserMetricsAction(
  104. "WindowBorder_ClickTogglesSingleAxisMaximize"));
  105. const WMEvent wm_event(WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE);
  106. target_state->OnWMEvent(&wm_event);
  107. event->StopPropagation();
  108. } else if (component == HTLEFT || component == HTRIGHT) {
  109. base::RecordAction(base::UserMetricsAction(
  110. "WindowBorder_ClickTogglesSingleAxisMaximize"));
  111. // If overview is in session, meaning that |target| is a clamshell split
  112. // view window, then end overview (thereby ending clamshell split view).
  113. OverviewController* overview_controller =
  114. Shell::Get()->overview_controller();
  115. if (overview_controller->InOverviewSession()) {
  116. DCHECK(SplitViewController::Get(target)->InClamshellSplitViewMode());
  117. DCHECK(SplitViewController::Get(target)->IsWindowInSplitView(target));
  118. // For |target| to have a snapped window state (in split view or not),
  119. // it must have no maximum size (see |WindowState::CanSnap|). That is
  120. // important here because when |target| has a maximum width, the
  121. // |WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE| event will do nothing, meaning
  122. // it would be rather inappropriate to end overview as below, and of
  123. // course it would be blatantly inappropriate to make the following call
  124. // to |OverviewSession::SetWindowListNotAnimatedWhenExiting|.
  125. DCHECK_EQ(gfx::Size(), target->delegate()->GetMaximumSize());
  126. overview_controller->overview_session()
  127. ->SetWindowListNotAnimatedWhenExiting(target->GetRootWindow());
  128. overview_controller->EndOverview(OverviewEndAction::kSplitView);
  129. }
  130. const WMEvent wm_event(WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE);
  131. target_state->OnWMEvent(&wm_event);
  132. event->StopPropagation();
  133. }
  134. }
  135. }
  136. } // namespace ash