172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/native_dialog_window.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <gtk/gtk.h>
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/chromeos/frame/bubble_window.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/window.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/gtk/gtk_signal.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/native/native_view_host.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/dialog_delegate.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/non_client_view.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kDialogPadding = 3;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNativeDialogHost[] = "_chromeos_native_dialog_host_";
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(xiyuan): Use gtk_window_get_default_widget with GTK 2.14+.
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Gets the default widget of given dialog.
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickGtkWidget* GetDialogDefaultWidget(GtkDialog* dialog) {
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* default_widget = NULL;
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GList* children = gtk_container_get_children(
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GTK_CONTAINER(dialog->action_area));
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GList* current = children;
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  while (current) {
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    GtkWidget* widget = reinterpret_cast<GtkWidget*>(current->data);
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (GTK_WIDGET_HAS_DEFAULT(widget)) {
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      default_widget = widget;
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      break;
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    current = g_list_next(current);
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_list_free(children);
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return default_widget;
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass NativeDialogHost : public views::View,
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         public views::DialogDelegate {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NativeDialogHost(gfx::NativeView native_dialog,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int flags,
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   const gfx::Size& size,
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   const gfx::Size& min_size);
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~NativeDialogHost();
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // views::DialogDelegate implementation:
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool CanResize() const { return flags_ & DIALOG_FLAG_RESIZEABLE; }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual int GetDialogButtons() const { return 0; }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::wstring GetWindowTitle() const { return title_; }
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual views::View* GetContentsView() { return this; }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool IsModal() const { return flags_ & DIALOG_FLAG_MODAL; }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void WindowClosing();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnCheckResize);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnDialogDestroy);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // views::View implementation:
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual gfx::Size GetPreferredSize();
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Layout();
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ViewHierarchyChanged(bool is_add,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    views::View* parent,
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    views::View* child);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Init and attach to native dialog.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Init();
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check and apply minimum size restriction.
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CheckSize();
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The GtkDialog whose vbox will be displayed in this view.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeView dialog_;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NativeViewHost for the dialog's contents.
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::NativeViewHost* contents_view_;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring title_;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int flags_;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size size_;
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size preferred_size_;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size min_size_;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int destroy_signal_id_;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(NativeDialogHost);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeDialogHost, public:
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeDialogHost::NativeDialogHost(gfx::NativeView native_dialog,
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   int flags,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const gfx::Size& size,
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const gfx::Size& min_size)
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : dialog_(native_dialog),
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents_view_(NULL),
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      flags_(flags),
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      size_(size),
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      preferred_size_(size),
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      min_size_(min_size),
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      destroy_signal_id_(0) {
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* title = gtk_window_get_title(GTK_WINDOW(dialog_));
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (title)
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UTF8ToWide(title, strlen(title), &title_);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  destroy_signal_id_ = g_signal_connect(dialog_, "destroy",
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      G_CALLBACK(&OnDialogDestroyThunk), this);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNativeDialogHost::~NativeDialogHost() {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::OnCheckResize(GtkWidget* widget) {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Do auto height resize only when we are asked to do so.
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (size_.height() == 0) {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::NativeView contents = contents_view_->native_view();
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Check whether preferred height has changed. We keep the current width
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // unchanged and pass "-1" as height to let gtk calculate a proper height.
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_set_size_request(contents, width(), -1);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkRequisition requsition = { 0 };
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_size_request(contents, &requsition);
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (preferred_size_.height() != requsition.height) {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      preferred_size_.set_width(requsition.width);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      preferred_size_.set_height(requsition.height);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CheckSize();
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SizeToPreferredSize();
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      gfx::Size window_size = window()->non_client_view()->GetPreferredSize();
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::Rect window_bounds = window()->GetBounds();
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window_bounds.set_width(window_size.width());
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window_bounds.set_height(window_size.height());
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      window()->SetWindowBounds(window_bounds, NULL);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::OnDialogDestroy(GtkWidget* widget) {
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dialog_ = NULL;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  destroy_signal_id_ = 0;
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  window()->CloseWindow();
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeDialogHost, views::DialogDelegate implementation:
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::WindowClosing() {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (dialog_) {
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Disconnect the "destroy" signal because we are about to destroy
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the dialog ourselves and no longer interested in it.
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    g_signal_handler_disconnect(G_OBJECT(dialog_), destroy_signal_id_);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_dialog_response(GTK_DIALOG(dialog_), GTK_RESPONSE_DELETE_EVENT);
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeDialogHost, views::View implementation:
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Size NativeDialogHost::GetPreferredSize() {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return preferred_size_;
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::Layout() {
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents_view_->SetBounds(0, 0, width(), height());
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::ViewHierarchyChanged(bool is_add,
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            views::View* parent,
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            views::View* child) {
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_add && child == this)
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Init();
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NativeDialogHost, private:
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::Init() {
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (contents_view_)
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Get default widget of the dialog.
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* default_widget = GetDialogDefaultWidget(GTK_DIALOG(dialog_));
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Get focus widget of the dialog.
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* focus_widget = gtk_window_get_focus(GTK_WINDOW(dialog_));
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a GtkAlignment as dialog contents container.
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* contents = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_alignment_set_padding(GTK_ALIGNMENT(contents),
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kDialogPadding, kDialogPadding,
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kDialogPadding, kDialogPadding);
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Move dialog contents into our container.
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* dialog_contents = GTK_DIALOG(dialog_)->vbox;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_object_ref(dialog_contents);
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_remove(GTK_CONTAINER(dialog_), dialog_contents);
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_add(GTK_CONTAINER(contents), dialog_contents);
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_object_unref(dialog_contents);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_hide(dialog_);
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_object_set_data(G_OBJECT(dialog_), kNativeDialogHost,
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reinterpret_cast<gpointer>(this));
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_show_all(contents);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents_view_ = new views::NativeViewHost();
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(xiyuan): Find a better way to get proper background.
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  contents_view_->set_background(views::Background::CreateSolidBackground(
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      BubbleWindow::kBackgroundColor));
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(contents_view_);
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents_view_->Attach(contents);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(window()->GetNativeWindow(), "check-resize",
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      G_CALLBACK(&OnCheckResizeThunk), this);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  const int padding = 2 * kDialogPadding;
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Use gtk's default size if size is not specified.
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (size_.IsEmpty()) {
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Use given width or height if given.
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (size_.width() || size_.height()) {
236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      int width = size_.width() == 0 ? -1 : size_.width() + padding;
237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      int height = size_.height() == 0 ? -1 : size_.height() + padding;
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gtk_widget_set_size_request(contents, width, height);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkRequisition requsition = { 0 };
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_size_request(contents, &requsition);
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    preferred_size_.set_width(requsition.width);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    preferred_size_.set_height(requsition.height);
245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    preferred_size_.set_width(size_.width() + padding);
247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    preferred_size_.set_height(size_.height() + padding);
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CheckSize();
2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (default_widget)
2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    gtk_widget_grab_default(default_widget);
2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (focus_widget)
2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    gtk_widget_grab_focus(focus_widget);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NativeDialogHost::CheckSize() {
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Apply the minimum size.
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (preferred_size_.width() < min_size_.width())
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    preferred_size_.set_width(min_size_.width());
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (preferred_size_.height() < min_size_.height())
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    preferred_size_.set_height(min_size_.height());
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShowNativeDialog(gfx::NativeWindow parent,
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      gfx::NativeView native_dialog,
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      int flags,
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const gfx::Size& size,
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const gfx::Size& min_size) {
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NativeDialogHost* native_dialog_host =
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new NativeDialogHost(native_dialog, flags, size, min_size);
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  browser::CreateViewsWindow(parent, gfx::Rect(), native_dialog_host);
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  native_dialog_host->window()->Show();
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeWindow GetNativeDialogWindow(gfx::NativeView native_dialog) {
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NativeDialogHost* host = reinterpret_cast<NativeDialogHost*>(
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_object_get_data(G_OBJECT(native_dialog), kNativeDialogHost));
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return host ? host->window()->GetNativeWindow() : NULL;
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect GetNativeDialogContentsBounds(gfx::NativeView native_dialog) {
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NativeDialogHost* host = reinterpret_cast<NativeDialogHost*>(
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_object_get_data(G_OBJECT(native_dialog), kNativeDialogHost));
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return host ? host->bounds() : gfx::Rect();
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace chromeos
291