Bug 1753067 - Make Wayland and X11 clipboard implementations a bit more similar. r=stransky

Differential Revision: https://phabricator.services.mozilla.com/D137619
This commit is contained in:
Emilio Cobos Álvarez 2022-02-02 14:55:13 +00:00
Родитель 63348aa663
Коммит c6da6d392f
4 изменённых файлов: 56 добавлений и 59 удалений

Просмотреть файл

@ -126,47 +126,65 @@ void nsRetrievalContextWayland::TransferClipboardData(
} }
} }
ClipboardTargets nsRetrievalContextWayland::GetTargets( ClipboardData nsRetrievalContextWayland::WaitForClipboardData(
int32_t aWhichClipboard) { ClipboardDataType aDataType, int32_t aWhichClipboard,
LOGCLIP("nsRetrievalContextWayland::GetTargets()\n"); const char* aMimeType) {
LOGCLIP("nsRetrievalContextWayland::WaitForClipboardData, MIME %s\n",
aMimeType);
if (!mMutex.TryLock()) { if (!mMutex.TryLock()) {
LOGCLIP(" nsRetrievalContextWayland is already used!\n"); LOGCLIP(" nsRetrievalContextWayland is already used!\n");
return {}; return {};
} }
auto releaseLock = MakeScopeExit([&] { mMutex.Unlock(); }); auto releaseLock = MakeScopeExit([&] { mMutex.Unlock(); });
int clipboardRequest = PrepareNewClipboardRequest(); MOZ_DIAGNOSTIC_ASSERT(mClipboardData.isNothing(),
"Clipboard contains old data?");
mClipboardData.reset();
int clipboardRequest = ++mClipboardRequestNumber;
GdkAtom selection = GetSelectionAtom(aWhichClipboard); GtkClipboard* clipboard =
gtk_clipboard_request_contents( gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
gtk_clipboard_get(selection), gdk_atom_intern("TARGETS", FALSE),
wayland_clipboard_contents_received_async,
new AsyncClipboardData(ClipboardDataType::Targets, clipboardRequest,
this));
return WaitForClipboardContent().ExtractTargets(); auto* asyncData = new AsyncClipboardData(aDataType, clipboardRequest, this);
switch (aDataType) {
case ClipboardDataType::Targets: {
gtk_clipboard_request_contents(
clipboard, gdk_atom_intern("TARGETS", FALSE),
wayland_clipboard_contents_received_async, asyncData);
break;
}
case ClipboardDataType::Data: {
gtk_clipboard_request_contents(
clipboard, gdk_atom_intern(aMimeType, FALSE),
wayland_clipboard_contents_received_async, asyncData);
break;
}
case ClipboardDataType::Text: {
gtk_clipboard_request_text(clipboard, wayland_clipboard_text_received,
asyncData);
break;
}
}
return WaitForClipboardContent();
}
ClipboardTargets nsRetrievalContextWayland::GetTargets(
int32_t aWhichClipboard) {
LOGCLIP("nsRetrievalContextWayland::GetTargets()\n");
return WaitForClipboardData(ClipboardDataType::Targets, aWhichClipboard)
.ExtractTargets();
} }
ClipboardData nsRetrievalContextWayland::GetClipboardData( ClipboardData nsRetrievalContextWayland::GetClipboardData(
const char* aMimeType, int32_t aWhichClipboard) { const char* aMimeType, int32_t aWhichClipboard) {
LOGCLIP("nsRetrievalContextWayland::GetClipboardData() mime %s\n", aMimeType); LOGCLIP("nsRetrievalContextWayland::GetClipboardData() mime %s\n", aMimeType);
if (!mMutex.TryLock()) { return WaitForClipboardData(ClipboardDataType::Data, aWhichClipboard,
LOGCLIP(" nsRetrievalContextWayland is already used!\n"); aMimeType);
return {};
}
auto releaseLock = MakeScopeExit([&] { mMutex.Unlock(); });
int clipboardRequest = PrepareNewClipboardRequest();
GdkAtom selection = GetSelectionAtom(aWhichClipboard);
gtk_clipboard_request_contents(
gtk_clipboard_get(selection), gdk_atom_intern(aMimeType, FALSE),
wayland_clipboard_contents_received_async,
new AsyncClipboardData(ClipboardDataType::Data, clipboardRequest, this));
return WaitForClipboardContent();
} }
GUniquePtr<char> nsRetrievalContextWayland::GetClipboardText( GUniquePtr<char> nsRetrievalContextWayland::GetClipboardText(
@ -176,26 +194,9 @@ GUniquePtr<char> nsRetrievalContextWayland::GetClipboardText(
LOGCLIP("nsRetrievalContextWayland::GetClipboardText(), clipboard %s\n", LOGCLIP("nsRetrievalContextWayland::GetClipboardText(), clipboard %s\n",
(selection == GDK_SELECTION_PRIMARY) ? "Primary" : "Selection"); (selection == GDK_SELECTION_PRIMARY) ? "Primary" : "Selection");
if (!mMutex.TryLock()) { return WaitForClipboardData(ClipboardDataType::Text, aWhichClipboard).mData;
LOGCLIP(" nsRetrievalContextWayland is already used!\n");
return nullptr;
}
auto releaseLock = MakeScopeExit([&] { mMutex.Unlock(); });
int clipboardRequest = PrepareNewClipboardRequest();
gtk_clipboard_request_text(
gtk_clipboard_get(selection), wayland_clipboard_text_received,
new AsyncClipboardData(ClipboardDataType::Text, clipboardRequest, this));
return WaitForClipboardContent().mData;
} }
int nsRetrievalContextWayland::PrepareNewClipboardRequest() {
MOZ_DIAGNOSTIC_ASSERT(mClipboardData.isNothing(),
"Clipboard contains old data?");
mClipboardData.reset();
return ++mClipboardRequestNumber;
}
ClipboardData nsRetrievalContextWayland::WaitForClipboardContent() { ClipboardData nsRetrievalContextWayland::WaitForClipboardContent() {
int iteration = 1; int iteration = 1;

Просмотреть файл

@ -38,8 +38,9 @@ class nsRetrievalContextWayland final : public nsRetrievalContext {
bool HasSelectionSupport(void) override { return true; } bool HasSelectionSupport(void) override { return true; }
private: private:
ClipboardData WaitForClipboardData(ClipboardDataType, int32_t aWhichClipboard,
const char* aMimeType = nullptr);
ClipboardData WaitForClipboardContent(); ClipboardData WaitForClipboardContent();
int PrepareNewClipboardRequest();
int mClipboardRequestNumber = 0; int mClipboardRequestNumber = 0;
mozilla::Maybe<ClipboardData> mClipboardData; mozilla::Maybe<ClipboardData> mClipboardData;

Просмотреть файл

@ -242,10 +242,13 @@ static void clipboard_text_received(GtkClipboard* clipboard, const gchar* text,
} }
ClipboardData nsRetrievalContextX11::WaitForClipboardData( ClipboardData nsRetrievalContextX11::WaitForClipboardData(
ClipboardDataType aDataType, GtkClipboard* clipboard, ClipboardDataType aDataType, int32_t aWhichClipboard,
const char* aMimeType) { const char* aMimeType) {
LOGCLIP("nsRetrievalContextX11::WaitForClipboardData, MIME %s\n", aMimeType); LOGCLIP("nsRetrievalContextX11::WaitForClipboardData, MIME %s\n", aMimeType);
GtkClipboard* clipboard =
gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
mState = State::Initial; mState = State::Initial;
NS_ASSERTION(!mClipboardData, "Leaking clipboard content!"); NS_ASSERTION(!mClipboardData, "Leaking clipboard content!");
@ -285,10 +288,7 @@ ClipboardTargets nsRetrievalContextX11::GetTargets(int32_t aWhichClipboard) {
aWhichClipboard == nsClipboard::kSelectionClipboard ? "primary" aWhichClipboard == nsClipboard::kSelectionClipboard ? "primary"
: "clipboard"); : "clipboard");
GtkClipboard* clipboard = return WaitForClipboardData(ClipboardDataType::Targets, aWhichClipboard)
gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
return WaitForClipboardData(ClipboardDataType::Targets, clipboard)
.ExtractTargets(); .ExtractTargets();
} }
@ -299,10 +299,8 @@ ClipboardData nsRetrievalContextX11::GetClipboardData(const char* aMimeType,
: "clipboard", : "clipboard",
aMimeType); aMimeType);
GtkClipboard* clipboard = return WaitForClipboardData(ClipboardDataType::Data, aWhichClipboard,
gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); aMimeType);
return WaitForClipboardData(ClipboardDataType::Data, clipboard, aMimeType);
} }
GUniquePtr<char> nsRetrievalContextX11::GetClipboardText( GUniquePtr<char> nsRetrievalContextX11::GetClipboardText(
@ -311,8 +309,5 @@ GUniquePtr<char> nsRetrievalContextX11::GetClipboardText(
aWhichClipboard == nsClipboard::kSelectionClipboard ? "primary" aWhichClipboard == nsClipboard::kSelectionClipboard ? "primary"
: "clipboard"); : "clipboard");
GtkClipboard* clipboard = return WaitForClipboardData(ClipboardDataType::Text, aWhichClipboard).mData;
gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
return WaitForClipboardData(ClipboardDataType::Text, clipboard).mData;
} }

Просмотреть файл

@ -33,7 +33,7 @@ class nsRetrievalContextX11 : public nsRetrievalContext {
private: private:
ClipboardData WaitForClipboardData(ClipboardDataType aDataType, ClipboardData WaitForClipboardData(ClipboardDataType aDataType,
GtkClipboard* clipboard, int32_t aWhichClipboard,
const char* aMimeType = nullptr); const char* aMimeType = nullptr);
/** /**