Bug 273456 - Fix for plugins that steal the focus in background tabs. r=jimm
authorTim Abraldes <tabraldes@mozilla.com>
Wed, 31 Aug 2011 14:19:03 -0500
changeset 76349 b4193e7aa44c17cb7aba097f2eac5f4f29e9a73a
parent 76348 de4425a74643cdfcfb6bd909a53de379b3c3003a
child 76350 1b888ee836c6f0c177f105b04a2f1b52c8cdb30b
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersjimm
bugs273456
milestone9.0a1
Bug 273456 - Fix for plugins that steal the focus in background tabs. r=jimm
widget/src/windows/nsWindow.cpp
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -555,16 +555,22 @@ nsWindow::Create(nsIWidget *aParent,
   }
 
   nsAutoString className;
   if (aInitData->mDropShadow) {
     GetWindowPopupClass(className);
   } else {
     GetWindowClass(className);
   }
+  // Plugins are created in the disabled state so that they can't
+  // steal focus away from our main window.  This is especially
+  // important if the plugin has loaded in a background tab.
+  if(aInitData->mWindowType == eWindowType_plugin) {
+    style |= WS_DISABLED;
+  }
   mWnd = ::CreateWindowExW(extendedStyle,
                            className.get(),
                            L"",
                            style,
                            aRect.x,
                            aRect.y,
                            aRect.width,
                            GetHeight(aRect.height),
@@ -7300,16 +7306,27 @@ nsWindow::SetWindowClipRegion(const nsTA
     if (current) {
       if (::GetWindowRgn(mWnd, current) != 0 /*ERROR*/) {
         ::CombineRgn(dest, dest, current, RGN_AND);
       }
       ::DeleteObject(current);
     }
   }
 
+  // If a plugin is not visibile, especially if it is in a background tab,
+  // it should not be able to steal keyboard focus.  This code checks whether
+  // the region that the plugin is being clipped to is NULLREGION.  If it is,
+  // the plugin window gets disabled.
+  if(mWindowType == eWindowType_plugin) {
+    if(NULLREGION == ::CombineRgn(dest, dest, dest, RGN_OR)) {
+      ::EnableWindow(mWnd, FALSE);
+    } else {
+      ::EnableWindow(mWnd, TRUE);
+    }
+  }
   if (!::SetWindowRgn(mWnd, dest, TRUE)) {
     ::DeleteObject(dest);
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 // WM_DESTROY event handler