<commit_before>// Copyright (c) 2010 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/chromeos/native_dialog_window.h"

#include "app/gtk_signal.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "views/controls/native/native_view_host.h"
#include "views/window/dialog_delegate.h"
#include "views/window/non_client_view.h"
#include "views/window/window.h"

namespace {

const int kDialogPadding = 3;

const char kNativeDialogHostWindow[] = "_chromeos_native_dialog_host_window_";

}  // namespace

namespace chromeos {

class NativeDialogHost : public views::View,
                         public views::DialogDelegate {
 public:
  NativeDialogHost(gfx::NativeView native_dialog,
                   int flags,
                   const gfx::Size& size,
                   const gfx::Size& min_size);
  ~NativeDialogHost();

  // views::DialogDelegate implementation:
  virtual bool CanResize() const { return flags_ & DIALOG_FLAG_RESIZEABLE; }
  virtual int GetDialogButtons() const { return 0; }
  virtual std::wstring GetWindowTitle() const { return title_; }
  virtual views::View* GetContentsView() { return this; }
  virtual bool IsModal() const { return flags_ & DIALOG_FLAG_MODAL; }
  virtual void WindowClosing();

 protected:
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnCheckResize);
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnDialogDestroy);

  // views::View implementation:
  virtual gfx::Size GetPreferredSize();
  virtual void Layout();
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);
 private:
  // Init and attach to native dialog.
  void Init();

  // The GtkDialog whose vbox will be displayed in this view.
  gfx::NativeView dialog_;

  // NativeViewHost for the dialog's contents.
  views::NativeViewHost* contents_view_;

  std::wstring title_;
  int flags_;
  gfx::Size size_;
  gfx::Size min_size_;

  int destroy_signal_id_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(NativeDialogHost);
};

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, public:

NativeDialogHost::NativeDialogHost(gfx::NativeView native_dialog,
                                   int flags,
                                   const gfx::Size& size,
                                   const gfx::Size& min_size)
    : dialog_(native_dialog),
      contents_view_(NULL),
      flags_(flags),
      size_(size),
      min_size_(min_size),
      destroy_signal_id_(0) {
  const char* title = gtk_window_get_title(GTK_WINDOW(dialog_));
  if (title)
    UTF8ToWide(title, strlen(title), &title_);

  destroy_signal_id_ = g_signal_connect(dialog_, "destroy",
      G_CALLBACK(&OnDialogDestroyThunk), this);
}

NativeDialogHost::~NativeDialogHost() {
}

void NativeDialogHost::OnCheckResize(GtkWidget* widget) {
  gfx::NativeView contents = contents_view_->native_view();

  // Check whether preferred height has changed. We keep the current width
  // unchanged and pass "-1" as height to let gtk calculate a proper height.
  gtk_widget_set_size_request(contents, width(), -1);
  GtkRequisition requsition = { 0 };
  gtk_widget_size_request(contents, &requsition);

  if (size_.height() != requsition.height) {
    size_.set_width(requsition.width);
    size_.set_height(requsition.height);
    SizeToPreferredSize();

    gfx::Size window_size = window()->GetNonClientView()->GetPreferredSize();
    gfx::Rect window_bounds = window()->GetBounds();
    window_bounds.set_width(window_size.width());
    window_bounds.set_height(window_size.height());
    window()->SetBounds(window_bounds, NULL);
  }
}

void NativeDialogHost::OnDialogDestroy(GtkWidget* widget) {
  dialog_ = NULL;
  destroy_signal_id_ = 0;
  window()->Close();
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, views::DialogDelegate implementation:
void NativeDialogHost::WindowClosing() {
  if (dialog_) {
    // Disconnect the "destroy" signal because we are about to destroy
    // the dialog ourselves and no longer interested in it.
    g_signal_handler_disconnect(G_OBJECT(dialog_), destroy_signal_id_);
    gtk_dialog_response(GTK_DIALOG(dialog_), GTK_RESPONSE_CLOSE);
  }
}
<commit_msg>Native dialogs need to send GTK_RESPONSE_DELETE_EVENT on close BUG=chromium-os:3211 TEST=Use html in bug, click "test" and then click close button.      App shouldn't freeze.<commit_after>// Copyright (c) 2010 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/chromeos/native_dialog_window.h"

#include "app/gtk_signal.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "views/controls/native/native_view_host.h"
#include "views/window/dialog_delegate.h"
#include "views/window/non_client_view.h"
#include "views/window/window.h"

namespace {

const int kDialogPadding = 3;

const char kNativeDialogHostWindow[] = "_chromeos_native_dialog_host_window_";

}  // namespace

namespace chromeos {

class NativeDialogHost : public views::View,
                         public views::DialogDelegate {
 public:
  NativeDialogHost(gfx::NativeView native_dialog,
                   int flags,
                   const gfx::Size& size,
                   const gfx::Size& min_size);
  ~NativeDialogHost();

  // views::DialogDelegate implementation:
  virtual bool CanResize() const { return flags_ & DIALOG_FLAG_RESIZEABLE; }
  virtual int GetDialogButtons() const { return 0; }
  virtual std::wstring GetWindowTitle() const { return title_; }
  virtual views::View* GetContentsView() { return this; }
  virtual bool IsModal() const { return flags_ & DIALOG_FLAG_MODAL; }
  virtual void WindowClosing();

 protected:
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnCheckResize);
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnDialogDestroy);

  // views::View implementation:
  virtual gfx::Size GetPreferredSize();
  virtual void Layout();
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);
 private:
  // Init and attach to native dialog.
  void Init();

  // The GtkDialog whose vbox will be displayed in this view.
  gfx::NativeView dialog_;

  // NativeViewHost for the dialog's contents.
  views::NativeViewHost* contents_view_;

  std::wstring title_;
  int flags_;
  gfx::Size size_;
  gfx::Size min_size_;

  int destroy_signal_id_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(NativeDialogHost);
};

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, public:

NativeDialogHost::NativeDialogHost(gfx::NativeView native_dialog,
                                   int flags,
                                   const gfx::Size& size,
                                   const gfx::Size& min_size)
    : dialog_(native_dialog),
      contents_view_(NULL),
      flags_(flags),
      size_(size),
      min_size_(min_size),
      destroy_signal_id_(0) {
  const char* title = gtk_window_get_title(GTK_WINDOW(dialog_));
  if (title)
    UTF8ToWide(title, strlen(title), &title_);

  destroy_signal_id_ = g_signal_connect(dialog_, "destroy",
      G_CALLBACK(&OnDialogDestroyThunk), this);
}

NativeDialogHost::~NativeDialogHost() {
}

void NativeDialogHost::OnCheckResize(GtkWidget* widget) {
  gfx::NativeView contents = contents_view_->native_view();

  // Check whether preferred height has changed. We keep the current width
  // unchanged and pass "-1" as height to let gtk calculate a proper height.
  gtk_widget_set_size_request(contents, width(), -1);
  GtkRequisition requsition = { 0 };
  gtk_widget_size_request(contents, &requsition);

  if (size_.height() != requsition.height) {
    size_.set_width(requsition.width);
    size_.set_height(requsition.height);
    SizeToPreferredSize();

    gfx::Size window_size = window()->GetNonClientView()->GetPreferredSize();
    gfx::Rect window_bounds = window()->GetBounds();
    window_bounds.set_width(window_size.width());
    window_bounds.set_height(window_size.height());
    window()->SetBounds(window_bounds, NULL);
  }
}

void NativeDialogHost::OnDialogDestroy(GtkWidget* widget) {
  dialog_ = NULL;
  destroy_signal_id_ = 0;
  window()->Close();
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, views::DialogDelegate implementation:
void NativeDialogHost::WindowClosing() {
  if (dialog_) {
    // Disconnect the "destroy" signal because we are about to destroy
    // the dialog ourselves and no longer interested in it.
    g_signal_handler_disconnect(G_OBJECT(dialog_), destroy_signal_id_);
    gtk_dialog_response(GTK_DIALOG(dialog_), GTK_RESPONSE_DELETE_EVENT);
  }
}

{'fraction_non_alphanumeric': 0.13620230700976044, 'fraction_numerical': 0.00354924578527063, 'mean_word_length': 3.1687471104946834, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5004157', 'n_tokens_mistral': 2664, 'n_tokens_neox': 2599, 'n_words': 618}