Bug 1833854 - Part 4: Move all code that deals with maintaining invariants into a...
[gecko.git] / widget / nsBaseClipboard.h
blobb57f67d0793715cb7924c9d7c239b293a3c6ed64
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/Logging.h"
10 #include "nsIClipboard.h"
11 #include "nsITransferable.h"
12 #include "nsCOMPtr.h"
14 static mozilla::LazyLogModule sWidgetClipboardLog("WidgetClipboard");
15 #define CLIPBOARD_LOG(...) \
16 MOZ_LOG(sWidgetClipboardLog, LogLevel::Debug, (__VA_ARGS__))
17 #define CLIPBOARD_LOG_ENABLED() \
18 MOZ_LOG_TEST(sWidgetClipboardLog, LogLevel::Debug)
20 class nsITransferable;
21 class nsIClipboardOwner;
22 class nsIWidget;
24 /**
25 * A helper base class to implement nsIClipboard::SetData/AsyncSetData, so that
26 * all platform can share the same implementation.
28 * XXX this could be merged into nsBaseClipboard once all platform use
29 * nsBaseClipboard as base clipboard class to share the common code, see bug
30 * 1773707.
32 class ClipboardSetDataHelper : public nsIClipboard {
33 public:
34 NS_DECL_ISUPPORTS
36 ClipboardSetDataHelper() = default;
38 // nsIClipboard
39 // XXX the Cocoa widget currently overrides `SetData` for `kSelectionCache`
40 // type, so it cannot be marked as final. Once the Cocoa widget handles
41 // `kSelectionCache` type more generic after bug 1812078, it can be marked
42 // as final, too.
43 NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
44 int32_t aWhichClipboard) override;
45 NS_IMETHOD AsyncSetData(int32_t aWhichClipboard,
46 nsIAsyncSetClipboardDataCallback* aCallback,
47 nsIAsyncSetClipboardData** _retval) override final;
49 protected:
50 virtual ~ClipboardSetDataHelper();
52 // Implement the native clipboard behavior.
53 NS_IMETHOD SetNativeClipboardData(nsITransferable* aTransferable,
54 nsIClipboardOwner* aOwner,
55 int32_t aWhichClipboard) = 0;
57 class AsyncSetClipboardData final : public nsIAsyncSetClipboardData {
58 public:
59 NS_DECL_ISUPPORTS
60 NS_DECL_NSIASYNCSETCLIPBOARDDATA
62 AsyncSetClipboardData(int32_t aClipboardType,
63 ClipboardSetDataHelper* aClipboard,
64 nsIAsyncSetClipboardDataCallback* aCallback);
66 private:
67 virtual ~AsyncSetClipboardData() = default;
68 bool IsValid() const {
69 // If this request is no longer valid, the callback should be notified.
70 MOZ_ASSERT_IF(!mClipboard, !mCallback);
71 return !!mClipboard;
73 void MaybeNotifyCallback(nsresult aResult);
75 // The clipboard type defined in nsIClipboard.
76 int32_t mClipboardType;
77 // It is safe to use a raw pointer as it will be nullified (by calling
78 // NotifyCallback()) once ClipboardSetDataHelper stops tracking us. This is
79 // also used to indicate whether this request is valid.
80 ClipboardSetDataHelper* mClipboard;
81 // mCallback will be nullified once the callback is notified to ensure the
82 // callback is only notified once.
83 nsCOMPtr<nsIAsyncSetClipboardDataCallback> mCallback;
86 private:
87 void RejectPendingAsyncSetDataRequestIfAny(int32_t aClipboardType);
89 // Track the pending request for each clipboard type separately. And only need
90 // to track the latest request for each clipboard type as the prior pending
91 // request will be canceled when a new request is made.
92 RefPtr<AsyncSetClipboardData>
93 mPendingWriteRequests[nsIClipboard::kClipboardTypeCount];
96 /**
97 * A base clipboard class for Windows and Cocoa widget.
99 class nsBaseClipboard : public ClipboardSetDataHelper {
100 public:
101 nsBaseClipboard();
103 // nsISupports
104 NS_DECL_ISUPPORTS_INHERITED
106 // nsIClipboard
107 NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* anOwner,
108 int32_t aWhichClipboard) override;
109 NS_IMETHOD GetData(nsITransferable* aTransferable,
110 int32_t aWhichClipboard) override;
111 NS_IMETHOD EmptyClipboard(int32_t aWhichClipboard) override;
112 NS_IMETHOD HasDataMatchingFlavors(const nsTArray<nsCString>& aFlavorList,
113 int32_t aWhichClipboard,
114 bool* _retval) override;
115 NS_IMETHOD IsClipboardTypeSupported(int32_t aWhichClipboard,
116 bool* _retval) override;
117 RefPtr<mozilla::GenericPromise> AsyncGetData(
118 nsITransferable* aTransferable, int32_t aWhichClipboard) override;
119 RefPtr<DataFlavorsPromise> AsyncHasDataMatchingFlavors(
120 const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) override;
122 protected:
123 virtual ~nsBaseClipboard();
125 // Implement the native clipboard behavior.
126 NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
127 int32_t aWhichClipboard) = 0;
129 void ClearClipboardCache();
131 bool mEmptyingForSetData;
132 nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
133 nsCOMPtr<nsITransferable> mTransferable;
135 private:
136 bool mIgnoreEmptyNotification = false;
139 #endif // nsBaseClipboard_h__