<commit_before>// Copyright (c) 2011 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 "chrome/browser/ui/touch/frame/touch_browser_frame_view.h"

#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/touch/frame/keyboard_container_view.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_view.h"
#include "content/common/content_notification_types.h"
#include "content/common/notification_service.h"
#include "content/common/view_messages.h"
#include "ui/base/animation/slide_animation.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
#include "views/controls/button/image_button.h"
#include "views/controls/textfield/textfield.h"
#include "views/focus/focus_manager.h"
#include "views/window/hit_test.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h"
#endif

namespace {

const int kDefaultKeyboardHeight = 300;
const int kKeyboardSlideDuration = 300;  // In milliseconds

PropertyAccessor<bool>* GetFocusedStateAccessor() {
  static PropertyAccessor<bool> state;
  return &state;
}

bool TabContentsHasFocus(const TabContents* contents) {
  views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
  return view->Contains(view->GetFocusManager()->GetFocusedView());
}

}  // namespace

// static
const char TouchBrowserFrameView::kViewClassName[] =
    "browser/ui/touch/frame/TouchBrowserFrameView";

///////////////////////////////////////////////////////////////////////////////
// TouchBrowserFrameView, public:

TouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame,
                                             BrowserView* browser_view)
    : OpaqueBrowserFrameView(frame, browser_view),
      keyboard_showing_(false),
      keyboard_height_(kDefaultKeyboardHeight),
      focus_listener_added_(false),
      keyboard_(NULL) {
  registrar_.Add(this,
                 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 chrome::NOTIFICATION_EDITABLE_ELEMENT_TOUCHED,
                 NotificationService::AllSources());

  browser_view->browser()->tabstrip_model()->AddObserver(this);

  animation_.reset(new ui::SlideAnimation(this));
  animation_->SetTweenType(ui::Tween::LINEAR);
  animation_->SetSlideDuration(kKeyboardSlideDuration);

#if defined(OS_CHROMEOS)
  chromeos::input_method::InputMethodManager* manager =
      chromeos::input_method::InputMethodManager::GetInstance();
  manager->AddVirtualKeyboardObserver(this);
#endif
}

TouchBrowserFrameView::~TouchBrowserFrameView() {
  browser_view()->browser()->tabstrip_model()->RemoveObserver(this);
}

int TouchBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
  if (keyboard_->GetMirroredBounds().Contains(point))
    return HTCLIENT;
  return OpaqueBrowserFrameView::NonClientHitTest(point);
}

std::string TouchBrowserFrameView::GetClassName() const {
  return kViewClassName;
}

void TouchBrowserFrameView::Layout() {
  OpaqueBrowserFrameView::Layout();

  if (!keyboard_)
    return;

  keyboard_->SetVisible(keyboard_showing_ || animation_->is_animating());
  gfx::Rect bounds = GetBoundsForReservedArea();
  if (animation_->is_animating() && !keyboard_showing_) {
    // The keyboard is in the process of hiding. So pretend it still has the
    // same bounds as when the keyboard is visible. But
    // |GetBoundsForReservedArea| should not take this into account so that the
    // render view gets the entire area to relayout itself.
    bounds.set_y(bounds.y() - keyboard_height_);
    bounds.set_height(keyboard_height_);
  }<commit_msg>touchui: Fix a crash when clicking before the keyboard shows up.<commit_after>// Copyright (c) 2011 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 "chrome/browser/ui/touch/frame/touch_browser_frame_view.h"

#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/touch/frame/keyboard_container_view.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_view.h"
#include "content/common/content_notification_types.h"
#include "content/common/notification_service.h"
#include "content/common/view_messages.h"
#include "ui/base/animation/slide_animation.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
#include "views/controls/button/image_button.h"
#include "views/controls/textfield/textfield.h"
#include "views/focus/focus_manager.h"
#include "views/window/hit_test.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h"
#endif

namespace {

const int kDefaultKeyboardHeight = 300;
const int kKeyboardSlideDuration = 300;  // In milliseconds

PropertyAccessor<bool>* GetFocusedStateAccessor() {
  static PropertyAccessor<bool> state;
  return &state;
}

bool TabContentsHasFocus(const TabContents* contents) {
  views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
  return view->Contains(view->GetFocusManager()->GetFocusedView());
}

}  // namespace

// static
const char TouchBrowserFrameView::kViewClassName[] =
    "browser/ui/touch/frame/TouchBrowserFrameView";

///////////////////////////////////////////////////////////////////////////////
// TouchBrowserFrameView, public:

TouchBrowserFrameView::TouchBrowserFrameView(BrowserFrame* frame,
                                             BrowserView* browser_view)
    : OpaqueBrowserFrameView(frame, browser_view),
      keyboard_showing_(false),
      keyboard_height_(kDefaultKeyboardHeight),
      focus_listener_added_(false),
      keyboard_(NULL) {
  registrar_.Add(this,
                 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED,
                 NotificationService::AllSources());
  registrar_.Add(this,
                 chrome::NOTIFICATION_EDITABLE_ELEMENT_TOUCHED,
                 NotificationService::AllSources());

  browser_view->browser()->tabstrip_model()->AddObserver(this);

  animation_.reset(new ui::SlideAnimation(this));
  animation_->SetTweenType(ui::Tween::LINEAR);
  animation_->SetSlideDuration(kKeyboardSlideDuration);

#if defined(OS_CHROMEOS)
  chromeos::input_method::InputMethodManager* manager =
      chromeos::input_method::InputMethodManager::GetInstance();
  manager->AddVirtualKeyboardObserver(this);
#endif
}

TouchBrowserFrameView::~TouchBrowserFrameView() {
  browser_view()->browser()->tabstrip_model()->RemoveObserver(this);
}

int TouchBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
  if (keyboard_ && keyboard_->GetMirroredBounds().Contains(point))
    return HTCLIENT;
  return OpaqueBrowserFrameView::NonClientHitTest(point);
}

std::string TouchBrowserFrameView::GetClassName() const {
  return kViewClassName;
}

void TouchBrowserFrameView::Layout() {
  OpaqueBrowserFrameView::Layout();

  if (!keyboard_)
    return;

  keyboard_->SetVisible(keyboard_showing_ || animation_->is_animating());
  gfx::Rect bounds = GetBoundsForReservedArea();
  if (animation_->is_animating() && !keyboard_showing_) {
    // The keyboard is in the process of hiding. So pretend it still has the
    // same bounds as when the keyboard is visible. But
    // |GetBoundsForReservedArea| should not take this into account so that the
    // render view gets the entire area to relayout itself.
    bounds.set_y(bounds.y() - keyboard_height_);
    bounds.set_height(keyboard_height_);
  }
{'fraction_non_alphanumeric': 0.12762059841237533, 'fraction_numerical': 0.0020354162426216163, 'mean_word_length': 4.38170865279299, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4040807', 'n_tokens_mistral': 2902, 'n_tokens_neox': 2878, 'n_words': 477}