File: selection_owner.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (156 lines) | stat: -rw-r--r-- 5,241 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_BASE_X_SELECTION_OWNER_H_
#define UI_BASE_X_SELECTION_OWNER_H_

#include <stddef.h>

#include <vector>

#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/memory/ref_counted_memory.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "ui/base/x/selection_utils.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/event.h"

namespace x11 {
class ScopedEventSelector;
}

namespace ui {

COMPONENT_EXPORT(UI_BASE_X) extern const char kIncr[];
COMPONENT_EXPORT(UI_BASE_X) extern const char kSaveTargets[];
COMPONENT_EXPORT(UI_BASE_X) extern const char kTargets[];

// Owns a specific X11 selection on an X window.
//
// The selection owner object keeps track of which xwindow is the current
// owner, and when its |xwindow_|, offers different data types to other
// processes.
class COMPONENT_EXPORT(UI_BASE_X) SelectionOwner {
 public:
  SelectionOwner(x11::Connection& connection,
                 x11::Window xwindow,
                 x11::Atom selection_name);

  SelectionOwner(const SelectionOwner&) = delete;
  SelectionOwner& operator=(const SelectionOwner&) = delete;

  ~SelectionOwner();

  // Returns the current selection data. Useful for fast paths.
  const SelectionFormatMap& selection_format_map() { return format_map_; }

  // Appends a list of types we're offering to |targets|.
  void RetrieveTargets(std::vector<x11::Atom>* targets);

  // Attempts to take ownership of the selection. If we're successful, present
  // |data| to other windows.
  void TakeOwnershipOfSelection(const SelectionFormatMap& data);

  // Clears our internal format map and clears the selection owner, whether we
  // own the selection or not.
  void ClearSelectionOwner();

  // It is our owner's responsibility to plumb X11 events on |xwindow_| to us.
  void OnSelectionRequest(const x11::SelectionRequestEvent& event);
  void OnSelectionClear(const x11::SelectionClearEvent& event);

  // Returns true if SelectionOwner can process the XPropertyEvent event,
  // |event|.
  bool CanDispatchPropertyEvent(const x11::PropertyNotifyEvent& event);

  void OnPropertyEvent(const x11::PropertyNotifyEvent& event);

 private:
  // Holds state related to an incremental data transfer.
  struct IncrementalTransfer {
    IncrementalTransfer(x11::Window window,
                        x11::Atom target,
                        x11::Atom property,
                        x11::ScopedEventSelector event_selector,
                        const scoped_refptr<base::RefCountedMemory>& data,
                        int offset,
                        base::TimeTicks timeout);

    IncrementalTransfer(const IncrementalTransfer&) = delete;
    IncrementalTransfer& operator=(const IncrementalTransfer&) = delete;

    ~IncrementalTransfer();

    // Move-only class.
    IncrementalTransfer(IncrementalTransfer&&);
    IncrementalTransfer& operator=(IncrementalTransfer&&);

    // Parameters from the XSelectionRequest. The data is transferred over
    // |property| on |window|.
    x11::Window window;
    x11::Atom target;
    x11::Atom property;

    // Selects events on |window|.
    x11::ScopedEventSelector event_selector;

    // The data to be transferred.
    scoped_refptr<base::RefCountedMemory> data;

    // The offset from the beginning of |data| of the first byte to be
    // transferred in the next chunk.
    size_t offset;

    // Time when the transfer should be aborted because the selection requestor
    // is taking too long to notify us that we can send the next chunk.
    base::TimeTicks timeout;
  };

  // Attempts to convert the selection to |target|. If the conversion is
  // successful, true is returned and the result is stored in the |property|
  // of |requestor|.
  bool ProcessTarget(x11::Atom target,
                     x11::Window requestor,
                     x11::Atom property);

  // Sends the next chunk of data for given the incremental data transfer.
  void ProcessIncrementalTransfer(IncrementalTransfer* transfer);

  // Aborts any incremental data transfers which have timed out.
  void AbortStaleIncrementalTransfers();

  // Called when the transfer at |it| has completed to do cleanup.
  void CompleteIncrementalTransfer(
      std::vector<IncrementalTransfer>::iterator it);

  // Returns the incremental data transfer, if any, which was waiting for
  // |event|.
  std::vector<IncrementalTransfer>::iterator FindIncrementalTransferForEvent(
      const x11::PropertyNotifyEvent& event);

  raw_ref<x11::Connection> connection_;

  // Our X11 state.
  x11::Window x_window_;

  // The X11 selection that this instance communicates on.
  x11::Atom selection_name_;

  // The time that this instance took ownership of its selection.
  x11::Time acquired_selection_timestamp_;

  // The data we are currently serving.
  SelectionFormatMap format_map_;

  std::vector<IncrementalTransfer> incremental_transfers_;

  // Used to abort stale incremental data transfers.
  base::RepeatingTimer incremental_transfer_abort_timer_;
};

}  // namespace ui

#endif  // UI_BASE_X_SELECTION_OWNER_H_