1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-22 15:06:45 +00:00

Added primary clipboard for Linux

This commit is contained in:
ConteZero
2021-10-12 09:43:50 +02:00
parent 0fd50ff217
commit 838c9d37b4
12 changed files with 192 additions and 6 deletions

View File

@@ -406,6 +406,20 @@ void DisplayServerX11::clipboard_set(const String &p_text) {
XSetSelectionOwner(x11_display, XInternAtom(x11_display, "CLIPBOARD", 0), windows[MAIN_WINDOW_ID].x11_window, CurrentTime);
}
void DisplayServerX11::clipboard_set_primary(const String &p_text) {
_THREAD_SAFE_METHOD_
if (!p_text.is_empty()) {
{
// The clipboard content can be accessed while polling for events.
MutexLock mutex_lock(events_mutex);
internal_clipboard_primary = p_text;
}
XSetSelectionOwner(x11_display, XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window, CurrentTime);
XSetSelectionOwner(x11_display, XInternAtom(x11_display, "PRIMARY", 0), windows[MAIN_WINDOW_ID].x11_window, CurrentTime);
}
}
Bool DisplayServerX11::_predicate_clipboard_selection(Display *display, XEvent *event, XPointer arg) {
if (event->type == SelectionNotify && event->xselection.requestor == *(Window *)arg) {
return True;
@@ -427,7 +441,12 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
Window selection_owner = XGetSelectionOwner(x11_display, p_source);
if (selection_owner == x11_window) {
return internal_clipboard;
static const char *target_type = "PRIMARY";
if (p_source != None && String(XGetAtomName(x11_display, p_source)) == target_type) {
return internal_clipboard_primary;
} else {
return internal_clipboard;
}
}
if (selection_owner != None) {
@@ -580,6 +599,19 @@ String DisplayServerX11::clipboard_get() const {
return ret;
}
String DisplayServerX11::clipboard_get_primary() const {
_THREAD_SAFE_METHOD_
String ret;
ret = _clipboard_get(XInternAtom(x11_display, "PRIMARY", 0), windows[MAIN_WINDOW_ID].x11_window);
if (ret.is_empty()) {
ret = _clipboard_get(XA_PRIMARY, windows[MAIN_WINDOW_ID].x11_window);
}
return ret;
}
Bool DisplayServerX11::_predicate_clipboard_save_targets(Display *display, XEvent *event, XPointer arg) {
if (event->xany.window == *(Window *)arg) {
return (event->type == SelectionRequest) ||
@@ -2417,7 +2449,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
Input::get_singleton()->parse_input_event(k);
}
Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const {
Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const {
if (p_target == XInternAtom(x11_display, "TARGETS", 0)) {
// Request to list all supported targets.
Atom data[9];
@@ -2459,7 +2491,13 @@ Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p
p_target == XInternAtom(x11_display, "text/plain", 0)) {
// Directly using internal clipboard because we know our window
// is the owner during a selection request.
CharString clip = internal_clipboard.utf8();
CharString clip;
static const char *target_type = "PRIMARY";
if (p_selection != None && String(XGetAtomName(x11_display, p_selection)) == target_type) {
clip = internal_clipboard_primary.utf8();
} else {
clip = internal_clipboard.utf8();
}
XChangeProperty(x11_display,
p_requestor,
p_property,
@@ -2497,7 +2535,7 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p
for (uint64_t i = 0; i < len; i += 2) {
Atom target = targets[i];
Atom &property = targets[i + 1];
property = _process_selection_request_target(target, p_event->requestor, property);
property = _process_selection_request_target(target, p_event->requestor, property, p_event->selection);
}
XChangeProperty(x11_display,
@@ -2515,7 +2553,7 @@ void DisplayServerX11::_handle_selection_request_event(XSelectionRequestEvent *p
}
} else {
// Request for target conversion.
respond.xselection.property = _process_selection_request_target(p_event->target, p_event->requestor, p_event->property);
respond.xselection.property = _process_selection_request_target(p_event->target, p_event->requestor, p_event->property, p_event->selection);
}
respond.xselection.type = SelectionNotify;