Merge mozilla-central to autoland. CLOSED TREE
[gecko.git] / widget / nsBaseClipboard.h
blob788eaef7dea66e57b1558f69eeb1520697085f84
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsBaseClipboard_h__
7 #define nsBaseClipboard_h__
9 #include "mozilla/dom/PContent.h"
10 #include "mozilla/Logging.h"
11 #include "mozilla/Result.h"
12 #include "nsIClipboard.h"
13 #include "nsITransferable.h"
14 #include "nsCOMPtr.h"
16 static mozilla::LazyLogModule sWidgetClipboardLog("WidgetClipboard");
17 #define CLIPBOARD_LOG(...) \
18 MOZ_LOG(sWidgetClipboardLog, LogLevel::Debug, (__VA_ARGS__))
19 #define CLIPBOARD_LOG_ENABLED() \
20 MOZ_LOG_TEST(sWidgetClipboardLog, LogLevel::Debug)
22 class nsITransferable;
23 class nsIClipboardOwner;
24 class nsIWidget;
26 /**
27 * A helper base class to implement nsIClipboard::SetData/AsyncSetData, so that
28 * all platform can share the same implementation.
30 * XXX this could be merged into nsBaseClipboard once all platform use
31 * nsBaseClipboard as base clipboard class to share the common code, see bug
32 * 1773707.
34 class ClipboardSetDataHelper : public nsIClipboard {
35 public:
36 NS_DECL_ISUPPORTS
38 ClipboardSetDataHelper() = default;
40 // nsIClipboard
41 NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
42 int32_t aWhichClipboard) override;
43 NS_IMETHOD AsyncSetData(int32_t aWhichClipboard,
44 nsIAsyncSetClipboardDataCallback* aCallback,
45 nsIAsyncSetClipboardData** _retval) override final;
47 protected:
48 virtual ~ClipboardSetDataHelper();
50 // Implement the native clipboard behavior.
51 NS_IMETHOD SetNativeClipboardData(nsITransferable* aTransferable,
52 nsIClipboardOwner* aOwner,
53 int32_t aWhichClipboard) = 0;
55 class AsyncSetClipboardData final : public nsIAsyncSetClipboardData {
56 public:
57 NS_DECL_ISUPPORTS
58 NS_DECL_NSIASYNCSETCLIPBOARDDATA
60 AsyncSetClipboardData(int32_t aClipboardType,
61 ClipboardSetDataHelper* aClipboard,
62 nsIAsyncSetClipboardDataCallback* aCallback);
64 private:
65 virtual ~AsyncSetClipboardData() = default;
66 bool IsValid() const {
67 // If this request is no longer valid, the callback should be notified.
68 MOZ_ASSERT_IF(!mClipboard, !mCallback);
69 return !!mClipboard;
71 void MaybeNotifyCallback(nsresult aResult);
73 // The clipboard type defined in nsIClipboard.
74 int32_t mClipboardType;
75 // It is safe to use a raw pointer as it will be nullified (by calling
76 // NotifyCallback()) once ClipboardSetDataHelper stops tracking us. This is
77 // also used to indicate whether this request is valid.
78 ClipboardSetDataHelper* mClipboard;
79 // mCallback will be nullified once the callback is notified to ensure the
80 // callback is only notified once.
81 nsCOMPtr<nsIAsyncSetClipboardDataCallback> mCallback;
84 private:
85 void RejectPendingAsyncSetDataRequestIfAny(int32_t aClipboardType);
87 // Track the pending request for each clipboard type separately. And only need
88 // to track the latest request for each clipboard type as the prior pending
89 // request will be canceled when a new request is made.
90 RefPtr<AsyncSetClipboardData>
91 mPendingWriteRequests[nsIClipboard::kClipboardTypeCount];
94 /**
95 * A base clipboard class for Windows and Cocoa widget.
97 class nsBaseClipboard : public ClipboardSetDataHelper {
98 public:
99 explicit nsBaseClipboard(
100 const mozilla::dom::ClipboardCapabilities& aClipboardCaps);
102 // nsISupports
103 NS_DECL_ISUPPORTS_INHERITED
105 // nsIClipboard
106 NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* anOwner,
107 int32_t aWhichClipboard) override final;
108 NS_IMETHOD GetData(nsITransferable* aTransferable,
109 int32_t aWhichClipboard) override final;
110 NS_IMETHOD EmptyClipboard(int32_t aWhichClipboard) override final;
111 NS_IMETHOD HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList,
112 int32_t aWhichClipboard,
113 bool* aOutResult) override final;
114 NS_IMETHOD IsClipboardTypeSupported(int32_t aWhichClipboard,
115 bool* aRetval) override final;
116 RefPtr<mozilla::GenericPromise> AsyncGetData(
117 nsITransferable* aTransferable, int32_t aWhichClipboard) override final;
118 RefPtr<DataFlavorsPromise> AsyncHasDataMatchingFlavors(
119 const nsTArray<nsCString>& aFlavorList,
120 int32_t aWhichClipboard) override final;
122 protected:
123 virtual ~nsBaseClipboard() = default;
125 // Implement the native clipboard behavior.
126 NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
127 int32_t aWhichClipboard) = 0;
128 virtual nsresult EmptyNativeClipboardData(int32_t aWhichClipboard) = 0;
129 virtual mozilla::Result<int32_t, nsresult> GetNativeClipboardSequenceNumber(
130 int32_t aWhichClipboard) = 0;
131 virtual mozilla::Result<bool, nsresult> HasNativeClipboardDataMatchingFlavors(
132 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) = 0;
134 private:
135 class ClipboardCache final {
136 public:
137 ~ClipboardCache() {
138 // In order to notify the old clipboard owner.
139 Clear();
143 * Clear the cached transferable and notify the original clipboard owner
144 * that it has lost ownership.
146 void Clear();
147 void Update(nsITransferable* aTransferable,
148 nsIClipboardOwner* aClipboardOwner, int32_t aSequenceNumber) {
149 // Clear first to notify the old clipboard owner.
150 Clear();
151 mTransferable = aTransferable;
152 mClipboardOwner = aClipboardOwner;
153 mSequenceNumber = aSequenceNumber;
155 nsITransferable* GetTransferable() const { return mTransferable; }
156 nsIClipboardOwner* GetClipboardOwner() const { return mClipboardOwner; }
157 int32_t GetSequenceNumber() const { return mSequenceNumber; }
159 private:
160 nsCOMPtr<nsITransferable> mTransferable;
161 nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
162 int32_t mSequenceNumber = -1;
165 // Return clipboard cache if the cached data is valid, otherwise clear the
166 // cached data and returns null.
167 ClipboardCache* GetClipboardCacheIfValid(int32_t aClipboardType);
169 mozilla::UniquePtr<ClipboardCache> mCaches[nsIClipboard::kClipboardTypeCount];
170 const mozilla::dom::ClipboardCapabilities mClipboardCaps;
171 bool mIgnoreEmptyNotification = false;
174 #endif // nsBaseClipboard_h__