X11: Optionally copy selection buffer to clipboard (STR 3229)

The new method Fl::selection_to_clipboard(int) enables copying
selection data to the clipboard on X11 if it is set to 1.

This feature was requested by STR 3229 and the implementation was
inspired by an `xterm` feature named "Select to Clipboard" which can
be enabled by 'ctrl + middle mouse button + "Select to Clipboard"'
in an xterm window.
This commit is contained in:
Albrecht Schlosser 2023-01-03 19:40:37 +01:00
parent 69773338b9
commit 8dd3ff8e12
3 changed files with 94 additions and 7 deletions

84
FL/Fl.H
View File

@ -1,7 +1,7 @@
//
// Main header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2022 by Bill Spitzak and others.
// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -144,6 +144,7 @@ private:
static int draw_GL_text_with_textures_;
static int box_shadow_width_;
static int box_border_radius_max_;
static int selection_to_clipboard_;
public:
@ -871,7 +872,86 @@ public:
To copy graphical data, use the Fl_Copy_Surface class. The \p type argument may allow
in the future to copy other kinds of data.
*/
static void copy(const char* stuff, int len, int destination = 0, const char *type = Fl::clipboard_plain_text); // platform dependent
/**
Copies data to the selection buffer, the clipboard, or both.
The \p destination can be:
- 0: selection buffer (see note below)
- 1: clipboard
- 2: both
The selection buffer exists only on the X11 platform and is used for middle-mouse
pastes and for drag-and-drop selections. The clipboard is used for traditional
copy/cut/paste operations. On all other platforms the selection buffer
(\p destination = 0) is mapped to the clipboard, i.e. on platforms other than X11
all \p destinations are equivalent and the data is always copied to the clipboard.
\note Please see Fl::section_to_clipboard() to enable duplication of the
selection buffer to the clipboard on X11, i.e. if \p destination = 0
(selection buffer) \b and Fl::selection_to_clipboard() is enabled, then
the data is copied to both the selection buffer and the clipboard.
This makes the X11 behavior similar to other platforms but keeps the
selection buffer for X11 specific inter process communication.
\p type should always be \p Fl::clipboard_plain_text which is the default.
Other values are ignored and reserved for future extensions.
\note This function is, at present, intended only to copy UTF-8 encoded
textual data. To copy graphical data, use the Fl_Copy_Surface class.
The \p type argument may allow to copy other kinds of data in the future.
\param[in] stuff text data to be copied
\param[in] len the number of relevant bytes in \p stuff
\param[in] destination 0 = selection, 1 = clipboard, 2 = both (see description)
\param[in] type usually plain text (see description)
\internal
Documented here because it is platform dependent (calls the platform driver):
\code
Fl::screen_driver()->copy(stuff, len, clipboard, type);
\endcode
*/
static void copy(const char *stuff, int len, int destination = 0,
const char *type = Fl::clipboard_plain_text);
/**
Copies selections on X11 directly to the clipboard if enabled.
This method can be called on all platforms. Other platforms than X11 are
not affected by this feature.
If this is switched on (\p mode = 1), Fl::copy() copies all data to the
clipboard regardless of its \p destination argument. If the destination is 0
(selection buffer) data is copied to both the selection buffer and the clipboard.
Drag and drop is also affected since drag-and-drop data is copied to the selection
buffer.
You can use this to make the experience of data selection and copying more like
that on other platforms (Windows, macOS, and even Wayland).
The default operation mode is the standard X11 behavior (disabled).
\note This feature is experimental and enabling it may have unexpected side effects.
It is your own responsibility if you enable it.
\since 1.4.0
\param[in] mode 1 = enable selection_to_clipboard, 0 = disable selection_to_clipboard
\see copy(const char *, int, int, const char *)
*/
static void selection_to_clipboard(int mode) {
selection_to_clipboard_ = mode ? 1 : 0;
}
/**
\brief Returns the current selection_to_clipboard mode.
\see void selection_to_clipboard(int)
*/
static int selection_to_clipboard() { return selection_to_clipboard_; }
/**
Pastes the data from the selection buffer (\p source is 0) or the clipboard

View File

@ -1,7 +1,7 @@
//
// Main event handling code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2022 by Bill Spitzak and others.
// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -74,6 +74,7 @@ Fl_Callback_Reason Fl::callback_reason_ = FL_REASON_UNKNOWN;
unsigned char Fl::options_[] = { 0, 0 };
unsigned char Fl::options_read_ = 0;
int Fl::selection_to_clipboard_ = 0;
Fl_Window *fl_xfocus = NULL; // which window X thinks has focus
Fl_Window *fl_xmousewin; // which window X thinks has FL_ENTER

View File

@ -1,7 +1,7 @@
//
// X specific code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2022 by Bill Spitzak and others.
// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -807,13 +807,19 @@ static int get_xwinprop(Window wnd, Atom prop, long max_length,
////////////////////////////////////////////////////////////////
// Code for copying to clipboard and DnD out of the program:
// See Fl::copy() for possible values of the destination (argument clipboard)
// See also Fl::selection_to_clipboard()
void Fl_X11_Screen_Driver::copy(const char *stuff, int len, int clipboard, const char *type) {
if (!stuff || len<0) return;
// if selection_to_clipboard is enabled *and* destination is 0 (selection buffer),
// then copy to both (STR 3229)
if (clipboard == 0 && Fl::selection_to_clipboard())
clipboard = 2;
if (clipboard >= 2) {
copy(stuff, len, 0, type);
copy(stuff, len, 1, type);
return;
copy(stuff, len, 1, type); // copy to clipboard first (this is a recursion!)
clipboard = 0; // ... and then to selection buffer: fall through
}
if (len+1 > fl_selection_buffer_length[clipboard]) {