Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(534)

Unified Diff: ui/base/x/selection_requestor.cc

Issue 391593002: Process SelectionRequestor::PerformBlockingConvertSelection() requests one at a time (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/base/x/selection_requestor.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/x/selection_requestor.cc
diff --git a/ui/base/x/selection_requestor.cc b/ui/base/x/selection_requestor.cc
index 516e0e0398c558b5bb0de603fe6a175ab840af7a..ac092ea3257766af933312ebc6434fa787f3bcbf 100644
--- a/ui/base/x/selection_requestor.cc
+++ b/ui/base/x/selection_requestor.cc
@@ -15,10 +15,22 @@ namespace ui {
namespace {
-const char kChromeSelection[] = "CHROME_SELECTION";
+// Properties to be used in XConvertSelection() requests. The number of
+// properties is arbitrary.
+const char* kChromeSelectionProperties[] = {
+ "CHROME_SELECTION0",
+ "CHROME_SELECTION1",
+ "CHROME_SELECTION2",
+ "CHROME_SELECTION3",
+ "CHROME_SELECTION4"
+};
const char* kAtomsToCache[] = {
- kChromeSelection,
+ kChromeSelectionProperties[0],
+ kChromeSelectionProperties[1],
+ kChromeSelectionProperties[2],
+ kChromeSelectionProperties[3],
+ kChromeSelectionProperties[4],
NULL
};
@@ -26,65 +38,61 @@ const char* kAtomsToCache[] = {
SelectionRequestor::SelectionRequestor(Display* x_display,
Window x_window,
- Atom selection_name,
PlatformEventDispatcher* dispatcher)
: x_display_(x_display),
x_window_(x_window),
- selection_name_(selection_name),
dispatcher_(dispatcher),
+ property_pool_(kChromeSelectionProperties,
+ kChromeSelectionProperties
+ + arraysize(kChromeSelectionProperties)),
atom_cache_(x_display_, kAtomsToCache) {
}
SelectionRequestor::~SelectionRequestor() {}
bool SelectionRequestor::PerformBlockingConvertSelection(
+ Atom selection,
Atom target,
scoped_refptr<base::RefCountedMemory>* out_data,
size_t* out_data_items,
Atom* out_type) {
- // The name of the property that we are either:
- // - Passing as a parameter with the XConvertSelection() request.
- // OR
- // - Asking the selection owner to set on |x_window_|.
- Atom property = atom_cache_.GetAtom(kChromeSelection);
-
- XConvertSelection(x_display_,
- selection_name_,
- target,
- property,
- x_window_,
- CurrentTime);
-
- // Now that we've thrown our message off to the X11 server, we block waiting
- // for a response.
- PendingRequest pending_request(target);
- BlockTillSelectionNotifyForRequest(&pending_request);
-
- bool success = false;
- if (pending_request.returned_property == property) {
- success = ui::GetRawBytesOfProperty(x_window_,
- pending_request.returned_property,
- out_data, out_data_items, out_type);
- }
- if (pending_request.returned_property != None)
- XDeleteProperty(x_display_, x_window_, pending_request.returned_property);
+ // Find a property for XConvertSelection() to use. The selection owner will
+ // set |property| on |xwindow_| with the data for the requested target. If
+ // there is no available property, make the request fail.
+ if (property_pool_.empty())
+ return false;
+
+ const char* property_name = property_pool_.back();
+ property_pool_.pop_back();
Daniel Erat 2014/07/15 01:04:09 with the disclaimer that i don't know much about s
pkotwicz 2014/07/15 02:07:24 The problem is that there are callers of clipboard
Daniel Erat 2014/07/15 03:32:01 oh. is the nested message loop in BlockTillSelecti
+ bool success = PerformBlockingConvertSelectionImpl(selection, target,
+ property_name, out_data, out_data_items, out_type);
+ property_pool_.push_back(property_name);
return success;
}
void SelectionRequestor::PerformBlockingConvertSelectionWithParameter(
+ Atom selection,
Atom target,
const std::vector< ::Atom>& parameter) {
- SetAtomArrayProperty(x_window_, kChromeSelection, "ATOM", parameter);
- PerformBlockingConvertSelection(target, NULL, NULL, NULL);
+ if (property_pool_.empty())
+ return;
+ const char* property_name = property_pool_.back();
+ property_pool_.pop_back();
+ SetAtomArrayProperty(x_window_, property_name, "ATOM", parameter);
+ PerformBlockingConvertSelectionImpl(selection, target, property_name, NULL,
+ NULL, NULL);
+ property_pool_.push_back(property_name);
}
SelectionData SelectionRequestor::RequestAndWaitForTypes(
+ Atom selection,
const std::vector< ::Atom>& types) {
for (std::vector< ::Atom>::const_iterator it = types.begin();
it != types.end(); ++it) {
scoped_refptr<base::RefCountedMemory> data;
::Atom type = None;
- if (PerformBlockingConvertSelection(*it,
+ if (PerformBlockingConvertSelection(selection,
+ *it,
&data,
NULL,
&type) &&
@@ -101,14 +109,12 @@ void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) {
// there are multiple pending requests on the same target, satisfy them in
// FIFO order.
PendingRequest* request_notified = NULL;
- if (selection_name_ == event.selection) {
- for (std::list<PendingRequest*>::iterator iter = pending_requests_.begin();
- iter != pending_requests_.end(); ++iter) {
- PendingRequest* request = *iter;
- if (request->returned)
- continue;
- if (request->target != event.target)
- continue;
+ for (std::list<PendingRequest*>::iterator iter = pending_requests_.begin();
+ iter != pending_requests_.end(); ++iter) {
+ PendingRequest* request = *iter;
+ if (!request->returned &&
+ request->selection == event.selection &&
+ request->target == event.target) {
request_notified = request;
break;
}
@@ -133,6 +139,37 @@ void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) {
request_notified->quit_closure.Run();
}
+bool SelectionRequestor::PerformBlockingConvertSelectionImpl(
+ Atom selection,
+ Atom target,
+ const char* property_name,
+ scoped_refptr<base::RefCountedMemory>* out_data,
+ size_t* out_data_items,
+ Atom* out_type) {
+ Atom property = atom_cache_.GetAtom(property_name);
+ XConvertSelection(x_display_,
+ selection,
+ target,
+ property,
+ x_window_,
+ CurrentTime);
+
+ // Now that we've thrown our message off to the X11 server, we block waiting
+ // for a response.
+ PendingRequest pending_request(selection, target);
+ BlockTillSelectionNotifyForRequest(&pending_request);
+
+ bool success = false;
+ if (pending_request.returned_property == property) {
+ success = ui::GetRawBytesOfProperty(x_window_,
+ pending_request.returned_property,
+ out_data, out_data_items, out_type);
+ }
+ if (pending_request.returned_property != None)
+ XDeleteProperty(x_display_, x_window_, pending_request.returned_property);
+ return success;
+}
+
void SelectionRequestor::BlockTillSelectionNotifyForRequest(
PendingRequest* request) {
pending_requests_.push_back(request);
@@ -171,8 +208,10 @@ void SelectionRequestor::BlockTillSelectionNotifyForRequest(
pending_requests_.pop_back();
}
-SelectionRequestor::PendingRequest::PendingRequest(Atom target)
- : target(target),
+SelectionRequestor::PendingRequest::PendingRequest(Atom requested_selection,
+ Atom requested_target)
+ : selection(requested_selection),
+ target(requested_target),
returned_property(None),
returned(false) {
}
« no previous file with comments | « ui/base/x/selection_requestor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698