diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-06 01:07:36 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-06 01:07:36 +0000 |
commit | 4a3111474cda4b74c26620fd58c3c843b96df7fc (patch) | |
tree | c23daaf1d521d866eefe895637d04ee5d3088e92 /views | |
parent | 341fbaa85d75ae8832993ec472ca67cdb82d45a1 (diff) | |
download | chromium_src-4a3111474cda4b74c26620fd58c3c843b96df7fc.zip chromium_src-4a3111474cda4b74c26620fd58c3c843b96df7fc.tar.gz chromium_src-4a3111474cda4b74c26620fd58c3c843b96df7fc.tar.bz2 |
Fixes bug where recreating fixed in NativeViewHostGtk causes focus to
get lost. This caused problems when going in/out of fullscreen mode.
I'm also improving the description of the WidgetGtk types.
CHROMEOS_BUG=1020
TEST=see bug
Review URL: http://codereview.chromium.org/518041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35594 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/native/native_view_host_gtk.cc | 35 | ||||
-rw-r--r-- | views/controls/native/native_view_host_gtk.h | 4 | ||||
-rw-r--r-- | views/widget/widget_gtk.h | 9 |
3 files changed, 46 insertions, 2 deletions
diff --git a/views/controls/native/native_view_host_gtk.cc b/views/controls/native/native_view_host_gtk.cc index ed4f5ba..30c562c 100644 --- a/views/controls/native/native_view_host_gtk.cc +++ b/views/controls/native/native_view_host_gtk.cc @@ -182,6 +182,17 @@ void NativeViewHostGtk::SetFocus() { // NativeViewHostGtk, private: void NativeViewHostGtk::CreateFixed(bool needs_window) { + GtkWidget* focused_widget = GetFocusedDescendant(); + bool fixed_is_focused = (focused_widget == fixed_); + + if (focused_widget) { + // A descendant of our fixed has focus. When we destroy the fixed focus is + // automatically moved. Temporarily move focus to our host widget, then + // restore focus after we create the new fixed_. This way focus hasn't + // really moved. + gtk_widget_grab_focus(GetHostWidget()->GetNativeView()); + } + DestroyFixed(); fixed_ = gtk_fixed_new(); @@ -192,8 +203,16 @@ void NativeViewHostGtk::CreateFixed(bool needs_window) { WidgetGtk* widget_gtk = GetHostWidget(); if (widget_gtk) widget_gtk->AddChild(fixed_); + if (host_->native_view()) gtk_container_add(GTK_CONTAINER(fixed_), host_->native_view()); + + if (widget_gtk && host_->native_view() && focused_widget) { + if (fixed_is_focused) + gtk_widget_grab_focus(fixed_); + else + gtk_widget_grab_focus(focused_widget); + } } void NativeViewHostGtk::DestroyFixed() { @@ -219,6 +238,22 @@ WidgetGtk* NativeViewHostGtk::GetHostWidget() const { return static_cast<WidgetGtk*>(host_->GetWidget()); } +GtkWidget* NativeViewHostGtk::GetFocusedDescendant() { + if (!fixed_) + return NULL; + WidgetGtk* host = GetHostWidget(); + if (!host) + return NULL; + GtkWidget* top_level = gtk_widget_get_toplevel(host->GetNativeView()); + if (!top_level || !GTK_IS_WINDOW(top_level)) + return NULL; + GtkWidget* focused = gtk_window_get_focus(GTK_WINDOW(top_level)); + if (!focused) + return NULL; + return (focused == fixed_ || gtk_widget_is_ancestor(focused, fixed_)) ? + focused : NULL; +} + // static void NativeViewHostGtk::CallDestroy(GtkObject* object, NativeViewHostGtk* host) { diff --git a/views/controls/native/native_view_host_gtk.h b/views/controls/native/native_view_host_gtk.h index b1bcc50..218db0d 100644 --- a/views/controls/native/native_view_host_gtk.h +++ b/views/controls/native/native_view_host_gtk.h @@ -51,6 +51,10 @@ class NativeViewHostGtk : public NativeViewHostWrapper { WidgetGtk* GetHostWidget() const; + // Returns the descendant of fixed_ that has focus, or NULL if focus is not + // on a descendant of fixed_. + GtkWidget* GetFocusedDescendant(); + // Invoked from the 'destroy' signal. static void CallDestroy(GtkObject* object, NativeViewHostGtk* host); diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index e748945..4efe515 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -38,12 +38,17 @@ class WidgetGtk // Type of widget. enum Type { // Used for popup type windows (bubbles, menus ...). + // NOTE: on X windows of this type can NOT get focus. If you need a popup + // like widget that can be focused use TYPE_WINDOW and set the window type + // to WINDOW_TYPE_CHROME_INFO_BUBBLE. TYPE_POPUP, - // A top level window with no title, no control buttons. - // control. + + // A top level window with no title or control buttons. TYPE_WINDOW, + // A top level, decorated window. TYPE_DECORATED_WINDOW, + // A child widget. TYPE_CHILD }; |