Bug 883554 - Don't clear too close to a SetData in case another program accesses on clipboard changes. r=jimm
authorBrian R. Bondy <netzen@gmail.com>
Tue, 09 Jul 2013 14:39:46 -0400
changeset 137808 5f62c9519423ef55c04cb3eaedfac7bd9fab0032
parent 137807 a8daf8516ed29f8b24db24916e151170783e8ef1
child 137809 7c8b68292a44fdb17fb9858b2ddadba280f7569e
push id30719
push userbbondy@mozilla.com
push dateTue, 09 Jul 2013 20:53:20 +0000
treeherdermozilla-inbound@5f62c9519423 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs883554
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 883554 - Don't clear too close to a SetData in case another program accesses on clipboard changes. r=jimm
widget/windows/nsClipboard.cpp
widget/xpwidgets/nsBaseClipboard.cpp
widget/xpwidgets/nsBaseClipboard.h
--- a/widget/windows/nsClipboard.cpp
+++ b/widget/windows/nsClipboard.cpp
@@ -922,17 +922,22 @@ nsClipboard::GetNativeClipboardData ( ns
   }
   return res;
 
 }
 
 NS_IMETHODIMP
 nsClipboard::EmptyClipboard(int32_t aWhichClipboard)
 {
-  if (aWhichClipboard == kGlobalClipboard) {
+  // Some programs such as ZoneAlarm monitor clipboard usage and then open the
+  // clipboard to scan it.  If we i) empty and then ii) set data, then the
+  // 'set data' can sometimes fail with access denied becacuse another program
+  // has the clipboard open.  So to avoid this race condition for OpenClipboard
+  // we do not empty the clipboard when we're setting it.
+  if (aWhichClipboard == kGlobalClipboard && !mEmptyingForSetData) {
     OleSetClipboard(NULL);
   }
   return nsBaseClipboard::EmptyClipboard(aWhichClipboard);
 }
 
 //-------------------------------------------------------------------------
 NS_IMETHODIMP nsClipboard::HasDataMatchingFlavors(const char** aFlavorList,
                                                   uint32_t aLength,
--- a/widget/xpwidgets/nsBaseClipboard.cpp
+++ b/widget/xpwidgets/nsBaseClipboard.cpp
@@ -10,17 +10,17 @@
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 
 nsBaseClipboard::nsBaseClipboard()
 {
   mClipboardOwner          = nullptr;
   mTransferable            = nullptr;
   mIgnoreEmptyNotification = false;
-
+  mEmptyingForSetData      = false;
 }
 
 nsBaseClipboard::~nsBaseClipboard()
 {
   EmptyClipboard(kSelectionClipboard);
   EmptyClipboard(kGlobalClipboard);
 }
 
@@ -37,17 +37,19 @@ NS_IMETHODIMP nsBaseClipboard::SetData(n
 
   if (aTransferable == mTransferable && anOwner == mClipboardOwner)
     return NS_OK;
   bool selectClipPresent;
   SupportsSelectionClipboard(&selectClipPresent);
   if ( !selectClipPresent && aWhichClipboard != kGlobalClipboard )
     return NS_ERROR_FAILURE;
 
+  mEmptyingForSetData = true;
   EmptyClipboard(aWhichClipboard);
+  mEmptyingForSetData = false;
 
   mClipboardOwner = anOwner;
   if ( anOwner )
     NS_ADDREF(mClipboardOwner);
 
   mTransferable = aTransferable;
   
   nsresult rv = NS_ERROR_FAILURE;
--- a/widget/xpwidgets/nsBaseClipboard.h
+++ b/widget/xpwidgets/nsBaseClipboard.h
@@ -33,16 +33,17 @@ public:
   // nsIClipboard  
   NS_DECL_NSICLIPBOARD
   
 protected:
 
   NS_IMETHOD SetNativeClipboardData ( int32_t aWhichClipboard ) = 0;
   NS_IMETHOD GetNativeClipboardData ( nsITransferable * aTransferable, int32_t aWhichClipboard ) = 0;
 
+  bool                mEmptyingForSetData;
   bool                mIgnoreEmptyNotification;
   nsIClipboardOwner * mClipboardOwner;
   nsITransferable   * mTransferable;
   nsRefPtr<nsClipboardPrivacyHandler> mPrivacyHandler;
 
 };
 
 #endif // nsBaseClipboard_h__