mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:27:45 +00:00
Clipboard: Add a key-value map alongside the clipboard storage
A clipping now consists of three things: - The raw clip data - A MIME type - A key-value map (String, String) for anything you like
This commit is contained in:
parent
51146e3075
commit
2e6d59b7b2
7 changed files with 34 additions and 11 deletions
|
@ -92,10 +92,11 @@ Clipboard::DataAndType Clipboard::data_and_type() const
|
||||||
}
|
}
|
||||||
auto data = ByteBuffer::copy(shared_buffer->data(), response->data_size());
|
auto data = ByteBuffer::copy(shared_buffer->data(), response->data_size());
|
||||||
auto type = response->mime_type();
|
auto type = response->mime_type();
|
||||||
return { data, type };
|
auto metadata = response->metadata().entries();
|
||||||
|
return { data, type, metadata };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clipboard::set_data(ReadonlyBytes data, const String& type)
|
void Clipboard::set_data(ReadonlyBytes data, const String& type, const HashMap<String, String>& metadata)
|
||||||
{
|
{
|
||||||
auto shared_buffer = SharedBuffer::create_with_size(data.size() + 1);
|
auto shared_buffer = SharedBuffer::create_with_size(data.size() + 1);
|
||||||
if (!shared_buffer) {
|
if (!shared_buffer) {
|
||||||
|
@ -109,7 +110,7 @@ void Clipboard::set_data(ReadonlyBytes data, const String& type)
|
||||||
shared_buffer->seal();
|
shared_buffer->seal();
|
||||||
shared_buffer->share_with(connection().server_pid());
|
shared_buffer->share_with(connection().server_pid());
|
||||||
|
|
||||||
connection().send_sync<Messages::ClipboardServer::SetClipboardData>(shared_buffer->shbuf_id(), data.size(), type);
|
connection().send_sync<Messages::ClipboardServer::SetClipboardData>(shared_buffer->shbuf_id(), data.size(), type, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipboardServerConnection::handle(const Messages::ClipboardClient::ClipboardDataChanged& message)
|
void ClipboardServerConnection::handle(const Messages::ClipboardClient::ClipboardDataChanged& message)
|
||||||
|
@ -119,4 +120,9 @@ void ClipboardServerConnection::handle(const Messages::ClipboardClient::Clipboar
|
||||||
clipboard.on_change(message.mime_type());
|
clipboard.on_change(message.mime_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clipboard::set_bitmap(const Gfx::Bitmap& bitmap)
|
||||||
|
{
|
||||||
|
(void) bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
|
#include <AK/HashMap.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <LibGUI/Forward.h>
|
#include <LibGUI/Forward.h>
|
||||||
|
#include <LibGfx/Forward.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
@ -38,16 +40,19 @@ public:
|
||||||
|
|
||||||
ByteBuffer data() const { return data_and_type().data; }
|
ByteBuffer data() const { return data_and_type().data; }
|
||||||
String mime_type() const { return data_and_type().mime_type; }
|
String mime_type() const { return data_and_type().mime_type; }
|
||||||
void set_data(ReadonlyBytes, const String& mime_type = "text/plain");
|
void set_data(ReadonlyBytes, const String& mime_type = "text/plain", const HashMap<String, String>& metadata = {});
|
||||||
|
|
||||||
void set_plain_text(const String& text)
|
void set_plain_text(const String& text)
|
||||||
{
|
{
|
||||||
set_data(text.bytes());
|
set_data(text.bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_bitmap(const Gfx::Bitmap&);
|
||||||
|
|
||||||
struct DataAndType {
|
struct DataAndType {
|
||||||
ByteBuffer data;
|
ByteBuffer data;
|
||||||
String mime_type;
|
String mime_type;
|
||||||
|
HashMap<String, String> metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
DataAndType data_and_type() const;
|
DataAndType data_and_type() const;
|
||||||
|
|
|
@ -33,7 +33,12 @@ namespace IPC {
|
||||||
|
|
||||||
class Dictionary {
|
class Dictionary {
|
||||||
public:
|
public:
|
||||||
Dictionary() {}
|
Dictionary() { }
|
||||||
|
|
||||||
|
Dictionary(const HashMap<String, String>& initial_entries)
|
||||||
|
: m_entries(initial_entries)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool is_empty() const { return m_entries.is_empty(); }
|
bool is_empty() const { return m_entries.is_empty(); }
|
||||||
size_t size() const { return m_entries.size(); }
|
size_t size() const { return m_entries.size(); }
|
||||||
|
|
|
@ -68,7 +68,7 @@ OwnPtr<Messages::ClipboardServer::SetClipboardDataResponse> ClientConnection::ha
|
||||||
did_misbehave("SetClipboardData: Bad shared buffer ID");
|
did_misbehave("SetClipboardData: Bad shared buffer ID");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Storage::the().set_data(*shared_buffer, message.data_size(), message.mime_type());
|
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>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ OwnPtr<Messages::ClipboardServer::GetClipboardDataResponse> ClientConnection::ha
|
||||||
// After we respond to GetClipboardData, we have to wait for the client to ref the buffer on his side.
|
// 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);
|
m_last_sent_buffer = move(shared_buffer);
|
||||||
}
|
}
|
||||||
return make<Messages::ClipboardServer::GetClipboardDataResponse>(shbuf_id, storage.data_size(), storage.mime_type());
|
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()
|
||||||
|
|
|
@ -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)
|
GetClipboardData() => (i32 shbuf_id, i32 data_size, [UTF8] String mime_type, IPC::Dictionary metadata)
|
||||||
SetClipboardData(i32 shbuf_id, i32 data_size, [UTF8] String mime_type) => ()
|
SetClipboardData(i32 shbuf_id, i32 data_size, [UTF8] String mime_type, IPC::Dictionary metadata) => ()
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,12 +44,16 @@ Storage::~Storage()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Storage::set_data(NonnullRefPtr<SharedBuffer> data, size_t data_size, const String& mime_type)
|
void Storage::set_data(NonnullRefPtr<SharedBuffer> data, size_t data_size, const String& mime_type, const HashMap<String, String>& metadata)
|
||||||
{
|
{
|
||||||
dbg() << "Storage::set_data <- [" << mime_type << "] " << data->data() << " (" << data_size << " bytes)";
|
dbg() << "Storage::set_data <- [" << mime_type << "] " << data->data() << " (" << data_size << " bytes)";
|
||||||
|
for (auto& it : metadata) {
|
||||||
|
dbg() << " " << it.key << ": " << it.value;
|
||||||
|
}
|
||||||
m_shared_buffer = move(data);
|
m_shared_buffer = move(data);
|
||||||
m_data_size = data_size;
|
m_data_size = data_size;
|
||||||
m_mime_type = mime_type;
|
m_mime_type = mime_type;
|
||||||
|
m_metadata = metadata;
|
||||||
|
|
||||||
if (on_content_change)
|
if (on_content_change)
|
||||||
on_content_change();
|
on_content_change();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Function.h>
|
#include <AK/Function.h>
|
||||||
|
#include <AK/HashMap.h>
|
||||||
#include <AK/SharedBuffer.h>
|
#include <AK/SharedBuffer.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ public:
|
||||||
bool has_data() const { return m_shared_buffer; }
|
bool has_data() const { return m_shared_buffer; }
|
||||||
|
|
||||||
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 u8* data() const
|
const u8* data() const
|
||||||
{
|
{
|
||||||
|
@ -55,7 +57,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_data(NonnullRefPtr<SharedBuffer>, size_t data_size, const String& mime_type);
|
void set_data(NonnullRefPtr<SharedBuffer>, size_t data_size, const String& mime_type, const HashMap<String, String>& metadata);
|
||||||
|
|
||||||
Function<void()> on_content_change;
|
Function<void()> on_content_change;
|
||||||
|
|
||||||
|
@ -65,6 +67,7 @@ private:
|
||||||
String m_mime_type;
|
String m_mime_type;
|
||||||
RefPtr<SharedBuffer> m_shared_buffer;
|
RefPtr<SharedBuffer> m_shared_buffer;
|
||||||
size_t m_data_size { 0 };
|
size_t m_data_size { 0 };
|
||||||
|
HashMap<String, String> m_metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue