[Solved] Is there a method to clear Clipboard data within the application?
-
Hello, men!
After setting the data to clipboard, it would be great to clear the clipboard application buffer:
@void SysTrayApp::TakeFullScreenShot()
{
QScreen *screen = QApplication::primaryScreen();
QPixmap *Image = new QPixmap();
*Image = screen->grabWindow(0); // here we got 8 MB memory allocation
QClipboard *Clipboard = QApplication::clipboard();
Clipboard->setPixmap(*Image);
delete Image; // after this the memory is still in use
}@So, I see that the data is passed to QApplication::clipboard and further to the system clipboard. Closing the application is safe - the data have been really transferred to system clipboard.
A method like QClipboardBufferClear is coming to mind - is there such one?
-
What does the comment "the memory is still in use" mean? Clipboard is not an application buffer. It's a system wide way to store objects, be it text, images or anything else that has a MIME type.
When you call setPixmap() it doesn't put your c++ QPixmap object in there. No other app would know what to do with it and nothing would have access to your app memory anyway. What happens is an image object (of some universal system defined type) is created based on the QPixmap data. You should only care about your local app object. The system object doesn't concern you. You don't have to manage that memory yourself.
If you want to clear the contents of the clipboard (because you put there a lot) you can call "clear()":http://qt-project.org/doc/qt-5/qclipboard.html#clear but remember that it's not really nice to the user to do that. Imagine he pressed "PrtScr" to capture something beautiful and you just deleted it for him.
-
Sure I won't clear the system clipboard.
But the memory is still in use by the application after the "delete Image" command - I am watching the memory allocation of the application with system monitor. That's why I think there is an application buffer in between the pixmap and the system clipboard which is not cleared (the documentation is telling us that the pixmap is converted to image before being transferred to clipboard - maybe the buffer for image is not cleared)/
-
Do you mean that there's a memory leak i.e. the memory is never released? How do you check that? What system are you on? System monitors show various stuff like reserved virtual memory that don't actually reflect what the app is "using" at the moment.
Btw. it's not related (I think), but why do you allocate the pixmap dynamically?
Why not just this?
@
{
QScreen *screen = QApplication::primaryScreen();
QPixmap image = screen->grabWindow(0);
QClipboard *clipboard = QApplication::clipboard();
clipboard->setPixmap(image);
}
@
Does this show the same problem? -
Yes, the stack allocation is showing the same problem - I was just trying so and so.
I am on Ubuntu 14.04 x64, Qt 5.2.1, checking the memory with System Monitor and top - below are the memory screenshots from the program compiled with image allocation on stack:
Before screenshot - https://db.tt/pHQnAdsC
After screenshot - https://db.tt/ctdNEDfk -
Sorry, I'm not a linux expert.
Did you check with valgrind if it actually leaks?
If you do a for loop with setPixmap will it keep growing? -
Actually it doesn't keep growing - but it doesn't release the allocated memory until exit.
Checked it with VMMap on Windows:
Before screenshot - https://db.tt/TEMTGTrT
After screenshot - https://db.tt/hbl13yBEI will check it with valgrind this monday at work .
-
So it doesn't leak.
My next guess would be that maybe QClipboard holds a copy of what it set previously as some sort of caching/optimization. Does it go down when you call clear() on the clipboard?Or maybe using clipboard loads some system library in the process (shared memory increases on your screenshots too) and that's what you see. You can check that with profiling in "Dependency Walker":http://www.dependencywalker.com/ on Windows.
-
Yes, Clipboard->clear() is releasing memory, but erases the system clipboard. Thus, we're at initial question "Is there a method to clear Clipboard data within the application?" :-)
Dependency Walker doesn't show any leaks too, so this behaviour is intended, by design.
There should be such a method - caching/optimization is supposed to be switchable.
-
The caching/optimization was just a wild guess, although I peeked at the actual implementation of QClipboard and it's not that far from the truth.
What happens is that Windows uses something called a "delayed rendering of content", which basically means that when you put something in the clipboard you put there only a pointer(well, an OLE pointer but pointer still) to your app managed data. The actual data is copied to the system clipboard(or the target) only when something is asking for it. This means that you can for example generate the actual data when it's asked for (not that Qt exposes this but winapi does).
It makes sense actually. You wouldn't want to freeze the clipboard just because you hit "ctrl+c" by mistake while having your 8GB movie selected.
There is a windows function that allows to "flush" the content to the clipboard right away, but I guess Qt is just playing it safe. Otherwise they would have to decide what is worth copying right away and what not and that's not easy. They currently only flush it when application closes, so the content will be available even if the source app was closed(there's a bug report comment that apparently they didn't do it at all in older versions).
This might or may not work similarly on other platforms, I haven't got enough willpower to check but it would make sense if it did.
It looks like the functionality to flush it could be exposed by Qt, but there might be other considerations that I don't know of. Sounds like a candidate for feature request if it's important to you. You can try to hit Qt guys on the mailing list.
-
Moreiver, if other program clears the system clipboard or put something into - the memory is deallocated from the Qt application.
So, I think maybe there is no any flush at all - just pointer work.
Anyway, such a behaviour is reasonable enough and I am tagging the post as Solved.
Thank you very much for interesting discussion, Chris!
-
No problem.
As for another app putting something in the clipboard - Before you put something in the clipboard you register your app as a "clipboard viewer". With this Windows keeps track of who put something there last and notifies that last app when contents of clipboard change. Qt handles properly this message and destroys the object, as it will never be asked for it again.