moebius#56: Fix: DataTransfer - Pasting image from clipboard fails in some cases

https://github.com/MoonchildProductions/moebius/pull/56
This commit is contained in:
janekptacijarabaci 2018-04-20 22:54:26 +02:00 committed by Roy Tam
commit 37c73e0634
13 changed files with 156 additions and 44 deletions

View file

@ -443,6 +443,82 @@ STDMETHODIMP_(ULONG) nsDataObj::AddRef()
return m_cRef;
}
namespace {
class RemoveTempFileHelper : public nsIObserver
{
public:
explicit RemoveTempFileHelper(nsIFile* aTempFile)
: mTempFile(aTempFile)
{
MOZ_ASSERT(mTempFile);
}
// The attach method is seperate from the constructor as we may be addref-ing
// ourself, and we want to be sure someone has a strong reference to us.
void Attach()
{
// We need to listen to both the xpcom shutdown message and our timer, and
// fire when the first of either of these two messages is received.
nsresult rv;
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
mTimer->Init(this, 500, nsITimer::TYPE_ONE_SHOT);
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
if (NS_WARN_IF(!observerService)) {
mTimer->Cancel();
mTimer = nullptr;
return;
}
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
}
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
~RemoveTempFileHelper()
{
if (mTempFile) {
mTempFile->Remove(false);
}
}
nsCOMPtr<nsIFile> mTempFile;
nsCOMPtr<nsITimer> mTimer;
};
NS_IMPL_ISUPPORTS(RemoveTempFileHelper, nsIObserver);
NS_IMETHODIMP
RemoveTempFileHelper::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
{
// Let's be careful and make sure that we don't die immediately
RefPtr<RemoveTempFileHelper> grip = this;
// Make sure that we aren't called again by destroying references to ourself.
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
if (observerService) {
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
if (mTimer) {
mTimer->Cancel();
mTimer = nullptr;
}
// Remove the tempfile
if (mTempFile) {
mTempFile->Remove(false);
mTempFile = nullptr;
}
return NS_OK;
}
} // namespace
//-----------------------------------------------------
STDMETHODIMP_(ULONG) nsDataObj::Release()
@ -456,17 +532,12 @@ STDMETHODIMP_(ULONG) nsDataObj::Release()
// We have released our last ref on this object and need to delete the
// temp file. External app acting as drop target may still need to open the
// temp file. Addref a timer so it can delay deleting file and destroying
// this object. Delete file anyway and destroy this obj if there's a problem.
// this object.
if (mCachedTempFile) {
nsresult rv;
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
mTimer->InitWithFuncCallback(nsDataObj::RemoveTempFile, this,
500, nsITimer::TYPE_ONE_SHOT);
return AddRef();
}
mCachedTempFile->Remove(false);
RefPtr<RemoveTempFileHelper> helper =
new RemoveTempFileHelper(mCachedTempFile);
mCachedTempFile = nullptr;
helper->Attach();
}
delete this;
@ -2154,13 +2225,3 @@ HRESULT nsDataObj::GetFileContents_IStream(FORMATETC& aFE, STGMEDIUM& aSTG)
return S_OK;
}
void nsDataObj::RemoveTempFile(nsITimer* aTimer, void* aClosure)
{
nsDataObj *timedDataObj = static_cast<nsDataObj *>(aClosure);
if (timedDataObj->mCachedTempFile) {
timedDataObj->mCachedTempFile->Remove(false);
timedDataObj->mCachedTempFile = nullptr;
}
timedDataObj->Release();
}