| Index: ui/base/x/selection_owner.cc
|
| diff --git a/ui/base/x/selection_owner.cc b/ui/base/x/selection_owner.cc
|
| index 170f32e19b2c0ea71e90bdb53e9386c5aea26fb0..79f071e49fcbde64717374707fda654194061694 100644
|
| --- a/ui/base/x/selection_owner.cc
|
| +++ b/ui/base/x/selection_owner.cc
|
| @@ -12,6 +12,7 @@
|
| #include "ui/base/x/selection_utils.h"
|
| #include "ui/base/x/x11_foreign_window_manager.h"
|
| #include "ui/base/x/x11_util.h"
|
| +#include "ui/events/platform/x11/x11_event_source.h"
|
|
|
| namespace ui {
|
|
|
| @@ -22,15 +23,10 @@ const char kIncr[] = "INCR";
|
| const char kMultiple[] = "MULTIPLE";
|
| const char kSaveTargets[] = "SAVE_TARGETS";
|
| const char kTargets[] = "TARGETS";
|
| +const char kTimestamp[] = "TIMESTAMP";
|
|
|
| -const char* kAtomsToCache[] = {
|
| - kAtomPair,
|
| - kIncr,
|
| - kMultiple,
|
| - kSaveTargets,
|
| - kTargets,
|
| - NULL
|
| -};
|
| +const char* kAtomsToCache[] = {kAtomPair, kIncr, kMultiple, kSaveTargets,
|
| + kTargets, kTimestamp, NULL};
|
|
|
| // The period of |incremental_transfer_abort_timer_|. Arbitrary but must be <=
|
| // than kIncrementalTransferTimeoutMs.
|
| @@ -122,7 +118,12 @@ void SelectionOwner::RetrieveTargets(std::vector<XAtom>* targets) {
|
|
|
| void SelectionOwner::TakeOwnershipOfSelection(
|
| const SelectionFormatMap& data) {
|
| - XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime);
|
| + // Note that we don't just use CurrentTime, since we need to return an actual
|
| + // timestamp for the TIMESTAMP target later.
|
| + acquired_selection_timestamp_ =
|
| + X11EventSource::GetInstance()->last_seen_server_time();
|
| + XSetSelectionOwner(x_display_, selection_name_, x_window_,
|
| + acquired_selection_timestamp_);
|
|
|
| if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) {
|
| // The X server agrees that we are the selection owner. Commit our data.
|
| @@ -219,14 +220,21 @@ bool SelectionOwner::ProcessTarget(XAtom target,
|
| XAtom multiple_atom = atom_cache_.GetAtom(kMultiple);
|
| XAtom save_targets_atom = atom_cache_.GetAtom(kSaveTargets);
|
| XAtom targets_atom = atom_cache_.GetAtom(kTargets);
|
| + XAtom timestamp_atom = atom_cache_.GetAtom(kTimestamp);
|
|
|
| if (target == multiple_atom || target == save_targets_atom)
|
| return false;
|
|
|
| - if (target == targets_atom) {
|
| + if (target == timestamp_atom) {
|
| + XChangeProperty(
|
| + x_display_, requestor, property, XA_INTEGER, 32, PropModeReplace,
|
| + reinterpret_cast<unsigned char*>(&acquired_selection_timestamp_), 1);
|
| + return true;
|
| + } else if (target == targets_atom) {
|
| // We have been asked for TARGETS. Send an atom array back with the data
|
| // types we support.
|
| std::vector<XAtom> targets;
|
| + targets.push_back(timestamp_atom);
|
| targets.push_back(targets_atom);
|
| targets.push_back(save_targets_atom);
|
| targets.push_back(multiple_atom);
|
|
|