From 8dd3ff8e12a7cabce9a1931831b311bf898aaaaf Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Tue, 3 Jan 2023 19:40:37 +0100 Subject: 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. --- FL/Fl.H | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/Fl.cxx | 3 ++- src/Fl_x.cxx | 14 +++++++--- 3 files changed, 94 insertions(+), 7 deletions(-) diff --git a/FL/Fl.H b/FL/Fl.H index 589d52109..611639753 100644 --- a/FL/Fl.H +++ b/FL/Fl.H @@ -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 diff --git a/src/Fl.cxx b/src/Fl.cxx index 53fb7fff1..fa0620fa6 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -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 diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index 2c2720033..14aacaa7b 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -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]) { -- cgit v1.2.3