diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 20:56:36 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-06 20:56:36 +0000 |
commit | f2887ad8d57d8ff1c826bda4311f7acd4edf637e (patch) | |
tree | d84499494880d0d78ea6f7562728360cf2b7ea53 | |
parent | 560440269665f15714c2dd1cee17dc2a7ed501dd (diff) | |
download | chromium_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.cc | 79 | ||||
-rw-r--r-- | chrome/browser/chromeos/native_dialog_window.h | 15 | ||||
-rw-r--r-- | chrome/browser/cookie_modal_dialog_gtk.cc | 12 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_util.cc | 31 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_util.h | 2 | ||||
-rw-r--r-- | chrome/browser/js_modal_dialog_gtk.cc | 12 | ||||
-rw-r--r-- | views/widget/widget_gtk.cc | 14 |
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. |