15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/resize_handle_window_targeter.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/ash_constants.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/immersive_fullscreen_controller.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_state.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace ash {
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResizeHandleWindowTargeter::ResizeHandleWindowTargeter(
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    aura::Window* window,
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ImmersiveFullscreenController* controller)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : window_(window),
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      immersive_controller_(controller) {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window_);
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  OnPostWindowStateTypeChange(window_state, wm::WINDOW_STATE_TYPE_DEFAULT);
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_state->AddObserver(this);
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_->AddObserver(this);
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResizeHandleWindowTargeter::~ResizeHandleWindowTargeter() {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window_) {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window_->RemoveObserver(this);
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    wm::GetWindowState(window_)->RemoveObserver(this);
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ResizeHandleWindowTargeter::OnPostWindowStateTypeChange(
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    wm::WindowState* window_state,
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wm::WindowStateType old_type) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window_state->IsMaximizedOrFullscreen()) {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    frame_border_inset_ = gfx::Insets();
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    frame_border_inset_ = gfx::Insets(kResizeInsideBoundsSize,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      kResizeInsideBoundsSize,
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      kResizeInsideBoundsSize,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      kResizeInsideBoundsSize);
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResizeHandleWindowTargeter::OnWindowDestroying(aura::Window* window) {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK_EQ(window_, window);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wm::GetWindowState(window_)->RemoveObserver(this);
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_ = NULL;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ui::EventTarget* ResizeHandleWindowTargeter::FindTargetForLocatedEvent(
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::EventTarget* root,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::LocatedEvent* event) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Window* window = static_cast<aura::Window*>(root);
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window == window_) {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::Insets insets;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (immersive_controller_ && immersive_controller_->IsEnabled() &&
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        !immersive_controller_->IsRevealed() &&
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        event->IsTouchEvent()) {
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // If the window is in immersive fullscreen, and top-of-window views are
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // not revealed, then touch events towards the top of the window
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // should not reach the child window so that touch gestures can be used to
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // reveal the top-of-windows views. This is needed because the child
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // window may consume touch events and prevent touch-scroll gesture from
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // being generated.
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      insets = gfx::Insets(kImmersiveFullscreenTopEdgeInset, 0, 0, 0);
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // If the event falls very close to the inside of the frame border, then
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // target the window itself, so that the window can be resized easily.
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      insets = frame_border_inset_;
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!insets.empty()) {
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::Rect bounds = gfx::Rect(window_->bounds().size());
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bounds.Inset(insets);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!bounds.Contains(event->location()))
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return window_;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return aura::WindowTargeter::FindTargetForLocatedEvent(root, event);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ResizeHandleWindowTargeter::SubtreeShouldBeExploredForEvent(
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::EventTarget* target,
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ui::LocatedEvent& event) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (target == window_) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Defer to the parent's targeter on whether |window_| should be able to
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // receive the event.
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ui::EventTarget* parent = target->GetParentTarget();
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (parent) {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ui::EventTargeter* targeter = parent->GetEventTargeter();
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (targeter)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return targeter->SubtreeShouldBeExploredForEvent(target, event);
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(target, event);
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace ash
100