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