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

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

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 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') | ui/base/x/selection_requestor_unittest.cc » ('j') | 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
deleted file mode 100644
index 5cab04fd91e46f5e0e2cf5478b182e07f09dade8..0000000000000000000000000000000000000000
--- a/ui/base/x/selection_requestor.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/base/x/selection_requestor.h"
-
-#include <algorithm>
-#include <X11/Xlib.h>
-
-#include "base/run_loop.h"
-#include "ui/base/x/selection_utils.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/events/platform/platform_event_source.h"
-#include "ui/gfx/x/x11_types.h"
-
-namespace ui {
-
-namespace {
-
-const char kChromeSelection[] = "CHROME_SELECTION";
-const char kIncr[] = "INCR";
-
-const char* kAtomsToCache[] = {
- kChromeSelection,
- kIncr,
- NULL
-};
-
-// The period of |abort_timer_|. Arbitrary but must be <= than
-// kRequestTimeoutMs.
-const int kTimerPeriodMs = 100;
-
-// The amount of time to wait for a request to complete before aborting it.
-const int kRequestTimeoutMs = 10000;
-
-COMPILE_ASSERT(kTimerPeriodMs <= kRequestTimeoutMs,
- timer_period_must_be_less_or_equal_to_request_timeout);
-
-// Combines |data| into a single RefCountedMemory object.
-scoped_refptr<base::RefCountedMemory> CombineRefCountedMemory(
- const std::vector<scoped_refptr<base::RefCountedMemory> >& data) {
- if (data.size() == 1u)
- return data[0];
-
- size_t length = 0;
- for (size_t i = 0; i < data.size(); ++i)
- length += data[i]->size();
- std::vector<unsigned char> combined_data;
- combined_data.reserve(length);
-
- for (size_t i = 0; i < data.size(); ++i) {
- combined_data.insert(combined_data.end(),
- data[i]->front(),
- data[i]->front() + data[i]->size());
- }
- return scoped_refptr<base::RefCountedMemory>(
- base::RefCountedBytes::TakeVector(&combined_data));
-}
-
-} // namespace
-
-SelectionRequestor::SelectionRequestor(XDisplay* x_display,
- XID x_window,
- PlatformEventDispatcher* dispatcher)
- : x_display_(x_display),
- x_window_(x_window),
- x_property_(None),
- dispatcher_(dispatcher),
- current_request_index_(0u),
- atom_cache_(x_display_, kAtomsToCache) {
- x_property_ = atom_cache_.GetAtom(kChromeSelection);
-}
-
-SelectionRequestor::~SelectionRequestor() {}
-
-bool SelectionRequestor::PerformBlockingConvertSelection(
- XAtom selection,
- XAtom target,
- scoped_refptr<base::RefCountedMemory>* out_data,
- size_t* out_data_items,
- XAtom* out_type) {
- base::TimeTicks timeout =
- base::TimeTicks::Now() +
- base::TimeDelta::FromMilliseconds(kRequestTimeoutMs);
- Request request(selection, target, timeout);
- requests_.push_back(&request);
- if (current_request_index_ == (requests_.size() - 1))
- ConvertSelectionForCurrentRequest();
- BlockTillSelectionNotifyForRequest(&request);
-
- std::vector<Request*>::iterator request_it = std::find(
- requests_.begin(), requests_.end(), &request);
- CHECK(request_it != requests_.end());
- if (static_cast<int>(current_request_index_) >
- request_it - requests_.begin()) {
- --current_request_index_;
- }
- requests_.erase(request_it);
-
- if (requests_.empty())
- abort_timer_.Stop();
-
- if (request.success) {
- if (out_data)
- *out_data = CombineRefCountedMemory(request.out_data);
- if (out_data_items)
- *out_data_items = request.out_data_items;
- if (out_type)
- *out_type = request.out_type;
- }
- return request.success;
-}
-
-void SelectionRequestor::PerformBlockingConvertSelectionWithParameter(
- XAtom selection,
- XAtom target,
- const std::vector<XAtom>& parameter) {
- SetAtomArrayProperty(x_window_, kChromeSelection, "ATOM", parameter);
- PerformBlockingConvertSelection(selection, target, NULL, NULL, NULL);
-}
-
-SelectionData SelectionRequestor::RequestAndWaitForTypes(
- XAtom selection,
- const std::vector<XAtom>& types) {
- for (std::vector<XAtom>::const_iterator it = types.begin();
- it != types.end(); ++it) {
- scoped_refptr<base::RefCountedMemory> data;
- XAtom type = None;
- if (PerformBlockingConvertSelection(selection,
- *it,
- &data,
- NULL,
- &type) &&
- type == *it) {
- return SelectionData(type, data);
- }
- }
-
- return SelectionData();
-}
-
-void SelectionRequestor::OnSelectionNotify(const XEvent& event) {
- Request* request = GetCurrentRequest();
- XAtom event_property = event.xselection.property;
- if (!request ||
- request->completed ||
- request->selection != event.xselection.selection ||
- request->target != event.xselection.target) {
- // ICCCM requires us to delete the property passed into SelectionNotify.
- if (event_property != None)
- XDeleteProperty(x_display_, x_window_, event_property);
- return;
- }
-
- bool success = false;
- if (event_property == x_property_) {
- scoped_refptr<base::RefCountedMemory> out_data;
- success = ui::GetRawBytesOfProperty(x_window_,
- x_property_,
- &out_data,
- &request->out_data_items,
- &request->out_type);
- if (success) {
- request->out_data.clear();
- request->out_data.push_back(out_data);
- }
- }
- if (event_property != None)
- XDeleteProperty(x_display_, x_window_, event_property);
-
- if (request->out_type == atom_cache_.GetAtom(kIncr)) {
- request->data_sent_incrementally = true;
- request->out_data.clear();
- request->out_data_items = 0u;
- request->out_type = None;
- request->timeout = base::TimeTicks::Now() +
- base::TimeDelta::FromMilliseconds(kRequestTimeoutMs);
- } else {
- CompleteRequest(current_request_index_, success);
- }
-}
-
-bool SelectionRequestor::CanDispatchPropertyEvent(const XEvent& event) {
- return event.xproperty.window == x_window_ &&
- event.xproperty.atom == x_property_ &&
- event.xproperty.state == PropertyNewValue;
-}
-
-void SelectionRequestor::OnPropertyEvent(const XEvent& event) {
- Request* request = GetCurrentRequest();
- if (!request || !request->data_sent_incrementally)
- return;
-
- scoped_refptr<base::RefCountedMemory> out_data;
- size_t out_data_items = 0u;
- Atom out_type = None;
- bool success = ui::GetRawBytesOfProperty(x_window_,
- x_property_,
- &out_data,
- &out_data_items,
- &out_type);
- if (!success) {
- CompleteRequest(current_request_index_, false);
- return;
- }
-
- if (request->out_type != None && request->out_type != out_type) {
- CompleteRequest(current_request_index_, false);
- return;
- }
-
- request->out_data.push_back(out_data);
- request->out_data_items += out_data_items;
- request->out_type = out_type;
-
- // Delete the property to tell the selection owner to send the next chunk.
- XDeleteProperty(x_display_, x_window_, x_property_);
-
- request->timeout = base::TimeTicks::Now() +
- base::TimeDelta::FromMilliseconds(kRequestTimeoutMs);
-
- if (out_data->size() == 0u)
- CompleteRequest(current_request_index_, true);
-}
-
-void SelectionRequestor::AbortStaleRequests() {
- base::TimeTicks now = base::TimeTicks::Now();
- for (size_t i = current_request_index_; i < requests_.size(); ++i) {
- if (requests_[i]->timeout <= now)
- CompleteRequest(i, false);
- }
-}
-
-void SelectionRequestor::CompleteRequest(size_t index, bool success) {
- if (index >= requests_.size())
- return;
-
- Request* request = requests_[index];
- if (request->completed)
- return;
- request->success = success;
- request->completed = true;
-
- if (index == current_request_index_) {
- while (GetCurrentRequest() && GetCurrentRequest()->completed)
- ++current_request_index_;
- ConvertSelectionForCurrentRequest();
- }
-
- if (!request->quit_closure.is_null())
- request->quit_closure.Run();
-}
-
-void SelectionRequestor::ConvertSelectionForCurrentRequest() {
- Request* request = GetCurrentRequest();
- if (request) {
- XConvertSelection(x_display_,
- request->selection,
- request->target,
- x_property_,
- x_window_,
- CurrentTime);
- }
-}
-
-void SelectionRequestor::BlockTillSelectionNotifyForRequest(Request* request) {
- if (PlatformEventSource::GetInstance()) {
- if (!abort_timer_.IsRunning()) {
- abort_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kTimerPeriodMs),
- this,
- &SelectionRequestor::AbortStaleRequests);
- }
-
- base::MessageLoop::ScopedNestableTaskAllower allow_nested(
- base::MessageLoopForUI::current());
- base::RunLoop run_loop;
- request->quit_closure = run_loop.QuitClosure();
- run_loop.Run();
-
- // We cannot put logic to process the next request here because the RunLoop
- // might be nested. For instance, request 'B' may start a RunLoop while the
- // RunLoop for request 'A' is running. It is not possible to end the RunLoop
- // for request 'A' without first ending the RunLoop for request 'B'.
- } else {
- // This occurs if PerformBlockingConvertSelection() is called during
- // shutdown and the PlatformEventSource has already been destroyed.
- while (!request->completed &&
- request->timeout > base::TimeTicks::Now()) {
- if (XPending(x_display_)) {
- XEvent event;
- XNextEvent(x_display_, &event);
- dispatcher_->DispatchEvent(&event);
- }
- }
- }
-}
-
-SelectionRequestor::Request* SelectionRequestor::GetCurrentRequest() {
- return current_request_index_ == requests_.size() ?
- NULL : requests_[current_request_index_];
-}
-
-SelectionRequestor::Request::Request(XAtom selection,
- XAtom target,
- base::TimeTicks timeout)
- : selection(selection),
- target(target),
- data_sent_incrementally(false),
- out_data_items(0u),
- out_type(None),
- success(false),
- timeout(timeout),
- completed(false) {
-}
-
-SelectionRequestor::Request::~Request() {
-}
-
-} // namespace ui
« no previous file with comments | « ui/base/x/selection_requestor.h ('k') | ui/base/x/selection_requestor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698