summaryrefslogtreecommitdiffstats
path: root/ui/views/widget
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-31 00:22:12 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-31 00:22:12 +0000
commit3922a54915d163db29212285274d54a56f06f33d (patch)
treec898d142511a71a6e4aa9688501cd8c134cf28d2 /ui/views/widget
parent82688f12338d406f4e58bdb2a14a1f8a3ecb51a2 (diff)
downloadchromium_src-3922a54915d163db29212285274d54a56f06f33d.zip
chromium_src-3922a54915d163db29212285274d54a56f06f33d.tar.gz
chromium_src-3922a54915d163db29212285274d54a56f06f33d.tar.bz2
aura desktop: Listen for _NET_ACTIVE_WINDOW changes.
We now react to normal window focus changes. (TODO: This doesn't dismiss bubbles correctly. That's what's next.) BUG=125106 TEST=none Review URL: https://chromiumcodereview.appspot.com/10445044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139703 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/widget')
-rw-r--r--ui/views/widget/desktop_native_widget_helper_aura.cc3
-rw-r--r--ui/views/widget/x11_window_event_filter.cc70
-rw-r--r--ui/views/widget/x11_window_event_filter.h20
3 files changed, 84 insertions, 9 deletions
diff --git a/ui/views/widget/desktop_native_widget_helper_aura.cc b/ui/views/widget/desktop_native_widget_helper_aura.cc
index ef90cd7..d29b9b7 100644
--- a/ui/views/widget/desktop_native_widget_helper_aura.cc
+++ b/ui/views/widget/desktop_native_widget_helper_aura.cc
@@ -120,7 +120,8 @@ void DesktopNativeWidgetHelperAura::PreInitialize(
root_window_event_filter_->AddFilter(input_method_filter_.get());
#if defined(USE_X11)
- x11_window_event_filter_.reset(new X11WindowEventFilter(root_window_.get()));
+ x11_window_event_filter_.reset(
+ new X11WindowEventFilter(root_window_.get(), widget_));
x11_window_event_filter_->SetUseHostWindowBorders(false);
root_window_event_filter_->AddFilter(x11_window_event_filter_.get());
#endif
diff --git a/ui/views/widget/x11_window_event_filter.cc b/ui/views/widget/x11_window_event_filter.cc
index 5553f95..4fc2ea7 100644
--- a/ui/views/widget/x11_window_event_filter.cc
+++ b/ui/views/widget/x11_window_event_filter.cc
@@ -4,14 +4,19 @@
#include "ui/views/widget/x11_window_event_filter.h"
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include "base/message_pump_aurax11.h"
+#include "ui/aura/dispatcher_linux.h"
#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/views/widget/native_widget_aura.h"
namespace {
@@ -45,6 +50,7 @@ const unsigned long kHintsDecorations = (1L << 1);
const char* kAtomsToCache[] = {
"_MOTIF_WM_HINTS",
+ "_NET_ACTIVE_WINDOW",
"_NET_WM_MOVERESIZE",
NULL
};
@@ -53,15 +59,30 @@ const char* kAtomsToCache[] = {
namespace views {
-X11WindowEventFilter::X11WindowEventFilter(aura::RootWindow* root_window)
- : root_window_(root_window),
+X11WindowEventFilter::X11WindowEventFilter(aura::RootWindow* root_window,
+ NativeWidgetAura* widget)
+ : widget_(widget),
xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
- xwindow_(root_window_->GetAcceleratedWidget()),
+ xwindow_(root_window->GetAcceleratedWidget()),
x_root_window_(DefaultRootWindow(xdisplay_)),
- atom_cache_(xdisplay_, kAtomsToCache) {
+ atom_cache_(xdisplay_, kAtomsToCache),
+ is_active_(false) {
+ static_cast<aura::DispatcherLinux*>(
+ aura::Env::GetInstance()->GetDispatcher())->
+ AddDispatcherForRootWindow(this);
+
+ XWindowAttributes attr;
+ XGetWindowAttributes(xdisplay_, x_root_window_, &attr);
+ XSelectInput(xdisplay_, x_root_window_,
+ attr.your_event_mask | PropertyChangeMask |
+ StructureNotifyMask | SubstructureNotifyMask);
}
-X11WindowEventFilter::~X11WindowEventFilter() {}
+X11WindowEventFilter::~X11WindowEventFilter() {
+ static_cast<aura::DispatcherLinux*>(
+ aura::Env::GetInstance()->GetDispatcher())->
+ RemoveDispatcherForRootWindow(this);
+}
void X11WindowEventFilter::SetUseHostWindowBorders(bool use_os_border) {
MotifWmHints motif_hints;
@@ -131,6 +152,25 @@ ui::GestureStatus X11WindowEventFilter::PreHandleGestureEvent(
return ui::GESTURE_STATUS_UNKNOWN;
}
+bool X11WindowEventFilter::Dispatch(const base::NativeEvent& event) {
+ // Check for a change to the active window.
+ switch (event->type) {
+ case PropertyNotify: {
+ ::Atom active_window = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
+
+ if (event->xproperty.window == x_root_window_ &&
+ event->xproperty.atom == active_window) {
+ int window;
+ if (ui::GetIntProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &window))
+ OnActiveWindowChanged(static_cast< ::Window>(window));
+ }
+ break;
+ }
+ }
+
+ return false;
+}
+
bool X11WindowEventFilter::DispatchHostWindowDragMovement(
int hittest,
const gfx::Point& screen_location) {
@@ -193,5 +233,25 @@ bool X11WindowEventFilter::DispatchHostWindowDragMovement(
return true;
}
+void X11WindowEventFilter::OnActiveWindowChanged(::Window window) {
+ if (xwindow_ == window) {
+ if (!is_active_) {
+ is_active_ = true;
+
+ widget_->Activate();
+ }
+ } else if (is_active_) {
+ is_active_ = false;
+
+ widget_->Deactivate();
+ // TODO(erg): Also tell the activation delegate of |window_| now that
+ // we've deactivated the widget_. This fixes the bubble case, but breaks
+ // menus. Figure out why.
+
+ // Force a redraw to show our inactive state.
+ widget_->GetWidget()->GetRootView()->SchedulePaint();
+ }
+}
+
} // namespace views
diff --git a/ui/views/widget/x11_window_event_filter.h b/ui/views/widget/x11_window_event_filter.h
index 9bc38db..65375c0 100644
--- a/ui/views/widget/x11_window_event_filter.h
+++ b/ui/views/widget/x11_window_event_filter.h
@@ -11,6 +11,7 @@
#undef RootWindow
#include "base/compiler_specific.h"
+#include "base/message_loop.h"
#include "ui/aura/event.h"
#include "ui/aura/event_filter.h"
#include "ui/aura/x11_atom_cache.h"
@@ -18,14 +19,18 @@
namespace aura {
class RootWindow;
+class Window;
}
namespace views {
+class NativeWidgetAura;
// An EventFilter that sets properties on X11 windows.
-class VIEWS_EXPORT X11WindowEventFilter : public aura::EventFilter {
+class VIEWS_EXPORT X11WindowEventFilter : public aura::EventFilter,
+ public MessageLoop::Dispatcher {
public:
- explicit X11WindowEventFilter(aura::RootWindow* root_window);
+ explicit X11WindowEventFilter(aura::RootWindow* root_window,
+ NativeWidgetAura* widget);
virtual ~X11WindowEventFilter();
// Changes whether borders are shown on this |root_window|.
@@ -42,13 +47,19 @@ class VIEWS_EXPORT X11WindowEventFilter : public aura::EventFilter {
aura::Window* target,
aura::GestureEvent* event) OVERRIDE;
+ // Overridden from MessageLoop::Dispatcher:
+ virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE;
+
private:
// Dispatches a _NET_WM_MOVERESIZE message to the window manager to tell it
// to act as if a border or titlebar drag occurred.
bool DispatchHostWindowDragMovement(int hittest,
const gfx::Point& screen_location);
- aura::RootWindow* root_window_;
+ // Handles changes in activation.
+ void OnActiveWindowChanged(::Window window);
+
+ NativeWidgetAura* widget_;
// The display and the native X window hosting the root window.
Display* xdisplay_;
@@ -59,6 +70,9 @@ class VIEWS_EXPORT X11WindowEventFilter : public aura::EventFilter {
aura::X11AtomCache atom_cache_;
+ // True if |xwindow_| is the current _NET_ACTIVE_WINDOW.
+ bool is_active_;
+
DISALLOW_COPY_AND_ASSIGN(X11WindowEventFilter);
};