gtk: Import chromium's ActiveWindowWatcherX.
This commit is contained in:
parent
e5c10f29de
commit
f4b6ca70a9
9 changed files with 398 additions and 1 deletions
7
atom.gyp
7
atom.gyp
|
@ -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',
|
||||
|
|
|
@ -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"
|
||||
|
|
99
atom/browser/ui/gtk/active_window_watcher_x.cc
Normal file
99
atom/browser/ui/gtk/active_window_watcher_x.cc
Normal 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
|
59
atom/browser/ui/gtk/active_window_watcher_x.h
Normal file
59
atom/browser/ui/gtk/active_window_watcher_x.h
Normal 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_
|
23
atom/browser/ui/gtk/active_window_watcher_x_observer.h
Normal file
23
atom/browser/ui/gtk/active_window_watcher_x_observer.h
Normal 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_
|
59
atom/browser/ui/gtk/root_window_property_watcher_x.cc
Normal file
59
atom/browser/ui/gtk/root_window_property_watcher_x.cc
Normal 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
|
43
atom/browser/ui/gtk/root_window_property_watcher_x.h
Normal file
43
atom/browser/ui/gtk/root_window_property_watcher_x.h
Normal 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_
|
53
atom/browser/ui/gtk/work_area_watcher_x.cc
Normal file
53
atom/browser/ui/gtk/work_area_watcher_x.cc
Normal 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
|
54
atom/browser/ui/gtk/work_area_watcher_x.h
Normal file
54
atom/browser/ui/gtk/work_area_watcher_x.h
Normal 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_
|
Loading…
Reference in a new issue