summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-06 01:07:36 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-06 01:07:36 +0000
commit4a3111474cda4b74c26620fd58c3c843b96df7fc (patch)
treec23daaf1d521d866eefe895637d04ee5d3088e92 /views
parent341fbaa85d75ae8832993ec472ca67cdb82d45a1 (diff)
downloadchromium_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.cc35
-rw-r--r--views/controls/native/native_view_host_gtk.h4
-rw-r--r--views/widget/widget_gtk.h9
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
};