// Copyright 2014 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/resize_handle_window_targeter.h" #include "ash/ash_constants.h" #include "ash/wm/immersive_fullscreen_controller.h" #include "ash/wm/window_state.h" #include "ui/aura/window.h" #include "ui/events/event.h" namespace ash { ResizeHandleWindowTargeter::ResizeHandleWindowTargeter( aura::Window* window, ImmersiveFullscreenController* controller) : window_(window), immersive_controller_(controller) { wm::WindowState* window_state = wm::GetWindowState(window_); OnPostWindowStateTypeChange(window_state, wm::WINDOW_STATE_TYPE_DEFAULT); window_state->AddObserver(this); window_->AddObserver(this); } ResizeHandleWindowTargeter::~ResizeHandleWindowTargeter() { if (window_) { window_->RemoveObserver(this); wm::GetWindowState(window_)->RemoveObserver(this); } } void ResizeHandleWindowTargeter::OnPostWindowStateTypeChange( wm::WindowState* window_state, wm::WindowStateType old_type) { if (window_state->IsMaximizedOrFullscreen()) { frame_border_inset_ = gfx::Insets(); } else { frame_border_inset_ = gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize, kResizeInsideBoundsSize, kResizeInsideBoundsSize); } } void ResizeHandleWindowTargeter::OnWindowDestroying(aura::Window* window) { CHECK_EQ(window_, window); wm::GetWindowState(window_)->RemoveObserver(this); window_ = NULL; } aura::Window* ResizeHandleWindowTargeter::FindTargetForLocatedEvent( aura::Window* window, ui::LocatedEvent* event) { if (window == window_) { gfx::Insets insets; if (immersive_controller_ && immersive_controller_->IsEnabled() && !immersive_controller_->IsRevealed() && event->IsTouchEvent()) { // If the window is in immersive fullscreen, and top-of-window views are // not revealed, then touch events towards the top of the window // should not reach the child window so that touch gestures can be used to // reveal the top-of-windows views. This is needed because the child // window may consume touch events and prevent touch-scroll gesture from // being generated. insets = gfx::Insets(kImmersiveFullscreenTopEdgeInset, 0, 0, 0); } else { // If the event falls very close to the inside of the frame border, then // target the window itself, so that the window can be resized easily. insets = frame_border_inset_; } if (!insets.IsEmpty()) { gfx::Rect bounds = gfx::Rect(window_->bounds().size()); bounds.Inset(insets); if (!bounds.Contains(event->location())) return window_; } } return aura::WindowTargeter::FindTargetForLocatedEvent(window, event); } bool ResizeHandleWindowTargeter::SubtreeShouldBeExploredForEvent( aura::Window* window, const ui::LocatedEvent& event) { if (window == window_) { // Defer to the parent's targeter on whether |window_| should be able to // receive the event. ui::EventTarget* parent = static_cast(window)->GetParentTarget(); if (parent) { aura::WindowTargeter* targeter = static_cast(parent->GetEventTargeter()); if (targeter) return targeter->SubtreeShouldBeExploredForEvent(window, event); } } return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(window, event); } } // namespace ash