Chromium Code Reviews| 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..a8521c4442b55a507530f080461cbc6c50273eb6 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,6 +118,12 @@ void SelectionOwner::RetrieveTargets(std::vector<XAtom>* targets) { |
| void SelectionOwner::TakeOwnershipOfSelection( |
| const SelectionFormatMap& data) { |
| + // Save the last server timestamp seen from X, to satisfy requests for the |
| + // TIMESTAMP target later… |
| + acquired_selection_timestamp_ = |
| + X11EventSource::GetInstance()->last_seen_server_time(); |
| + // …but always pass CurrentTime to XSetSelectionOwner to increase the chances |
| + // of this succeeding. |
| XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime); |
|
dcheng
2016/04/20 00:55:26
For whatever reason, using last_seen_server_time()
|
| if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) { |
| @@ -219,14 +221,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); |