x11: Implement window state events

This commit is contained in:
Cheng Zhao 2014-11-25 12:43:25 +08:00
parent 06cc27c6b3
commit b77e6c369a
7 changed files with 144 additions and 3 deletions

View file

@ -112,6 +112,30 @@ void Window::OnWindowFocus() {
Emit("focus");
}
void Window::OnWindowMaximize() {
Emit("maximize");
}
void Window::OnWindowUnmaximize() {
Emit("unmaximize");
}
void Window::OnWindowMinimize() {
Emit("minimize");
}
void Window::OnWindowRestore() {
Emit("restore");
}
void Window::OnWindowEnterFullScreen() {
Emit("enter-full-screen");
}
void Window::OnWindowLeaveFullScreen() {
Emit("leave-full-screen");
}
void Window::OnRendererUnresponsive() {
Emit("unresponsive");
}

View file

@ -43,7 +43,7 @@ class Window : public mate::EventEmitter,
explicit Window(const mate::Dictionary& options);
virtual ~Window();
// Implementations of NativeWindowObserver:
// NativeWindowObserver:
void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) override;
void WillCreatePopupWindow(const base::string16& frame_name,
@ -54,6 +54,12 @@ class Window : public mate::EventEmitter,
void OnWindowClosed() override;
void OnWindowBlur() override;
void OnWindowFocus() override;
void OnWindowMaximize() override;
void OnWindowUnmaximize() override;
void OnWindowMinimize() override;
void OnWindowRestore() override;
void OnWindowEnterFullScreen() override;
void OnWindowLeaveFullScreen() override;
void OnRendererUnresponsive() override;
void OnRendererResponsive() override;

View file

@ -466,6 +466,32 @@ void NativeWindow::NotifyWindowFocus() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowFocus());
}
void NativeWindow::NotifyWindowMaximize() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMaximize());
}
void NativeWindow::NotifyWindowUnmaximize() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowUnmaximize());
}
void NativeWindow::NotifyWindowMinimize() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowMinimize());
}
void NativeWindow::NotifyWindowRestore() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowRestore());
}
void NativeWindow::NotifyWindowEnterFullScreen() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnWindowEnterFullScreen());
}
void NativeWindow::NotifyWindowLeaveFullScreen() {
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
OnWindowLeaveFullScreen());
}
bool NativeWindow::ShouldCreateWebContents(
content::WebContents* web_contents,
int route_id,

View file

@ -192,6 +192,12 @@ class NativeWindow : public brightray::DefaultWebContentsDelegate,
void NotifyWindowClosed();
void NotifyWindowBlur();
void NotifyWindowFocus();
void NotifyWindowMaximize();
void NotifyWindowUnmaximize();
void NotifyWindowMinimize();
void NotifyWindowRestore();
void NotifyWindowEnterFullScreen();
void NotifyWindowLeaveFullScreen();
void AddObserver(NativeWindowObserver* obs) {
observers_.AddObserver(obs);

View file

@ -39,6 +39,14 @@ class NativeWindowObserver {
// Called when window gains focus.
virtual void OnWindowFocus() {}
// Called when window state changed.
virtual void OnWindowMaximize() {}
virtual void OnWindowUnmaximize() {}
virtual void OnWindowMinimize() {}
virtual void OnWindowRestore() {}
virtual void OnWindowEnterFullScreen() {}
virtual void OnWindowLeaveFullScreen() {}
// Called when renderer is hung.
virtual void OnRendererUnresponsive() {}

View file

@ -4,13 +4,31 @@
#include "atom/browser/ui/views/window_state_watcher.h"
#if defined(USE_X11)
#include <X11/Xlib.h>
#endif
#include "ui/events/platform/platform_event_source.h"
namespace atom {
namespace {
const char* kAtomsToCache[] = {
"_NET_WM_STATE",
NULL,
};
} // namespace
WindowStateWatcher::WindowStateWatcher(NativeWindowViews* window)
: window_(window),
widget_(window->GetAcceleratedWidget()) {
widget_(window->GetAcceleratedWidget()),
#if defined(USE_X11)
atom_cache_(gfx::GetXDisplay(), kAtomsToCache),
#endif
was_minimized_(false),
was_maximized_(false) {
ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
}
@ -19,10 +37,50 @@ WindowStateWatcher::~WindowStateWatcher() {
}
void WindowStateWatcher::WillProcessEvent(const ui::PlatformEvent& event) {
LOG(ERROR) << "WillProcessEvent";
if (IsWindowStateEvent(event)) {
was_minimized_ = window_->IsMinimized();
was_maximized_ = window_->IsMaximized();
}
}
void WindowStateWatcher::DidProcessEvent(const ui::PlatformEvent& event) {
if (IsWindowStateEvent(event)) {
bool is_minimized = window_->IsMinimized();
bool is_maximized = window_->IsMaximized();
bool is_fullscreen = window_->IsFullscreen();
if (is_minimized != was_minimized_) {
if (is_minimized)
window_->NotifyWindowMinimize();
else
window_->NotifyWindowRestore();
} else if (is_maximized != was_maximized_) {
if (is_maximized)
window_->NotifyWindowMaximize();
else
window_->NotifyWindowUnmaximize();
} else {
// If this is neither a "maximize" or "minimize" event, then we think it
// is a "fullscreen" event.
// The "IsFullscreen()" becomes true immediately before "WillProcessEvent"
// is called, so we can not handle this like "maximize" and "minimize" by
// watching whether they have changed.
if (is_fullscreen)
window_->NotifyWindowEnterFullScreen();
else
window_->NotifyWindowLeaveFullScreen();
}
}
}
bool WindowStateWatcher::IsWindowStateEvent(const ui::PlatformEvent& event) {
#if defined(USE_X11)
::Atom changed_atom = event->xproperty.atom;
return (changed_atom == atom_cache_.GetAtom("_NET_WM_STATE") &&
event->type == PropertyNotify &&
event->xproperty.window == widget_);
#else
return false;
#endif
}
} // namespace atom

View file

@ -6,6 +6,10 @@
#include "atom/browser/native_window_views.h"
#if defined(USE_X11)
#include "ui/gfx/x/x11_atom_cache.h"
#endif
namespace atom {
class WindowStateWatcher : public ui::PlatformEventObserver {
@ -19,9 +23,18 @@ class WindowStateWatcher : public ui::PlatformEventObserver {
void DidProcessEvent(const ui::PlatformEvent& event) override;
private:
bool IsWindowStateEvent(const ui::PlatformEvent& event);
NativeWindowViews* window_;
gfx::AcceleratedWidget widget_;
#if defined(USE_X11)
ui::X11AtomCache atom_cache_;
#endif
bool was_minimized_;
bool was_maximized_;
DISALLOW_COPY_AND_ASSIGN(WindowStateWatcher);
};