summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-31 01:19:57 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-31 01:19:57 +0000
commita92d2fd9d1fe0e74f6ca7d540858a4711b46367e (patch)
tree3ec4bb1ee681af04ee6757fa65e47b2abd5dff04 /chrome
parent69b43bdc17d84729fca4e34595e51a88cec099af (diff)
downloadchromium_src-a92d2fd9d1fe0e74f6ca7d540858a4711b46367e.zip
chromium_src-a92d2fd9d1fe0e74f6ca7d540858a4711b46367e.tar.gz
chromium_src-a92d2fd9d1fe0e74f6ca7d540858a4711b46367e.tar.bz2
Make sure that Clipboard operations that require dispatching
of windows messages are performed on the UI thread. SetClipboardData requires the clipboard to be open with a handle to a window that will be notified when the contents are going to change again. If Windows messages are not processed, any other app writing to the clipboard will be locked while we acknowledge their request (by processing the message). The IO thread doesn't pump windows messages anymore so write clipboard operations cannot be performed from that thread and have to be posted to another thread. BUG=5823 Review URL: http://codereview.chromium.org/19733 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9003 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/resource_message_filter.cc30
1 files changed, 29 insertions, 1 deletions
diff --git a/chrome/browser/resource_message_filter.cc b/chrome/browser/resource_message_filter.cc
index 63ea64d..dd0dd5a 100644
--- a/chrome/browser/resource_message_filter.cc
+++ b/chrome/browser/resource_message_filter.cc
@@ -62,6 +62,25 @@ class ContextMenuMessageDispatcher : public Task {
DISALLOW_COPY_AND_ASSIGN(ContextMenuMessageDispatcher);
};
+// Completes a clipboard write initiated by the renderer. The write must be
+// performed on the UI thread because the clipboard service from the IO thread
+// cannot create windows so it cannot be the "owner" of the clipboard's
+// contents.
+class WriteClipboardTask : public Task {
+ public:
+ explicit WriteClipboardTask(Clipboard::ObjectMap* objects)
+ : objects_(objects) {}
+ ~WriteClipboardTask() {}
+
+ void Run() {
+ g_browser_process->clipboard_service()->WriteObjects(*objects_.get());
+ }
+
+ private:
+ scoped_ptr<Clipboard::ObjectMap> objects_;
+};
+
+
} // namespace
ResourceMessageFilter::ResourceMessageFilter(
@@ -445,10 +464,19 @@ void ResourceMessageFilter::OnDownloadUrl(const IPC::Message& message,
void ResourceMessageFilter::OnClipboardWriteObjects(
const Clipboard::ObjectMap& objects) {
+ // We cannot write directly from the IO thread, and cannot service the IPC
+ // on the UI thread. We'll copy the relevant data and get a handle to any
+ // shared memory so it doesn't go away when we resume the renderer, and post
+ // a task to perform the write on the UI thread.
+ Clipboard::ObjectMap* long_living_objects = new Clipboard::ObjectMap(objects);
+
// We pass the render_handle_ to assist the clipboard with using shared
// memory objects. render_handle_ is a handle to the process that would
// own any shared memory that might be in the object list.
- GetClipboardService()->WriteObjects(objects, render_handle_);
+ Clipboard::DuplicateRemoteHandles(render_handle_, long_living_objects);
+
+ render_widget_helper_->ui_loop()->PostTask(FROM_HERE,
+ new WriteClipboardTask(long_living_objects));
}
void ResourceMessageFilter::OnClipboardIsFormatAvailable(unsigned int format,