Merge backouts
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 27 Jan 2010 13:21:25 -0500
changeset 46625 c04a2911a953c72a2a925d65554da9c5c7a32439
parent 46623 686aedb56727e992700c4cb6dcc0162dab5b895b (current diff)
parent 46624 9fb0650cbfc08daf9b1371544987878f7bb3ecd6 (diff)
child 46626 15fc08aacb4e7f5339447fb672f18f6740de0907
push idunknown
push userunknown
push dateunknown
milestone1.9.3a1pre
Merge backouts
build/automation.py.in
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -503,17 +503,17 @@ user_pref("camino.use_system_proxy_setti
       return ('', True)
 
     def isPidAlive(self, pid):
       STILL_ACTIVE = 259
       PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
       pHandle = self.ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid)
       if not pHandle:
         return False
-      pExitCode = self.wintypes.DWORD()
+      pExitCode = ctypes.wintypes.DWORD()
       self.ctypes.windll.kernel32.GetExitCodeProcess(pHandle, self.ctypes.byref(pExitCode))
       self.ctypes.windll.kernel32.CloseHandle(pHandle)
       if (pExitCode.value == STILL_ACTIVE):
         return True
       else:
         return False
 
     def killPid(self, pid):
--- a/dom/plugins/BrowserStreamChild.cpp
+++ b/dom/plugins/BrowserStreamChild.cpp
@@ -82,16 +82,17 @@ BrowserStreamChild::StreamConstructed(
             PStreamNotifyChild* notifyData,
             const nsCString& headers,
             const nsCString& mimeType,
             const bool& seekable,
             uint16_t* stype)
 {
   NPError rv = NPERR_NO_ERROR;
 
+  *stype = NP_NORMAL;
   rv = mInstance->mPluginIface->newstream(
     &mInstance->mData, const_cast<char*>(NullableStringGet(mimeType)),
     &mStream, seekable, stype);
   if (rv != NPERR_NO_ERROR)
     mClosed = true;
 
   return rv;
 }
--- a/dom/plugins/PPluginInstance.ipdl
+++ b/dom/plugins/PPluginInstance.ipdl
@@ -156,12 +156,17 @@ child:
     returns (NPError rv,
              uint16_t stype);
 
 parent:
   /* NPN_NewStream */
   rpc PPluginStream(nsCString mimeType,
                     nsCString target)
     returns (NPError result);
+
+parent:
+  rpc PluginGotFocus();
+child:
+  rpc SetPluginFocus();
 };
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -679,16 +679,28 @@ PluginInstanceChild::PluginWindowProc(HW
         GetProp(hWnd, kPluginInstanceChildProperty));
     if (!self) {
         NS_NOTREACHED("Badness!");
         return 0;
     }
 
     NS_ASSERTION(self->mPluginWindowHWND == hWnd, "Wrong window!");
 
+    // The plugin received keyboard focus, let the parent know so the dom is up to date.
+    if (message == WM_MOUSEACTIVATE)
+        self->CallPluginGotFocus();
+
+    // Prevent lockups due to plugins making rpc calls when the parent
+    // is making a synchronous SetFocus api call. (bug 541362) Add more
+    // windowing events as needed for other api.
+    if (message == WM_KILLFOCUS && 
+        ((InSendMessageEx(NULL) & (ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND)) {
+        ReplyMessage(0); // Unblock the caller
+    }
+
     LRESULT res = CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
                                  lParam);
 
     if (message == WM_CLOSE)
         self->DestroyPluginWindow();
 
     if (message == WM_NCDESTROY)
         RemoveProp(hWnd, kPluginInstanceChildProperty);
@@ -867,16 +879,33 @@ PluginInstanceChild::SharedSurfacePaint(
               return true;
         break;
     }
     return false;
 }
 
 #endif // OS_WIN
 
+bool
+PluginInstanceChild::AnswerSetPluginFocus()
+{
+    PR_LOG(gPluginLog, PR_LOG_DEBUG, ("%s", FULLFUNCTION));
+
+#if defined(OS_WIN)
+    // Parent is letting us know something set focus to the plugin.
+    if (::GetFocus() == mPluginWindowHWND)
+        return true;
+    ::SetFocus(mPluginWindowHWND);
+    return true;
+#else
+    NS_NOTREACHED("PluginInstanceChild::AnswerSetPluginFocus not implemented!");
+    return false;
+#endif
+}
+
 PPluginScriptableObjectChild*
 PluginInstanceChild::AllocPPluginScriptableObject()
 {
     AssertPluginThread();
     return new PluginScriptableObjectChild(Proxy);
 }
 
 bool
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -140,16 +140,19 @@ protected:
     AllocPStreamNotify(const nsCString& url, const nsCString& target,
                        const bool& post, const nsCString& buffer,
                        const bool& file,
                        NPError* result);
 
     NS_OVERRIDE virtual bool
     DeallocPStreamNotify(PStreamNotifyChild* notifyData);
 
+    virtual bool
+    AnswerSetPluginFocus();
+
 public:
     PluginInstanceChild(const NPPluginFuncs* aPluginIface);
 
     virtual ~PluginInstanceChild();
 
     bool Initialize();
 
     NPP GetNPP()
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -43,27 +43,36 @@
 #include "PluginModuleParent.h"
 #include "PluginStreamParent.h"
 #include "StreamNotifyParent.h"
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 
 #if defined(OS_WIN)
 #include <windowsx.h>
+
+// Plugin focus event for widget.
+extern const PRUnichar* kOOPPPluginFocusEventId;
+UINT gOOPPPluginFocusEvent =
+    RegisterWindowMessage(kOOPPPluginFocusEventId);
 #endif
 
 using namespace mozilla::plugins;
 
 PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
                                            NPP npp,
                                            const NPNetscapeFuncs* npniface)
-  : mParent(parent),
-    mNPP(npp),
-    mNPNIface(npniface),
-    mWindowType(NPWindowTypeWindow)
+  : mParent(parent)
+    , mNPP(npp)
+    , mNPNIface(npniface)
+    , mWindowType(NPWindowTypeWindow)
+#if defined(OS_WIN)
+    , mPluginHWND(NULL)
+    , mPluginWndProc(NULL)
+#endif // defined(XP_WIN)
 {
 }
 
 PluginInstanceParent::~PluginInstanceParent()
 {
     if (mNPP)
         mNPP->pdata = NULL;
 }
@@ -94,16 +103,17 @@ PluginInstanceParent::Destroy()
     NPError retval;
     if (!CallNPP_Destroy(&retval)) {
         NS_WARNING("Failed to send message!");
         return NPERR_GENERIC_ERROR;
     }
 
 #if defined(OS_WIN)
     SharedSurfaceRelease();
+    UnsubclassPluginWindow();
 #endif
 
     return retval;
 }
 
 PBrowserStreamParent*
 PluginInstanceParent::AllocPBrowserStream(const nsCString& url,
                                           const uint32_t& length,
@@ -355,16 +365,18 @@ PluginInstanceParent::NPP_SetWindow(cons
     // On windowless controls, reset the shared memory surface as needed.
     if (mWindowType == NPWindowTypeDrawable) {
         // SharedSurfaceSetWindow will take care of NPRemoteWindow.
         if (!SharedSurfaceSetWindow(aWindow, window)) {
           return NPERR_OUT_OF_MEMORY_ERROR;
         }
     }
     else {
+        SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
+
         window.window = reinterpret_cast<unsigned long>(aWindow->window);
         window.x = aWindow->x;
         window.y = aWindow->y;
         window.width = aWindow->width;
         window.height = aWindow->height;
         window.type = aWindow->type;
     }
 #else
@@ -827,16 +839,96 @@ PluginInstanceParent::AnswerNPN_GetAuthe
         username->Adopt(u, ulen);
         password->Adopt(p, plen);
     }
     return true;
 }
 
 #if defined(OS_WIN)
 
+/*
+  plugin focus changes between processes
+
+  focus from dom -> child:
+    Focs manager calls on widget to set the focus on the window.
+    We pick up the resulting wm_setfocus event here, and forward
+    that over ipc to the child which calls set focus on itself. 
+
+  focus from child -> focus manager:
+    Child picks up the local wm_setfocus and sends it via ipc over
+    here. We then post a custom event to widget/src/windows/nswindow
+    which fires off a gui event letting the browser know.
+*/
+
+static const PRUnichar kPluginInstanceParentProperty[] =
+                         L"PluginInstanceParentProperty";
+
+// static
+LRESULT CALLBACK
+PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
+                                           UINT message,
+                                           WPARAM wParam,
+                                           LPARAM lParam)
+{
+    PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
+        ::GetPropW(hWnd, kPluginInstanceParentProperty));
+    if (!self) {
+        NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
+        return DefWindowProc(hWnd, message, wParam, lParam);
+    }
+
+    NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
+
+    switch (message) {
+        case WM_SETFOCUS:
+        self->CallSetPluginFocus();
+        break;
+
+        case WM_CLOSE:
+        self->UnsubclassPluginWindow();
+        break;
+    }
+
+    return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
+                            lParam);
+}
+
+void
+PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
+{
+    NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
+      "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
+
+    if (!mPluginHWND) {
+        mPluginHWND = aWnd;
+        mPluginWndProc = 
+            (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
+                         reinterpret_cast<LONG>(PluginWindowHookProc));
+        bool bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
+        NS_ASSERTION(mPluginWndProc,
+          "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
+        NS_ASSERTION(bRes,
+          "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
+   }
+}
+
+void
+PluginInstanceParent::UnsubclassPluginWindow()
+{
+    if (mPluginHWND && mPluginWndProc) {
+        ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
+                            reinterpret_cast<LONG>(mPluginWndProc));
+
+        ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
+
+        mPluginWndProc = NULL;
+        mPluginHWND = NULL;
+    }
+}
+
 /* windowless drawing helpers */
 
 /*
  * Origin info:
  *
  * windowless, offscreen:
  *
  * WM_WINDOWPOSCHANGED: origin is relative to container 
@@ -951,8 +1043,26 @@ PluginInstanceParent::SharedSurfaceAfter
              dirtyRect.height,
              mSharedSurfaceDib.GetHDC(),
              dirtyRect.x,
              dirtyRect.y,
              SRCCOPY);
 }
 
 #endif // defined(OS_WIN)
+
+bool
+PluginInstanceParent::AnswerPluginGotFocus()
+{
+    PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
+
+    // Currently only in use on windows - an rpc event we receive from the
+    // child when it's plugin window (or one of it's children) receives keyboard
+    // focus. We forward the event down to widget so the dom/focus manager can
+    // be updated.
+#if defined(OS_WIN)
+    ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, 0, 0);
+    return true;
+#else
+    NS_NOTREACHED("PluginInstanceParent::AnswerPluginGotFocus not implemented!");
+    return false;
+#endif
+}
--- a/dom/plugins/PluginInstanceParent.h
+++ b/dom/plugins/PluginInstanceParent.h
@@ -217,16 +217,19 @@ public:
     GetActorForNPObject(NPObject* aObject);
 
     NPP
     GetNPP()
     {
       return mNPP;
     }
 
+    virtual bool
+    AnswerPluginGotFocus();
+
 private:
     bool InternalGetValueForNPObject(NPNVariable aVariable,
                                      PPluginScriptableObjectParent** aValue,
                                      NPError* aResult);
 
 private:
     PluginModuleParent* mParent;
     NPP mNPP;
@@ -237,21 +240,28 @@ private:
 
 #if defined(OS_WIN)
 private:
     // Used in rendering windowless plugins in other processes.
     bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
     void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
     void SharedSurfaceAfterPaint(NPEvent* npevent);
     void SharedSurfaceRelease();
+    // Used in handling parent/child forwarding of events.
+    static LRESULT CALLBACK PluginWindowHookProc(HWND hWnd, UINT message,
+                                                 WPARAM wParam, LPARAM lParam);
+    void SubclassPluginWindow(HWND aWnd);
+    void UnsubclassPluginWindow();
 
 private:
     gfx::SharedDIBWin  mSharedSurfaceDib;
     nsIntRect          mPluginPort;
     nsIntRect          mSharedSize;
+    HWND               mPluginHWND;
+    WNDPROC            mPluginWndProc;
 #endif // defined(XP_WIN)
 };
 
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceParent_h
--- a/ipc/chromium/src/base/thread.cc
+++ b/ipc/chromium/src/base/thread.cc
@@ -97,27 +97,61 @@ bool Thread::StartWithOptions(const Opti
 void Thread::Stop() {
   if (!thread_was_started())
     return;
 
   // We should only be called on the same thread that started us.
   DCHECK_NE(thread_id_, PlatformThread::CurrentId());
 
   // StopSoon may have already been called.
-  if (message_loop_)
+  if (message_loop_) {
+
+
+
+
+#ifdef OS_LINUX
+      printf("TEST-UNEXPECTED-FAIL | process %d | posted quit task to other thread\n", getpid());
+#endif
+
+
+
+
+
     message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
+  }
 
   // Wait for the thread to exit.  It should already have terminated but make
   // sure this assumption is valid.
   //
   // TODO(darin): Unfortunately, we need to keep message_loop_ around until
   // the thread exits.  Some consumers are abusing the API.  Make them stop.
   //
+
+
+
+
+#ifdef OS_LINUX
+  printf("TEST-UNEXPECTED-FAIL | process %d | joining other thread\n", getpid());
+#endif
+
+
+
+
   PlatformThread::Join(thread_);
 
+
+
+
+#ifdef OS_LINUX
+  printf("TEST-UNEXPECTED-FAIL | process %d | other thread joined\n", getpid());
+#endif
+
+
+
+
   // The thread can't receive messages anymore.
   message_loop_ = NULL;
 
   // The thread no longer needs to be joined.
   startup_data_ = NULL;
 }
 
 void Thread::StopSoon() {
--- a/ipc/chromium/src/chrome/common/child_process.cc
+++ b/ipc/chromium/src/chrome/common/child_process.cc
@@ -24,19 +24,38 @@ ChildProcess::~ChildProcess() {
   DCHECK(child_process_ == this);
 
   // Signal this event before destroying the child process.  That way all
   // background threads can cleanup.
   // For example, in the renderer the RenderThread instances will be able to
   // notice shutdown before the render process begins waiting for them to exit.
   shutdown_event_.Signal();
 
-  if (child_thread_.get())
+  if (child_thread_.get()) {
+
+
+#ifdef OS_LINUX
+      printf("TEST-UNEXPECTED-FAIL | plugin process %d | IO thread is Stop()ing XPCOM thread\n", getpid());
+#endif
+
+
+
     child_thread_->Stop();
 
+
+
+#ifdef OS_LINUX
+      printf("TEST-UNEXPECTED-FAIL | plugin process %d | XPCOM thread has been Stop()d\n", getpid());
+#endif
+
+
+
+
+  }
+
   child_process_ = NULL;
 }
 
 void ChildProcess::AddRefProcess() {
   DCHECK(!child_thread_.get() ||  // null in unittests.
          MessageLoop::current() == child_thread_->message_loop());
   ref_count_++;
 }
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -376,16 +376,25 @@ bool Channel::ChannelImpl::ProcessIncomi
       if (bytes_read < 0) {
         if (errno == EAGAIN) {
           return true;
         } else {
           LOG(ERROR) << "pipe error (" << pipe_ << "): " << strerror(errno);
           return false;
         }
       } else if (bytes_read == 0) {
+
+
+
+
+          printf("TEST-UNEXPECTED-FAIL | process %d | read 0 bytes from pipe, it's closed\n", getpid());
+
+
+
+
         // The pipe has closed...
         Close();
         return false;
       }
     }
     DCHECK(bytes_read);
 
     if (client_pipe_ != -1) {
@@ -692,17 +701,30 @@ void Channel::ChannelImpl::OnFileCanRead
 
     waiting_connect_ = false;
     send_server_hello_msg = true;
   }
 
   if (!waiting_connect_ && fd == pipe_) {
     if (!ProcessIncomingMessages()) {
       Close();
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | notifying client of channel error (read)\n", getpid());
+
+
+
       listener_->OnChannelError();
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | client notified(read)\n", getpid());
+
+
     }
   }
 
   // If we're a server and handshaking, then we want to make sure that we
   // only send our handshake message after we've processed the client's.
   // This gives us a chance to kill the client if the incoming handshake
   // is invalid.
   if (send_server_hello_msg) {
@@ -710,30 +732,65 @@ void Channel::ChannelImpl::OnFileCanRead
     DCHECK(is_blocked_on_write_ == false);
     ProcessOutgoingMessages();
   }
 }
 
 // Called by libevent when we can write to the pipe without blocking.
 void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) {
   if (!ProcessOutgoingMessages()) {
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | failed to process outgoing messages\n", getpid());
+
+
+
     Close();
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | notifying client of channel error (write)\n", getpid());
+
+
+
     listener_->OnChannelError();
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | client notified(write)\n", getpid());
+
+
+
   }
 }
 
 void Channel::ChannelImpl::Close() {
   // Close can be called multiple time, so we need to make sure we're
   // idempotent.
 
   // Unregister libevent for the listening socket and close it.
   server_listen_connection_watcher_.StopWatchingFileDescriptor();
 
   if (server_listen_pipe_ != -1) {
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | closing pipe\n", getpid());
+
+
+
     HANDLE_EINTR(close(server_listen_pipe_));
+
+
+
+      printf("TEST-UNEXPECTED-FAIL | process %d | pipe closed\n", getpid());
+
+
+
     server_listen_pipe_ = -1;
   }
 
   // Unregister libevent for the FIFO and close it.
   read_watcher_.StopWatchingFileDescriptor();
   write_watcher_.StopWatchingFileDescriptor();
   if (pipe_ != -1) {
     HANDLE_EINTR(close(pipe_));
--- a/ipc/glue/AsyncChannel.cpp
+++ b/ipc/glue/AsyncChannel.cpp
@@ -68,16 +68,25 @@ AsyncChannel::AsyncChannel(AsyncListener
     mChannelErrorTask(NULL)
 {
     MOZ_COUNT_CTOR(AsyncChannel);
 }
 
 AsyncChannel::~AsyncChannel()
 {
     MOZ_COUNT_DTOR(AsyncChannel);
+
+
+
+#ifdef OS_LINUX
+        printf("TEST-UNEXPECTED-FAIL | process %d | ~AsyncChannel()\n", getpid());
+#endif
+
+
+
     Clear();
 }
 
 bool
 AsyncChannel::Open(Transport* aTransport, MessageLoop* aIOLoop)
 {
     NS_PRECONDITION(!mTransport, "Open() called > once");
     NS_PRECONDITION(aTransport, "need transport layer");
--- a/modules/plugin/base/src/nsPluginNativeWindowWin.cpp
+++ b/modules/plugin/base/src/nsPluginNativeWindowWin.cpp
@@ -301,27 +301,29 @@ static LRESULT CALLBACK PluginWndProc(HW
     case WM_KEYUP:
       enablePopups = PR_TRUE;
 
       break;
 
 #ifndef WINCE
     case WM_MOUSEACTIVATE: {
       // If a child window of this plug-in is already focused,
-      // don't focus the parent to avoid focus dance.
-      // The following WM_SETFOCUS message will give the focus
-      // to the appropriate window anyway.
+      // don't focus the parent to avoid focus dance. We'll 
+      // receive a follow up WM_SETFOCUS which will notify
+      // the appropriate window anyway.
       HWND focusedWnd = ::GetFocus();
       if (!::IsChild((HWND)win->window, focusedWnd)) {
-        // This seems to be the only way we're
-        // notified when a child window that doesn't have this handler proc
-        // (read as: windows created by plugins like Adobe Acrobat)
-        // has been activated via clicking.
-        // should be handled here because some plugins won't forward
-        // messages to original WinProc.
+        // Notify the dom / focus manager the plugin has focus when one of
+        // it's child windows receives it. OOPP specific - this code is
+        // critical in notifying the dom of focus changes when the plugin
+        // window in the child process receives focus via a mouse click.
+        // WM_MOUSEACTIVATE is sent by nsWindow via a custom window event
+        // sent from PluginInstanceParent in response to focus events sent
+        // from the child. (bug 540052) Note, this gui event could also be
+        // sent directly from widget.
         nsCOMPtr<nsIWidget> widget;
         win->GetPluginWidget(getter_AddRefs(widget));
         if (widget) {
           nsGUIEvent event(PR_TRUE, NS_PLUGIN_ACTIVATE, widget);
           nsEventStatus status;
           widget->DispatchEvent(&event, status);
         }
       }
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -363,16 +363,24 @@ XRE_InitChildProcess(int aArgc,
 
     ChildProcess process(mainThread);
 
     // Do IPC event loop
     sIOMessageLoop = MessageLoop::current();
 
     sIOMessageLoop->Run();
 
+
+
+#ifdef OS_LINUX
+    printf("TEST-UNEXPECTED-FAIL | plugin process %d | broke out of IO event loop\n", getpid());
+#endif
+
+
+
     sIOMessageLoop = nsnull;
   }
 
 
 #ifdef OS_LINUX
   printf("TEST-UNEXPECTED-FAIL | plugin process %d | IO thread joined XPCOM thread, exiting\n", getpid());
 #endif
 
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -204,20 +204,16 @@
 #include "npapi.h"
 
 #include "nsWindowDefs.h"
 
 #ifdef WINCE_WINDOWS_MOBILE
 #include "nsGfxCIID.h"
 #endif
 
-// A magic APP message that can be sent to quit, sort of like a QUERYENDSESSION/ENDSESSION,
-// but without the query.
-#define MOZ_WM_APP_QUIT (WM_APP+0x0300)
-
 /**************************************************************
  **************************************************************
  **
  ** BLOCK: Variables
  **
  ** nsWindow Class static initializations and global variables. 
  **
  **************************************************************
@@ -277,16 +273,23 @@ PRBool          nsWindow::sTrackPointHac
 #ifdef ACCESSIBILITY
 BOOL            nsWindow::sIsAccessibilityOn      = FALSE;
 // Accessibility wm_getobject handler
 HINSTANCE       nsWindow::sAccLib                 = 0;
 LPFNLRESULTFROMOBJECT 
                 nsWindow::sLresultFromObject      = 0;
 #endif // ACCESSIBILITY
 
+#ifdef MOZ_IPC
+// Used in OOPP plugin focus processing.
+const PRUnichar* kOOPPPluginFocusEventId   = L"OOPP Plugin Focus Widget Event";
+PRUint32        nsWindow::sOOPPPluginFocusEvent   =
+                  RegisterWindowMessageW(kOOPPPluginFocusEventId);
+#endif
+
 /**************************************************************
  *
  * SECTION: globals variables
  *
  **************************************************************/
 
 static const char *sScreenManagerContractID       = "@mozilla.org/gfx/screenmanager;1";
 
@@ -325,17 +328,16 @@ PRUint32        gLastInputEventTime     
 static void UpdateLastInputEventTime() {
   gLastInputEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
   nsCOMPtr<nsIIdleService> idleService = do_GetService("@mozilla.org/widget/idleservice;1");
   nsIdleService* is = static_cast<nsIdleService*>(idleService.get());
   if (is)
     is->IdleTimeWasModified();
 }
 
-
 // Global user preference for disabling native theme. Used
 // in NativeWindowTheme.
 PRBool          gDisableNativeTheme               = PR_FALSE;
 
 // Global used in Show window enumerations.
 static PRBool   gWindowsVisible                   = PR_FALSE;
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
@@ -4602,16 +4604,25 @@ PRBool nsWindow::ProcessMessage(UINT msg
         HeapDump(msg, wParam, lParam);
         result = PR_TRUE;
       }
 #endif
 #if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_WIN7
       if (msg == nsAppShell::GetTaskbarButtonCreatedMessage())
         SetHasTaskbarIconBeenCreated();
 #endif
+#ifdef MOZ_IPC
+    if (msg == sOOPPPluginFocusEvent) {
+      // With OOPP, the plugin window exists in another process and is a child of
+      // this window. This window is a placeholder plugin window for the dom. We
+      // receive this event when the child window receives focus. (sent from
+      // PluginInstanceParent.cpp)
+      ::SendMessage(mWnd, WM_MOUSEACTIVATE, 0, 0); // See nsPluginNativeWindowWin.cpp
+    } 
+#endif
     }
     break;
   }
 
   //*aRetValue = result;
   if (mWnd) {
     return result;
   }
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -441,16 +441,19 @@ protected:
   static BOOL           sIsOleInitialized;
   static HCURSOR        sHCursor;
   static imgIContainer* sCursorImgContainer;
   static PRBool         sSwitchKeyboardLayout;
   static PRBool         sJustGotDeactivate;
   static PRBool         sJustGotActivate;
   static int            sTrimOnMinimize;
   static PRBool         sTrackPointHack;
+#ifdef MOZ_IPC
+  static PRUint32       sOOPPPluginFocusEvent;
+#endif
 
   // Hook Data Memebers for Dropdowns. sProcessHook Tells the
   // hook methods whether they should be processing the hook
   // messages.
   static HHOOK          sMsgFilterHook;
   static HHOOK          sCallProcHook;
   static HHOOK          sCallMouseHook;
   static PRPackedBool   sProcessHook;
--- a/widget/src/windows/nsWindowDefs.h
+++ b/widget/src/windows/nsWindowDefs.h
@@ -48,16 +48,20 @@
 #include "resource.h"
 
 /**************************************************************
  *
  * SECTION: defines
  * 
  **************************************************************/
 
+// A magic APP message that can be sent to quit, sort of like a QUERYENDSESSION/ENDSESSION,
+// but without the query.
+#define MOZ_WM_APP_QUIT                   (WM_APP+0x0300)
+
 // GetWindowsVersion constants
 #define WIN2K_VERSION                     0x500
 #define WINXP_VERSION                     0x501
 #define WIN2K3_VERSION                    0x502
 #define VISTA_VERSION                     0x600
 #define WIN7_VERSION                      0x601
 
 #define WM_XP_THEMECHANGED                0x031A
--- a/xpcom/base/nsTraceRefcntImpl.cpp
+++ b/xpcom/base/nsTraceRefcntImpl.cpp
@@ -615,16 +615,22 @@ static void RecycleSerialNumberPtr(void*
   PL_HashTableRemove(gSerialNumbers, aPtr);
 }
 
 static PRBool LogThisObj(PRInt32 aSerialNumber)
 {
   return nsnull != PL_HashTableLookup(gObjectsToLog, (const void*)(aSerialNumber));
 }
 
+#ifdef XP_WIN
+#define FOPEN_NO_INHERIT "N"
+#else
+#define FOPEN_NO_INHERIT
+#endif
+
 static PRBool InitLog(const char* envVar, const char* msg, FILE* *result)
 {
   const char* value = getenv(envVar);
   if (value) {
     if (nsCRT::strcmp(value, "1") == 0) {
       *result = stdout;
       fprintf(stdout, "### %s defined -- logging %s to stdout\n",
               envVar, msg);
@@ -648,17 +654,17 @@ static PRBool InitLog(const char* envVar
         fname.AppendLiteral("_");
         fname.Append((char*)XRE_ChildProcessTypeToString(XRE_GetProcessType()));
         fname.AppendLiteral("_pid");
         fname.AppendInt((PRUint32)getpid());
         if (hasLogExtension)
           fname.AppendLiteral(".log");
       }
 #endif
-      stream = ::fopen(fname.get(), "w");
+      stream = ::fopen(fname.get(), "w" FOPEN_NO_INHERIT);
       if (stream != NULL) {
         *result = stream;
         fprintf(stdout, "### %s defined -- logging %s to %s\n",
                 envVar, msg, fname.get());
       }
       else {
         fprintf(stdout, "### %s defined -- unable to log %s to %s\n",
                 envVar, msg, fname.get());