From 35229255bb4dafaced955d012c1d46202960c4b8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 20 Mar 2014 17:44:08 +0800 Subject: [PATCH] gtk: Ask whether window is active from WM. It could happpen that the WM thinks a window is active but it's actually not, like when showing a context menu. In most cases we should follow what WM says to keep consistent bevaviour on all platforms. --- atom/browser/native_window_gtk.cc | 12 ++++++++++++ atom/browser/native_window_gtk.h | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_gtk.cc b/atom/browser/native_window_gtk.cc index 180db861ed4f..212996d6c688 100644 --- a/atom/browser/native_window_gtk.cc +++ b/atom/browser/native_window_gtk.cc @@ -16,6 +16,7 @@ #include "content/public/common/renderer_preferences.h" #include "ui/base/accelerators/platform_accelerator_gtk.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/base/x/active_window_watcher_x.h" #include "ui/base/x/x11_util.h" #include "ui/gfx/gtk_util.h" #include "ui/gfx/rect.h" @@ -39,6 +40,7 @@ NativeWindowGtk::NativeWindowGtk(content::WebContents* web_contents, vbox_(gtk_vbox_new(FALSE, 0)), state_(GDK_WINDOW_STATE_WITHDRAWN), is_always_on_top_(false), + is_active_(false), suppress_window_raise_(false), frame_cursor_(NULL) { gtk_container_add(GTK_CONTAINER(window_), vbox_); @@ -53,6 +55,8 @@ NativeWindowGtk::NativeWindowGtk(content::WebContents* web_contents, if (!icon_.IsEmpty()) gtk_window_set_icon(window_, icon_.ToGdkPixbuf()); + ui::ActiveWindowWatcherX::AddObserver(this); + // In some (older) versions of compiz, raising top-level windows when they // are partially off-screen causes them to get snapped back on screen, not // always even on the current virtual desktop. If we are running under @@ -109,6 +113,10 @@ void NativeWindowGtk::Focus(bool focus) { } bool NativeWindowGtk::IsFocused() { + if (ui::ActiveWindowWatcherX::WMSupportsActivation()) + return is_active_; + + // This still works even though we don't get the activation notification. return gtk_window_is_active(window_); } @@ -290,6 +298,10 @@ void NativeWindowGtk::UpdateDraggableRegions( } } +void NativeWindowGtk::ActiveWindowChanged(GdkWindow* active_window) { + is_active_ = gtk_widget_get_window(GTK_WIDGET(window_)) == active_window; +} + void NativeWindowGtk::RegisterAccelerators() { DCHECK(menu_); accelerator_table_.clear(); diff --git a/atom/browser/native_window_gtk.h b/atom/browser/native_window_gtk.h index 69f5d124f5f8..cafed467ea48 100644 --- a/atom/browser/native_window_gtk.h +++ b/atom/browser/native_window_gtk.h @@ -16,12 +16,14 @@ #include "third_party/skia/include/core/SkRegion.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/gtk/gtk_signal.h" +#include "ui/base/x/active_window_watcher_x_observer.h" #include "ui/gfx/size.h" namespace atom { class NativeWindowGtk : public NativeWindow, - public MenuGtk::Delegate { + public MenuGtk::Delegate, + public ui::ActiveWindowWatcherXObserver { public: explicit NativeWindowGtk(content::WebContents* web_contents, base::DictionaryValue* options); @@ -69,6 +71,9 @@ class NativeWindowGtk : public NativeWindow, virtual void UpdateDraggableRegions( const std::vector& regions) OVERRIDE; + // Overridden from ActiveWindowWatcherXObserver. + virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; + private: // Register accelerators supported by the menu model. void RegisterAccelerators(); @@ -111,6 +116,11 @@ class NativeWindowGtk : public NativeWindow, // clicked to maximize. scoped_ptr draggable_region_; + // True if the window manager thinks the window is active. It could happpen + // that the WM thinks a window is active but it's actually not, like when + // showing a context menu. + bool is_active_; + // If true, don't call gdk_window_raise() when we get a click in the title // bar or window border. This is to work around a compiz bug. bool suppress_window_raise_;