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

Side by Side Diff: ui/base/x/selection_owner.cc

Issue 2700043002: [Desktop Linux]: Fix copy and pasting long selections (Closed)
Patch Set: Created 3 years, 10 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 unified diff | Download patch
« ui/base/x/selection_owner.h ('K') | « ui/base/x/selection_owner.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/x/selection_owner.h" 5 #include "ui/base/x/selection_owner.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 #include <X11/Xatom.h> 9 #include <X11/Xatom.h>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h"
12 #include "ui/base/x/selection_utils.h" 13 #include "ui/base/x/selection_utils.h"
13 #include "ui/base/x/x11_util.h" 14 #include "ui/base/x/x11_util.h"
14 #include "ui/base/x/x11_window_event_manager.h" 15 #include "ui/base/x/x11_window_event_manager.h"
15 #include "ui/events/platform/x11/x11_event_source.h" 16 #include "ui/events/platform/x11/x11_event_source.h"
16 17
17 namespace ui { 18 namespace ui {
18 19
19 namespace { 20 namespace {
20 21
21 const char kAtomPair[] = "ATOM_PAIR"; 22 const char kAtomPair[] = "ATOM_PAIR";
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // TODO(erg): If we receive a SelectionClear event while we're handling data, 195 // TODO(erg): If we receive a SelectionClear event while we're handling data,
195 // we need to delay clearing. 196 // we need to delay clearing.
196 } 197 }
197 198
198 bool SelectionOwner::CanDispatchPropertyEvent(const XEvent& event) { 199 bool SelectionOwner::CanDispatchPropertyEvent(const XEvent& event) {
199 return event.xproperty.state == PropertyDelete && 200 return event.xproperty.state == PropertyDelete &&
200 FindIncrementalTransferForEvent(event) != incremental_transfers_.end(); 201 FindIncrementalTransferForEvent(event) != incremental_transfers_.end();
201 } 202 }
202 203
203 void SelectionOwner::OnPropertyEvent(const XEvent& event) { 204 void SelectionOwner::OnPropertyEvent(const XEvent& event) {
204 std::vector<IncrementalTransfer>::iterator it = 205 IncrementalTransferIt it = FindIncrementalTransferForEvent(event);
205 FindIncrementalTransferForEvent(event);
206 if (it == incremental_transfers_.end()) 206 if (it == incremental_transfers_.end())
207 return; 207 return;
208 208
209 ProcessIncrementalTransfer(&(*it)); 209 IncrementalTransfer* incremental_transfer = (*it).get();
dcheng 2017/02/17 07:42:13 Does it->get() work?
pkotwicz 2017/02/17 19:19:07 Yes it does :) Thank you!
210 if (!it->data.get()) 210 ProcessIncrementalTransfer(incremental_transfer);
211 if (!incremental_transfer->data.get())
211 CompleteIncrementalTransfer(it); 212 CompleteIncrementalTransfer(it);
212 } 213 }
213 214
214 bool SelectionOwner::ProcessTarget(XAtom target, 215 bool SelectionOwner::ProcessTarget(XAtom target,
215 XID requestor, 216 XID requestor,
216 XAtom property) { 217 XAtom property) {
217 XAtom multiple_atom = atom_cache_.GetAtom(kMultiple); 218 XAtom multiple_atom = atom_cache_.GetAtom(kMultiple);
218 XAtom save_targets_atom = atom_cache_.GetAtom(kSaveTargets); 219 XAtom save_targets_atom = atom_cache_.GetAtom(kSaveTargets);
219 XAtom targets_atom = atom_cache_.GetAtom(kTargets); 220 XAtom targets_atom = atom_cache_.GetAtom(kTargets);
220 XAtom timestamp_atom = atom_cache_.GetAtom(kTimestamp); 221 XAtom timestamp_atom = atom_cache_.GetAtom(kTimestamp);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 PropModeReplace, 263 PropModeReplace,
263 reinterpret_cast<unsigned char*>(&length), 264 reinterpret_cast<unsigned char*>(&length),
264 1); 265 1);
265 266
266 // Wait for the selection requestor to indicate that it has processed 267 // Wait for the selection requestor to indicate that it has processed
267 // the selection result before sending the first chunk of data. The 268 // the selection result before sending the first chunk of data. The
268 // selection requestor indicates this by deleting |property|. 269 // selection requestor indicates this by deleting |property|.
269 base::TimeTicks timeout = 270 base::TimeTicks timeout =
270 base::TimeTicks::Now() + 271 base::TimeTicks::Now() +
271 base::TimeDelta::FromMilliseconds(kIncrementalTransferTimeoutMs); 272 base::TimeDelta::FromMilliseconds(kIncrementalTransferTimeoutMs);
272 requestor_events_.reset( 273 std::unique_ptr<IncrementalTransfer> incremental_transfer(
273 new ui::XScopedEventSelector(requestor, PropertyChangeMask)); 274 new IncrementalTransfer(requestor, target, property,
274 incremental_transfers_.push_back(IncrementalTransfer( 275 base::WrapUnique(new XScopedEventSelector(
dcheng 2017/02/17 07:42:13 Nit: base::MakeUnique
pkotwicz 2017/02/17 19:19:07 Done.
275 requestor, target, property, it->second, 0, timeout)); 276 requestor, PropertyChangeMask)),
277 it->second, 0, timeout));
278 incremental_transfers_.push_back(std::move(incremental_transfer));
276 279
277 // Start a timer to abort the data transfer in case that the selection 280 // Start a timer to abort the data transfer in case that the selection
278 // requestor does not support the INCR property or gets destroyed during 281 // requestor does not support the INCR property or gets destroyed during
279 // the data transfer. 282 // the data transfer.
280 if (!incremental_transfer_abort_timer_.IsRunning()) { 283 if (!incremental_transfer_abort_timer_.IsRunning()) {
281 incremental_transfer_abort_timer_.Start( 284 incremental_transfer_abort_timer_.Start(
282 FROM_HERE, 285 FROM_HERE,
283 base::TimeDelta::FromMilliseconds(kTimerPeriodMs), 286 base::TimeDelta::FromMilliseconds(kTimerPeriodMs),
284 this, 287 this,
285 &SelectionOwner::AbortStaleIncrementalTransfers); 288 &SelectionOwner::AbortStaleIncrementalTransfers);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 // transfer->data once the zero-sized chunk is sent to indicate that state 327 // transfer->data once the zero-sized chunk is sent to indicate that state
325 // related to this data transfer can be cleared. 328 // related to this data transfer can be cleared.
326 if (chunk_length == 0) 329 if (chunk_length == 0)
327 transfer->data = NULL; 330 transfer->data = NULL;
328 } 331 }
329 332
330 void SelectionOwner::AbortStaleIncrementalTransfers() { 333 void SelectionOwner::AbortStaleIncrementalTransfers() {
331 base::TimeTicks now = base::TimeTicks::Now(); 334 base::TimeTicks now = base::TimeTicks::Now();
332 for (int i = static_cast<int>(incremental_transfers_.size()) - 1; 335 for (int i = static_cast<int>(incremental_transfers_.size()) - 1;
333 i >= 0; --i) { 336 i >= 0; --i) {
334 if (incremental_transfers_[i].timeout <= now) 337 if (incremental_transfers_[i]->timeout <= now)
335 CompleteIncrementalTransfer(incremental_transfers_.begin() + i); 338 CompleteIncrementalTransfer(incremental_transfers_.begin() + i);
336 } 339 }
337 } 340 }
338 341
339 void SelectionOwner::CompleteIncrementalTransfer( 342 void SelectionOwner::CompleteIncrementalTransfer(IncrementalTransferIt it) {
340 std::vector<IncrementalTransfer>::iterator it) {
341 requestor_events_.reset();
dcheng 2017/02/17 07:42:13 Is it possible to just only reset this when transf
pkotwicz 2017/02/17 19:19:07 Unfortunately, there may be multiple requesting ap
342
343 incremental_transfers_.erase(it); 343 incremental_transfers_.erase(it);
344 344
345 if (incremental_transfers_.empty()) 345 if (incremental_transfers_.empty())
346 incremental_transfer_abort_timer_.Stop(); 346 incremental_transfer_abort_timer_.Stop();
347 } 347 }
348 348
349 std::vector<SelectionOwner::IncrementalTransfer>::iterator 349 SelectionOwner::IncrementalTransferIt
350 SelectionOwner::FindIncrementalTransferForEvent(const XEvent& event) { 350 SelectionOwner::FindIncrementalTransferForEvent(const XEvent& event) {
351 for (std::vector<IncrementalTransfer>::iterator it = 351 for (IncrementalTransferIt it = incremental_transfers_.begin();
352 incremental_transfers_.begin(); 352 it != incremental_transfers_.end(); ++it) {
353 it != incremental_transfers_.end(); 353 IncrementalTransfer* incremental_transfer = (*it).get();
dcheng 2017/02/17 07:42:13 Nit: Does it->get() work?
pkotwicz 2017/02/17 19:19:07 Done.
354 ++it) { 354 if (incremental_transfer->window == event.xproperty.window &&
355 if (it->window == event.xproperty.window && 355 incremental_transfer->property == event.xproperty.atom) {
356 it->property == event.xproperty.atom) {
357 return it; 356 return it;
358 } 357 }
359 } 358 }
360 return incremental_transfers_.end(); 359 return incremental_transfers_.end();
361 } 360 }
362 361
363 SelectionOwner::IncrementalTransfer::IncrementalTransfer( 362 SelectionOwner::IncrementalTransfer::IncrementalTransfer(
364 XID window, 363 XID window,
365 XAtom target, 364 XAtom target,
366 XAtom property, 365 XAtom property,
366 std::unique_ptr<XScopedEventSelector> event_selector,
367 const scoped_refptr<base::RefCountedMemory>& data, 367 const scoped_refptr<base::RefCountedMemory>& data,
368 int offset, 368 int offset,
369 base::TimeTicks timeout) 369 base::TimeTicks timeout)
370 : window(window), 370 : window(window),
371 target(target), 371 target(target),
372 property(property), 372 property(property),
373 event_selector(std::move(event_selector)),
373 data(data), 374 data(data),
374 offset(offset), 375 offset(offset),
375 timeout(timeout) {} 376 timeout(timeout) {}
376 377
377 SelectionOwner::IncrementalTransfer::IncrementalTransfer(
378 const IncrementalTransfer& other) = default;
379
380 SelectionOwner::IncrementalTransfer::~IncrementalTransfer() { 378 SelectionOwner::IncrementalTransfer::~IncrementalTransfer() {
381 } 379 }
382 380
383 } // namespace ui 381 } // namespace ui
OLDNEW
« ui/base/x/selection_owner.h ('K') | « ui/base/x/selection_owner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698