1// Copyright 2014 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 5#include "ash/wm/resize_handle_window_targeter.h" 6 7#include "ash/ash_constants.h" 8#include "ash/wm/immersive_fullscreen_controller.h" 9#include "ash/wm/window_state.h" 10#include "ui/aura/window.h" 11 12namespace ash { 13 14ResizeHandleWindowTargeter::ResizeHandleWindowTargeter( 15 aura::Window* window, 16 ImmersiveFullscreenController* controller) 17 : window_(window), 18 immersive_controller_(controller) { 19 wm::WindowState* window_state = wm::GetWindowState(window_); 20 OnPostWindowStateTypeChange(window_state, wm::WINDOW_STATE_TYPE_DEFAULT); 21 window_state->AddObserver(this); 22 window_->AddObserver(this); 23} 24 25ResizeHandleWindowTargeter::~ResizeHandleWindowTargeter() { 26 if (window_) { 27 window_->RemoveObserver(this); 28 wm::GetWindowState(window_)->RemoveObserver(this); 29 } 30} 31 32void ResizeHandleWindowTargeter::OnPostWindowStateTypeChange( 33 wm::WindowState* window_state, 34 wm::WindowStateType old_type) { 35 if (window_state->IsMaximizedOrFullscreen()) { 36 frame_border_inset_ = gfx::Insets(); 37 } else { 38 frame_border_inset_ = gfx::Insets(kResizeInsideBoundsSize, 39 kResizeInsideBoundsSize, 40 kResizeInsideBoundsSize, 41 kResizeInsideBoundsSize); 42 } 43} 44 45void ResizeHandleWindowTargeter::OnWindowDestroying(aura::Window* window) { 46 CHECK_EQ(window_, window); 47 wm::GetWindowState(window_)->RemoveObserver(this); 48 window_ = NULL; 49} 50 51ui::EventTarget* ResizeHandleWindowTargeter::FindTargetForLocatedEvent( 52 ui::EventTarget* root, 53 ui::LocatedEvent* event) { 54 aura::Window* window = static_cast<aura::Window*>(root); 55 if (window == window_) { 56 gfx::Insets insets; 57 if (immersive_controller_ && immersive_controller_->IsEnabled() && 58 !immersive_controller_->IsRevealed() && 59 event->IsTouchEvent()) { 60 // If the window is in immersive fullscreen, and top-of-window views are 61 // not revealed, then touch events towards the top of the window 62 // should not reach the child window so that touch gestures can be used to 63 // reveal the top-of-windows views. This is needed because the child 64 // window may consume touch events and prevent touch-scroll gesture from 65 // being generated. 66 insets = gfx::Insets(kImmersiveFullscreenTopEdgeInset, 0, 0, 0); 67 } else { 68 // If the event falls very close to the inside of the frame border, then 69 // target the window itself, so that the window can be resized easily. 70 insets = frame_border_inset_; 71 } 72 73 if (!insets.empty()) { 74 gfx::Rect bounds = gfx::Rect(window_->bounds().size()); 75 bounds.Inset(insets); 76 if (!bounds.Contains(event->location())) 77 return window_; 78 } 79 } 80 return aura::WindowTargeter::FindTargetForLocatedEvent(root, event); 81} 82 83bool ResizeHandleWindowTargeter::SubtreeShouldBeExploredForEvent( 84 ui::EventTarget* target, 85 const ui::LocatedEvent& event) { 86 if (target == window_) { 87 // Defer to the parent's targeter on whether |window_| should be able to 88 // receive the event. 89 ui::EventTarget* parent = target->GetParentTarget(); 90 if (parent) { 91 ui::EventTargeter* targeter = parent->GetEventTargeter(); 92 if (targeter) 93 return targeter->SubtreeShouldBeExploredForEvent(target, event); 94 } 95 } 96 return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(target, event); 97} 98 99} // namespace ash 100