win: Implement focus and blur event.
authorCheng Zhao <zcbenz@gmail.com>
Sat, 24 May 2014 04:57:14 +0000 (12:57 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Sat, 24 May 2014 05:04:04 +0000 (13:04 +0800)
atom/browser/native_window_win.cc
atom/browser/native_window_win.h

index 27b0d63..2635101 100644 (file)
@@ -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();
index ce4c829..47984c4 100644 (file)
@@ -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<ui::Accelerator, MenuItem> AcceleratorTable;