mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 14:58:37 +09:00
moebius#56: Fix: DataTransfer - Pasting image from clipboard fails in some cases
https://github.com/MoonchildProductions/moebius/pull/56
This commit is contained in:
parent
2f455353a4
commit
37c73e0634
13 changed files with 156 additions and 44 deletions
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue