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

Side by Side Diff: ui/base/x/selection_requestor.h

Issue 391593002: Process SelectionRequestor::PerformBlockingConvertSelection() requests one at a time (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
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 #ifndef UI_BASE_X_SELECTION_REQUESTOR_H_ 5 #ifndef UI_BASE_X_SELECTION_REQUESTOR_H_
6 #define UI_BASE_X_SELECTION_REQUESTOR_H_ 6 #define UI_BASE_X_SELECTION_REQUESTOR_H_
7 7
8 #include <X11/Xlib.h>
9
10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class.
11 #undef RootWindow
12
13 #include <list>
14 #include <vector> 8 #include <vector>
15 9
16 #include "base/basictypes.h" 10 #include "base/basictypes.h"
17 #include "base/callback.h" 11 #include "base/callback.h"
18 #include "base/event_types.h" 12 #include "base/event_types.h"
19 #include "base/memory/ref_counted_memory.h" 13 #include "base/memory/ref_counted_memory.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
20 #include "ui/base/ui_base_export.h" 16 #include "ui/base/ui_base_export.h"
21 #include "ui/gfx/x/x11_atom_cache.h" 17 #include "ui/gfx/x/x11_atom_cache.h"
22 #include "ui/gfx/x/x11_types.h" 18 #include "ui/gfx/x/x11_types.h"
23 19
24 namespace ui { 20 namespace ui {
25 class PlatformEventDispatcher; 21 class PlatformEventDispatcher;
26 class SelectionData; 22 class SelectionData;
27 23
28 // Requests and later receives data from the X11 server through the selection 24 // Requests and later receives data from the X11 server through the selection
29 // system. 25 // system.
30 // 26 //
31 // X11 uses a system called "selections" to implement clipboards and drag and 27 // X11 uses a system called "selections" to implement clipboards and drag and
32 // drop. This class interprets messages from the statefull selection request 28 // drop. This class interprets messages from the stateful selection request
33 // API. SelectionRequestor should only deal with the X11 details; it does not 29 // API. SelectionRequestor should only deal with the X11 details; it does not
34 // implement per-component fast-paths. 30 // implement per-component fast-paths.
35 class UI_BASE_EXPORT SelectionRequestor { 31 class UI_BASE_EXPORT SelectionRequestor {
36 public: 32 public:
37 SelectionRequestor(XDisplay* xdisplay, 33 SelectionRequestor(XDisplay* xdisplay,
38 XID xwindow, 34 XID xwindow,
39 XAtom selection_name,
40 PlatformEventDispatcher* dispatcher); 35 PlatformEventDispatcher* dispatcher);
41 ~SelectionRequestor(); 36 ~SelectionRequestor();
42 37
43 // Does the work of requesting |target| from the selection we handle, 38 // Does the work of requesting |target| from |selection|, spinning up the
44 // spinning up the nested message loop, and reading the resulting data 39 // nested message loop, and reading the resulting data back. The result is
45 // back. The result is stored in |out_data|. 40 // stored in |out_data|.
46 // |out_data_items| is the length of |out_data| in |out_type| items. 41 // |out_data_items| is the length of |out_data| in |out_type| items.
47 bool PerformBlockingConvertSelection( 42 bool PerformBlockingConvertSelection(
43 XAtom selection,
48 XAtom target, 44 XAtom target,
49 scoped_refptr<base::RefCountedMemory>* out_data, 45 scoped_refptr<base::RefCountedMemory>* out_data,
50 size_t* out_data_items, 46 size_t* out_data_items,
51 XAtom* out_type); 47 XAtom* out_type);
52 48
53 // Requests |target| from the selection that we handle, passing |parameter| 49 // Requests |target| from |selection|, passing |parameter| as a parameter to
54 // as a parameter to XConvertSelection(). 50 // XConvertSelection().
55 void PerformBlockingConvertSelectionWithParameter( 51 void PerformBlockingConvertSelectionWithParameter(
52 XAtom selection,
56 XAtom target, 53 XAtom target,
57 const std::vector<XAtom>& parameter); 54 const std::vector<XAtom>& parameter);
58 55
59 // Returns the first of |types| offered by the current selection holder, or 56 // Returns the first of |types| offered by the current owner of |selection|.
60 // returns NULL if none of those types are available. 57 // Returns an empty SelectionData object if none of |types| are available.
61 SelectionData RequestAndWaitForTypes(const std::vector<XAtom>& types); 58 SelectionData RequestAndWaitForTypes(XAtom selection,
59 const std::vector<XAtom>& types);
62 60
63 // It is our owner's responsibility to plumb X11 SelectionNotify events on 61 // It is our owner's responsibility to plumb X11 SelectionNotify events on
64 // |xwindow_| to us. 62 // |xwindow_| to us.
65 void OnSelectionNotify(const XEvent& event); 63 void OnSelectionNotify(const XEvent& event);
66 64
67 private: 65 private:
68 // A request that has been issued and we are waiting for a response to. 66 friend class SelectionRequestorTest;
69 struct PendingRequest {
70 explicit PendingRequest(XAtom target);
71 ~PendingRequest();
72 67
73 // Data to the current XConvertSelection request. Used for error detection; 68 // A request that has been issued.
74 // we verify it on the return message. 69 struct Request {
70 Request(XAtom selection, XAtom target, base::TimeTicks timeout);
71 ~Request();
72
73 // The target and selection requested in the XConvertSelection() request.
74 // Used for error detection.
75 XAtom selection;
75 XAtom target; 76 XAtom target;
76 77
78 // The result data for the XConvertSelection() request.
79 scoped_refptr<base::RefCountedMemory> out_data;
80 size_t out_data_items;
81 XAtom out_type;
82
83 // Whether the XConvertSelection() request was successful.
84 bool success;
85
86 // The time when the request should be aborted.
87 base::TimeTicks timeout;
88
77 // Called to terminate the nested message loop. 89 // Called to terminate the nested message loop.
78 base::Closure quit_closure; 90 base::Closure quit_closure;
79 91
80 // The property in the returning SelectNotify message is used to signal 92 // True if the request is complete.
81 // success. If None, our request failed somehow. If equal to the property 93 bool completed;
82 // atom that we sent in the XConvertSelection call, we can read that 94 };
83 // property on |x_window_| for the requested data.
84 XAtom returned_property;
85 95
86 // Set to true when return_property is populated. 96 // Aborts requests which have timed out.
87 bool returned; 97 void AbortStaleRequests();
88 }; 98
99 // Mark |request| as completed. If the current request is completed, converts
100 // the selection for the next request.
101 void CompleteRequest(size_t index);
102
103 // Converts the selection for the request at |current_request_index_|.
104 void ConvertSelectionForCurrentRequest();
89 105
90 // Blocks till SelectionNotify is received for the target specified in 106 // Blocks till SelectionNotify is received for the target specified in
91 // |request|. 107 // |request|.
92 void BlockTillSelectionNotifyForRequest(PendingRequest* request); 108 void BlockTillSelectionNotifyForRequest(Request* request);
109
110 // Returns the request at |current_request_index_| or NULL if there isn't any.
111 Request* GetCurrentRequest();
93 112
94 // Our X11 state. 113 // Our X11 state.
95 XDisplay* x_display_; 114 XDisplay* x_display_;
96 XID x_window_; 115 XID x_window_;
97 116
98 // The X11 selection that this instance communicates on. 117 // The property on |x_window_| set by the selection owner with the value of
99 XAtom selection_name_; 118 // the selection.
119 XAtom x_property_;
100 120
101 // Dispatcher which handles SelectionNotify and SelectionRequest for 121 // Dispatcher which handles SelectionNotify and SelectionRequest for
102 // |selection_name_|. PerformBlockingConvertSelection() calls the 122 // |selection_name_|. PerformBlockingConvertSelection() calls the
103 // dispatcher directly if PerformBlockingConvertSelection() is called after 123 // dispatcher directly if PerformBlockingConvertSelection() is called after
104 // the PlatformEventSource is destroyed. 124 // the PlatformEventSource is destroyed.
105 // Not owned. 125 // Not owned.
106 PlatformEventDispatcher* dispatcher_; 126 PlatformEventDispatcher* dispatcher_;
107 127
108 // A list of requests for which we are waiting for responses. 128 // In progress requests initiated by PerformBlockingConvertSelection(). A
109 std::list<PendingRequest*> pending_requests_; 129 // request is in progress if the PerformBlockingConvertSelection() call
130 // which initiated the request has not yet returned.
Daniel Erat 2014/07/16 22:17:01 could you add a comment describing the ownership o
131 std::vector<Request*> requests_;
132
133 // The index of the currently active request in |requests_|. The active
134 // request is the request for which XConvertSelection() has been
135 // called and for which we are waiting for a SelectionNotify response.
136 size_t current_request_index_;
137
138 base::RepeatingTimer<SelectionRequestor> abort_timer_;
110 139
111 X11AtomCache atom_cache_; 140 X11AtomCache atom_cache_;
112 141
113 DISALLOW_COPY_AND_ASSIGN(SelectionRequestor); 142 DISALLOW_COPY_AND_ASSIGN(SelectionRequestor);
114 }; 143 };
115 144
116 } // namespace ui 145 } // namespace ui
117 146
118 #endif // UI_BASE_X_SELECTION_REQUESTOR_H_ 147 #endif // UI_BASE_X_SELECTION_REQUESTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698