From 6a071e1b4d5478685df85269bd37bbdb31b60670 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 24 May 2014 12:57:14 +0800 Subject: [PATCH] win: Implement focus and blur event. --- atom/browser/native_window_win.cc | 30 ++++++++++++++++++++++++++++++ atom/browser/native_window_win.h | 6 ++++++ 2 files changed, 36 insertions(+) diff --git a/atom/browser/native_window_win.cc b/atom/browser/native_window_win.cc index 27b0d634e67f..2635101f5150 100644 --- a/atom/browser/native_window_win.cc +++ b/atom/browser/native_window_win.cc @@ -34,6 +34,22 @@ namespace { const int kResizeInsideBoundsSize = 5; const int kResizeAreaCornerSize = 16; +// Returns true if |possible_parent| is a parent window of |child|. +bool IsParent(gfx::NativeView child, gfx::NativeView possible_parent) { + if (!child) + return false; + if (::GetWindow(child, GW_OWNER) == possible_parent) + return true; + gfx::NativeView parent = ::GetParent(child); + while (parent) { + if (possible_parent == parent) + return true; + parent = ::GetParent(parent); + } + + return false; +} + // Wrapper of NativeWidgetWin to handle WM_MENUCOMMAND messages, which are // triggered by window menus. class MenuCommandNativeWidget : public views::NativeWidgetWin { @@ -215,6 +231,8 @@ NativeWindowWin::NativeWindowWin(content::WebContents* web_contents, window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_NATIVE); window_->Init(params); + views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this); + int width = 800, height = 600; options->GetInteger(switches::kWidth, &width); options->GetInteger(switches::kHeight, &height); @@ -524,6 +542,18 @@ views::NonClientFrameView* NativeWindowWin::CreateNonClientFrameView( return new NativeWindowFramelessView(widget, this); } +void NativeWindowWin::OnNativeFocusChange(gfx::NativeView focused_before, + gfx::NativeView focused_now) { + gfx::NativeView this_window = GetWidget()->GetNativeView(); + if (IsParent(focused_now, this_window)) + return; + + if (focused_now == this_window) + NotifyWindowFocus(); + else if (focused_before == this_window) + NotifyWindowBlur(); +} + void NativeWindowWin::ClientAreaSizeToWindowSize(gfx::Size* size) { gfx::Size window = window_->GetWindowBoundsInScreen().size(); gfx::Size client = window_->GetClientAreaBoundsInScreen().size(); diff --git a/atom/browser/native_window_win.h b/atom/browser/native_window_win.h index ce4c829f24a6..47984c4c61f4 100644 --- a/atom/browser/native_window_win.h +++ b/atom/browser/native_window_win.h @@ -14,6 +14,7 @@ #include "atom/browser/native_window.h" #include "atom/browser/ui/accelerator_util.h" #include "ui/gfx/size.h" +#include "ui/views/focus/widget_focus_manager.h" #include "ui/views/widget/widget_delegate.h" namespace ui { @@ -30,6 +31,7 @@ namespace atom { class Menu2; class NativeWindowWin : public NativeWindow, + public views::WidgetFocusChangeListener, public views::WidgetDelegateView { public: explicit NativeWindowWin(content::WebContents* web_contents, @@ -111,6 +113,10 @@ class NativeWindowWin : public NativeWindow, virtual views::NonClientFrameView* CreateNonClientFrameView( views::Widget* widget) OVERRIDE; + // Overridden from views::WidgetFocusChangeListener: + virtual void OnNativeFocusChange(gfx::NativeView focused_before, + gfx::NativeView focused_now) OVERRIDE; + private: typedef struct { int position; ui::MenuModel* model; } MenuItem; typedef std::map AcceleratorTable;