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(); |
sadrul
2016/04/20 17:58:43
Can this use something else (like CurrentTime) if
dcheng
2016/04/20 18:55:43
=/
I could, but I'm not a fan of adding checks fo
|
+ // …but always pass CurrentTime to XSetSelectionOwner to increase the chances |
+ // of this succeeding. |
sadrul
2016/04/20 17:58:43
um, lol?
dcheng
2016/04/20 18:55:42
I couldn't figure out why, but without doing this,
|
XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime); |
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) { |
sadrul
2016/04/20 17:58:43
Don't need the else.
dcheng
2016/04/20 18:55:43
Done. I updated the rest of this function to be co
|
// 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); |