diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-15 22:58:02 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-15 22:58:02 +0000 |
commit | 5076008b85807c1059f0451abd406ebc747ffe6c (patch) | |
tree | bbf918a2febf48cba0110f0e6aff11e69e774142 /chrome/browser/ui | |
parent | eb93b619bebd38510f21d3f04d8f2641bf71af35 (diff) | |
download | chromium_src-5076008b85807c1059f0451abd406ebc747ffe6c.zip chromium_src-5076008b85807c1059f0451abd406ebc747ffe6c.tar.gz chromium_src-5076008b85807c1059f0451abd406ebc747ffe6c.tar.bz2 |
Focus on collected cookie contrained window when a TabContents gets focus.
- On Linux, use "hierarchy-changed" to set initial focus as other constrained
dialogs do;
- On ChromeOS, set initial focus as the following:
FocusManager::RestoreFocusedView (after info bubble dismiss) ->
... ->
NativeTabContentsContainerGtk::Focus ->
TabContentsViewGtk::Focus ->
ConstrainedWindowGtk::FocusConstrainedWindow ->
ConstrainedWindowGtkDelegate::Focus (overridden by CollectedCookiesGtk)
BUG=chromium:72592
TEST=Verify fix for chromium:72592.
Review URL: http://codereview.chromium.org/6475013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75024 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui')
12 files changed, 77 insertions, 51 deletions
diff --git a/chrome/browser/ui/gtk/collected_cookies_gtk.cc b/chrome/browser/ui/gtk/collected_cookies_gtk.cc index 2c2349e..f76b90c 100644 --- a/chrome/browser/ui/gtk/collected_cookies_gtk.cc +++ b/chrome/browser/ui/gtk/collected_cookies_gtk.cc @@ -249,11 +249,11 @@ void CollectedCookiesGtk::Init() { gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(button_box), gtk_util::kControlSpacing); gtk_box_pack_end(GTK_BOX(dialog_), button_box, FALSE, TRUE, 0); - GtkWidget* close = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_button_set_label(GTK_BUTTON(close), + close_button_ = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + gtk_button_set_label(GTK_BUTTON(close_button_), l10n_util::GetStringUTF8(IDS_CLOSE).c_str()); - g_signal_connect(close, "clicked", G_CALLBACK(OnCloseThunk), this); - gtk_box_pack_end(GTK_BOX(button_box), close, FALSE, TRUE, 0); + g_signal_connect(close_button_, "clicked", G_CALLBACK(OnCloseThunk), this); + gtk_box_pack_end(GTK_BOX(button_box), close_button_, FALSE, TRUE, 0); // Show the dialog. allowed_cookies_tree_adapter_->Init(); @@ -270,6 +270,10 @@ GtkWidget* CollectedCookiesGtk::GetWidgetRoot() { return dialog_; } +GtkWidget* CollectedCookiesGtk::GetFocusWidget() { + return close_button_; +} + void CollectedCookiesGtk::DeleteDelegate() { delete this; } diff --git a/chrome/browser/ui/gtk/collected_cookies_gtk.h b/chrome/browser/ui/gtk/collected_cookies_gtk.h index afb56fe..7907acd 100644 --- a/chrome/browser/ui/gtk/collected_cookies_gtk.h +++ b/chrome/browser/ui/gtk/collected_cookies_gtk.h @@ -32,6 +32,7 @@ class CollectedCookiesGtk : public ConstrainedDialogDelegate, // ConstrainedDialogDelegate methods. virtual GtkWidget* GetWidgetRoot(); + virtual GtkWidget* GetFocusWidget(); virtual void DeleteDelegate(); private: @@ -81,6 +82,7 @@ class CollectedCookiesGtk : public ConstrainedDialogDelegate, GtkWidget* allow_blocked_cookie_button_; GtkWidget* for_session_blocked_cookie_button_; + GtkWidget* close_button_; // The table listing the cookies. GtkWidget* allowed_tree_; diff --git a/chrome/browser/ui/gtk/constrained_html_delegate_gtk.cc b/chrome/browser/ui/gtk/constrained_html_delegate_gtk.cc index ed8d532..18b718f 100644 --- a/chrome/browser/ui/gtk/constrained_html_delegate_gtk.cc +++ b/chrome/browser/ui/gtk/constrained_html_delegate_gtk.cc @@ -28,6 +28,9 @@ class ConstrainedHtmlDelegateGtk : public ConstrainedWindowGtkDelegate, virtual GtkWidget* GetWidgetRoot() { return tab_contents_container_.widget(); } + virtual GtkWidget* GetFocusWidget() { + return tab_contents_.GetContentNativeView(); + } virtual void DeleteDelegate() { html_delegate_->OnDialogClosed(""); delete this; diff --git a/chrome/browser/ui/gtk/constrained_window_gtk.cc b/chrome/browser/ui/gtk/constrained_window_gtk.cc index 0579efc..5299d0b 100644 --- a/chrome/browser/ui/gtk/constrained_window_gtk.cc +++ b/chrome/browser/ui/gtk/constrained_window_gtk.cc @@ -7,6 +7,7 @@ #include <gdk/gdkkeysyms.h> #include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_thread.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/ui/gtk/gtk_util.h" @@ -62,6 +63,8 @@ ConstrainedWindowGtk::ConstrainedWindowGtk( gtk_widget_add_events(widget(), GDK_KEY_PRESS_MASK); g_signal_connect(widget(), "key-press-event", G_CALLBACK(OnKeyPressThunk), this); + g_signal_connect(widget(), "hierarchy-changed", + G_CALLBACK(OnHierarchyChangedThunk), this); } ConstrainedWindowGtk::~ConstrainedWindowGtk() { @@ -87,6 +90,27 @@ void ConstrainedWindowGtk::CloseConstrainedWindow() { delete this; } +void ConstrainedWindowGtk::FocusConstrainedWindow() { + GtkWidget* focus_widget = delegate_->GetFocusWidget(); + if (!focus_widget) + return; + + // The user may have focused another tab. In this case do not grab focus + // until this tab is refocused. + if ((!owner_->delegate() || + owner_->delegate()->ShouldFocusConstrainedWindow()) && + gtk_util::IsWidgetAncestryVisible(focus_widget)) { + gtk_widget_grab_focus(focus_widget); + } else { + // TODO(estade): this define should not need to be here because this class + // should not be used on linux/views. +#if defined(TOOLKIT_GTK) + static_cast<TabContentsViewGtk*>(owner_->view())-> + SetFocusedWidget(focus_widget); +#endif + } +} + ConstrainedWindowGtk::TabContentsViewType* ConstrainedWindowGtk::ContainingView() { return static_cast<TabContentsViewType*>(owner_->view()); @@ -106,6 +130,15 @@ gboolean ConstrainedWindowGtk::OnKeyPress(GtkWidget* sender, return FALSE; } +void ConstrainedWindowGtk::OnHierarchyChanged(GtkWidget* sender, + GtkWidget* previous_toplevel) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(widget()))) + return; + + FocusConstrainedWindow(); +} + // static ConstrainedWindow* ConstrainedWindow::CreateConstrainedDialog( TabContents* parent, diff --git a/chrome/browser/ui/gtk/constrained_window_gtk.h b/chrome/browser/ui/gtk/constrained_window_gtk.h index 2f01079..23ec224 100644 --- a/chrome/browser/ui/gtk/constrained_window_gtk.h +++ b/chrome/browser/ui/gtk/constrained_window_gtk.h @@ -27,6 +27,9 @@ class ConstrainedWindowGtkDelegate { // Returns the widget that will be put in the constrained window's container. virtual GtkWidget* GetWidgetRoot() = 0; + // Returns the widget that should get focus when ConstrainedWindow is focused. + virtual GtkWidget* GetFocusWidget() = 0; + // Tells the delegate to either delete itself or set up a task to delete // itself later. virtual void DeleteDelegate() = 0; @@ -53,6 +56,7 @@ class ConstrainedWindowGtk : public ConstrainedWindow { // Overridden from ConstrainedWindow: virtual void ShowConstrainedWindow(); virtual void CloseConstrainedWindow(); + virtual void FocusConstrainedWindow(); // Returns the TabContents that constrains this Constrained Window. TabContents* owner() const { return owner_; } @@ -69,9 +73,11 @@ class ConstrainedWindowGtk : public ConstrainedWindow { ConstrainedWindowGtk(TabContents* owner, ConstrainedWindowGtkDelegate* delegate); - // Handler for Escape. + // Signal callbacks. CHROMEGTK_CALLBACK_1(ConstrainedWindowGtk, gboolean, OnKeyPress, GdkEventKey*); + CHROMEGTK_CALLBACK_1(ConstrainedWindowGtk, void, OnHierarchyChanged, + GtkWidget*); // The TabContents that owns and constrains this ConstrainedWindow. TabContents* owner_; diff --git a/chrome/browser/ui/gtk/repost_form_warning_gtk.cc b/chrome/browser/ui/gtk/repost_form_warning_gtk.cc index 68aa14e..3a64e20 100644 --- a/chrome/browser/ui/gtk/repost_form_warning_gtk.cc +++ b/chrome/browser/ui/gtk/repost_form_warning_gtk.cc @@ -54,9 +54,6 @@ RepostFormWarningGtk::RepostFormWarningGtk(GtkWindow* parent, g_signal_connect(ok_, "clicked", G_CALLBACK(OnRefreshThunk), this); gtk_box_pack_end(GTK_BOX(buttonBox), ok_, FALSE, TRUE, 0); - g_signal_connect(cancel_, "hierarchy-changed", - G_CALLBACK(OnHierarchyChangedThunk), this); - controller_->Show(this); } @@ -64,6 +61,10 @@ GtkWidget* RepostFormWarningGtk::GetWidgetRoot() { return dialog_; } +GtkWidget* RepostFormWarningGtk::GetFocusWidget() { + return cancel_; +} + void RepostFormWarningGtk::DeleteDelegate() { delete this; } @@ -79,12 +80,3 @@ void RepostFormWarningGtk::OnRefresh(GtkWidget* widget) { void RepostFormWarningGtk::OnCancel(GtkWidget* widget) { controller_->Cancel(); } - -void RepostFormWarningGtk::OnHierarchyChanged(GtkWidget* root, - GtkWidget* previous_toplevel) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (!GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(cancel_))) { - return; - } - gtk_widget_grab_focus(cancel_); -} diff --git a/chrome/browser/ui/gtk/repost_form_warning_gtk.h b/chrome/browser/ui/gtk/repost_form_warning_gtk.h index 6fa7cef..935fd48 100644 --- a/chrome/browser/ui/gtk/repost_form_warning_gtk.h +++ b/chrome/browser/ui/gtk/repost_form_warning_gtk.h @@ -25,7 +25,7 @@ class RepostFormWarningGtk : public ConstrainedDialogDelegate { // ConstrainedDialogDelegate methods virtual GtkWidget* GetWidgetRoot(); - + virtual GtkWidget* GetFocusWidget(); virtual void DeleteDelegate(); private: @@ -34,10 +34,6 @@ class RepostFormWarningGtk : public ConstrainedDialogDelegate { // Callbacks CHROMEGTK_CALLBACK_0(RepostFormWarningGtk, void, OnRefresh); CHROMEGTK_CALLBACK_0(RepostFormWarningGtk, void, OnCancel); - CHROMEGTK_CALLBACK_1(RepostFormWarningGtk, - void, - OnHierarchyChanged, - GtkWidget*); scoped_ptr<RepostFormWarningController> controller_; diff --git a/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc b/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc index bc5be25..4afe254 100644 --- a/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc +++ b/chrome/browser/ui/gtk/ssl_client_certificate_selector.cc @@ -48,6 +48,7 @@ class SSLClientCertificateSelector : public ConstrainedDialogDelegate { // ConstrainedDialogDelegate implementation: virtual GtkWidget* GetWidgetRoot() { return root_widget_.get(); } + virtual GtkWidget* GetFocusWidget(); virtual void DeleteDelegate(); private: @@ -190,6 +191,10 @@ void SSLClientCertificateSelector::Show() { window_ = parent_->CreateConstrainedDialog(this); } +GtkWidget* SSLClientCertificateSelector::GetFocusWidget() { + return select_button_; +} + void SSLClientCertificateSelector::DeleteDelegate() { if (delegate_) { // The dialog was closed by escape key. @@ -356,7 +361,6 @@ void SSLClientCertificateSelector::OnPromptShown(GtkWidget* widget, return; GTK_WIDGET_SET_FLAGS(select_button_, GTK_CAN_DEFAULT); gtk_widget_grab_default(select_button_); - gtk_widget_grab_focus(select_button_); } } // namespace diff --git a/chrome/browser/ui/login/login_prompt_gtk.cc b/chrome/browser/ui/login/login_prompt_gtk.cc index e6487a5..990ab1f 100644 --- a/chrome/browser/ui/login/login_prompt_gtk.cc +++ b/chrome/browser/ui/login/login_prompt_gtk.cc @@ -121,6 +121,10 @@ class LoginHandlerGtk : public LoginHandler, return root_.get(); } + virtual GtkWidget* GetFocusWidget() { + return username_entry_; + } + virtual void DeleteDelegate() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -172,23 +176,6 @@ void LoginHandlerGtk::OnPromptHierarchyChanged(GtkWidget* sender, // button the default action and mess with the focus. GTK_WIDGET_SET_FLAGS(ok_, GTK_CAN_DEFAULT); gtk_widget_grab_default(ok_); - - TabContents* contents = GetTabContentsForLogin(); - - // The user may have focused another tab. In this case do not grab focus - // until this tab is refocused. - if ((!contents->delegate() || - contents->delegate()->ShouldFocusConstrainedWindow()) && - gtk_util::IsWidgetAncestryVisible(username_entry_)) { - gtk_widget_grab_focus(username_entry_); - } else { - // TODO(estade): this define should not need to be here because this class - // should not be used on linux/views. -#if defined(TOOLKIT_GTK) - static_cast<TabContentsViewGtk*>(contents->view())-> - SetFocusedWidget(username_entry_); -#endif - } } // static diff --git a/chrome/browser/ui/views/constrained_html_delegate_gtk.cc b/chrome/browser/ui/views/constrained_html_delegate_gtk.cc index 462f5b8..04aee79 100644 --- a/chrome/browser/ui/views/constrained_html_delegate_gtk.cc +++ b/chrome/browser/ui/views/constrained_html_delegate_gtk.cc @@ -38,6 +38,9 @@ class ConstrainedHtmlDelegateGtk : public views::WidgetGtk, virtual GtkWidget* GetWidgetRoot() { return GetNativeView(); } + virtual GtkWidget* GetFocusWidget() { + return html_tab_contents_.GetContentNativeView(); + } virtual void DeleteDelegate() { html_delegate_->OnDialogClosed(""); tab_container_->ChangeTabContents(NULL); diff --git a/chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.cc b/chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.cc index 2013a65..f9bffef 100644 --- a/chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.cc +++ b/chrome/browser/ui/views/tab_contents/native_tab_contents_container_gtk.cc @@ -99,17 +99,8 @@ bool NativeTabContentsContainerGtk::IsFocusable() const { } void NativeTabContentsContainerGtk::Focus() { - if (container_->tab_contents()) { - // Set the native focus on the actual content of the tab, that is the - // interstitial if one is showing. - if (container_->tab_contents()->interstitial_page()) { - container_->tab_contents()->interstitial_page()->Focus(); - return; - } - GtkWidget* widget = container_->tab_contents()->GetContentNativeView(); - if (widget) - gtk_widget_grab_focus(widget); - } + if (container_->tab_contents()) + container_->tab_contents()->Focus(); } void NativeTabContentsContainerGtk::RequestFocus() { diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc index f9f5979..bc780b7 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_gtk.cc @@ -267,6 +267,11 @@ void TabContentsViewGtk::Focus() { return; } + if (constrained_windows_.size()) { + constrained_windows_.back()->FocusConstrainedWindow(); + return; + } + RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView(); gtk_widget_grab_focus(rwhv ? rwhv->GetNativeView() : GetNativeView()); } |