123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- // 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 "ash/wm/workspace/workspace_event_handler.h"
- #include "ash/shell.h"
- #include "ash/wm/overview/overview_controller.h"
- #include "ash/wm/overview/overview_session.h"
- #include "ash/wm/splitview/split_view_controller.h"
- #include "ash/wm/window_state.h"
- #include "ash/wm/window_util.h"
- #include "ash/wm/wm_event.h"
- #include "base/metrics/user_metrics.h"
- #include "ui/aura/window.h"
- #include "ui/aura/window_delegate.h"
- #include "ui/base/hit_test.h"
- #include "ui/events/event.h"
- namespace ash {
- WorkspaceEventHandler::WorkspaceEventHandler(aura::Window* workspace_window)
- : workspace_window_(workspace_window), click_component_(HTNOWHERE) {
- workspace_window_->AddPreTargetHandler(this);
- }
- WorkspaceEventHandler::~WorkspaceEventHandler() {
- workspace_window_->RemovePreTargetHandler(this);
- }
- void WorkspaceEventHandler::OnMouseEvent(ui::MouseEvent* event) {
- aura::Window* target = static_cast<aura::Window*>(event->target());
- if (event->type() == ui::ET_MOUSE_PRESSED && event->IsOnlyLeftMouseButton() &&
- ((event->flags() & (ui::EF_IS_DOUBLE_CLICK | ui::EF_IS_TRIPLE_CLICK)) ==
- 0)) {
- click_component_ =
- window_util::GetNonClientComponent(target, event->location());
- }
- if (event->handled())
- return;
- switch (event->type()) {
- case ui::ET_MOUSE_MOVED: {
- int component =
- window_util::GetNonClientComponent(target, event->location());
- multi_window_resize_controller_.Show(target, component,
- event->location());
- break;
- }
- case ui::ET_MOUSE_ENTERED:
- break;
- case ui::ET_MOUSE_CAPTURE_CHANGED:
- case ui::ET_MOUSE_EXITED:
- break;
- case ui::ET_MOUSE_PRESSED: {
- WindowState* target_state = WindowState::Get(target);
- // No action for windows that aren't managed by WindowState.
- if (!target_state)
- return;
- if (event->IsOnlyLeftMouseButton()) {
- if (event->flags() & ui::EF_IS_DOUBLE_CLICK) {
- int component =
- window_util::GetNonClientComponent(target, event->location());
- if (component == HTCAPTION && component == click_component_) {
- base::RecordAction(
- base::UserMetricsAction("Caption_ClickTogglesMaximize"));
- const WMEvent wm_event(WM_EVENT_TOGGLE_MAXIMIZE_CAPTION);
- target_state->OnWMEvent(&wm_event);
- event->StopPropagation();
- }
- click_component_ = HTNOWHERE;
- }
- } else {
- click_component_ = HTNOWHERE;
- }
- HandleResizeDoubleClick(target_state, event);
- break;
- }
- default:
- break;
- }
- }
- void WorkspaceEventHandler::OnGestureEvent(ui::GestureEvent* event) {
- if (event->handled() || event->type() != ui::ET_GESTURE_TAP)
- return;
- aura::Window* target = static_cast<aura::Window*>(event->target());
- int previous_target_component = click_component_;
- click_component_ =
- window_util::GetNonClientComponent(target, event->location());
- if (click_component_ != HTCAPTION)
- return;
- if (event->details().tap_count() != 2)
- return;
- if (click_component_ == previous_target_component) {
- base::RecordAction(
- base::UserMetricsAction("Caption_GestureTogglesMaximize"));
- const WMEvent wm_event(WM_EVENT_TOGGLE_MAXIMIZE_CAPTION);
- WindowState::Get(target)->OnWMEvent(&wm_event);
- event->StopPropagation();
- }
- click_component_ = HTNOWHERE;
- }
- void WorkspaceEventHandler::HandleResizeDoubleClick(WindowState* target_state,
- ui::MouseEvent* event) {
- aura::Window* target = target_state->window();
- if ((event->flags() & ui::EF_IS_DOUBLE_CLICK) != 0 && target->delegate()) {
- const int component =
- window_util::GetNonClientComponent(target, event->location());
- if (component == HTBOTTOM || component == HTTOP) {
- base::RecordAction(base::UserMetricsAction(
- "WindowBorder_ClickTogglesSingleAxisMaximize"));
- const WMEvent wm_event(WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE);
- target_state->OnWMEvent(&wm_event);
- event->StopPropagation();
- } else if (component == HTLEFT || component == HTRIGHT) {
- base::RecordAction(base::UserMetricsAction(
- "WindowBorder_ClickTogglesSingleAxisMaximize"));
- // If overview is in session, meaning that |target| is a clamshell split
- // view window, then end overview (thereby ending clamshell split view).
- OverviewController* overview_controller =
- Shell::Get()->overview_controller();
- if (overview_controller->InOverviewSession()) {
- DCHECK(SplitViewController::Get(target)->InClamshellSplitViewMode());
- DCHECK(SplitViewController::Get(target)->IsWindowInSplitView(target));
- // For |target| to have a snapped window state (in split view or not),
- // it must have no maximum size (see |WindowState::CanSnap|). That is
- // important here because when |target| has a maximum width, the
- // |WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE| event will do nothing, meaning
- // it would be rather inappropriate to end overview as below, and of
- // course it would be blatantly inappropriate to make the following call
- // to |OverviewSession::SetWindowListNotAnimatedWhenExiting|.
- DCHECK_EQ(gfx::Size(), target->delegate()->GetMaximumSize());
- overview_controller->overview_session()
- ->SetWindowListNotAnimatedWhenExiting(target->GetRootWindow());
- overview_controller->EndOverview(OverviewEndAction::kSplitView);
- }
- const WMEvent wm_event(WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE);
- target_state->OnWMEvent(&wm_event);
- event->StopPropagation();
- }
- }
- }
- } // namespace ash
|