1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 20:07:36 +00:00

Clipboard+LibGUI: Move clipboard service to anonymous files

This commit is contained in:
Andreas Kling 2021-01-17 00:14:37 +01:00
parent 1cb44ec5ee
commit 5522e8f59d
6 changed files with 21 additions and 60 deletions

View file

@ -25,7 +25,6 @@
*/ */
#include <AK/Badge.h> #include <AK/Badge.h>
#include <AK/SharedBuffer.h>
#include <Clipboard/ClipboardClientEndpoint.h> #include <Clipboard/ClipboardClientEndpoint.h>
#include <Clipboard/ClipboardServerEndpoint.h> #include <Clipboard/ClipboardServerEndpoint.h>
#include <LibGUI/Clipboard.h> #include <LibGUI/Clipboard.h>
@ -79,18 +78,9 @@ Clipboard::Clipboard()
Clipboard::DataAndType Clipboard::data_and_type() const Clipboard::DataAndType Clipboard::data_and_type() const
{ {
auto response = connection().send_sync<Messages::ClipboardServer::GetClipboardData>(); auto response = connection().send_sync<Messages::ClipboardServer::GetClipboardData>();
if (response->shbuf_id() < 0) if (!response->data().is_valid())
return {}; return {};
auto shared_buffer = SharedBuffer::create_from_shbuf_id(response->shbuf_id()); auto data = ByteBuffer::copy(response->data().data<void>(), response->data().size());
if (!shared_buffer) {
dbgln("GUI::Clipboard::data() failed to attach to the shared buffer");
return {};
}
if (response->data_size() > shared_buffer->size()) {
dbgln("GUI::Clipboard::data() clipping contents size is greater than shared buffer size");
return {};
}
auto data = ByteBuffer::copy(shared_buffer->data<void>(), response->data_size());
auto type = response->mime_type(); auto type = response->mime_type();
auto metadata = response->metadata().entries(); auto metadata = response->metadata().entries();
return { data, type, metadata }; return { data, type, metadata };
@ -98,17 +88,15 @@ Clipboard::DataAndType Clipboard::data_and_type() const
void Clipboard::set_data(ReadonlyBytes data, const String& type, const HashMap<String, String>& metadata) void Clipboard::set_data(ReadonlyBytes data, const String& type, const HashMap<String, String>& metadata)
{ {
auto shared_buffer = SharedBuffer::create_with_size(data.size()); auto buffer = Core::AnonymousBuffer::create_with_size(data.size());
if (!shared_buffer) { if (!buffer.is_valid()) {
dbgln("GUI::Clipboard::set_data() failed to create a shared buffer"); dbgln("GUI::Clipboard::set_data() failed to create a buffer");
return; return;
} }
if (!data.is_empty()) if (!data.is_empty())
memcpy(shared_buffer->data<void>(), data.data(), data.size()); memcpy(buffer.data<void>(), data.data(), data.size());
shared_buffer->seal();
shared_buffer->share_with(connection().server_pid());
connection().send_sync<Messages::ClipboardServer::SetClipboardData>(shared_buffer->shbuf_id(), data.size(), type, metadata); connection().send_sync<Messages::ClipboardServer::SetClipboardData>(move(buffer), type, metadata);
} }
void ClipboardServerConnection::handle(const Messages::ClipboardClient::ClipboardDataChanged& message) void ClipboardServerConnection::handle(const Messages::ClipboardClient::ClipboardDataChanged& message)

View file

@ -25,7 +25,6 @@
*/ */
#include <AK/Badge.h> #include <AK/Badge.h>
#include <AK/SharedBuffer.h>
#include <Clipboard/ClientConnection.h> #include <Clipboard/ClientConnection.h>
#include <Clipboard/ClipboardClientEndpoint.h> #include <Clipboard/ClipboardClientEndpoint.h>
#include <Clipboard/Storage.h> #include <Clipboard/Storage.h>
@ -63,36 +62,14 @@ OwnPtr<Messages::ClipboardServer::GreetResponse> ClientConnection::handle(const
OwnPtr<Messages::ClipboardServer::SetClipboardDataResponse> ClientConnection::handle(const Messages::ClipboardServer::SetClipboardData& message) OwnPtr<Messages::ClipboardServer::SetClipboardDataResponse> ClientConnection::handle(const Messages::ClipboardServer::SetClipboardData& message)
{ {
auto shared_buffer = SharedBuffer::create_from_shbuf_id(message.shbuf_id()); Storage::the().set_data(message.data(), message.mime_type(), message.metadata().entries());
if (!shared_buffer) {
did_misbehave("SetClipboardData: Bad shared buffer ID");
return {};
}
Storage::the().set_data(*shared_buffer, message.data_size(), message.mime_type(), message.metadata().entries());
return make<Messages::ClipboardServer::SetClipboardDataResponse>(); return make<Messages::ClipboardServer::SetClipboardDataResponse>();
} }
OwnPtr<Messages::ClipboardServer::GetClipboardDataResponse> ClientConnection::handle(const Messages::ClipboardServer::GetClipboardData&) OwnPtr<Messages::ClipboardServer::GetClipboardDataResponse> ClientConnection::handle(const Messages::ClipboardServer::GetClipboardData&)
{ {
auto& storage = Storage::the(); auto& storage = Storage::the();
return make<Messages::ClipboardServer::GetClipboardDataResponse>(storage.buffer(), storage.mime_type(), storage.metadata());
i32 shbuf_id = -1;
if (storage.data_size()) {
// FIXME: Optimize case where an app is copy/pasting within itself.
// We can just reuse the SharedBuffer then, since it will have the same peer PID.
// It would be even nicer if a SharedBuffer could have an arbitrary number of clients..
RefPtr<SharedBuffer> shared_buffer = SharedBuffer::create_with_size(storage.data_size());
ASSERT(shared_buffer);
memcpy(shared_buffer->data<void>(), storage.data(), storage.data_size());
shared_buffer->seal();
shared_buffer->share_with(client_pid());
shbuf_id = shared_buffer->shbuf_id();
// FIXME: This is a workaround for the fact that SharedBuffers will go away if neither side is retaining them.
// After we respond to GetClipboardData, we have to wait for the client to ref the buffer on his side.
m_last_sent_buffer = move(shared_buffer);
}
return make<Messages::ClipboardServer::GetClipboardDataResponse>(shbuf_id, storage.data_size(), storage.mime_type(), storage.metadata());
} }
void ClientConnection::notify_about_clipboard_change() void ClientConnection::notify_about_clipboard_change()

View file

@ -53,8 +53,6 @@ private:
virtual OwnPtr<Messages::ClipboardServer::GreetResponse> handle(const Messages::ClipboardServer::Greet&) override; virtual OwnPtr<Messages::ClipboardServer::GreetResponse> handle(const Messages::ClipboardServer::Greet&) override;
virtual OwnPtr<Messages::ClipboardServer::GetClipboardDataResponse> handle(const Messages::ClipboardServer::GetClipboardData&) override; virtual OwnPtr<Messages::ClipboardServer::GetClipboardDataResponse> handle(const Messages::ClipboardServer::GetClipboardData&) override;
virtual OwnPtr<Messages::ClipboardServer::SetClipboardDataResponse> handle(const Messages::ClipboardServer::SetClipboardData&) override; virtual OwnPtr<Messages::ClipboardServer::SetClipboardDataResponse> handle(const Messages::ClipboardServer::SetClipboardData&) override;
RefPtr<SharedBuffer> m_last_sent_buffer;
}; };
} }

View file

@ -2,6 +2,6 @@ endpoint ClipboardServer = 802
{ {
Greet() => (i32 client_id) Greet() => (i32 client_id)
GetClipboardData() => (i32 shbuf_id, i32 data_size, [UTF8] String mime_type, IPC::Dictionary metadata) GetClipboardData() => (Core::AnonymousBuffer data, [UTF8] String mime_type, IPC::Dictionary metadata)
SetClipboardData(i32 shbuf_id, i32 data_size, [UTF8] String mime_type, IPC::Dictionary metadata) => () SetClipboardData(Core::AnonymousBuffer data, [UTF8] String mime_type, IPC::Dictionary metadata) => ()
} }

View file

@ -44,14 +44,10 @@ Storage::~Storage()
{ {
} }
void Storage::set_data(NonnullRefPtr<SharedBuffer> data, size_t data_size, const String& mime_type, const HashMap<String, String>& metadata) void Storage::set_data(Core::AnonymousBuffer data, const String& mime_type, const HashMap<String, String>& metadata)
{ {
dbg() << "Storage::set_data <- [" << mime_type << "] " << data->data<void>() << " (" << data_size << " bytes)"; m_buffer = move(data);
for (auto& it : metadata) { m_data_size = data.size();
dbg() << " " << it.key << ": " << it.value;
}
m_shared_buffer = move(data);
m_data_size = data_size;
m_mime_type = mime_type; m_mime_type = mime_type;
m_metadata = metadata; m_metadata = metadata;

View file

@ -28,8 +28,8 @@
#include <AK/Function.h> #include <AK/Function.h>
#include <AK/HashMap.h> #include <AK/HashMap.h>
#include <AK/SharedBuffer.h>
#include <AK/String.h> #include <AK/String.h>
#include <LibCore/AnonymousBuffer.h>
namespace Clipboard { namespace Clipboard {
@ -38,7 +38,7 @@ public:
static Storage& the(); static Storage& the();
~Storage(); ~Storage();
bool has_data() const { return m_shared_buffer; } bool has_data() const { return m_buffer.is_valid(); }
const String& mime_type() const { return m_mime_type; } const String& mime_type() const { return m_mime_type; }
const HashMap<String, String>& metadata() const { return m_metadata; } const HashMap<String, String>& metadata() const { return m_metadata; }
@ -47,7 +47,7 @@ public:
{ {
if (!has_data()) if (!has_data())
return nullptr; return nullptr;
return m_shared_buffer->data<u8>(); return m_buffer.data<u8>();
} }
size_t data_size() const size_t data_size() const
@ -57,15 +57,17 @@ public:
return 0; return 0;
} }
void set_data(NonnullRefPtr<SharedBuffer>, size_t data_size, const String& mime_type, const HashMap<String, String>& metadata); void set_data(Core::AnonymousBuffer, const String& mime_type, const HashMap<String, String>& metadata);
Function<void()> on_content_change; Function<void()> on_content_change;
const Core::AnonymousBuffer& buffer() const { return m_buffer; }
private: private:
Storage(); Storage();
String m_mime_type; String m_mime_type;
RefPtr<SharedBuffer> m_shared_buffer; Core::AnonymousBuffer m_buffer;
size_t m_data_size { 0 }; size_t m_data_size { 0 };
HashMap<String, String> m_metadata; HashMap<String, String> m_metadata;
}; };