summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 20:56:36 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 20:56:36 +0000
commitf2887ad8d57d8ff1c826bda4311f7acd4edf637e (patch)
treed84499494880d0d78ea6f7562728360cf2b7ea53
parent560440269665f15714c2dd1cee17dc2a7ed501dd (diff)
downloadchromium_src-f2887ad8d57d8ff1c826bda4311f7acd4edf637e.zip
chromium_src-f2887ad8d57d8ff1c826bda4311f7acd4edf637e.tar.gz
chromium_src-f2887ad8d57d8ff1c826bda4311f7acd4edf637e.tar.bz2
Host cookie modal dialog and js modal modal dialog in NativeDialogHost
- Enable modal dialog in NativeDialogHost. This is not fully work in ChromeOS because e.g. user could still alt-tab away. However, setting modal would block user from interacting with relevant browser window and avoid crashes; - Move dialog close code from NativeHostDialog's destructor to WindowClosing because a dialog's "response" signal handler could rely on the contents; - Add "check-resize" signal handler to make GtkExpander work nicely with NativeDialogHost; - Add ShowModalDialogWithMinLocalizedWidth to gtk_util for cookie and js modal dialog; - Change in WidgetGtk::SetBounds to call gtk_window_move/resize always to keep GtkWindow's geometry info up-to-date; BUG=none TEST=Verify cookie prompt and js dialog on ChromeOS is hosted in a Chrome window and not occupy the whole screen. Review URL: http://codereview.chromium.org/1995001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46619 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/native_dialog_window.cc79
-rw-r--r--chrome/browser/chromeos/native_dialog_window.h15
-rw-r--r--chrome/browser/cookie_modal_dialog_gtk.cc12
-rw-r--r--chrome/browser/gtk/gtk_util.cc31
-rw-r--r--chrome/browser/gtk/gtk_util.h2
-rw-r--r--chrome/browser/js_modal_dialog_gtk.cc12
-rw-r--r--views/widget/widget_gtk.cc14
7 files changed, 119 insertions, 46 deletions
diff --git a/chrome/browser/chromeos/native_dialog_window.cc b/chrome/browser/chromeos/native_dialog_window.cc
index 69abbeb..3c7cc72 100644
--- a/chrome/browser/chromeos/native_dialog_window.cc
+++ b/chrome/browser/chromeos/native_dialog_window.cc
@@ -9,6 +9,7 @@
#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 {
@@ -24,18 +25,22 @@ namespace chromeos {
class NativeDialogHost : public views::View,
public views::DialogDelegate {
public:
- explicit NativeDialogHost(gfx::NativeView native_dialog,
- const gfx::Size& size,
- bool resizeable);
+ 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 resizeable_; }
+ 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:
@@ -55,8 +60,9 @@ class NativeDialogHost : public views::View,
views::NativeViewHost* contents_view_;
std::wstring title_;
+ int flags_;
gfx::Size size_;
- bool resizeable_;
+ gfx::Size min_size_;
int destroy_signal_id_;
@@ -67,27 +73,45 @@ class NativeDialogHost : public views::View,
// NativeDialogHost, public:
NativeDialogHost::NativeDialogHost(gfx::NativeView native_dialog,
+ int flags,
const gfx::Size& size,
- bool resizeable)
+ const gfx::Size& min_size)
: dialog_(native_dialog),
contents_view_(NULL),
+ flags_(flags),
size_(size),
- resizeable_(resizeable),
+ 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);
+ G_CALLBACK(&OnDialogDestroyThunk), this);
}
NativeDialogHost::~NativeDialogHost() {
- 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);
+}
+
+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);
}
}
@@ -98,7 +122,18 @@ void NativeDialogHost::OnDialogDestroy(GtkWidget* widget) {
}
///////////////////////////////////////////////////////////////////////////////
-// NativeDialogHost, views::View overrides:
+// 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);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// NativeDialogHost, views::View implementation:
gfx::Size NativeDialogHost::GetPreferredSize() {
return size_;
@@ -144,6 +179,9 @@ void NativeDialogHost::Init() {
AddChildView(contents_view_);
contents_view_->Attach(contents);
+ g_signal_connect(window()->GetNativeWindow(), "check-resize",
+ G_CALLBACK(&OnCheckResizeThunk), this);
+
// Use gtk's default size if size is not speicified.
if (size_.IsEmpty()) {
// Use given width or height if given.
@@ -158,14 +196,21 @@ void NativeDialogHost::Init() {
size_.set_width(requsition.width);
size_.set_height(requsition.height);
}
+
+ // Apply the minimum size.
+ if (size_.width() < min_size_.width())
+ size_.set_width(min_size_.width());
+ if (size_.height() < min_size_.height())
+ size_.set_height(min_size_.height());
}
void ShowNativeDialog(gfx::NativeWindow parent,
gfx::NativeView native_dialog,
- const gfx::Size& dialog_size,
- bool resizeable) {
+ int flags,
+ const gfx::Size& size,
+ const gfx::Size& min_size) {
NativeDialogHost* native_dialog_host =
- new NativeDialogHost(native_dialog, dialog_size, resizeable);
+ new NativeDialogHost(native_dialog, flags, size, min_size);
views::Window::CreateChromeWindow(parent, gfx::Rect(), native_dialog_host);
native_dialog_host->window()->Show();
}
diff --git a/chrome/browser/chromeos/native_dialog_window.h b/chrome/browser/chromeos/native_dialog_window.h
index 2dd14c4..82fa853 100644
--- a/chrome/browser/chromeos/native_dialog_window.h
+++ b/chrome/browser/chromeos/native_dialog_window.h
@@ -13,11 +13,22 @@ class Size;
namespace chromeos {
-// Shows a native dialog in views::Window.
+// Flags for ShowNativeDialog.
+enum NativeDialogFlags {
+ DIALOG_FLAG_DEFAULT = 0x00, // Default non-resizeable, non-modal dialog.
+ DIALOG_FLAG_RESIZEABLE = 0x01, // For resizeable dialog.
+ DIALOG_FLAG_MODAL = 0x02, // For modal dialog.
+};
+
+// Shows a |native_dialog| hosted in a views::Window. |flags| are combinations
+// of the NativeDialogFlags. |size| is a default size. Zero width/height of
+// |size| means let gtk choose a proper size for that dimension. |min_size| is
+// the minimum size of the final host Window.
void ShowNativeDialog(gfx::NativeWindow parent,
gfx::NativeView native_dialog,
+ int flags,
const gfx::Size& size,
- bool resizeable);
+ const gfx::Size& min_size);
// Gets the container window of the given |native_dialog|.
gfx::NativeWindow GetNativeDialogWindow(gfx::NativeView native_dialog);
diff --git a/chrome/browser/cookie_modal_dialog_gtk.cc b/chrome/browser/cookie_modal_dialog_gtk.cc
index fed41de..e2add83 100644
--- a/chrome/browser/cookie_modal_dialog_gtk.cc
+++ b/chrome/browser/cookie_modal_dialog_gtk.cc
@@ -32,16 +32,8 @@ void OnExpanderActivate(GtkExpander* expander) {
void CookiePromptModalDialog::CreateAndShowDialog() {
dialog_ = CreateNativeDialog();
- gtk_widget_show_all(GTK_WIDGET(dialog_));
-
- // Suggest a minimum size.
- gint width;
- GtkRequisition req;
- gtk_widget_size_request(dialog_, &req);
- gtk_util::GetWidgetSizeFromResources(dialog_, IDS_ALERT_DIALOG_WIDTH_CHARS, 0,
- &width, NULL);
- if (width > req.width)
- gtk_widget_set_size_request(dialog_, width, -1);
+ gtk_util::ShowModalDialogWithMinLocalizedWidth(GTK_WIDGET(dialog_),
+ IDS_ALERT_DIALOG_WIDTH_CHARS);
}
void CookiePromptModalDialog::AcceptWindow() {
diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc
index cab430c..c170da1 100644
--- a/chrome/browser/gtk/gtk_util.cc
+++ b/chrome/browser/gtk/gtk_util.cc
@@ -918,7 +918,7 @@ bool AddWindowAlphaChannel(GtkWidget* window) {
void ShowDialog(GtkWidget* dialog) {
chromeos::ShowNativeDialog(chromeos::GetOptionsViewParent(),
- dialog, gfx::Size(), false);
+ dialog, chromeos::DIALOG_FLAG_DEFAULT, gfx::Size(), gfx::Size());
}
void ShowDialogWithLocalizedSize(GtkWidget* dialog,
@@ -932,8 +932,22 @@ void ShowDialogWithLocalizedSize(GtkWidget* dialog,
chromeos::ShowNativeDialog(chromeos::GetOptionsViewParent(),
dialog,
+ resizeable ? chromeos::DIALOG_FLAG_RESIZEABLE :
+ chromeos::DIALOG_FLAG_DEFAULT,
gfx::Size(width, height),
- resizeable);
+ gfx::Size());
+}
+
+void ShowModalDialogWithMinLocalizedWidth(GtkWidget* dialog,
+ int width_id) {
+ int width = (width_id == -1) ? 0 :
+ views::Window::GetLocalizedContentsWidth(width_id);
+
+ chromeos::ShowNativeDialog(chromeos::GetOptionsViewParent(),
+ dialog,
+ chromeos::DIALOG_FLAG_MODAL,
+ gfx::Size(),
+ gfx::Size(width, 0));
}
void PresentWindow(GtkWidget* window, int timestamp) {
@@ -964,6 +978,19 @@ void ShowDialogWithLocalizedSize(GtkWidget* dialog,
gtk_widget_show_all(dialog);
}
+void ShowModalDialogWithMinLocalizedWidth(GtkWidget* dialog,
+ int width_id) {
+ gtk_widget_show_all(dialog);
+
+ // Suggest a minimum size.
+ gint width;
+ GtkRequisition req;
+ gtk_widget_size_request(dialog, &req);
+ gtk_util::GetWidgetSizeFromResources(dialog, width_id, 0, &width, NULL);
+ if (width > req.width)
+ gtk_widget_set_size_request(dialog, width, -1);
+}
+
void PresentWindow(GtkWidget* window, int timestamp) {
if (timestamp)
gtk_window_present_with_time(GTK_WINDOW(window), timestamp);
diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h
index b121e03..5b8104a 100644
--- a/chrome/browser/gtk/gtk_util.h
+++ b/chrome/browser/gtk/gtk_util.h
@@ -288,6 +288,8 @@ void ShowDialogWithLocalizedSize(GtkWidget* dialog,
int width_id,
int height_id,
bool resizeable);
+void ShowModalDialogWithMinLocalizedWidth(GtkWidget* dialog,
+ int width_id);
// Wrapper to present a window. On Linux, it just calls gtk_window_present or
// gtk_window_present_with_time for non-zero timestamp. For ChromeOS, it first
diff --git a/chrome/browser/js_modal_dialog_gtk.cc b/chrome/browser/js_modal_dialog_gtk.cc
index 73d7f16..29111d1 100644
--- a/chrome/browser/js_modal_dialog_gtk.cc
+++ b/chrome/browser/js_modal_dialog_gtk.cc
@@ -48,16 +48,8 @@ bool ShouldSuppressJSDialogs(GtkDialog* dialog) {
void JavaScriptAppModalDialog::CreateAndShowDialog() {
dialog_ = CreateNativeDialog();
- gtk_widget_show_all(GTK_WIDGET(GTK_DIALOG(dialog_)));
-
- // Suggest a minimum size.
- gint width;
- GtkRequisition req;
- gtk_widget_size_request(dialog_, &req);
- gtk_util::GetWidgetSizeFromResources(dialog_, IDS_ALERT_DIALOG_WIDTH_CHARS, 0,
- &width, NULL);
- if (width > req.width)
- gtk_widget_set_size_request(dialog_, width, -1);
+ gtk_util::ShowModalDialogWithMinLocalizedWidth(GTK_WIDGET(dialog_),
+ IDS_ALERT_DIALOG_WIDTH_CHARS);
}
void JavaScriptAppModalDialog::HandleDialogResponse(GtkDialog* dialog,
diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc
index f7b35e0..4fa0f39 100644
--- a/views/widget/widget_gtk.cc
+++ b/views/widget/widget_gtk.cc
@@ -626,12 +626,16 @@ void WidgetGtk::SetBounds(const gfx::Rect& bounds) {
if (parent != null_parent_)
gtk_fixed_move(GTK_FIXED(parent), widget_, bounds.x(), bounds.y());
}
- } else if (GTK_WIDGET_MAPPED(widget_)) {
- // If the widget is mapped (on screen), we can move and resize with one
- // call, which avoids two separate window manager steps.
- gdk_window_move_resize(widget_->window, bounds.x(), bounds.y(),
- bounds.width(), bounds.height());
} else {
+ if (GTK_WIDGET_MAPPED(widget_)) {
+ // If the widget is mapped (on screen), we can move and resize with one
+ // call, which avoids two separate window manager steps.
+ gdk_window_move_resize(widget_->window, bounds.x(), bounds.y(),
+ bounds.width(), bounds.height());
+ }
+
+ // Always call gtk_window_move and gtk_window_resize so that GtkWindow's
+ // geometry info is up-to-date.
GtkWindow* gtk_window = GTK_WINDOW(widget_);
// TODO: this may need to set an initial size if not showing.
// TODO: need to constrain based on screen size.