gtk: Import chromium's ActiveWindowWatcherX.

This commit is contained in:
Cheng Zhao 2014-06-29 04:05:29 +00:00
parent e5c10f29de
commit f4b6ca70a9
9 changed files with 398 additions and 1 deletions

View file

@ -129,10 +129,17 @@
'atom/browser/ui/file_dialog_gtk.cc',
'atom/browser/ui/file_dialog_mac.mm',
'atom/browser/ui/file_dialog_win.cc',
'atom/browser/ui/gtk/active_window_watcher_x.cc',
'atom/browser/ui/gtk/active_window_watcher_x.h',
'atom/browser/ui/gtk/active_window_watcher_x_observer.h',
'atom/browser/ui/gtk/app_indicator_icon.cc',
'atom/browser/ui/gtk/app_indicator_icon.h',
'atom/browser/ui/gtk/root_window_property_watcher_x.cc',
'atom/browser/ui/gtk/root_window_property_watcher_x.h',
'atom/browser/ui/gtk/status_icon.cc',
'atom/browser/ui/gtk/status_icon.h',
'atom/browser/ui/gtk/work_area_watcher_x.cc',
'atom/browser/ui/gtk/work_area_watcher_x.h',
'atom/browser/ui/message_box.h',
'atom/browser/ui/message_box_gtk.cc',
'atom/browser/ui/message_box_mac.mm',

View file

@ -7,6 +7,7 @@
#include <string>
#include <vector>
#include "atom/browser/ui/gtk/active_window_watcher_x.h"
#include "atom/common/draggable_region.h"
#include "atom/common/options_switches.h"
#include "base/environment.h"
@ -20,7 +21,6 @@
#include "native_mate/dictionary.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/font_render_params_linux.h"
#include "ui/gfx/gtk_util.h"

View file

@ -0,0 +1,99 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "atom/browser/ui/gtk/active_window_watcher_x.h"
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include "atom/browser/ui/gtk/active_window_watcher_x_observer.h"
#include "atom/browser/ui/gtk/root_window_property_watcher_x.h"
#include "base/memory/singleton.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/gdk_compat.h"
#include "ui/gfx/gtk_compat.h"
namespace ui {
static const char* const kNetActiveWindow = "_NET_ACTIVE_WINDOW";
// static
ActiveWindowWatcherX* ActiveWindowWatcherX::GetInstance() {
return Singleton<ActiveWindowWatcherX>::get();
}
// static
void ActiveWindowWatcherX::AddObserver(ActiveWindowWatcherXObserver* observer) {
// Ensure that RootWindowPropertyWatcherX exists.
internal::RootWindowPropertyWatcherX::GetInstance();
GetInstance()->observers_.AddObserver(observer);
}
// static
void ActiveWindowWatcherX::RemoveObserver(
ActiveWindowWatcherXObserver* observer) {
GetInstance()->observers_.RemoveObserver(observer);
}
// static
Atom ActiveWindowWatcherX::GetPropertyAtom() {
return GetAtom(kNetActiveWindow);
}
// static
void ActiveWindowWatcherX::Notify() {
GetInstance()->NotifyActiveWindowChanged();
}
// static
bool ActiveWindowWatcherX::WMSupportsActivation() {
return gdk_x11_screen_supports_net_wm_hint(
gdk_screen_get_default(),
gdk_atom_intern_static_string(kNetActiveWindow));
}
ActiveWindowWatcherX::ActiveWindowWatcherX() {
}
ActiveWindowWatcherX::~ActiveWindowWatcherX() {
}
void ActiveWindowWatcherX::NotifyActiveWindowChanged() {
// We don't use gdk_screen_get_active_window() because it caches
// whether or not the window manager supports _NET_ACTIVE_WINDOW.
// This causes problems at startup for chromiumos.
Atom type = None;
int format = 0; // size in bits of each item in 'property'
long unsigned int num_items = 0, remaining_bytes = 0;
unsigned char* property = NULL;
XGetWindowProperty(gdk_x11_get_default_xdisplay(),
GDK_WINDOW_XID(gdk_get_default_root_window()),
GetAtom(kNetActiveWindow),
0, // offset into property data to read
1, // length to get in 32-bit quantities
False, // deleted
AnyPropertyType,
&type,
&format,
&num_items,
&remaining_bytes,
&property);
// Check that the property was set and contained a single 32-bit item (we
// don't check that remaining_bytes is 0, though, as XFCE's window manager
// seems to actually store two values in the property for some unknown
// reason.)
if (format == 32 && num_items == 1) {
int xid = *reinterpret_cast<int*>(property);
GdkDisplay* display = gdk_display_get_default();
GdkWindow* active_window = gdk_x11_window_lookup_for_display(display, xid);
FOR_EACH_OBSERVER(ActiveWindowWatcherXObserver, observers_,
ActiveWindowChanged(active_window));
}
if (property)
XFree(property);
}
} // namespace ui

View file

@ -0,0 +1,59 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_GTK_ACTIVE_WINDOW_WATCHER_X_H_
#define ATOM_BROWSER_UI_GTK_ACTIVE_WINDOW_WATCHER_X_H_
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "ui/base/x/x11_util.h"
template <typename T> struct DefaultSingletonTraits;
namespace ui {
class ActiveWindowWatcherXObserver;
namespace internal {
class RootWindowPropertyWatcherX;
}
// This is a helper class that is used to keep track of which window the X
// window manager thinks is active. Add an Observer to listen for changes to
// the active window.
class ActiveWindowWatcherX {
public:
static ActiveWindowWatcherX* GetInstance();
static void AddObserver(ActiveWindowWatcherXObserver* observer);
static void RemoveObserver(ActiveWindowWatcherXObserver* observer);
// Checks if the WM supports the active window property. Note that the return
// value can change, especially during system startup.
static bool WMSupportsActivation();
private:
friend struct DefaultSingletonTraits<ActiveWindowWatcherX>;
friend class ui::internal::RootWindowPropertyWatcherX;
ActiveWindowWatcherX();
~ActiveWindowWatcherX();
// Gets the atom for the default display for the property this class is
// watching for.
static Atom GetPropertyAtom();
// Notify observers that the active window has changed.
static void Notify();
// Instance method that implements Notify().
void NotifyActiveWindowChanged();
ObserverList<ActiveWindowWatcherXObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(ActiveWindowWatcherX);
};
} // namespace ui
#endif // ATOM_BROWSER_UI_GTK_ACTIVE_WINDOW_WATCHER_X_H_

View file

@ -0,0 +1,23 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_OBSERVER_H_
#define UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_OBSERVER_H_
#include <gdk/gdk.h>
namespace ui {
class ActiveWindowWatcherXObserver {
public:
// |active_window| will be NULL if the active window isn't one of Chrome's.
virtual void ActiveWindowChanged(GdkWindow* active_window) = 0;
protected:
virtual ~ActiveWindowWatcherXObserver() {}
};
} // namespace ui
#endif // UI_BASE_X_ACTIVE_WINDOW_WATCHER_X_OBSERVER_H_

View file

@ -0,0 +1,59 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "atom/browser/ui/gtk/root_window_property_watcher_x.h"
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include "base/memory/singleton.h"
#include "atom/browser/ui/gtk/active_window_watcher_x.h"
#include "atom/browser/ui/gtk/work_area_watcher_x.h"
namespace ui {
namespace internal {
// static
RootWindowPropertyWatcherX* RootWindowPropertyWatcherX::GetInstance() {
return Singleton<RootWindowPropertyWatcherX>::get();
}
RootWindowPropertyWatcherX::RootWindowPropertyWatcherX() {
GdkWindow* root = gdk_get_default_root_window();
// Set up X Event filter to listen for PropertyChange X events.
// Don't use XSelectInput directly here, as gdk internally seems to cache the
// mask and reapply XSelectInput after this, resetting any mask we set here.
gdk_window_set_events(root,
static_cast<GdkEventMask>(gdk_window_get_events(root) |
GDK_PROPERTY_CHANGE_MASK));
gdk_window_add_filter(root,
&RootWindowPropertyWatcherX::OnWindowXEventThunk,
this);
}
RootWindowPropertyWatcherX::~RootWindowPropertyWatcherX() {
gdk_window_remove_filter(NULL,
&RootWindowPropertyWatcherX::OnWindowXEventThunk,
this);
}
GdkFilterReturn RootWindowPropertyWatcherX::OnWindowXEvent(
GdkXEvent* xevent, GdkEvent* event) {
XEvent* xev = static_cast<XEvent*>(xevent);
if (xev->xany.type == PropertyNotify) {
if (xev->xproperty.atom == ActiveWindowWatcherX::GetPropertyAtom())
ActiveWindowWatcherX::Notify();
else if (xev->xproperty.atom == WorkAreaWatcherX::GetPropertyAtom())
WorkAreaWatcherX::Notify();
}
return GDK_FILTER_CONTINUE;
}
} // namespace internal
} // namespace ui

View file

@ -0,0 +1,43 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_GTK_ROOT_WINDOW_PROPERTY_WATCHER_X_H_
#define ATOM_BROWSER_UI_GTK_ROOT_WINDOW_PROPERTY_WATCHER_X_H_
#include <gdk/gdk.h>
#include "base/basictypes.h"
#include "ui/base/gtk/gtk_signal.h"
template <typename T> struct DefaultSingletonTraits;
namespace ui {
namespace internal {
// This class keeps track of changes to properties on the root window. This is
// not to be used directly. Implement a watcher for the specific property you're
// interested in.
class RootWindowPropertyWatcherX {
public:
static RootWindowPropertyWatcherX* GetInstance();
private:
friend struct DefaultSingletonTraits<RootWindowPropertyWatcherX>;
RootWindowPropertyWatcherX();
~RootWindowPropertyWatcherX();
// Callback for PropertyChange XEvents.
CHROMEG_CALLBACK_1(RootWindowPropertyWatcherX, GdkFilterReturn,
OnWindowXEvent, GdkXEvent*, GdkEvent*);
DISALLOW_COPY_AND_ASSIGN(RootWindowPropertyWatcherX);
};
} // namespace internal
} // namespace ui
#endif // ATOM_BROWSER_UI_GTK_ROOT_WINDOW_PROPERTY_WATCHER_X_H_

View file

@ -0,0 +1,53 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "atom/browser/ui/gtk/work_area_watcher_x.h"
#include "base/memory/singleton.h"
#include "ui/base/work_area_watcher_observer.h"
#include "atom/browser/ui/gtk/root_window_property_watcher_x.h"
#include "ui/base/x/x11_util.h"
namespace ui {
static const char* const kNetWorkArea = "_NET_WORKAREA";
// static
WorkAreaWatcherX* WorkAreaWatcherX::GetInstance() {
return Singleton<WorkAreaWatcherX>::get();
}
// static
void WorkAreaWatcherX::AddObserver(WorkAreaWatcherObserver* observer) {
// Ensure that RootWindowPropertyWatcherX exists.
internal::RootWindowPropertyWatcherX::GetInstance();
GetInstance()->observers_.AddObserver(observer);
}
// static
void WorkAreaWatcherX::RemoveObserver(WorkAreaWatcherObserver* observer) {
GetInstance()->observers_.RemoveObserver(observer);
}
// static
void WorkAreaWatcherX::Notify() {
GetInstance()->NotifyWorkAreaChanged();
}
// static
Atom WorkAreaWatcherX::GetPropertyAtom() {
return GetAtom(kNetWorkArea);
}
WorkAreaWatcherX::WorkAreaWatcherX() {
}
WorkAreaWatcherX::~WorkAreaWatcherX() {
}
void WorkAreaWatcherX::NotifyWorkAreaChanged() {
FOR_EACH_OBSERVER(WorkAreaWatcherObserver, observers_, WorkAreaChanged());
}
} // namespace ui

View file

@ -0,0 +1,54 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_UI_GTK_WORK_AREA_WATCHER_X_H_
#define ATOM_BROWSER_UI_GTK_WORK_AREA_WATCHER_X_H_
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "ui/base/x/x11_util.h"
template <typename T> struct DefaultSingletonTraits;
namespace ui {
class WorkAreaWatcherObserver;
namespace internal {
class RootWindowPropertyWatcherX;
}
// This is a helper class that is used to keep track of changes to work area.
// Add an observer to track changes.
class WorkAreaWatcherX {
public:
static WorkAreaWatcherX* GetInstance();
static void AddObserver(WorkAreaWatcherObserver* observer);
static void RemoveObserver(WorkAreaWatcherObserver* observer);
private:
friend struct DefaultSingletonTraits<WorkAreaWatcherX>;
friend class ui::internal::RootWindowPropertyWatcherX;
WorkAreaWatcherX();
~WorkAreaWatcherX();
// Gets the atom for the default display for the property this class is
// watching for.
static Atom GetPropertyAtom();
// Notify observers that the work area has changed.
static void Notify();
// Instance method that implements Notify().
void NotifyWorkAreaChanged();
ObserverList<WorkAreaWatcherObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(WorkAreaWatcherX);
};
} // namespace ui
#endif // ATOM_BROWSER_UI_GTK_WORK_AREA_WATCHER_X_H_