Merging cedar with mozilla-central.
authorMounir Lamouri <mounir.lamouri@gmail.com>
Thu, 19 May 2011 15:05:34 +0200
changeset 69716 3cd7b0b686ff07375d7fb7e257e18cd496f1cacf
parent 69715 7642608ac4a5a322a30a3d0149209e4f2eed3b32 (current diff)
parent 69689 4fd08a1e0644afe1ec180b4730e3d81ff4423044 (diff)
child 69717 ed5162a1a8f2e92a4c2affc0214815a78fad2668
push idunknown
push userunknown
push dateunknown
milestone6.0a1
Merging cedar with mozilla-central.
content/canvas/src/nsCanvasRenderingContext2D.cpp
modules/plugin/Makefile.in
modules/plugin/test/Makefile.in
modules/plugin/test/crashtests/110650-1.html
modules/plugin/test/crashtests/41276-1.html
modules/plugin/test/crashtests/48856-1.html
modules/plugin/test/crashtests/539897-1.html
modules/plugin/test/crashtests/540114-1.html
modules/plugin/test/crashtests/570884.html
modules/plugin/test/crashtests/598862.html
modules/plugin/test/crashtests/626602-1.html
modules/plugin/test/crashtests/crashtests.list
modules/plugin/test/mochitest/307-xo-redirect.sjs
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/mochitest/cocoa_focus.html
modules/plugin/test/mochitest/cocoa_window_focus.html
modules/plugin/test/mochitest/crashing_subpage.html
modules/plugin/test/mochitest/large-pic.jpg
modules/plugin/test/mochitest/loremipsum.txt
modules/plugin/test/mochitest/loremipsum.xtest
modules/plugin/test/mochitest/loremipsum.xtest^headers^
modules/plugin/test/mochitest/loremipsum_file.txt
modules/plugin/test/mochitest/loremipsum_nocache.txt
modules/plugin/test/mochitest/loremipsum_nocache.txt^headers^
modules/plugin/test/mochitest/neverending.sjs
modules/plugin/test/mochitest/plugin_visibility_loader.html
modules/plugin/test/mochitest/plugin_window.html
modules/plugin/test/mochitest/pluginstream.js
modules/plugin/test/mochitest/post.sjs
modules/plugin/test/mochitest/test_GCrace.html
modules/plugin/test/mochitest/test_bug479979.xul
modules/plugin/test/mochitest/test_bug532208.html
modules/plugin/test/mochitest/test_bug539565-1.html
modules/plugin/test/mochitest/test_bug539565-2.html
modules/plugin/test/mochitest/test_clear_site_data.html
modules/plugin/test/mochitest/test_cocoa_focus.html
modules/plugin/test/mochitest/test_cocoa_window_focus.html
modules/plugin/test/mochitest/test_convertpoint.xul
modules/plugin/test/mochitest/test_cookies.html
modules/plugin/test/mochitest/test_copyText.html
modules/plugin/test/mochitest/test_crash_nested_loop.html
modules/plugin/test/mochitest/test_crash_notify.xul
modules/plugin/test/mochitest/test_crash_notify_no_report.xul
modules/plugin/test/mochitest/test_crash_submit.xul
modules/plugin/test/mochitest/test_crashing.html
modules/plugin/test/mochitest/test_crashing2.html
modules/plugin/test/mochitest/test_enumerate.html
modules/plugin/test/mochitest/test_fullpage.html
modules/plugin/test/mochitest/test_getauthenticationinfo.html
modules/plugin/test/mochitest/test_hanging.html
modules/plugin/test/mochitest/test_instantiation.html
modules/plugin/test/mochitest/test_multipleinstanceobjects.html
modules/plugin/test/mochitest/test_newstreamondestroy.html
modules/plugin/test/mochitest/test_npn_asynccall.html
modules/plugin/test/mochitest/test_npn_timers.html
modules/plugin/test/mochitest/test_npobject_getters.html
modules/plugin/test/mochitest/test_npruntime.xul
modules/plugin/test/mochitest/test_npruntime_construct.html
modules/plugin/test/mochitest/test_npruntime_identifiers.html
modules/plugin/test/mochitest/test_npruntime_npnevaluate.html
modules/plugin/test/mochitest/test_npruntime_npninvoke.html
modules/plugin/test/mochitest/test_npruntime_npninvokedefault.html
modules/plugin/test/mochitest/test_npruntime_npnsetexception.html
modules/plugin/test/mochitest/test_painting.html
modules/plugin/test/mochitest/test_plugin_scroll_painting.html
modules/plugin/test/mochitest/test_pluginstream_asfile.html
modules/plugin/test/mochitest/test_pluginstream_asfileonly.html
modules/plugin/test/mochitest/test_pluginstream_err.html
modules/plugin/test/mochitest/test_pluginstream_geturl.html
modules/plugin/test/mochitest/test_pluginstream_geturlnotify.html
modules/plugin/test/mochitest/test_pluginstream_newstream.html
modules/plugin/test/mochitest/test_pluginstream_post.html
modules/plugin/test/mochitest/test_pluginstream_poststream.html
modules/plugin/test/mochitest/test_pluginstream_seek.html
modules/plugin/test/mochitest/test_pluginstream_seek_close.html
modules/plugin/test/mochitest/test_pluginstream_src.html
modules/plugin/test/mochitest/test_positioning.html
modules/plugin/test/mochitest/test_privatemode.xul
modules/plugin/test/mochitest/test_propertyAndMethod.html
modules/plugin/test/mochitest/test_redirect_handling.html
modules/plugin/test/mochitest/test_streamNotify.html
modules/plugin/test/mochitest/test_streamatclose.html
modules/plugin/test/mochitest/test_twostreams.html
modules/plugin/test/mochitest/test_visibility.html
modules/plugin/test/mochitest/test_windowed_invalidate.html
modules/plugin/test/mochitest/test_wmode.xul
modules/plugin/test/mochitest/test_xulbrowser_plugin_visibility.xul
modules/plugin/test/mochitest/test_zero_opacity.html
modules/plugin/test/mochitest/utils.js
modules/plugin/test/mochitest/xulbrowser_plugin_visibility.xul
modules/plugin/test/reftest/border-padding-1-ref.html
modules/plugin/test/reftest/border-padding-1.html
modules/plugin/test/reftest/border-padding-2-ref.html
modules/plugin/test/reftest/border-padding-2.html
modules/plugin/test/reftest/border-padding-3-ref.html
modules/plugin/test/reftest/border-padding-3.html
modules/plugin/test/reftest/div-alpha-opacity.html
modules/plugin/test/reftest/div-alpha-zindex.html
modules/plugin/test/reftest/div-sanity.html
modules/plugin/test/reftest/plugin-alpha-opacity.html
modules/plugin/test/reftest/plugin-alpha-zindex.html
modules/plugin/test/reftest/plugin-background-1-step.html
modules/plugin/test/reftest/plugin-background-10-step.html
modules/plugin/test/reftest/plugin-background-2-step.html
modules/plugin/test/reftest/plugin-background-5-step.html
modules/plugin/test/reftest/plugin-background-ref.html
modules/plugin/test/reftest/plugin-background.css
modules/plugin/test/reftest/plugin-background.html
modules/plugin/test/reftest/plugin-background.js
modules/plugin/test/reftest/plugin-busy-alpha-zindex.html
modules/plugin/test/reftest/plugin-canvas-alpha-zindex.html
modules/plugin/test/reftest/plugin-sanity.html
modules/plugin/test/reftest/plugin-transform-1-ref.html
modules/plugin/test/reftest/plugin-transform-1.html
modules/plugin/test/reftest/plugin-transform-2-ref.html
modules/plugin/test/reftest/plugin-transform-2.html
modules/plugin/test/reftest/plugin-transform-alpha-zindex.html
modules/plugin/test/reftest/pluginproblemui-direction-1-ref.html
modules/plugin/test/reftest/pluginproblemui-direction-1.html
modules/plugin/test/reftest/pluginproblemui-direction-2-ref.html
modules/plugin/test/reftest/pluginproblemui-direction-2.html
modules/plugin/test/reftest/reftest.list
modules/plugin/test/reftest/windowless-clipping-1-ref.html
modules/plugin/test/reftest/windowless-clipping-1.html
modules/plugin/test/testplugin/Info.plist
modules/plugin/test/testplugin/Makefile.in
modules/plugin/test/testplugin/README
modules/plugin/test/testplugin/nptest.cpp
modules/plugin/test/testplugin/nptest.def
modules/plugin/test/testplugin/nptest.h
modules/plugin/test/testplugin/nptest.rc
modules/plugin/test/testplugin/nptest_droid.cpp
modules/plugin/test/testplugin/nptest_gtk2.cpp
modules/plugin/test/testplugin/nptest_macosx.mm
modules/plugin/test/testplugin/nptest_os2.cpp
modules/plugin/test/testplugin/nptest_platform.h
modules/plugin/test/testplugin/nptest_qt.cpp
modules/plugin/test/testplugin/nptest_utils.cpp
modules/plugin/test/testplugin/nptest_utils.h
modules/plugin/test/testplugin/nptest_windows.cpp
modules/plugin/test/unit/head_plugins.js
modules/plugin/test/unit/test_bug455213.js
modules/plugin/test/unit/test_bug471245.js
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -354,17 +354,16 @@ appUpdater.prototype =
      * See nsIUpdateService.idl
      */
     onError: function(aRequest, aUpdate) {
       // Errors in the update check are treated as no updates found. If the
       // update check fails repeatedly without a success the user will be
       // notified with the normal app update user interface so this is safe.
       gAppUpdater.isChecking = false;
       gAppUpdater.selectPanel("noUpdatesFound");
-      return;
     },
 
     /**
      * See nsISupports.idl
      */
     QueryInterface: function(aIID) {
       if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
           !aIID.equals(Components.interfaces.nsISupports))
@@ -608,16 +607,18 @@ var gChannelSelector = {
 
   apply: function() {
     this.channelValue = document.getElementById("channelMenulist").selectedItem.value;
     this.setChannelLabel(this.channelValue);
 
     // Change app update channel.
     Services.prefs.setCharPref("app.update.desiredChannel", this.channelValue);
 
+    // Stop any downloads in progress
+    gAppUpdater.aus.pauseDownload();
     // App updater will look at app.update.desiredChannel for new channel value
     // and will clear it when the update is complete.
     gAppUpdater.isChecking = true;
     gAppUpdater.checker.checkForUpdates(gAppUpdater.updateCheckListener, true);
 
     this.hide();
   },
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1535,18 +1535,20 @@
                   this._removingTabs.length == 0 &&
                   (this._windowIsClosing = window.closeWindow(true)))
                 return null;
 
               newTab = true;
             }
 
             this._removingTabs.push(aTab);
-
-            this.tabContainer.updateVisibility();
+            if (newTab)
+              this.addTab("about:blank", {skipAnimation: true});
+            else
+              this.tabContainer.updateVisibility();
 
             // We're committed to closing the tab now.
             // Dispatch a notification.
             // We dispatch it before any teardown so that event listeners can
             // inspect the tab that's about to close.
             var evt = document.createEvent("UIEvent");
             evt.initUIEvent("TabClose", true, false, window, aTabWillBeMoved ? 1 : 0);
             aTab.dispatchEvent(evt);
@@ -1592,18 +1594,16 @@
               aCloseWindow = false;
               aNewTab = false;
             }
 
             this._lastRelatedTab = null;
 
             // update the UI early for responsiveness
             aTab.collapsed = true;
-            if (aNewTab)
-              this.addTab("about:blank", {skipAnimation: true});
             this.tabContainer._fillTrailingGap();
             this._blurTab(aTab);
 
             this._removingTabs.splice(this._removingTabs.indexOf(aTab), 1);
 
             if (aCloseWindow) {
               this._windowIsClosing = true;
               while (this._removingTabs.length)
--- a/configure.in
+++ b/configure.in
@@ -6135,18 +6135,25 @@ MOZ_ARG_DISABLE_BOOL(angle,
     MOZ_ANGLE=1)
 
 if test -n "$MOZ_ANGLE"; then
   if test -z "$_WIN32_MSVC"; then
     AC_MSG_ERROR([Building ANGLE requires MSVC.  To build without ANGLE, reconfigure with --disable-angle.])
   fi
 
   # Get the SDK path from the registry.
-  MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK' | head -n 1`
-  MOZ_DIRECTX_SDK_PATH=`reg query "$MOZ_DIRECTX_SDK_REG_KEY" //v InstallPath | grep REG_SZ | sed 's,  *, ,g' | cut -d' ' -f4-`
+  # First try to get the June 2010 SDK
+  MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK (June 2010)' | head -n 1`
+  if test -z "$MOZ_DIRECTX_SDK_REG_KEY" ; then
+    # Otherwise just take whatever comes first
+    MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK' | head -n 1`
+  fi
+  echo "MOZ_DIRECTX_SDK_REG_KEY=$MOZ_DIRECTX_SDK_REG_KEY"
+  MOZ_DIRECTX_SDK_PATH=`reg query "$MOZ_DIRECTX_SDK_REG_KEY" //v InstallPath | grep REG_SZ | sed 's/.*\([[a-zA-Z]]\)\\:\\\\/\\1\\:\\\\/'`
+  echo "MOZ_DIRECTX_SDK_PATH=$MOZ_DIRECTX_SDK_PATH"
 
   MOZ_ANGLE=
 
   if test -n "$MOZ_DIRECTX_SDK_PATH" ; then
     if test -f "$MOZ_DIRECTX_SDK_PATH"/include/d3dx9.h && test -f "$MOZ_DIRECTX_SDK_PATH"/lib/$MOZ_DIRECTX_SDK_CPU_SUFFIX/dxguid.lib ; then
       AC_MSG_RESULT([Found DirectX SDK via registry, using $MOZ_DIRECTX_SDK_PATH])
       MOZ_ANGLE=1
     fi
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -3374,16 +3374,17 @@ nsCanvasRenderingContext2D::DrawImage(ns
       return NS_ERROR_DOM_INDEX_SIZE_ERR;
     }
 
     matrix.Translate(gfxPoint(sx, sy));
     matrix.Scale(sw/dw, sh/dh);
 
     pattern = new gfxPattern(imgsurf);
     pattern->SetMatrix(matrix);
+    pattern->SetExtend(gfxPattern::EXTEND_PAD);
 
     if (CurrentState().imageSmoothingEnabled)
         pattern->SetFilter(gfxPattern::FILTER_GOOD);
     else
         pattern->SetFilter(gfxPattern::FILTER_NEAREST);
 
     PathAutoSaveRestore pathSR(this);
 
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -386,16 +386,17 @@ public:
                                   PRBool aScrollHorizontal);
   static void EndTransaction();
   static void OnEvent(nsEvent* aEvent);
   static void Shutdown();
   static PRUint32 GetTimeoutTime();
   static PRInt32 AccelerateWheelDelta(PRInt32 aScrollLines,
                    PRBool aIsHorizontal, PRBool aAllowScrollSpeedOverride,
                    nsIScrollableFrame::ScrollUnit *aScrollQuantity);
+  static PRBool IsAccelerationEnabled();
 
   enum {
     kScrollSeriesTimeout = 80
   };
 protected:
   static nsIntPoint GetScreenPoint(nsGUIEvent* aEvent);
   static void OnFailToScrollTarget();
   static void OnTimeout(nsITimer *aTimer, void *aClosure);
@@ -646,16 +647,22 @@ nsMouseWheelTransaction::GetTimeoutTime(
 
 PRUint32
 nsMouseWheelTransaction::GetIgnoreMoveDelayTime()
 {
   return (PRUint32)
     nsContentUtils::GetIntPref("mousewheel.transaction.ignoremovedelay", 100);
 }
 
+PRBool
+nsMouseWheelTransaction::IsAccelerationEnabled()
+{
+  return GetAccelerationStart() >= 0 && GetAccelerationFactor() > 0;
+}
+
 PRInt32
 nsMouseWheelTransaction::AccelerateWheelDelta(PRInt32 aScrollLines,
                            PRBool aIsHorizontal,
                            PRBool aAllowScrollSpeedOverride,
                            nsIScrollableFrame::ScrollUnit *aScrollQuantity)
 {
   if (aAllowScrollSpeedOverride) {
     aScrollLines = OverrideSystemScrollSpeed(aScrollLines, aIsHorizontal);
@@ -2646,16 +2653,22 @@ nsEventStateManager::DoScrollText(nsIFra
           }
         }
       }
     }
   }
 
   if (!passToParent && frameToScroll) {
     if (aQueryEvent) {
+      // If acceleration is enabled, pixel scroll shouldn't be used for
+      // high resolution scrolling.
+      if (nsMouseWheelTransaction::IsAccelerationEnabled()) {
+        return NS_OK;
+      }
+
       nscoord appUnitsPerDevPixel =
         aTargetFrame->PresContext()->AppUnitsPerDevPixel();
       aQueryEvent->mReply.mLineHeight =
         frameToScroll->GetLineScrollAmount().height / appUnitsPerDevPixel;
       aQueryEvent->mReply.mPageHeight =
         frameToScroll->GetPageScrollAmount().height / appUnitsPerDevPixel;
       aQueryEvent->mReply.mPageWidth =
         frameToScroll->GetPageScrollAmount().width / appUnitsPerDevPixel;
--- a/content/media/nsAudioStream.cpp
+++ b/content/media/nsAudioStream.cpp
@@ -42,20 +42,23 @@
 #include "mozilla/dom/AudioChild.h"
 #include "nsXULAppAPI.h"
 using namespace mozilla::dom;
 
 #include <stdio.h>
 #include <math.h>
 #include "prlog.h"
 #include "prmem.h"
+#include "prdtoa.h"
 #include "nsAutoPtr.h"
 #include "nsAudioStream.h"
 #include "nsAlgorithm.h"
 #include "VideoUtils.h"
+#include "nsContentUtils.h"
+#include "mozilla/Mutex.h"
 extern "C" {
 #include "sydneyaudio/sydney_audio.h"
 }
 #include "mozilla/TimeStamp.h"
 #include "nsThreadUtils.h"
 
 #if defined(XP_MACOSX)
 #define SA_PER_STREAM_VOLUME 1
@@ -308,26 +311,57 @@ class AudioShutdownEvent : public nsRunn
     if (mAudioChild->IsIPCOpen())
       mAudioChild->SendShutdown();
     return NS_OK;
   }
   
   nsRefPtr<AudioChild> mAudioChild;
 };
 
+static mozilla::Mutex* gVolumeScaleLock = nsnull;
+
+static double gVolumeScale = 1.0;
+
+static int VolumeScaleChanged(const char* aPref, void *aClosure) {
+  nsAdoptingString value =
+    nsContentUtils::GetStringPref("media.volume_scale");
+  mozilla::MutexAutoLock lock(*gVolumeScaleLock);
+  if (value.IsEmpty()) {
+    gVolumeScale = 1.0;
+  } else {
+    NS_ConvertUTF16toUTF8 utf8(value);
+    gVolumeScale = PR_MAX(0, PR_strtod(utf8.get(), nsnull));
+  }
+  return 0;
+}
+
+static double GetVolumeScale() {
+  mozilla::MutexAutoLock lock(*gVolumeScaleLock);
+  return gVolumeScale;
+}
 
 void nsAudioStream::InitLibrary()
 {
 #ifdef PR_LOGGING
   gAudioStreamLog = PR_NewLogModule("nsAudioStream");
 #endif
+  gVolumeScaleLock = new mozilla::Mutex("nsAudioStream::gVolumeScaleLock");
+  VolumeScaleChanged(nsnull, nsnull);
+  nsContentUtils::RegisterPrefCallback("media.volume_scale",
+                                       VolumeScaleChanged,
+                                       nsnull);
 }
 
 void nsAudioStream::ShutdownLibrary()
 {
+  nsContentUtils::UnregisterPrefCallback("media.volume_scale",
+                                         VolumeScaleChanged,
+                                         nsnull);
+  delete gVolumeScaleLock;
+  gVolumeScaleLock = nsnull;
 }
 
 nsIThread *
 nsAudioStream::GetThread()
 {
   if (!mAudioPlaybackThread) {
     NS_NewThread(getter_AddRefs(mAudioPlaybackThread));
   }
@@ -434,41 +468,42 @@ nsresult nsAudioStreamLocal::Write(const
   nsAutoArrayPtr<short> s_data(new short[count]);
 
   if (s_data) {
     for (PRUint32 i=0; i < offset; ++i) {
       s_data[i] = mBufferOverflow.ElementAt(i);
     }
     mBufferOverflow.Clear();
 
+    double scaled_volume = GetVolumeScale() * mVolume;
     switch (mFormat) {
       case FORMAT_U8: {
         const PRUint8* buf = static_cast<const PRUint8*>(aBuf);
-        PRInt32 volume = PRInt32((1 << 16) * mVolume);
+        PRInt32 volume = PRInt32((1 << 16) * scaled_volume);
         for (PRUint32 i = 0; i < aCount; ++i) {
           s_data[i + offset] = short(((PRInt32(buf[i]) - 128) * volume) >> 8);
         }
         break;
       }
       case FORMAT_S16_LE: {
         const short* buf = static_cast<const short*>(aBuf);
-        PRInt32 volume = PRInt32((1 << 16) * mVolume);
+        PRInt32 volume = PRInt32((1 << 16) * scaled_volume);
         for (PRUint32 i = 0; i < aCount; ++i) {
           short s = buf[i];
 #if defined(IS_BIG_ENDIAN)
           s = ((s & 0x00ff) << 8) | ((s & 0xff00) >> 8);
 #endif
           s_data[i + offset] = short((PRInt32(s) * volume) >> 16);
         }
         break;
       }
       case FORMAT_FLOAT32: {
         const float* buf = static_cast<const float*>(aBuf);
         for (PRUint32 i = 0; i <  aCount; ++i) {
-          float scaled_value = floorf(0.5 + 32768 * buf[i] * mVolume);
+          float scaled_value = floorf(0.5 + 32768 * buf[i] * scaled_volume);
           if (buf[i] < 0.0) {
             s_data[i + offset] = (scaled_value < -32768.0) ?
               -32768 :
               short(scaled_value);
           } else {
             s_data[i+offset] = (scaled_value > 32767.0) ?
               32767 :
               short(scaled_value);
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -83,12 +83,19 @@ DIRS += \
   plugins/ipc \
   indexedDB \
   system \
   ipc \
   $(NULL)
 
 ifdef ENABLE_TESTS
 DIRS += tests
+
+# These subdirs rely on GTK libraries and header files, it is not
+#  buildable on other non-GTK unix builds
+
+ifneq (,$(filter gtk2 cocoa windows android qt os2,$(MOZ_WIDGET_TOOLKIT)))
+DIRS += plugins/test
+endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/plugins/base/Makefile.in
+++ b/dom/plugins/base/Makefile.in
@@ -160,8 +160,12 @@ EXTRA_DSO_LDOPTS += $(TK_LIBS)
 ifdef MOZ_ENABLE_GTK2
 EXTRA_DSO_LDOPTS += -lgtkxtbin $(XLDFLAGS) $(XT_LIBS) $(XLIBS) $(XEXT_LIBS) $(XCOMPOSITE_LIBS)
 endif           #MOZ_ENABLE_GTK2
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
 EXTRA_DSO_LDOPTS += $(XEXT_LIBS) $(XCOMPOSITE_LIBS)
 endif
 
+$(DIST)/bin/plugins:
+	$(NSINSTALL) -D $@
+
+export:: $(DIST)/bin/plugins
--- a/dom/plugins/ipc/PPluginModule.ipdl
+++ b/dom/plugins/ipc/PPluginModule.ipdl
@@ -63,16 +63,20 @@ both:
    * may be called by either child or parent. If a race occurs by calling the
    * constructor with the same string or int argument then we create two actors
    * and detect the second instance in the child. We prevent the parent's actor
    * from leaking out to plugin code and only allow the child's to be used.
    */
   async PPluginIdentifier(nsCString aString,
                           int32_t aInt);
 
+  // Window-specific message which instructs the RPC mechanism to enter
+  // a nested event loop for the current RPC call.
+  async ProcessNativeEventsInRPCCall();
+
 child:
   // Forces the child process to update its plugin function table.
   rpc NP_GetEntryPoints()
     returns (NPError rv);
 
   // Return the plugin's thread ID, if it can be found.
   rpc NP_Initialize()
     returns (NativeThreadId tid, NPError rv);
@@ -118,20 +122,16 @@ parent:
              bool aBoolVal);
 
   // Wake up and process a few native events.  Periodically called by
   // Gtk-specific code upon detecting that the plugin process has
   // entered a nested event loop.  If the browser doesn't process
   // native events, then "livelock" and some other glitches can occur.
   rpc ProcessSomeEvents();
 
-  // Window-specific message which instructs the RPC mechanism to enter
-  // a nested event loop for the current RPC call.
-  async ProcessNativeEventsInRPCCall();
-
   sync AppendNotesToCrashReport(nsCString aNotes);
 
   // OS X Specific calls to manage the plugin's window
   // when interposing system calls.
   async PluginShowWindow(uint32_t aWindowId, bool aModal,
                          int32_t aX, int32_t aY,
                          size_t aWidth, size_t aHeight);
   async PluginHideWindow(uint32_t aWindowId);
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -1548,64 +1548,22 @@ PluginInstanceChild::CreateWinlessPopupS
 void
 PluginInstanceChild::DestroyWinlessPopupSurrogate()
 {
     if (mWinlessPopupSurrogateHWND)
         DestroyWindow(mWinlessPopupSurrogateHWND);
     mWinlessPopupSurrogateHWND = NULL;
 }
 
-/* windowless handle event helpers */
-
-static bool
-NeedsNestedEventCoverage(UINT msg)
-{
-    // Events we assume some sort of modal ui *might* be generated.
-    switch (msg) {
-        case WM_LBUTTONUP:
-        case WM_RBUTTONUP:
-        case WM_MBUTTONUP:
-        case WM_LBUTTONDOWN:
-        case WM_RBUTTONDOWN:
-        case WM_MBUTTONDOWN:
-        case WM_CONTEXTMENU:
-            return true;
-    }
-    return false;
-}
-
-static bool
-IsMouseInputEvent(UINT msg)
-{
-    switch (msg) {
-        case WM_MOUSEMOVE:
-        case WM_LBUTTONUP:
-        case WM_RBUTTONUP:
-        case WM_MBUTTONUP:
-        case WM_LBUTTONDOWN:
-        case WM_RBUTTONDOWN:
-        case WM_MBUTTONDOWN:
-        case WM_LBUTTONDBLCLK:
-        case WM_MBUTTONDBLCLK:
-        case WM_RBUTTONDBLCLK:
-            return true;
-    }
-    return false;
-}
-
 int16_t
 PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
 {
     if (!mPluginIface->event)
         return false;
 
-    if (!NeedsNestedEventCoverage(event.event)) {
-        return mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
-    }
-
     // Events that might generate nested event dispatch loops need
     // special handling during delivery.
     int16_t handled;
 
     // TrackPopupMenu will fail if the parent window is not associated with
     // our ui thread. So we hook TrackPopupMenu so we can hand in a surrogate
     // parent created in the child process.
     if ((GetQuirks() & PluginModuleChild::QUIRK_WINLESS_TRACKPOPUP_HOOK) && // XXX turn on by default?
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -63,20 +63,16 @@
 #include <windowsx.h>
 #include "mozilla/plugins/PluginSurfaceParent.h"
 
 // Plugin focus event for widget.
 extern const PRUnichar* kOOPPPluginFocusEventId;
 UINT gOOPPPluginFocusEvent =
     RegisterWindowMessage(kOOPPPluginFocusEventId);
 extern const PRUnichar* kFlashFullscreenClass;
-UINT gOOPPSpinNativeLoopEvent =
-    RegisterWindowMessage(L"SyncChannel Spin Inner Loop Message");
-UINT gOOPPStopNativeLoopEvent =
-    RegisterWindowMessage(L"SyncChannel Stop Inner Loop Message");
 #elif defined(MOZ_WIDGET_GTK2)
 #include <gdk/gdk.h>
 #elif defined(XP_MACOSX)
 #include <ApplicationServices/ApplicationServices.h>
 #endif // defined(XP_MACOSX)
 
 using namespace mozilla::plugins;
 
@@ -95,16 +91,17 @@ PluginInstanceParent::PluginInstancePare
   : mParent(parent)
     , mNPP(npp)
     , mNPNIface(npniface)
     , mWindowType(NPWindowTypeWindow)
 #if defined(OS_WIN)
     , mPluginHWND(NULL)
     , mPluginWndProc(NULL)
     , mNestedEventState(false)
+    , mInAnswerFocusChange(false)
 #endif // defined(XP_WIN)
     , mQuirks(0)
 #if defined(XP_MACOSX)
     , mShWidth(0)
     , mShHeight(0)
     , mShColorSpace(nsnull)
     , mDrawingModel(NPDrawingModelCoreGraphics)
     , mIOSurface(nsnull)
@@ -1558,17 +1555,18 @@ PluginInstanceParent::PluginWindowHookPr
         return DefWindowProc(hWnd, message, wParam, lParam);
     }
 
     NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
 
     switch (message) {
         case WM_SETFOCUS:
         // Let the child plugin window know it should take focus.
-        self->CallSetPluginFocus();
+        if (!self->mInAnswerFocusChange)
+          self->CallSetPluginFocus();
         break;
 
         case WM_CLOSE:
         self->UnsubclassPluginWindow();
         break;
     }
 
     return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
@@ -1738,16 +1736,18 @@ PluginInstanceParent::AnswerPluginFocusC
 {
     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)
+    AutoRestore<bool> ar(mInAnswerFocusChange);
+    mInAnswerFocusChange = true;
     ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, gotFocus ? 1 : 0, 0);
     return true;
 #else
     NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
     return false;
 #endif
 }
 
--- a/dom/plugins/ipc/PluginInstanceParent.h
+++ b/dom/plugins/ipc/PluginInstanceParent.h
@@ -344,16 +344,17 @@ private:
 
 private:
     gfx::SharedDIBWin  mSharedSurfaceDib;
     nsIntRect          mPluginPort;
     nsIntRect          mSharedSize;
     HWND               mPluginHWND;
     WNDPROC            mPluginWndProc;
     bool               mNestedEventState;
+    bool               mInAnswerFocusChange;
 #endif // defined(XP_WIN)
 #if defined(OS_MACOSX)
 private:
     Shmem              mShSurface; 
     size_t             mShWidth;
     size_t             mShHeight;
     CGColorSpaceRef    mShColorSpace;
     int16_t            mDrawingModel;
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -2290,14 +2290,28 @@ PluginModuleChild::ResetEventHooks()
         UnhookWindowsHookEx(mNestedEventHook);
     mNestedEventHook = NULL;
     if (mGlobalCallWndProcHook)
         UnhookWindowsHookEx(mGlobalCallWndProcHook);
     mGlobalCallWndProcHook = NULL;
 }
 #endif
 
+bool
+PluginModuleChild::RecvProcessNativeEventsInRPCCall()
+{
+    PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
+#if defined(OS_WIN)
+    ProcessNativeEventsInRPCCall();
+    return true;
+#else
+    NS_RUNTIMEABORT(
+        "PluginModuleChild::RecvProcessNativeEventsInRPCCall not implemented!");
+    return false;
+#endif
+}
+
 #ifdef OS_MACOSX
 void
 PluginModuleChild::ProcessNativeEvents() {
     CallProcessSomeEvents();    
 }
 #endif
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -152,16 +152,19 @@ protected:
     virtual bool
     AnswerNPP_GetSitesWithData(InfallibleTArray<nsCString>* aResult);
 
     virtual void
     ActorDestroy(ActorDestroyReason why);
 
     NS_NORETURN void QuickExit();
 
+    NS_OVERRIDE virtual bool
+    RecvProcessNativeEventsInRPCCall();
+
 public:
     PluginModuleChild();
     virtual ~PluginModuleChild();
 
     // aPluginFilename is UTF8, not native-charset!
     bool Init(const std::string& aPluginFilename,
               base::ProcessHandle aParentProcessHandle,
               MessageLoop* aIOLoop,
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -995,21 +995,32 @@ bool
 PluginModuleParent::RecvProcessNativeEventsInRPCCall()
 {
     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
 #if defined(OS_WIN)
     ProcessNativeEventsInRPCCall();
     return true;
 #else
     NS_NOTREACHED(
-        "PluginInstanceParent::RecvProcessNativeEventsInRPCCall not implemented!");
+        "PluginModuleParent::RecvProcessNativeEventsInRPCCall not implemented!");
     return false;
 #endif
 }
 
+void
+PluginModuleParent::ProcessRemoteNativeEventsInRPCCall()
+{
+#if defined(OS_WIN)
+    SendProcessNativeEventsInRPCCall();
+    return;
+#endif
+    NS_NOTREACHED(
+        "PluginModuleParent::ProcessRemoteNativeEventsInRPCCall not implemented!");
+}
+
 bool
 PluginModuleParent::RecvPluginShowWindow(const uint32_t& aWindowId, const bool& aModal,
                                          const int32_t& aX, const int32_t& aY,
                                          const size_t& aWidth, const size_t& aHeight)
 {
     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
 #if defined(XP_MACOSX)
     CGRect windowBound = ::CGRectMake(aX, aY, aWidth, aHeight);
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -134,16 +134,18 @@ public:
 
     bool OkToCleanup() const {
         return !IsOnCxxStack();
     }
 
     PPluginIdentifierParent*
     GetIdentifierForNPIdentifier(NPIdentifier aIdentifier);
 
+    void ProcessRemoteNativeEventsInRPCCall();
+
 #ifdef OS_MACOSX
     void AddToRefreshTimer(PluginInstanceParent *aInstance);
     void RemoveFromRefreshTimer(PluginInstanceParent *aInstance);
 #endif
 
 protected:
     NS_OVERRIDE
     virtual mozilla::ipc::RPCChannel::RacyRPCPolicy
rename from modules/plugin/test/Makefile.in
rename to dom/plugins/test/Makefile.in
--- a/modules/plugin/test/Makefile.in
+++ b/dom/plugins/test/Makefile.in
@@ -35,17 +35,17 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-relativesrcdir = modules/plugin/test
+relativesrcdir = dom/plugins/test
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = test_plugin
 
 DIRS = testplugin
 
 XPCSHELL_TESTS = \
rename from modules/plugin/test/crashtests/110650-1.html
rename to dom/plugins/test/crashtests/110650-1.html
rename from modules/plugin/test/crashtests/41276-1.html
rename to dom/plugins/test/crashtests/41276-1.html
rename from modules/plugin/test/crashtests/48856-1.html
rename to dom/plugins/test/crashtests/48856-1.html
rename from modules/plugin/test/crashtests/539897-1.html
rename to dom/plugins/test/crashtests/539897-1.html
rename from modules/plugin/test/crashtests/540114-1.html
rename to dom/plugins/test/crashtests/540114-1.html
rename from modules/plugin/test/crashtests/570884.html
rename to dom/plugins/test/crashtests/570884.html
rename from modules/plugin/test/crashtests/598862.html
rename to dom/plugins/test/crashtests/598862.html
rename from modules/plugin/test/crashtests/626602-1.html
rename to dom/plugins/test/crashtests/626602-1.html
rename from modules/plugin/test/crashtests/crashtests.list
rename to dom/plugins/test/crashtests/crashtests.list
rename from modules/plugin/test/mochitest/307-xo-redirect.sjs
rename to dom/plugins/test/mochitest/307-xo-redirect.sjs
--- a/modules/plugin/test/mochitest/307-xo-redirect.sjs
+++ b/dom/plugins/test/mochitest/307-xo-redirect.sjs
@@ -1,6 +1,6 @@
 function handleRequest(request, response)
 {
   response.setStatusLine(request.httpVersion, 307, "Moved temporarily");
-  response.setHeader("Location", "http://example.org/tests/modules/plugin/test/loremipsum.txt");
+  response.setHeader("Location", "http://example.org/tests/dom/plugins/test/loremipsum.txt");
   response.setHeader("Content-Type", "text/html");
 }
rename from modules/plugin/test/mochitest/Makefile.in
rename to dom/plugins/test/mochitest/Makefile.in
--- a/modules/plugin/test/mochitest/Makefile.in
+++ b/dom/plugins/test/mochitest/Makefile.in
@@ -34,17 +34,17 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-relativesrcdir  = modules/plugin/test
+relativesrcdir  = dom/plugins/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _MOCHITEST_FILES = \
   utils.js \
   test_getauthenticationinfo.html \
   test_npobject_getters.html \
rename from modules/plugin/test/mochitest/cocoa_focus.html
rename to dom/plugins/test/mochitest/cocoa_focus.html
rename from modules/plugin/test/mochitest/cocoa_window_focus.html
rename to dom/plugins/test/mochitest/cocoa_window_focus.html
rename from modules/plugin/test/mochitest/crashing_subpage.html
rename to dom/plugins/test/mochitest/crashing_subpage.html
rename from modules/plugin/test/mochitest/large-pic.jpg
rename to dom/plugins/test/mochitest/large-pic.jpg
rename from modules/plugin/test/mochitest/loremipsum.txt
rename to dom/plugins/test/mochitest/loremipsum.txt
rename from modules/plugin/test/mochitest/loremipsum.xtest
rename to dom/plugins/test/mochitest/loremipsum.xtest
rename from modules/plugin/test/mochitest/loremipsum.xtest^headers^
rename to dom/plugins/test/mochitest/loremipsum.xtest^headers^
rename from modules/plugin/test/mochitest/loremipsum_file.txt
rename to dom/plugins/test/mochitest/loremipsum_file.txt
rename from modules/plugin/test/mochitest/loremipsum_nocache.txt
rename to dom/plugins/test/mochitest/loremipsum_nocache.txt
rename from modules/plugin/test/mochitest/loremipsum_nocache.txt^headers^
rename to dom/plugins/test/mochitest/loremipsum_nocache.txt^headers^
rename from modules/plugin/test/mochitest/neverending.sjs
rename to dom/plugins/test/mochitest/neverending.sjs
rename from modules/plugin/test/mochitest/plugin_visibility_loader.html
rename to dom/plugins/test/mochitest/plugin_visibility_loader.html
rename from modules/plugin/test/mochitest/plugin_window.html
rename to dom/plugins/test/mochitest/plugin_window.html
rename from modules/plugin/test/mochitest/pluginstream.js
rename to dom/plugins/test/mochitest/pluginstream.js
rename from modules/plugin/test/mochitest/post.sjs
rename to dom/plugins/test/mochitest/post.sjs
rename from modules/plugin/test/mochitest/test_GCrace.html
rename to dom/plugins/test/mochitest/test_GCrace.html
rename from modules/plugin/test/mochitest/test_bug479979.xul
rename to dom/plugins/test/mochitest/test_bug479979.xul
rename from modules/plugin/test/mochitest/test_bug532208.html
rename to dom/plugins/test/mochitest/test_bug532208.html
rename from modules/plugin/test/mochitest/test_bug539565-1.html
rename to dom/plugins/test/mochitest/test_bug539565-1.html
rename from modules/plugin/test/mochitest/test_bug539565-2.html
rename to dom/plugins/test/mochitest/test_bug539565-2.html
rename from modules/plugin/test/mochitest/test_clear_site_data.html
rename to dom/plugins/test/mochitest/test_clear_site_data.html
rename from modules/plugin/test/mochitest/test_cocoa_focus.html
rename to dom/plugins/test/mochitest/test_cocoa_focus.html
rename from modules/plugin/test/mochitest/test_cocoa_window_focus.html
rename to dom/plugins/test/mochitest/test_cocoa_window_focus.html
rename from modules/plugin/test/mochitest/test_convertpoint.xul
rename to dom/plugins/test/mochitest/test_convertpoint.xul
rename from modules/plugin/test/mochitest/test_cookies.html
rename to dom/plugins/test/mochitest/test_cookies.html
rename from modules/plugin/test/mochitest/test_copyText.html
rename to dom/plugins/test/mochitest/test_copyText.html
rename from modules/plugin/test/mochitest/test_crash_nested_loop.html
rename to dom/plugins/test/mochitest/test_crash_nested_loop.html
rename from modules/plugin/test/mochitest/test_crash_notify.xul
rename to dom/plugins/test/mochitest/test_crash_notify.xul
rename from modules/plugin/test/mochitest/test_crash_notify_no_report.xul
rename to dom/plugins/test/mochitest/test_crash_notify_no_report.xul
rename from modules/plugin/test/mochitest/test_crash_submit.xul
rename to dom/plugins/test/mochitest/test_crash_submit.xul
rename from modules/plugin/test/mochitest/test_crashing.html
rename to dom/plugins/test/mochitest/test_crashing.html
rename from modules/plugin/test/mochitest/test_crashing2.html
rename to dom/plugins/test/mochitest/test_crashing2.html
rename from modules/plugin/test/mochitest/test_enumerate.html
rename to dom/plugins/test/mochitest/test_enumerate.html
rename from modules/plugin/test/mochitest/test_fullpage.html
rename to dom/plugins/test/mochitest/test_fullpage.html
rename from modules/plugin/test/mochitest/test_getauthenticationinfo.html
rename to dom/plugins/test/mochitest/test_getauthenticationinfo.html
rename from modules/plugin/test/mochitest/test_hanging.html
rename to dom/plugins/test/mochitest/test_hanging.html
rename from modules/plugin/test/mochitest/test_instantiation.html
rename to dom/plugins/test/mochitest/test_instantiation.html
rename from modules/plugin/test/mochitest/test_multipleinstanceobjects.html
rename to dom/plugins/test/mochitest/test_multipleinstanceobjects.html
rename from modules/plugin/test/mochitest/test_newstreamondestroy.html
rename to dom/plugins/test/mochitest/test_newstreamondestroy.html
rename from modules/plugin/test/mochitest/test_npn_asynccall.html
rename to dom/plugins/test/mochitest/test_npn_asynccall.html
rename from modules/plugin/test/mochitest/test_npn_timers.html
rename to dom/plugins/test/mochitest/test_npn_timers.html
rename from modules/plugin/test/mochitest/test_npobject_getters.html
rename to dom/plugins/test/mochitest/test_npobject_getters.html
rename from modules/plugin/test/mochitest/test_npruntime.xul
rename to dom/plugins/test/mochitest/test_npruntime.xul
rename from modules/plugin/test/mochitest/test_npruntime_construct.html
rename to dom/plugins/test/mochitest/test_npruntime_construct.html
rename from modules/plugin/test/mochitest/test_npruntime_identifiers.html
rename to dom/plugins/test/mochitest/test_npruntime_identifiers.html
rename from modules/plugin/test/mochitest/test_npruntime_npnevaluate.html
rename to dom/plugins/test/mochitest/test_npruntime_npnevaluate.html
rename from modules/plugin/test/mochitest/test_npruntime_npninvoke.html
rename to dom/plugins/test/mochitest/test_npruntime_npninvoke.html
rename from modules/plugin/test/mochitest/test_npruntime_npninvokedefault.html
rename to dom/plugins/test/mochitest/test_npruntime_npninvokedefault.html
rename from modules/plugin/test/mochitest/test_npruntime_npnsetexception.html
rename to dom/plugins/test/mochitest/test_npruntime_npnsetexception.html
rename from modules/plugin/test/mochitest/test_painting.html
rename to dom/plugins/test/mochitest/test_painting.html
rename from modules/plugin/test/mochitest/test_plugin_scroll_painting.html
rename to dom/plugins/test/mochitest/test_plugin_scroll_painting.html
rename from modules/plugin/test/mochitest/test_pluginstream_asfile.html
rename to dom/plugins/test/mochitest/test_pluginstream_asfile.html
rename from modules/plugin/test/mochitest/test_pluginstream_asfileonly.html
rename to dom/plugins/test/mochitest/test_pluginstream_asfileonly.html
rename from modules/plugin/test/mochitest/test_pluginstream_err.html
rename to dom/plugins/test/mochitest/test_pluginstream_err.html
rename from modules/plugin/test/mochitest/test_pluginstream_geturl.html
rename to dom/plugins/test/mochitest/test_pluginstream_geturl.html
rename from modules/plugin/test/mochitest/test_pluginstream_geturlnotify.html
rename to dom/plugins/test/mochitest/test_pluginstream_geturlnotify.html
rename from modules/plugin/test/mochitest/test_pluginstream_newstream.html
rename to dom/plugins/test/mochitest/test_pluginstream_newstream.html
rename from modules/plugin/test/mochitest/test_pluginstream_post.html
rename to dom/plugins/test/mochitest/test_pluginstream_post.html
rename from modules/plugin/test/mochitest/test_pluginstream_poststream.html
rename to dom/plugins/test/mochitest/test_pluginstream_poststream.html
rename from modules/plugin/test/mochitest/test_pluginstream_seek.html
rename to dom/plugins/test/mochitest/test_pluginstream_seek.html
rename from modules/plugin/test/mochitest/test_pluginstream_seek_close.html
rename to dom/plugins/test/mochitest/test_pluginstream_seek_close.html
rename from modules/plugin/test/mochitest/test_pluginstream_src.html
rename to dom/plugins/test/mochitest/test_pluginstream_src.html
rename from modules/plugin/test/mochitest/test_positioning.html
rename to dom/plugins/test/mochitest/test_positioning.html
rename from modules/plugin/test/mochitest/test_privatemode.xul
rename to dom/plugins/test/mochitest/test_privatemode.xul
rename from modules/plugin/test/mochitest/test_propertyAndMethod.html
rename to dom/plugins/test/mochitest/test_propertyAndMethod.html
rename from modules/plugin/test/mochitest/test_redirect_handling.html
rename to dom/plugins/test/mochitest/test_redirect_handling.html
--- a/modules/plugin/test/mochitest/test_redirect_handling.html
+++ b/dom/plugins/test/mochitest/test_redirect_handling.html
@@ -8,17 +8,17 @@
   <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
 
   <script class="testbody" type="application/javascript">
     SimpleTest.waitForExplicitFinish();
 
     var p = document.getElementById("plugin1");
 
     var redirectingURL = "307-xo-redirect.sjs";
-    var redirectTargetURL = "http://example.org/tests/modules/plugin/test/loremipsum.txt";
+    var redirectTargetURL = "http://example.org/tests/dom/plugins/test/loremipsum.txt";
 
     var expectedWriteURL = "";
     var expectedNotifyStatus = -1;
 
     function redirectCallback(url, httpStatus) {
       is(url, redirectTargetURL, "Test for expected redirect notify URL.");
       is(httpStatus, 307, "Test for expected http redirect status.");
     }
rename from modules/plugin/test/mochitest/test_streamNotify.html
rename to dom/plugins/test/mochitest/test_streamNotify.html
rename from modules/plugin/test/mochitest/test_streamatclose.html
rename to dom/plugins/test/mochitest/test_streamatclose.html
rename from modules/plugin/test/mochitest/test_twostreams.html
rename to dom/plugins/test/mochitest/test_twostreams.html
rename from modules/plugin/test/mochitest/test_visibility.html
rename to dom/plugins/test/mochitest/test_visibility.html
rename from modules/plugin/test/mochitest/test_windowed_invalidate.html
rename to dom/plugins/test/mochitest/test_windowed_invalidate.html
rename from modules/plugin/test/mochitest/test_wmode.xul
rename to dom/plugins/test/mochitest/test_wmode.xul
rename from modules/plugin/test/mochitest/test_xulbrowser_plugin_visibility.xul
rename to dom/plugins/test/mochitest/test_xulbrowser_plugin_visibility.xul
rename from modules/plugin/test/mochitest/test_zero_opacity.html
rename to dom/plugins/test/mochitest/test_zero_opacity.html
rename from modules/plugin/test/mochitest/utils.js
rename to dom/plugins/test/mochitest/utils.js
rename from modules/plugin/test/mochitest/xulbrowser_plugin_visibility.xul
rename to dom/plugins/test/mochitest/xulbrowser_plugin_visibility.xul
--- a/modules/plugin/test/mochitest/xulbrowser_plugin_visibility.xul
+++ b/dom/plugins/test/mochitest/xulbrowser_plugin_visibility.xul
@@ -19,17 +19,17 @@
     const ok = window.opener.wrappedJSObject.ok;
     const is = window.opener.wrappedJSObject.is;
     const done = window.opener.wrappedJSObject.done;
     const SimpleTest = window.opener.wrappedJSObject.SimpleTest;
 
     const nsIWebProgress = Components.interfaces.nsIWebProgress;
     const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
 
-    const kURI = 'http://mochi.test:8888/chrome/modules/plugin/test/plugin_visibility_loader.html';
+    const kURI = 'http://mochi.test:8888/chrome/dom/plugins/test/plugin_visibility_loader.html';
 
     function ProgressListener() {
     }
     ProgressListener.prototype.onStateChange =
       function(progress, req, flags, status) {
         if ((flags & nsIWebProgressListener.STATE_IS_WINDOW) &&
             (flags & nsIWebProgressListener.STATE_STOP))
           browserLoaded();
rename from modules/plugin/test/reftest/border-padding-1-ref.html
rename to dom/plugins/test/reftest/border-padding-1-ref.html
rename from modules/plugin/test/reftest/border-padding-1.html
rename to dom/plugins/test/reftest/border-padding-1.html
rename from modules/plugin/test/reftest/border-padding-2-ref.html
rename to dom/plugins/test/reftest/border-padding-2-ref.html
rename from modules/plugin/test/reftest/border-padding-2.html
rename to dom/plugins/test/reftest/border-padding-2.html
rename from modules/plugin/test/reftest/border-padding-3-ref.html
rename to dom/plugins/test/reftest/border-padding-3-ref.html
rename from modules/plugin/test/reftest/border-padding-3.html
rename to dom/plugins/test/reftest/border-padding-3.html
rename from modules/plugin/test/reftest/div-alpha-opacity.html
rename to dom/plugins/test/reftest/div-alpha-opacity.html
rename from modules/plugin/test/reftest/div-alpha-zindex.html
rename to dom/plugins/test/reftest/div-alpha-zindex.html
rename from modules/plugin/test/reftest/div-sanity.html
rename to dom/plugins/test/reftest/div-sanity.html
rename from modules/plugin/test/reftest/plugin-alpha-opacity.html
rename to dom/plugins/test/reftest/plugin-alpha-opacity.html
rename from modules/plugin/test/reftest/plugin-alpha-zindex.html
rename to dom/plugins/test/reftest/plugin-alpha-zindex.html
rename from modules/plugin/test/reftest/plugin-background-1-step.html
rename to dom/plugins/test/reftest/plugin-background-1-step.html
rename from modules/plugin/test/reftest/plugin-background-10-step.html
rename to dom/plugins/test/reftest/plugin-background-10-step.html
rename from modules/plugin/test/reftest/plugin-background-2-step.html
rename to dom/plugins/test/reftest/plugin-background-2-step.html
rename from modules/plugin/test/reftest/plugin-background-5-step.html
rename to dom/plugins/test/reftest/plugin-background-5-step.html
rename from modules/plugin/test/reftest/plugin-background-ref.html
rename to dom/plugins/test/reftest/plugin-background-ref.html
rename from modules/plugin/test/reftest/plugin-background.css
rename to dom/plugins/test/reftest/plugin-background.css
rename from modules/plugin/test/reftest/plugin-background.html
rename to dom/plugins/test/reftest/plugin-background.html
rename from modules/plugin/test/reftest/plugin-background.js
rename to dom/plugins/test/reftest/plugin-background.js
rename from modules/plugin/test/reftest/plugin-busy-alpha-zindex.html
rename to dom/plugins/test/reftest/plugin-busy-alpha-zindex.html
rename from modules/plugin/test/reftest/plugin-canvas-alpha-zindex.html
rename to dom/plugins/test/reftest/plugin-canvas-alpha-zindex.html
rename from modules/plugin/test/reftest/plugin-sanity.html
rename to dom/plugins/test/reftest/plugin-sanity.html
rename from modules/plugin/test/reftest/plugin-transform-1-ref.html
rename to dom/plugins/test/reftest/plugin-transform-1-ref.html
rename from modules/plugin/test/reftest/plugin-transform-1.html
rename to dom/plugins/test/reftest/plugin-transform-1.html
rename from modules/plugin/test/reftest/plugin-transform-2-ref.html
rename to dom/plugins/test/reftest/plugin-transform-2-ref.html
rename from modules/plugin/test/reftest/plugin-transform-2.html
rename to dom/plugins/test/reftest/plugin-transform-2.html
rename from modules/plugin/test/reftest/plugin-transform-alpha-zindex.html
rename to dom/plugins/test/reftest/plugin-transform-alpha-zindex.html
rename from modules/plugin/test/reftest/pluginproblemui-direction-1-ref.html
rename to dom/plugins/test/reftest/pluginproblemui-direction-1-ref.html
rename from modules/plugin/test/reftest/pluginproblemui-direction-1.html
rename to dom/plugins/test/reftest/pluginproblemui-direction-1.html
rename from modules/plugin/test/reftest/pluginproblemui-direction-2-ref.html
rename to dom/plugins/test/reftest/pluginproblemui-direction-2-ref.html
rename from modules/plugin/test/reftest/pluginproblemui-direction-2.html
rename to dom/plugins/test/reftest/pluginproblemui-direction-2.html
rename from modules/plugin/test/reftest/reftest.list
rename to dom/plugins/test/reftest/reftest.list
rename from modules/plugin/test/reftest/windowless-clipping-1-ref.html
rename to dom/plugins/test/reftest/windowless-clipping-1-ref.html
rename from modules/plugin/test/reftest/windowless-clipping-1.html
rename to dom/plugins/test/reftest/windowless-clipping-1.html
rename from modules/plugin/test/testplugin/Info.plist
rename to dom/plugins/test/testplugin/Info.plist
rename from modules/plugin/test/testplugin/Makefile.in
rename to dom/plugins/test/testplugin/Makefile.in
rename from modules/plugin/test/testplugin/README
rename to dom/plugins/test/testplugin/README
rename from modules/plugin/test/testplugin/nptest.cpp
rename to dom/plugins/test/testplugin/nptest.cpp
rename from modules/plugin/test/testplugin/nptest.def
rename to dom/plugins/test/testplugin/nptest.def
rename from modules/plugin/test/testplugin/nptest.h
rename to dom/plugins/test/testplugin/nptest.h
rename from modules/plugin/test/testplugin/nptest.rc
rename to dom/plugins/test/testplugin/nptest.rc
rename from modules/plugin/test/testplugin/nptest_droid.cpp
rename to dom/plugins/test/testplugin/nptest_droid.cpp
rename from modules/plugin/test/testplugin/nptest_gtk2.cpp
rename to dom/plugins/test/testplugin/nptest_gtk2.cpp
rename from modules/plugin/test/testplugin/nptest_macosx.mm
rename to dom/plugins/test/testplugin/nptest_macosx.mm
rename from modules/plugin/test/testplugin/nptest_os2.cpp
rename to dom/plugins/test/testplugin/nptest_os2.cpp
rename from modules/plugin/test/testplugin/nptest_platform.h
rename to dom/plugins/test/testplugin/nptest_platform.h
rename from modules/plugin/test/testplugin/nptest_qt.cpp
rename to dom/plugins/test/testplugin/nptest_qt.cpp
rename from modules/plugin/test/testplugin/nptest_utils.cpp
rename to dom/plugins/test/testplugin/nptest_utils.cpp
rename from modules/plugin/test/testplugin/nptest_utils.h
rename to dom/plugins/test/testplugin/nptest_utils.h
rename from modules/plugin/test/testplugin/nptest_windows.cpp
rename to dom/plugins/test/testplugin/nptest_windows.cpp
rename from modules/plugin/test/unit/head_plugins.js
rename to dom/plugins/test/unit/head_plugins.js
rename from modules/plugin/test/unit/test_bug455213.js
rename to dom/plugins/test/unit/test_bug455213.js
rename from modules/plugin/test/unit/test_bug471245.js
rename to dom/plugins/test/unit/test_bug471245.js
--- a/ipc/glue/RPCChannel.cpp
+++ b/ipc/glue/RPCChannel.cpp
@@ -490,16 +490,20 @@ RPCChannel::Incall(const Message& call, 
         }
 
         // we "lost" and need to process the other side's in-call.
         // don't need to fix up the mRemoteStackDepthGuess here,
         // because we're just about to increment it in DispatchCall(),
         // which will make it correct again
     }
 
+#ifdef OS_WIN
+    SyncStackFrame frame(this, true);
+#endif
+
     DispatchIncall(call);
 }
 
 void
 RPCChannel::DispatchIncall(const Message& call)
 {
     AssertWorkerThread();
     mMonitor.AssertNotCurrentThreadOwns();
--- a/ipc/glue/RPCChannel.h
+++ b/ipc/glue/RPCChannel.h
@@ -106,16 +106,17 @@ public:
             NS_RUNTIMEABORT("default impl shouldn't be invoked");
         }
 
         virtual RacyRPCPolicy MediateRPCRace(const Message& parent,
                                              const Message& child)
         {
             return RRPChildWins;
         }
+        virtual void ProcessRemoteNativeEventsInRPCCall() {};
     };
 
     RPCChannel(RPCListener* aListener);
 
     virtual ~RPCChannel();
 
     NS_OVERRIDE
     void Clear();
@@ -173,16 +174,17 @@ public:
      *
      * @note This method is used on Windows when we detect that an outbound
      * OLE RPC call is being made to unblock the parent.
      */
     void FlushPendingRPCQueue();
 
 #ifdef OS_WIN
     void ProcessNativeEventsInRPCCall();
+    static void NotifyGeckoEventDispatch();
 
 protected:
     bool WaitForNotify();
     void SpinInternalEventLoop();
 #endif
 
   private:
     // Called on worker thread only
--- a/ipc/glue/SyncChannel.h
+++ b/ipc/glue/SyncChannel.h
@@ -100,16 +100,17 @@ public:
 #ifdef OS_WIN
     struct NS_STACK_CLASS SyncStackFrame
     {
         SyncStackFrame(SyncChannel* channel, bool rpc);
         ~SyncStackFrame();
 
         bool mRPC;
         bool mSpinNestedEvents;
+        bool mListenerNotified;
         SyncChannel* mChannel;
 
         /* the previous stack frame for this channel */
         SyncStackFrame* mPrev;
 
         /* the previous stack frame on any channel */
         SyncStackFrame* mStaticPrev;
     };
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -579,16 +579,17 @@ TimeoutHasExpired(const TimeoutData& aDa
   return now >= aData.targetTicks;
 }
 
 } // anonymous namespace
 
 RPCChannel::SyncStackFrame::SyncStackFrame(SyncChannel* channel, bool rpc)
   : mRPC(rpc)
   , mSpinNestedEvents(false)
+  , mListenerNotified(false)
   , mChannel(channel)
   , mPrev(mChannel->mTopFrame)
   , mStaticPrev(sStaticTopFrame)
 {
   mChannel->mTopFrame = this;
   sStaticTopFrame = this;
 
   if (!mStaticPrev) {
@@ -612,21 +613,39 @@ RPCChannel::SyncStackFrame::~SyncStackFr
     NS_ASSERTION(gNeuteredWindows, "Bad pointer!");
     delete gNeuteredWindows;
     gNeuteredWindows = NULL;
   }
 }
 
 SyncChannel::SyncStackFrame* SyncChannel::sStaticTopFrame;
 
+// nsAppShell's notification that gecko events are being processed.
+// If we are here and there is an RPC Incall active, we are spinning
+// a nested gecko event loop. In which case the remote process needs
+// to know about it.
+void /* static */
+RPCChannel::NotifyGeckoEventDispatch()
+{
+  // sStaticTopFrame is only valid for RPC channels
+  if (!sStaticTopFrame || sStaticTopFrame->mListenerNotified)
+    return;
+
+  sStaticTopFrame->mListenerNotified = true;
+  RPCChannel* channel = static_cast<RPCChannel*>(sStaticTopFrame->mChannel);
+  channel->Listener()->ProcessRemoteNativeEventsInRPCCall();
+}
+
+// invoked by the module that receives the spin event loop
+// message.
 void
 RPCChannel::ProcessNativeEventsInRPCCall()
 {
   if (!mTopFrame) {
-    NS_ERROR("Child logic error: no RPC frame");
+    NS_ERROR("Spin logic error: no RPC frame");
     return;
   }
 
   mTopFrame->mSpinNestedEvents = true;
 }
 
 // Spin loop is called in place of WaitForNotify when modal ui is being shown
 // in a child. There are some intricacies in using it however. Spin loop is
@@ -991,29 +1010,40 @@ DeferredRedrawMessage::Run()
 
 #ifdef DEBUG
   BOOL ret =
 #endif
   RedrawWindow(hWnd, NULL, NULL, flags);
   NS_ASSERTION(ret, "RedrawWindow failed!");
 }
 
+DeferredUpdateMessage::DeferredUpdateMessage(HWND aHWnd)
+{
+  mWnd = aHWnd;
+  if (!GetUpdateRect(mWnd, &mUpdateRect, FALSE)) {
+    memset(&mUpdateRect, 0, sizeof(RECT));
+    return;
+  }
+  ValidateRect(mWnd, &mUpdateRect);
+}
+
 void
 DeferredUpdateMessage::Run()
 {
-  AssertWindowIsNotNeutered(hWnd);
-  if (!IsWindow(hWnd)) {
+  AssertWindowIsNotNeutered(mWnd);
+  if (!IsWindow(mWnd)) {
     NS_ERROR("Invalid window!");
     return;
   }
 
+  InvalidateRect(mWnd, &mUpdateRect, FALSE);
 #ifdef DEBUG
   BOOL ret =
 #endif
-  UpdateWindow(hWnd);
+  UpdateWindow(mWnd);
   NS_ASSERTION(ret, "UpdateWindow failed!");
 }
 
 DeferredSettingChangeMessage::DeferredSettingChangeMessage(HWND aHWnd,
                                                            UINT aMessage,
                                                            WPARAM aWParam,
                                                            LPARAM aLParam)
 : DeferredSendMessage(aHWnd, aMessage, aWParam, aLParam)
--- a/ipc/glue/WindowsMessageLoop.h
+++ b/ipc/glue/WindowsMessageLoop.h
@@ -108,24 +108,23 @@ private:
   HWND hWnd;
   UINT flags;
 };
 
 // Uses UpdateWindow to generate a WM_PAINT message if needed.
 class DeferredUpdateMessage : public DeferredMessage
 {
 public:
-  DeferredUpdateMessage(HWND aHWnd)
-    : hWnd(aHWnd)
-  { }
+  DeferredUpdateMessage(HWND aHWnd);
 
   virtual void Run();
 
 private:
-  HWND hWnd;
+  HWND mWnd;
+  RECT mUpdateRect;
 };
 
 // This class duplicates a string that may exist in the lParam member of the
 // message.
 class DeferredSettingChangeMessage : public DeferredSendMessage
 {
 public:
   DeferredSettingChangeMessage(HWND aHWnd,
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -2831,18 +2831,17 @@ class _GenerateProtocolActorCode(ipdl.as
         # protocols with union types need Lookup().  we'll give it to
         # all for the time being (simpler)
         if 1 or ptype.isManager():
             self.cls.addstmts(self.implementManagerIface())
 
         # User-facing shmem methods
         self.cls.addstmts(self.makeShmemIface())
 
-        if (ptype.isToplevel() and self.side is 'parent'
-            and ptype.talksRpc()):
+        if (ptype.isToplevel() and ptype.talksRpc()):
 
             processnative = MethodDefn(
                 MethodDecl('ProcessNativeEventsInRPCCall', ret=Type.VOID))
 
             processnative.addstmts([
                     CppDirective('ifdef', 'OS_WIN'),
                     StmtExpr(ExprCall(
                             ExprSelect(p.channelVar(), '.',
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -434,20 +434,21 @@ FrameLayerBuilder::Init(nsDisplayListBui
 {
   mRootPresContext = aBuilder->ReferenceFrame()->PresContext()->GetRootPresContext();
   if (mRootPresContext) {
     mInitialDOMGeneration = mRootPresContext->GetDOMGeneration();
   }
 }
 
 PRBool
-FrameLayerBuilder::DisplayItemDataEntry::HasContainerLayer()
+FrameLayerBuilder::DisplayItemDataEntry::HasNonEmptyContainerLayer()
 {
   for (PRUint32 i = 0; i < mData.Length(); ++i) {
-    if (mData[i].mLayer->GetType() == Layer::TYPE_CONTAINER)
+    if (mData[i].mLayer->GetType() == Layer::TYPE_CONTAINER &&
+        mData[i].mLayerState != LAYER_ACTIVE_EMPTY)
       return PR_TRUE;
   }
   return PR_FALSE;
 }
 
 /* static */ void
 FrameLayerBuilder::InternalDestroyDisplayItemData(nsIFrame* aFrame,
                                                   void* aPropertyValue,
@@ -604,17 +605,17 @@ FrameLayerBuilder::UpdateDisplayItemData
     // mFramesWithLayers, but we won't. That's OK because our caller
     // is DidEndTransaction, which would recreate the user data
     // anyway.
     InternalDestroyDisplayItemData(f, prop, PR_FALSE);
     SetNoContainerLayer(f);
     return PL_DHASH_REMOVE;
   }
 
-  if (newDisplayItems->HasContainerLayer()) {
+  if (newDisplayItems->HasNonEmptyContainerLayer()) {
     // Reset or create the invalid region now so we can start collecting
     // new dirty areas.
     // Note that the NS_FRAME_HAS_CONTAINER_LAYER bit is set in
     // BuildContainerLayerFor, so we don't need to set it here.
     nsRegion* invalidRegion = static_cast<nsRegion*>
       (props.Get(ThebesLayerInvalidRegionProperty()));
     if (invalidRegion) {
       invalidRegion->SetEmpty();
@@ -1309,18 +1310,17 @@ ContainerState::ProcessDisplayItems(cons
     nsIntRect itemVisibleRect =
       item->GetVisibleRect().ToOutsidePixels(appUnitsPerDevPixel);
     nsRect itemContent = item->GetBounds(mBuilder);
     if (aClip.mHaveClipRect) {
       itemContent.IntersectRect(aClip.mClipRect, itemContent);
     }
     mBounds.UnionRect(mBounds, itemContent);
     nsIntRect itemDrawRect = itemContent.ToOutsidePixels(appUnitsPerDevPixel);
-    nsDisplayItem::LayerState layerState =
-      item->GetLayerState(mBuilder, mManager);
+    LayerState layerState = item->GetLayerState(mBuilder, mManager);
 
     nsIFrame* activeScrolledRoot =
       nsLayoutUtils::GetActiveScrolledRootFor(item, mBuilder);
 
     // Assign the item to a layer
     if (layerState == LAYER_ACTIVE_FORCE ||
         layerState == LAYER_ACTIVE_EMPTY ||
         layerState == LAYER_ACTIVE && (aClip.mRoundedClipRects.IsEmpty() ||
@@ -1379,17 +1379,17 @@ ContainerState::ProcessDisplayItems(cons
         oldContainer->RemoveChild(ownLayer);
       }
       NS_ASSERTION(!mNewChildLayers.Contains(ownLayer),
                    "Layer already in list???");
 
       InvalidateForLayerChange(item, ownLayer);
 
       mNewChildLayers.AppendElement(ownLayer);
-      mBuilder->LayerBuilder()->AddLayerDisplayItem(ownLayer, item);
+      mBuilder->LayerBuilder()->AddLayerDisplayItem(ownLayer, item, layerState);
     } else {
       nsRefPtr<ThebesLayer> thebesLayer =
         FindThebesLayerFor(item, itemVisibleRect, itemDrawRect, aClip,
                            activeScrolledRoot);
 
       thebesLayer->SetIsFixedPosition(!nsLayoutUtils::ScrolledByViewportScrolling(
                                          activeScrolledRoot, mBuilder));
 
@@ -1457,39 +1457,40 @@ FrameLayerBuilder::NeedToInvalidateFixed
 
 void
 FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
                                         nsDisplayItem* aItem,
                                         const Clip& aClip,
                                         nsIFrame* aContainerLayerFrame,
                                         LayerState aLayerState)
 {
-  AddLayerDisplayItem(aLayer, aItem);
+  AddLayerDisplayItem(aLayer, aItem, aLayerState);
 
   ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
   if (entry) {
     entry->mContainerLayerFrame = aContainerLayerFrame;
     NS_ASSERTION(aItem->GetUnderlyingFrame(), "Must have frame");
     ClippedDisplayItem* cdi =
       entry->mItems.AppendElement(ClippedDisplayItem(aItem, aClip));
     cdi->mInactiveLayer = aLayerState != LAYER_NONE;
   }
 }
 
 void
 FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
-                                       nsDisplayItem* aItem)
+                                       nsDisplayItem* aItem,
+                                       LayerState aLayerState)
 {
   if (aLayer->Manager() != mRetainingManager)
     return;
 
   nsIFrame* f = aItem->GetUnderlyingFrame();
   DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(f);
   if (entry) {
-    entry->mData.AppendElement(DisplayItemData(aLayer, aItem->GetPerFrameKey()));
+    entry->mData.AppendElement(DisplayItemData(aLayer, aItem->GetPerFrameKey(), aLayerState));
   }
 }
 
 nsIntPoint
 FrameLayerBuilder::GetLastPaintOffset(ThebesLayer* aLayer)
 {
   ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
   if (entry && entry->mHasExplicitLastPaintOffset)
@@ -1630,24 +1631,34 @@ FrameLayerBuilder::BuildContainerLayerFo
   }
   if (!containerLayer) {
     // No suitable existing layer was found.
     containerLayer = aManager->CreateContainerLayer();
     if (!containerLayer)
       return nsnull;
   }
 
+  if (aContainerItem &&
+      aContainerItem->GetLayerState(aBuilder, aManager) == LAYER_ACTIVE_EMPTY) {
+    // Empty layers only have metadata and should never have display items. We
+    // early exit because later, invalidation will walk up the frame tree to
+    // determine which thebes layer gets invalidated. Since an empty layer
+    // should never have anything to paint, it should never be invalidated.
+    NS_ASSERTION(aChildren.IsEmpty(), "Should have no children");
+    return containerLayer.forget();
+  }
+
   ContainerState state(aBuilder, aManager, aContainerFrame, containerLayer);
   nscoord appUnitsPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
 
   if (aManager == mRetainingManager) {
     DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(aContainerFrame);
     if (entry) {
       entry->mData.AppendElement(
-          DisplayItemData(containerLayer, containerDisplayItemKey));
+          DisplayItemData(containerLayer, containerDisplayItemKey, LAYER_ACTIVE));
     }
 
     nsPoint* offsetAtLastPaint = static_cast<nsPoint*>
       (props.Get(ThebesLayerLastPaintOffsetProperty()));
     nsPoint currentOffset = aBuilder->ToReferenceFrame(aContainerFrame);
 
     nsRegion* invalidThebesContent(static_cast<nsRegion*>
       (props.Get(ThebesLayerInvalidRegionProperty())));
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -219,17 +219,19 @@ public:
   /******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/
   /* These are only in the public section because they need
    * to be called by file-scope helper functions in FrameLayerBuilder.cpp.
    */
   
   /**
    * Record aItem as a display item that is rendered by aLayer.
    */
-  void AddLayerDisplayItem(Layer* aLayer, nsDisplayItem* aItem);
+  void AddLayerDisplayItem(Layer* aLayer,
+                           nsDisplayItem* aItem,
+                           LayerState aLayerState);
 
   /**
    * Record aItem as a display item that is rendered by the ThebesLayer
    * aLayer, with aClipRect, where aContainerLayerFrame is the frame
    * for the container layer this ThebesItem belongs to.
    * aItem must have an underlying frame.
    */
   struct Clip;
@@ -377,21 +379,22 @@ public:
 protected:
   /**
    * We store an array of these for each frame that is associated with
    * one or more retained layers. Each DisplayItemData records the layer
    * used to render one of the frame's display items.
    */
   class DisplayItemData {
   public:
-    DisplayItemData(Layer* aLayer, PRUint32 aKey)
-      : mLayer(aLayer), mDisplayItemKey(aKey) {}
+    DisplayItemData(Layer* aLayer, PRUint32 aKey, LayerState aLayerState)
+      : mLayer(aLayer), mDisplayItemKey(aKey), mLayerState(aLayerState) {}
 
     nsRefPtr<Layer> mLayer;
     PRUint32        mDisplayItemKey;
+    LayerState    mLayerState;
   };
 
   static void InternalDestroyDisplayItemData(nsIFrame* aFrame,
                                              void* aPropertyValue,
                                              PRBool aRemoveFromFramesWithLayers);
   static void DestroyDisplayItemData(nsIFrame* aFrame, void* aPropertyValue);
 
   /**
@@ -411,17 +414,17 @@ protected:
   public:
     DisplayItemDataEntry(const nsIFrame *key) : nsPtrHashKey<nsIFrame>(key) {}
     DisplayItemDataEntry(const DisplayItemDataEntry &toCopy) :
       nsPtrHashKey<nsIFrame>(toCopy.mKey), mData(toCopy.mData)
     {
       NS_ERROR("Should never be called, since we ALLOW_MEMMOVE");
     }
 
-    PRBool HasContainerLayer();
+    PRBool HasNonEmptyContainerLayer();
 
     nsTArray<DisplayItemData> mData;
 
     enum { ALLOW_MEMMOVE = PR_TRUE };
   };
 
   /**
    * We store one of these for each display item associated with a
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -277,17 +277,17 @@ OS_LIBS += -framework OpenGL
 endif
 
 # Add explicit X11 dependency when building against X11 toolkits
 ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS)
 endif
 
 ifdef MOZ_SYDNEYAUDIO
-ifneq (,$(filter DragonFly FreeBSD GNU GNU_% NetBSD OpenBSD,$(OS_ARCH)))
+ifneq (,$(filter GNU GNU_% NetBSD OpenBSD,$(OS_ARCH)))
 EXTRA_DSO_LDOPTS += -lossaudio
 endif
 
 ifeq ($(OS_ARCH),Linux)
 EXTRA_DSO_LDOPTS += $(MOZ_ALSA_LIBS)
 endif
 ifeq ($(OS_ARCH),Darwin)
 OS_LIBS += -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -framework IOKit
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -208,17 +208,17 @@ include ../../parser/htmlparser/tests/re
 
 # percent-overflow-sizing/
 include percent-overflow-sizing/reftest.list
 
 # pixel-rounding/
 include pixel-rounding/reftest.list
 
 # plugin/
-include ../../modules/plugin/test/reftest/reftest.list
+include ../../dom/plugins/test/reftest/reftest.list
 
 # printing
 include printing/reftest.list
 include pagination/reftest.list
 
 # scrolling
 include scrolling/reftest.list
 
--- a/layout/reftests/svg/as-image/reftest.list
+++ b/layout/reftests/svg/as-image/reftest.list
@@ -26,19 +26,19 @@ include zoom/reftest.list
 == border-image-simple-2.html       lime100x100-ref.html
 
 # Test for canvas "drawImage" method
 # NOTE: The canvas reftests that involve scaling currently fail with fuzziness
 # on various edges, as noted below. These will be fixed in followup bugs.
 == canvas-drawImage-simple-1a.html lime100x100-ref.html
 == canvas-drawImage-simple-1b.html lime100x100-ref.html
 
-fails-if(Android) fails-if(gtk2Widget) fails-if(winWidget) == canvas-drawImage-scale-1a.html lime100x100-ref.html # XXX top & left edges fuzzy
-fails-if(Android) fails-if(gtk2Widget) fails-if(winWidget) == canvas-drawImage-scale-1b.html lime100x100-ref.html # XXX top & left edges fuzzy
-fails-if(Android) fails-if(gtk2Widget) fails-if(winWidget) == canvas-drawImage-scale-1c.html lime100x100-ref.html # XXX all edges fuzzy
+== canvas-drawImage-scale-1a.html lime100x100-ref.html
+== canvas-drawImage-scale-1b.html lime100x100-ref.html
+== canvas-drawImage-scale-1c.html lime100x100-ref.html
 
 fails == canvas-drawImage-scale-2a.html canvas-drawImage-scale-2-ref.html # XXX all edges fuzzy
 fails == canvas-drawImage-scale-2b.html canvas-drawImage-scale-2-ref.html # XXX all edges fuzzy
 
 == canvas-drawImage-slice-1a.html lime100x100-ref.html
 fails == canvas-drawImage-slice-1b.html lime100x100-ref.html # XXX all edges fuzzy
 
 # Simple <img> tests
--- a/mobile/chrome/content/bindings/browser.js
+++ b/mobile/chrome/content/bindings/browser.js
@@ -332,16 +332,20 @@ let ContentScroll =  {
         if (displayport.isEmpty())
           break;
 
         // Map ID to element
         let element = rootCwu.findElementWithViewId(json.id);
         if (!element)
           break;
 
+        let binding = element.ownerDocument.getBindingParent(element);
+        if (binding instanceof Ci.nsIDOMHTMLInputElement && binding.mozIsTextField(false))
+          break;
+
         // Set the scroll offset for this element if specified
         if (json.scrollX >= 0 && json.scrollY >= 0) {
           this.setScrollOffsetForElement(element, json.scrollX, json.scrollY)
           if (json.id == 1)
             this._scrollOffset = this.getScrollOffset(content);
         }
 
         // Set displayport. We want to set this after setting the scroll offset, because
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -164,16 +164,19 @@ pref("browser.triple_click_selects_parag
 
 // When loading <video> or <audio>, check for Access-Control-Allow-Origin
 // header, and disallow the connection if not present or permitted.
 pref("media.enforce_same_site_origin", false);
 
 // Media cache size in kilobytes
 pref("media.cache_size", 512000);
 
+// Master HTML5 media volume scale.
+pref("media.volume_scale", "1.0");
+
 #ifdef MOZ_RAW
 pref("media.raw.enabled", true);
 #endif
 #ifdef MOZ_OGG
 pref("media.ogg.enabled", true);
 #endif
 #ifdef MOZ_WAVE
 pref("media.wave.enabled", true);
@@ -1103,19 +1106,16 @@ pref("middlemouse.scrollbarPosition", fa
 // Clipboard behavior
 pref("clipboard.autocopy", false);
 
 // mouse wheel scroll transaction period of time (in milliseconds)
 pref("mousewheel.transaction.timeout", 1500);
 // mouse wheel scroll transaction is held even if the mouse cursor is moved.
 pref("mousewheel.transaction.ignoremovedelay", 100);
 
-// Macbook touchpad two finger pixel scrolling
-pref("mousewheel.enable_pixel_scrolling", true);
-
 // prefs for app level mouse wheel scrolling acceleration.
 // number of mousewheel clicks when acceleration starts
 // acceleration can be turned off if pref is set to -1
 pref("mousewheel.acceleration.start", -1);
 // factor to be multiplied for constant acceleration
 pref("mousewheel.acceleration.factor", 10);
 
 // Prefs for override the system mouse wheel scrolling speed on the root
@@ -1844,16 +1844,19 @@ pref("intl.tsf.on_layout_change_interval
 pref("ui.panel.default_level_parent", true);
 #else
 // See bug 448927, on topmost panel, some IMEs are not usable on Windows.
 pref("ui.panel.default_level_parent", false);
 #endif
 
 pref("mousewheel.system_scroll_override_on_root_content.enabled", true);
 
+// High resolution scrolling with supported mouse drivers on Vista or later.
+pref("mousewheel.enable_pixel_scrolling", false);
+
 // If your mouse drive sends WM_*SCROLL messages when you turn your mouse wheel,
 // set this to true.  Then, gecko processes them as mouse wheel messages.
 pref("mousewheel.emulate_at_wm_scroll", false);
 
 // Enables or disabled the TrackPoint hack, -1 is autodetect, 0 is off,
 // and 1 is on.  Set this to 1 if TrackPoint scrolling is not working.
 pref("ui.trackpoint_hack.enabled", -1);
 
@@ -2292,16 +2295,19 @@ pref("print.print_extra_margin", 90); //
 
 // See bug 404131, topmost <panel> element wins to Dashboard on MacOSX.
 pref("ui.panel.default_level_parent", false);
 
 pref("ui.plugin.cancel_composition_at_input_source_changed", false);
 
 pref("mousewheel.system_scroll_override_on_root_content.enabled", false);
 
+// Macbook touchpad two finger pixel scrolling
+pref("mousewheel.enable_pixel_scrolling", true);
+
 # XP_MACOSX
 #endif
 
 #ifdef XP_OS2
 
 pref("ui.key.menuAccessKeyFocuses", true);
 
 pref("font.alias-list", "sans,sans-serif,serif,monospace,Tms Rmn,Helv,Courier,Times New Roman");
deleted file mode 100644
--- a/modules/plugin/Makefile.in
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = plugin
-
-# These subdirs rely on GTK libraries and header files, it is not
-#  buildable on other non-GTK unix builds
-
-ifdef ENABLE_TESTS
-ifneq (,$(filter gtk2 cocoa windows android qt os2,$(MOZ_WIDGET_TOOLKIT)))
-DIRS += test
-endif
-endif
-
-include $(topsrcdir)/config/rules.mk
-
-$(DIST)/bin/plugins:
-	$(NSINSTALL) -D $@
-
-export:: $(DIST)/bin/plugins
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -1154,23 +1154,21 @@ nsHtml5StreamParser::ContinueAfterScript
         "ParseUntilBlocked() was supposed to ensure we don't come "
         "here when scripts are executing.");
       NS_ASSERTION(mExecutor->IsInFlushLoop(), "How are we here if "
         "RunFlushLoop() didn't call ParseUntilBlocked() which is the "
         "only caller of this method?");
       mSpeculations.RemoveElementAt(0);
       if (mSpeculations.IsEmpty()) {
         // yes, it was still the only speculation. Now stop speculating
-        if (mTreeBuilder->IsDiscretionaryFlushSafe()) {
-          // However, before telling the executor to read from stage, flush
-          // any pending ops straight to the executor, because otherwise
-          // they remain unflushed until we get more data from the network.
-          mTreeBuilder->SetOpSink(mExecutor);
-          mTreeBuilder->Flush();
-        }
+        // However, before telling the executor to read from stage, flush
+        // any pending ops straight to the executor, because otherwise
+        // they remain unflushed until we get more data from the network.
+        mTreeBuilder->SetOpSink(mExecutor);
+        mTreeBuilder->Flush(PR_TRUE);
         mTreeBuilder->SetOpSink(mExecutor->GetStage());
         mExecutor->StartReadingFromStage();
         mSpeculating = PR_FALSE;
       }
     }
     nsCOMPtr<nsIRunnable> event = new nsHtml5StreamParserContinuation(this);
     if (NS_FAILED(mThread->Dispatch(event, nsIThread::DISPATCH_NORMAL))) {
       NS_WARNING("Failed to dispatch nsHtml5StreamParserContinuation");
@@ -1263,20 +1261,14 @@ nsHtml5StreamParser::TimerFlush()
   mFlushTimerEverFired = PR_TRUE;
 
   if (IsTerminatedOrInterrupted()) {
     return;
   }
 
   // we aren't speculating and we don't know when new data is
   // going to arrive. Send data to the main thread.
-  // However, don't do if the current element on the stack is a 
-  // foster-parenting element and there's pending text, because flushing in 
-  // that case would make the tree shape dependent on where the flush points 
-  // fall.
-  if (mTreeBuilder->IsDiscretionaryFlushSafe()) {
-    if (mTreeBuilder->Flush()) {
-      if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
-        NS_WARNING("failed to dispatch executor flush event");
-      }
+  if (mTreeBuilder->Flush(PR_TRUE)) {
+    if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
+      NS_WARNING("failed to dispatch executor flush event");
     }
   }
 }
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -597,19 +597,28 @@ nsHtml5TreeBuilder::HasScript()
   PRUint32 len = mOpQueue.Length();
   if (!len) {
     return PR_FALSE;
   }
   return mOpQueue.ElementAt(len - 1).IsRunScript();
 }
 
 PRBool
-nsHtml5TreeBuilder::Flush()
+nsHtml5TreeBuilder::Flush(PRBool aDiscretionary)
 {
-  flushCharacters();
+  if (!aDiscretionary ||
+      !(charBufferLen &&
+        currentPtr >= 0 &&
+        stack[currentPtr]->isFosterParenting())) {
+    // Don't flush text on discretionary flushes if the current element on
+    // the stack is a foster-parenting element and there's pending text,
+    // because flushing in that case would make the tree shape dependent on
+    // where the flush points fall.
+    flushCharacters();
+  }
   FlushLoads();
   if (mOpSink) {
     PRBool hasOps = !mOpQueue.IsEmpty();
     if (hasOps) {
       mOpSink->MoveOpsFrom(mOpQueue);
     }
     return hasOps;
   }
@@ -662,24 +671,16 @@ nsHtml5TreeBuilder::NeedsCharsetSwitchTo
 void
 nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, PRInt32 aLine)
 {
   NS_PRECONDITION(HasScript(), "No script to add a snapshot to!");
   NS_PRECONDITION(aSnapshot, "Got null snapshot.");
   mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
 }
 
-PRBool 
-nsHtml5TreeBuilder::IsDiscretionaryFlushSafe()
-{
-  return !(charBufferLen && 
-           currentPtr >= 0 && 
-           stack[currentPtr]->isFosterParenting());
-}
-
 void
 nsHtml5TreeBuilder::DropHandles()
 {
   mOldHandles.Clear();
   mHandlesUsed = 0;
 }
 
 // DocumentModeHandler
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -67,29 +67,27 @@
 
   public:
 
     nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
                        nsHtml5TreeOpStage* aStage);
 
     ~nsHtml5TreeBuilder();
     
-    PRBool IsDiscretionaryFlushSafe();
-
     PRBool HasScript();
     
     void SetOpSink(nsAHtml5TreeOpSink* aOpSink) {
       mOpSink = aOpSink;
     }
 
     void ClearOps() {
       mOpQueue.Clear();
     }
     
-    PRBool Flush();
+    PRBool Flush(PRBool aDiscretionary = PR_FALSE);
     
     void FlushLoads();
 
     void SetDocumentCharset(nsACString& aCharset, PRInt32 aCharsetSource);
 
     void StreamEnded();
 
     void NeedsCharsetSwitchTo(const nsACString& aEncoding, PRInt32 aSource);
--- a/testing/crashtest/crashtests.list
+++ b/testing/crashtest/crashtests.list
@@ -42,17 +42,17 @@ include ../../layout/svg/crashtests/cras
 include ../../layout/tables/crashtests/crashtests.list
 include ../../layout/xul/base/src/crashtests/crashtests.list
 include ../../layout/xul/base/src/grid/crashtests/crashtests.list
 include ../../layout/xul/base/src/tree/src/crashtests/crashtests.list
 
 include ../../gfx/tests/crashtests/crashtests.list
 
 include ../../modules/libpr0n/test/crashtests/crashtests.list
-include ../../modules/plugin/test/crashtests/crashtests.list
+include ../../dom/plugins/test/crashtests/crashtests.list
 
 include ../../parser/htmlparser/tests/crashtests/crashtests.list
 
 include ../../security/manager/ssl/crashtests/crashtests.list
 
 include ../../view/crashtests/crashtests.list
 
 include ../../widget/src/cocoa/crashtests/crashtests.list
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -433,17 +433,17 @@ class Mochitest(object):
     """ Build the url path to the specific test harness and test file or directory """
     testHost = "http://mochi.test:8888"
     testURL = testHost + self.TEST_PATH + options.testPath
     if options.chrome or options.a11y:
        testURL = testHost + self.CHROME_PATH
     elif options.browserChrome:
       testURL = "about:blank"
     elif options.ipcplugins:
-      testURL = testHost + self.TEST_PATH + "modules/plugin/test"
+      testURL = testHost + self.TEST_PATH + "dom/plugins/test"
     return testURL
 
   def startWebSocketServer(self, options, debuggerInfo):
     """ Launch the websocket server """
     if options.webServer != '127.0.0.1':
       return
 
     self.wsserver = WebSocketServer(self.automation, options,
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -90,26 +90,26 @@ mochitest-chrome:
 
 mochitest-a11y:
 	$(RUN_MOCHITEST) --a11y
 	$(CHECK_TEST_ERROR)
 
 mochitest-ipcplugins:
 ifeq (Darwin,$(OS_ARCH))
 ifeq (i386,$(TARGET_CPU))
-	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled.i386.test.plugin=false --test-path=modules/plugin/test
+	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled.i386.test.plugin=false --test-path=dom/plugins/test
 endif
 ifeq (x86_64,$(TARGET_CPU))
-	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled.x86_64.test.plugin=false --test-path=modules/plugin/test
+	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled.x86_64.test.plugin=false --test-path=dom/plugins/test
 endif
 ifeq (powerpc,$(TARGET_CPU))
-	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled.ppc.test.plugin=false --test-path=modules/plugin/test
+	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled.ppc.test.plugin=false --test-path=dom/plugins/test
 endif
 else
-	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled=false --test-path=modules/plugin/test
+	$(RUN_MOCHITEST) --setpref=dom.ipc.plugins.enabled=false --test-path=dom/plugins/test
 endif
 	$(CHECK_TEST_ERROR)
 
 # Usage: |make [EXTRA_TEST_ARGS=...] *test|.
 RUN_REFTEST = rm -f ./$@.log && $(PYTHON) _tests/reftest/runreftest.py \
   $(SYMBOLS_PATH) $(EXTRA_TEST_ARGS) $(1) | tee ./$@.log
 
 ifeq ($(OS_ARCH),WINNT) #{
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -172,17 +172,17 @@ EXTRA_DSO_LDOPTS += \
 	-framework Carbon \
 	-framework CoreAudio \
 	-framework AudioToolbox \
 	-framework AudioUnit \
 	$(NULL)
 endif
 endif
 
-ifneq (,$(filter DragonFly FreeBSD GNU GNU_% NetBSD OpenBSD,$(OS_ARCH)))
+ifneq (,$(filter GNU GNU_% NetBSD OpenBSD,$(OS_ARCH)))
 ifdef MOZ_SYDNEYAUDIO
 EXTRA_DSO_LDOPTS += -lossaudio
 endif
 endif
 
 ifdef MOZ_PLATFORM_MAEMO
 EXTRA_DSO_LDOPTS += $(MOZ_PLATFORM_MAEMO_LIBS)
 endif 
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -1291,17 +1291,17 @@ function sortElements(aElements, aSortBy
 
   function getValue(aObj, aKey) {
     if (!aObj)
       return null;
 
     if (aObj.hasAttribute(aKey))
       return aObj.getAttribute(aKey);
 
-    addon = aObj.mAddon || aObj.mInstall;
+    var addon = aObj.mAddon || aObj.mInstall;
     if (!addon)
       return null;
 
     if (aKey == "uiState") {
       if (addon.pendingOperations == AddonManager.PENDING_DISABLE)
         return "pendingDisable";
       if (addon.pendingOperations == AddonManager.PENDING_UNINSTALL)
         return "pendingUninstall";
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -490,17 +490,20 @@ function writeVersionFile(dir, version) 
   var versionFile = dir.clone();
   versionFile.append(FILE_UPDATE_VERSION);
   writeStringToFile(versionFile, version);
 }
 
 function createChannelChangeFile(dir) {
   var channelChangeFile = dir.clone();
   channelChangeFile.append(FILE_CHANNELCHANGE);
-  channelChangeFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+  if (!channelChangeFile.exists()) {
+    channelChangeFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE,
+                             FileUtils.PERMS_FILE);
+  }
 }
 
 /**
  * Removes the contents of the Updates Directory
  */
 function cleanUpUpdatesDir() {
   // Bail out if we don't have appropriate permissions
   try {
@@ -531,17 +534,17 @@ function cleanUpUpdatesDir() {
         f.moveTo(dir, FILE_LAST_LOG);
         continue;
       }
       catch (e) {
         LOG("cleanUpUpdatesDir - failed to move file " + f.path + " to " +
             dir.path + " and rename it to " + FILE_LAST_LOG);
       }
     }
-    // Now, recursively remove this file.  The recusive removal is really
+    // Now, recursively remove this file.  The recursive removal is really
     // only needed on Mac OSX because this directory will contain a copy of
     // updater.app, which is itself a directory.
     try {
       f.remove(true);
     }
     catch (e) {
       LOG("cleanUpUpdatesDir - failed to remove file " + f.path);
     }
@@ -1170,16 +1173,17 @@ UpdateService.prototype = {
     switch (topic) {
     case "post-update-processing":
       // Clean up any extant updates
       this._postUpdateProcessing();
       break;
     case "xpcom-shutdown":
       Services.obs.removeObserver(this, "xpcom-shutdown");
 
+      this.pauseDownload();
       // Prevent leaking the downloader (bug 454964)
       this._downloader = null;
       break;
     }
   },
 
   /**
    * The following needs to happen during the post-update-processing
@@ -1367,44 +1371,45 @@ UpdateService.prototype = {
    *          An array of available nsIUpdate items
    * @returns The nsIUpdate to offer.
    */
   selectUpdate: function AUS_selectUpdate(updates) {
     if (updates.length == 0)
       return null;
 
     if (getDesiredChannel()) {
-      LOG("Checker:selectUpdate - skipping version checks for change change " +
-          "request");
+      LOG("UpdateService:selectUpdate - skipping version checks for channel " +
+          "change request");
       return updates[0];
     }
 
     // Choose the newest of the available minor and major updates.
     var majorUpdate = null;
     var minorUpdate = null;
     var vc = Services.vc;
 
     updates.forEach(function(aUpdate) {
       // Ignore updates for older versions of the application and updates for
       // the same version of the application with the same build ID.
       if (vc.compare(aUpdate.appVersion, Services.appinfo.version) < 0 ||
           vc.compare(aUpdate.appVersion, Services.appinfo.version) == 0 &&
           aUpdate.buildID == Services.appinfo.appBuildID) {
-        LOG("Checker:selectUpdate - skipping update because the update's " +
-            "application version is less than the current application version");
+        LOG("UpdateService:selectUpdate - skipping update because the " +
+            "update's application version is less than the current " +
+            "application version");
         return;
       }
 
       // Skip the update if the user responded with "never" to this update's
       // application version and the update specifies showNeverForVersion
       // (see bug 350636).
       let neverPrefName = PREF_APP_UPDATE_NEVER_BRANCH + aUpdate.appVersion;
       if (aUpdate.showNeverForVersion &&
           getPref("getBoolPref", neverPrefName, false)) {
-        LOG("Checker:selectUpdate - skipping update because the " +
+        LOG("UpdateService:selectUpdate - skipping update because the " +
             "preference " + neverPrefName + " is true");
         return;
       }
 
       switch (aUpdate.type) {
         case "major":
           if (!majorUpdate)
             majorUpdate = aUpdate;
@@ -1413,17 +1418,17 @@ UpdateService.prototype = {
           break;
         case "minor":
           if (!minorUpdate)
             minorUpdate = aUpdate;
           else if (vc.compare(minorUpdate.appVersion, aUpdate.appVersion) <= 0)
             minorUpdate = aUpdate;
           break;
         default:
-          LOG("Checker:selectUpdate - skipping unknown update type: " +
+          LOG("UpdateService:selectUpdate - skipping unknown update type: " +
               aUpdate.type);
           break;
       }
     });
 
     return minorUpdate || majorUpdate;
   },
 
@@ -1448,24 +1453,24 @@ UpdateService.prototype = {
       return;
 
     var update = this.selectUpdate(updates, updates.length);
     if (!update)
       return;
 
     var updateEnabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
     if (!updateEnabled) {
-      LOG("Checker:_selectAndInstallUpdate - not prompting because update is " +
-          "disabled");
+      LOG("UpdateService:_selectAndInstallUpdate - not prompting because " +
+          "update is disabled");
       return;
     }
 
     if (!gCanApplyUpdates) {
-      LOG("Checker:_selectAndInstallUpdate - the user is unable to apply " +
-          "updates... prompting");
+      LOG("UpdateService:_selectAndInstallUpdate - the user is unable to " +
+          "apply updates... prompting");
       this._showPrompt(update);
       return;
     }
 
     /**
 #      From this point on there are two possible outcomes:
 #      1. download and install the update automatically
 #      2. notify the user about the availability of an update
@@ -1487,24 +1492,24 @@ UpdateService.prototype = {
 #      the following deprecated behavior will occur:
 #      Update Type   Mode   Incompatible Add-ons   Outcome
 #      Major         all    N/A                    Notify
 #      Minor         0      N/A                    Auto Install
 #      Minor         1      Yes                    Notify
 #      Minor         1      No                     Auto Install
      */
     if (update.showPrompt) {
-      LOG("Checker:_selectAndInstallUpdate - prompting because the update " +
-          "snippet specified showPrompt");
+      LOG("UpdateService:_selectAndInstallUpdate - prompting because the " +
+          "update snippet specified showPrompt");
       this._showPrompt(update);
       return;
     }
 
     if (!getPref("getBoolPref", PREF_APP_UPDATE_AUTO, true)) {
-      LOG("Checker:_selectAndInstallUpdate - prompting because silent " +
+      LOG("UpdateService:_selectAndInstallUpdate - prompting because silent " +
           "install is disabled");
       this._showPrompt(update);
       return;
     }
 
     if (getPref("getIntPref", PREF_APP_UPDATE_MODE, 1) == 0) {
       // Do not prompt regardless of add-on incompatibilities
       LOG("UpdateService:_selectAndInstallUpdate - no need to show prompt, " +
@@ -1648,18 +1653,18 @@ UpdateService.prototype = {
     this.onCompatibilityUpdateAvailable(addon);
   },
 
   onUpdateFinished: function(addon) {
     if (--this._updateCheckCount > 0)
       return;
 
     if (this._incompatibleAddons.length > 0 || !gCanApplyUpdates) {
-      LOG("Checker:onUpdateEnded - prompting because there are incompatible " +
-          "add-ons");
+      LOG("UpdateService:onUpdateEnded - prompting because there are " +
+          "incompatible add-ons");
       this._showPrompt(this._update);
     }
     else {
       LOG("UpdateService:onUpdateEnded - no need to show prompt, just " +
           "download the update");
       var status = this.downloadUpdate(this._update, true);
       if (status == STATE_NONE)
         cleanupActiveUpdate();
@@ -1737,16 +1742,17 @@ UpdateService.prototype = {
           "current application version: " + Services.appinfo.version + "\n" +
           "update application version : " + update.appVersion + "\n" +
           "current build ID: " + Services.appinfo.appBuildID + "\n" +
           "update build ID : " + update.buildID);
       cleanupActiveUpdate();
       return STATE_NONE;
     }
 
+    // If a download request is in progress vs. a download ready to resume
     if (this.isDownloading) {
       if (update.isCompleteUpdate == this._downloader.isCompleteUpdate &&
           background == this._downloader.background) {
         LOG("UpdateService:downloadUpdate - no support for downloading more " +
             "than one update at a time");
         return readStatusFile(getUpdatesDir());
       }
       this._downloader.cancel();
@@ -2123,16 +2129,21 @@ Checker.prototype = {
   checkForUpdates: function UC_checkForUpdates(listener, force) {
     if (!listener)
       throw Cr.NS_ERROR_NULL_POINTER;
 
     var url = this.getUpdateURL(force);
     if (!url || (!this.enabled && !force))
       return;
 
+    // If the user changes the update channel there can be leftover files from
+    // a previous download so clean the updates directory for manual checks.
+    if (force)
+      cleanUpUpdatesDir();
+
     this._request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
                     createInstance(Ci.nsIXMLHttpRequest);
     this._request.open("GET", url, true);
     var allowNonBuiltIn = !getPref("getBoolPref",
                                    PREF_APP_UPDATE_CERT_REQUIREBUILTIN, true);
     this._request.channel.notificationCallbacks = new gCertUtils.BadCertHandler(allowNonBuiltIn);
     this._request.overrideMimeType("text/xml");
     this._request.setRequestHeader("Cache-Control", "no-cache");
@@ -2725,27 +2736,27 @@ Downloader.prototype = {
         if (this._update.isCompleteUpdate || this._update.patchCount != 2)
           deleteActiveUpdate = true;
 
         // Destroy the updates directory, since we're done with it.
         cleanUpUpdatesDir();
       }
     }
     else if (status != Cr.NS_BINDING_ABORTED &&
-             status != Cr.NS_ERROR_ABORT) {
+             status != Cr.NS_ERROR_ABORT &&
+             status != Cr.NS_ERROR_DOCUMENT_NOT_CACHED) {
       LOG("Downloader:onStopRequest - non-verification failure");
       // Some sort of other failure, log this in the |statusText| property
       state = STATE_DOWNLOAD_FAILED;
 
       // XXXben - if |request| (The Incremental Download) provided a means
       // for accessing the http channel we could do more here.
 
-      const NS_BINDING_FAILED = 2152398849;
       this._update.statusText = getStatusTextFromCode(status,
-        NS_BINDING_FAILED);
+                                                      Cr.NS_BINDING_FAILED);
 
       // Destroy the updates directory, since we're done with it.
       cleanUpUpdatesDir();
 
       deleteActiveUpdate = true;
     }
     LOG("Downloader:onStopRequest - setting state to: " + state);
     this._patch.state = state;
--- a/toolkit/mozapps/update/test/unit/test_0030_general.js
+++ b/toolkit/mozapps/update/test/unit/test_0030_general.js
@@ -90,22 +90,27 @@ function run_test_helper_pt1(aMsg, aExpe
   gNextRunFunc = aNextRunFunc;
   gExpectedStatusResult = aExpectedStatusResult;
   logTestInfo(aMsg, Components.stack.caller);
   gUpdateChecker.checkForUpdates(updateCheckListener, true);
 }
 
 function check_test_helper_pt1_1() {
   do_check_eq(gUpdateCount, 1);
+  let channelchange = getUpdatesDir();
+  channelchange.append("0");
+  channelchange.append(CHANNEL_CHANGE_FILE);
+  do_check_false(channelchange.exists());
   gCheckFunc = check_test_helper_pt1_2;
   var bestUpdate = gAUS.selectUpdate(gUpdates, gUpdateCount);
   var state = gAUS.downloadUpdate(bestUpdate, false);
   if (state == STATE_NONE || state == STATE_FAILED)
     do_throw("nsIApplicationUpdateService:downloadUpdate returned " + state);
   gAUS.addDownloadListener(downloadListener);
+  channelchange.create(AUS_Ci.nsIFile.FILE_TYPE, PERMS_FILE);
 }
 
 function check_test_helper_pt1_2() {
   do_check_eq(gStatusResult, gExpectedStatusResult);
   gAUS.removeDownloadListener(downloadListener);
   gNextRunFunc();
 }
 
--- a/toolkit/mozapps/update/test/unit/test_0070_update_dir_cleanup.js
+++ b/toolkit/mozapps/update/test/unit/test_0070_update_dir_cleanup.js
@@ -53,16 +53,21 @@ function run_test() {
   writeStatusFile(STATE_SUCCEEDED);
 
   var dir = getUpdatesDir();
   var log = dir.clone();
   log.append("0");
   log.append(FILE_UPDATE_LOG);
   writeFile(log, "Last Update Log");
 
+  let channelchange = dir.clone();
+  channelchange.append("0");
+  channelchange.append(CHANNEL_CHANGE_FILE);
+  channelchange.create(AUS_Ci.nsIFile.FILE_TYPE, PERMS_FILE);
+
   standardInit();
 
   logTestInfo("testing " + log.path + " shouldn't exist");
   do_check_false(log.exists());
 
   log = dir.clone();
   log.append(FILE_LAST_LOG);
   logTestInfo("testing " + log.path + " should exist");
@@ -75,14 +80,17 @@ function run_test() {
   log.append(FILE_BACKUP_LOG);
   logTestInfo("testing " + log.path + " shouldn't exist");
   do_check_false(log.exists());
 
   dir.append("0");
   logTestInfo("testing " + dir.path + " should exist (bug 512994)");
   do_check_true(dir.exists());
 
+  logTestInfo("testing " + channelchange.path + " shouldn't exist");
+  do_check_false(channelchange.exists());
+
   do_test_finished();
 }
 
 function end_test() {
   cleanUp();
 }
--- a/toolkit/mozapps/update/test/unit/test_0120_channelChange_complete.js
+++ b/toolkit/mozapps/update/test/unit/test_0120_channelChange_complete.js
@@ -242,19 +242,19 @@ function run_test() {
 
   setupUpdaterTest(MAR_COMPLETE_FILE);
 
   let updatesDir = do_get_file(TEST_ID + UPDATES_DIR_SUFFIX);
   let applyToDir = getApplyDirFile();
 
   // Check that trying to change channels for a complete update changes the
   // update channel (the channel-prefs.js file should be updated).
-  let force = updatesDir.clone();
-  force.append(CHANNEL_CHANGE_FILE);
-  force.create(AUS_Ci.nsIFile.FILE_TYPE, PERMS_FILE);
+  let channelchange = updatesDir.clone();
+  channelchange.append(CHANNEL_CHANGE_FILE);
+  channelchange.create(AUS_Ci.nsIFile.FILE_TYPE, PERMS_FILE);
 
   // For Mac OS X set the last modified time for the root directory to a date in
   // the past to test that the last modified time is updated on a successful
   // update (bug 600098).
   if (IS_MACOSX) {
     let now = Date.now();
     let yesterday = now - (1000 * 60 * 60 * 24);
     applyToDir.lastModifiedTime = yesterday;
--- a/toolkit/toolkit-makefiles.sh
+++ b/toolkit/toolkit-makefiles.sh
@@ -80,16 +80,19 @@ MAKEFILES_dom="
   dom/src/geolocation/Makefile
   dom/src/json/Makefile
   dom/src/offline/Makefile
   dom/src/storage/Makefile
   dom/src/threads/Makefile
   dom/locales/Makefile
   dom/plugins/base/Makefile
   dom/plugins/ipc/Makefile
+  dom/plugins/test/Makefile
+  dom/plugins/test/mochitest/Makefile
+  dom/plugins/test/testplugin/Makefile
   js/jetpack/Makefile
 "
 
 MAKEFILES_editor="
   editor/Makefile
   editor/public/Makefile
   editor/idl/Makefile
   editor/txmgr/Makefile
@@ -349,20 +352,16 @@ MAKEFILES_libsydneyaudio="
 "
 
 MAKEFILES_libnestegg="
   media/libnestegg/Makefile
   media/libnestegg/include/Makefile
   media/libnestegg/src/Makefile
 "
 
-MAKEFILES_plugin="
-  modules/plugin/Makefile
-"
-
 MAKEFILES_netwerk="
   netwerk/Makefile
   netwerk/base/Makefile
   netwerk/base/public/Makefile
   netwerk/base/src/Makefile
   netwerk/build/Makefile
   netwerk/cache/Makefile
   netwerk/cookie/Makefile
@@ -862,19 +861,16 @@ if [ "$ENABLE_TESTS" ]; then
     layout/tools/reftest/Makefile
     layout/xul/base/test/Makefile
     layout/xul/test/Makefile
     modules/libjar/test/chrome/Makefile
     modules/libjar/test/mochitest/Makefile
     modules/libpr0n/test/Makefile
     modules/libpr0n/test/mochitest/Makefile
     modules/libpref/test/Makefile
-    modules/plugin/test/Makefile
-    modules/plugin/test/mochitest/Makefile
-    modules/plugin/test/testplugin/Makefile
     netwerk/test/httpserver/Makefile
     parser/htmlparser/tests/mochitest/Makefile
     parser/xml/test/Makefile
     rdf/tests/triplescat/Makefile
     startupcache/test/Makefile
     testing/mochitest/Makefile
     testing/mochitest/MochiKit/Makefile
     testing/mochitest/chrome/Makefile
--- a/toolkit/toolkit-tiers.mk
+++ b/toolkit/toolkit-tiers.mk
@@ -167,17 +167,16 @@ endif
 
 tier_platform_dirs	+= \
 		uriloader \
 		modules/libimg \
 		caps \
 		parser \
 		gfx \
 		modules/libpr0n \
-		modules/plugin \
 		dom \
 		view \
 		widget \
 		content \
 		editor \
 		layout \
 		docshell \
 		embedding \
--- a/widget/src/windows/nsAppShell.cpp
+++ b/widget/src/windows/nsAppShell.cpp
@@ -33,16 +33,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "mozilla/ipc/RPCChannel.h"
 #include "nsAppShell.h"
 #include "nsToolkit.h"
 #include "nsThreadUtils.h"
 #include "WinTaskbar.h"
 #include "nsString.h"
 #include "nsIMM32Handler.h"
 
 // For skidmark code
@@ -302,16 +303,19 @@ nsAppShell::ProcessNextNativeEvent(PRBoo
 {
 #if defined(_MSC_VER) && defined(_M_IX86)
   if (sXPCOMHasLoadedNewDLLs && sLoadedModules) {
     sXPCOMHasLoadedNewDLLs = PR_FALSE;
     CollectNewLoadedModules();
   }
 #endif
 
+  // Notify ipc we are spinning a (possibly nested) gecko event loop.
+  mozilla::ipc::RPCChannel::NotifyGeckoEventDispatch();
+
   PRBool gotMessage = PR_FALSE;
 
   do {
     MSG msg;
     // Give priority to keyboard and mouse messages.
     if (PeekUIMessage(&msg) ||
         ::PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
       gotMessage = PR_TRUE;
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -293,16 +293,17 @@ LPFNLRESULTFROMOBJECT
 
 // Used in OOPP plugin focus processing.
 const PRUnichar* kOOPPPluginFocusEventId   = L"OOPP Plugin Focus Widget Event";
 PRUint32        nsWindow::sOOPPPluginFocusEvent   =
                   RegisterWindowMessageW(kOOPPPluginFocusEventId);
 
 MSG             nsWindow::sRedirectedKeyDown;
 
+PRBool          nsWindow::sEnablePixelScrolling = PR_TRUE;
 PRBool          nsWindow::sNeedsToInitMouseWheelSettings = PR_TRUE;
 ULONG           nsWindow::sMouseWheelScrollLines  = 0;
 ULONG           nsWindow::sMouseWheelScrollChars  = 0;
 
 HWND            nsWindow::sLastMouseWheelWnd = NULL;
 PRInt32         nsWindow::sRemainingDeltaForScroll = 0;
 PRInt32         nsWindow::sRemainingDeltaForPixel = 0;
 PRBool          nsWindow::sLastMouseWheelDeltaIsPositive = PR_FALSE;
@@ -662,16 +663,21 @@ nsWindow::Create(nsIWidget *aParent,
 
         if (NS_SUCCEEDED(prefBranch->GetBoolPref("intl.keyboard.per_window_layout",
                                                  &temp)))
           sSwitchKeyboardLayout = temp;
 
         if (NS_SUCCEEDED(prefBranch->GetBoolPref("mozilla.widget.disable-native-theme",
                                                  &temp)))
           gDisableNativeTheme = temp;
+
+        if (NS_SUCCEEDED(prefBranch->GetBoolPref("mousewheel.enable_pixel_scrolling",
+                                                 &temp))) {
+          sEnablePixelScrolling = temp;
+        }
       }
     }
   }
 
   return NS_OK;
 }
 
 // Close this nsWindow
@@ -6406,37 +6412,43 @@ nsWindow::OnMouseWheel(UINT aMessage, WP
     ResetRemainingWheelDelta();
   }
   sLastMouseWheelWnd = mWnd;
   sLastMouseWheelDeltaIsPositive = (nativeDelta > 0);
   sLastMouseWheelOrientationIsVertical = isVertical;
   sLastMouseWheelUnitIsPage = isPageScroll;
   sLastMouseWheelTime = now;
 
-  nsMouseScrollEvent testEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
-  InitEvent(testEvent);
-  testEvent.scrollFlags = isPageScroll ? nsMouseScrollEvent::kIsFullPage : 0;
-  testEvent.scrollFlags |= isVertical ? nsMouseScrollEvent::kIsVertical :
-                                        nsMouseScrollEvent::kIsHorizontal;
-  testEvent.delta = sLastMouseWheelDeltaIsPositive ? -1 : 1;
-  nsQueryContentEvent queryEvent(PR_TRUE, NS_QUERY_SCROLL_TARGET_INFO, this);
-  InitEvent(queryEvent);
-  queryEvent.InitForQueryScrollTargetInfo(&testEvent);
-  DispatchWindowEvent(&queryEvent);
-  // If the necessary interger isn't larger than 0, we should assume that
-  // the event failed for us.
-  if (queryEvent.mSucceeded) {
-    if (isPageScroll) {
-      if (isVertical) {
-        queryEvent.mSucceeded = (queryEvent.mReply.mPageHeight > 0);
+  PRBool dispatchPixelScrollEvent = PR_FALSE;
+  PRInt32 pixelsPerUnit = 0;
+
+  if (sEnablePixelScrolling) {
+    nsMouseScrollEvent testEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
+    InitEvent(testEvent);
+    testEvent.scrollFlags = isPageScroll ? nsMouseScrollEvent::kIsFullPage : 0;
+    testEvent.scrollFlags |= isVertical ? nsMouseScrollEvent::kIsVertical :
+                                          nsMouseScrollEvent::kIsHorizontal;
+    testEvent.delta = sLastMouseWheelDeltaIsPositive ? -1 : 1;
+    nsQueryContentEvent queryEvent(PR_TRUE, NS_QUERY_SCROLL_TARGET_INFO, this);
+    InitEvent(queryEvent);
+    queryEvent.InitForQueryScrollTargetInfo(&testEvent);
+    DispatchWindowEvent(&queryEvent);
+    // If the necessary interger isn't larger than 0, we should assume that
+    // the event failed for us.
+    if (queryEvent.mSucceeded) {
+      if (isPageScroll) {
+        if (isVertical) {
+          pixelsPerUnit = queryEvent.mReply.mPageHeight;
+        } else {
+          pixelsPerUnit = queryEvent.mReply.mPageWidth;
+        }
       } else {
-        queryEvent.mSucceeded = (queryEvent.mReply.mPageWidth > 0);
+        pixelsPerUnit = queryEvent.mReply.mLineHeight;
       }
-    } else {
-      queryEvent.mSucceeded = (queryEvent.mReply.mLineHeight > 0);
+      dispatchPixelScrollEvent = (pixelsPerUnit > 0);
     }
   }
 
   *aRetValue = isVertical ? FALSE : TRUE; // means we process this message
   nsModifierKeyState modKeyState;
 
   // Our positive delta value means to bottom or right.
   // But positive nativeDelta value means to top or right.
@@ -6451,19 +6463,18 @@ nsWindow::OnMouseWheel(UINT aMessage, WP
       static_cast<DWORD>(::GetMessageTime()) < mAssumeWheelIsZoomUntil) {
     isControl = PR_TRUE;
   } else {
     isControl = modKeyState.mIsControlDown;
   }
 
   nsMouseScrollEvent scrollEvent(PR_TRUE, NS_MOUSE_SCROLL, this);
   InitEvent(scrollEvent);
-  // If the query event failed, we cannot send pixel events.
   scrollEvent.scrollFlags =
-    queryEvent.mSucceeded ? nsMouseScrollEvent::kHasPixels : 0;
+    dispatchPixelScrollEvent ? nsMouseScrollEvent::kHasPixels : 0;
   scrollEvent.isShift     = modKeyState.mIsShiftDown;
   scrollEvent.isControl   = isControl;
   scrollEvent.isMeta      = PR_FALSE;
   scrollEvent.isAlt       = modKeyState.mIsAltDown;
 
   PRInt32 nativeDeltaForScroll = nativeDelta + sRemainingDeltaForScroll;
 
   if (isPageScroll) {
@@ -6496,17 +6507,17 @@ nsWindow::OnMouseWheel(UINT aMessage, WP
     aHandled = DispatchWindowEvent(&scrollEvent);
     if (mOnDestroyCalled) {
       ResetRemainingWheelDelta();
       return PR_FALSE;
     }
   }
 
   // If the query event failed, we cannot send pixel events.
-  if (!queryEvent.mSucceeded) {
+  if (!dispatchPixelScrollEvent) {
     sRemainingDeltaForPixel = 0;
     return PR_FALSE;
   }
 
   nsMouseScrollEvent pixelEvent(PR_TRUE, NS_MOUSE_PIXEL_SCROLL, this);
   InitEvent(pixelEvent);
   pixelEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll |
     (scrollEvent.scrollFlags & ~nsMouseScrollEvent::kHasPixels);
@@ -6514,28 +6525,24 @@ nsWindow::OnMouseWheel(UINT aMessage, WP
   pixelEvent.isControl   = modKeyState.mIsControlDown;
   pixelEvent.isMeta      = PR_FALSE;
   pixelEvent.isAlt       = modKeyState.mIsAltDown;
 
   PRInt32 nativeDeltaForPixel = nativeDelta + sRemainingDeltaForPixel;
 
   double deltaPerPixel;
   if (isPageScroll) {
-    if (isVertical) {
-      deltaPerPixel = (double)WHEEL_DELTA / queryEvent.mReply.mPageHeight;
-    } else {
-      deltaPerPixel = (double)WHEEL_DELTA / queryEvent.mReply.mPageWidth;
-    }
+    deltaPerPixel = (double)WHEEL_DELTA / pixelsPerUnit;
   } else {
     if (isVertical) {
       deltaPerPixel = (double)WHEEL_DELTA / sMouseWheelScrollLines;
     } else {
       deltaPerPixel = (double)WHEEL_DELTA / sMouseWheelScrollChars;
     }
-    deltaPerPixel /= queryEvent.mReply.mLineHeight;
+    deltaPerPixel /= pixelsPerUnit;
   }
   pixelEvent.delta =
     RoundDelta((double)nativeDeltaForPixel * orienter / deltaPerPixel);
   PRInt32 recomputedNativeDelta =
     (PRInt32)(pixelEvent.delta * orienter * deltaPerPixel);
   sRemainingDeltaForPixel = nativeDeltaForPixel - recomputedNativeDelta;
   if (pixelEvent.delta != 0) {
     aHandled = DispatchWindowEvent(&pixelEvent);
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -611,16 +611,17 @@ protected:
   static HINSTANCE      sAccLib;
   static LPFNLRESULTFROMOBJECT sLresultFromObject;
 #endif // ACCESSIBILITY
 
   // sRedirectedKeyDown is WM_KEYDOWN message or WM_SYSKEYDOWN message which
   // was reirected to SendInput() API by OnKeyDown().
   static MSG            sRedirectedKeyDown;
 
+  static PRBool sEnablePixelScrolling;
   static PRBool sNeedsToInitMouseWheelSettings;
   static ULONG sMouseWheelScrollLines;
   static ULONG sMouseWheelScrollChars;
   static void InitMouseWheelScrollData();
 
   static HWND sLastMouseWheelWnd;
   static PRInt32 sRemainingDeltaForScroll;
   static PRInt32 sRemainingDeltaForPixel;