- add sources.
[platform/framework/web/crosswalk.git] / src / ui / base / x / active_window_watcher_x.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/x/active_window_watcher_x.h"
6
7 #include <gdk/gdk.h>
8 #include <gdk/gdkx.h>
9
10 #include "base/memory/singleton.h"
11 #include "ui/base/x/active_window_watcher_x_observer.h"
12 #include "ui/base/x/root_window_property_watcher_x.h"
13 #include "ui/base/x/x11_util.h"
14 #include "ui/gfx/gdk_compat.h"
15 #include "ui/gfx/gtk_compat.h"
16
17 namespace ui {
18
19 static const char* const kNetActiveWindow = "_NET_ACTIVE_WINDOW";
20
21 // static
22 ActiveWindowWatcherX* ActiveWindowWatcherX::GetInstance() {
23   return Singleton<ActiveWindowWatcherX>::get();
24 }
25
26 // static
27 void ActiveWindowWatcherX::AddObserver(ActiveWindowWatcherXObserver* observer) {
28   // Ensure that RootWindowPropertyWatcherX exists.
29   internal::RootWindowPropertyWatcherX::GetInstance();
30   GetInstance()->observers_.AddObserver(observer);
31 }
32
33 // static
34 void ActiveWindowWatcherX::RemoveObserver(
35     ActiveWindowWatcherXObserver* observer) {
36   GetInstance()->observers_.RemoveObserver(observer);
37 }
38
39 // static
40 Atom ActiveWindowWatcherX::GetPropertyAtom() {
41   return GetAtom(kNetActiveWindow);
42 }
43
44 // static
45 void ActiveWindowWatcherX::Notify() {
46   GetInstance()->NotifyActiveWindowChanged();
47 }
48
49 // static
50 bool ActiveWindowWatcherX::WMSupportsActivation() {
51   return gdk_x11_screen_supports_net_wm_hint(
52       gdk_screen_get_default(),
53       gdk_atom_intern_static_string(kNetActiveWindow));
54 }
55
56 ActiveWindowWatcherX::ActiveWindowWatcherX() {
57 }
58
59 ActiveWindowWatcherX::~ActiveWindowWatcherX() {
60 }
61
62 void ActiveWindowWatcherX::NotifyActiveWindowChanged() {
63   // We don't use gdk_screen_get_active_window() because it caches
64   // whether or not the window manager supports _NET_ACTIVE_WINDOW.
65   // This causes problems at startup for chromiumos.
66   Atom type = None;
67   int format = 0;  // size in bits of each item in 'property'
68   long unsigned int num_items = 0, remaining_bytes = 0;
69   unsigned char* property = NULL;
70
71   XGetWindowProperty(gdk_x11_get_default_xdisplay(),
72                      GDK_WINDOW_XID(gdk_get_default_root_window()),
73                      GetAtom(kNetActiveWindow),
74                      0,      // offset into property data to read
75                      1,      // length to get in 32-bit quantities
76                      False,  // deleted
77                      AnyPropertyType,
78                      &type,
79                      &format,
80                      &num_items,
81                      &remaining_bytes,
82                      &property);
83
84   // Check that the property was set and contained a single 32-bit item (we
85   // don't check that remaining_bytes is 0, though, as XFCE's window manager
86   // seems to actually store two values in the property for some unknown
87   // reason.)
88   if (format == 32 && num_items == 1) {
89     int xid = *reinterpret_cast<int*>(property);
90     GdkDisplay* display = gdk_display_get_default();
91     GdkWindow* active_window = gdk_x11_window_lookup_for_display(display, xid);
92     FOR_EACH_OBSERVER(ActiveWindowWatcherXObserver, observers_,
93                       ActiveWindowChanged(active_window));
94   }
95   if (property)
96     XFree(property);
97 }
98
99 }  // namespace ui