From b77e6c369a24146020461b25cc1ac428e0e40625 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 25 Nov 2014 12:43:25 +0800 Subject: [PATCH] x11: Implement window state events --- atom/browser/api/atom_api_window.cc | 24 +++++++ atom/browser/api/atom_api_window.h | 8 ++- atom/browser/native_window.cc | 26 ++++++++ atom/browser/native_window.h | 6 ++ atom/browser/native_window_observer.h | 8 +++ atom/browser/ui/views/window_state_watcher.cc | 62 ++++++++++++++++++- atom/browser/ui/views/window_state_watcher.h | 13 ++++ 7 files changed, 144 insertions(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 49ba2c8df7b2..903e4b5ddd0a 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -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"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 370634f13105..de5a2f471c08 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -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; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 26a8559445e3..c93df2c646ce 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -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, diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index a434d28175ad..edf5449e34b7 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -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); diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 3d3240585f4d..e83018087524 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -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() {} diff --git a/atom/browser/ui/views/window_state_watcher.cc b/atom/browser/ui/views/window_state_watcher.cc index 2d4545226952..53feafe1c184 100644 --- a/atom/browser/ui/views/window_state_watcher.cc +++ b/atom/browser/ui/views/window_state_watcher.cc @@ -4,13 +4,31 @@ #include "atom/browser/ui/views/window_state_watcher.h" +#if defined(USE_X11) +#include +#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 diff --git a/atom/browser/ui/views/window_state_watcher.h b/atom/browser/ui/views/window_state_watcher.h index b78086c29949..17ad64024a61 100644 --- a/atom/browser/ui/views/window_state_watcher.h +++ b/atom/browser/ui/views/window_state_watcher.h @@ -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); };