patch 9.1.1927: Wayland: clipboard code too complex
Commit:
https://github.com/vim/vim/commit/efa3b1f86d0985a5a1c5b87981c2b7dcaca0815e
Author: Foxe Chen <[email protected]>
Date: Tue Nov 25 22:04:58 2025 +0000
patch 9.1.1927: Wayland: clipboard code too complex
Problem: Wayland: clipboard code too complex
Solution: Simplify clipboard related code around W23/W24
(Foxe Chen).
Improve Wayland and clipboard related code:
- improve documentation
- remove unused code
- fix error handling
- remove warning per Clipboard_T
closes: #18794
Signed-off-by: Foxe Chen <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index f8c9843e4..c67a801ad 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2025 Nov 23
+*options.txt* For Vim version 9.1. Last change: 2025 Nov 25
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1843,9 +1843,9 @@ A jump table for the options with a short description can
be found at |Q_op|.
option, yank operations (but not delete, change or
put) will additionally copy the text into register
'*'. If Wayland is being used and the compositor does
- not support the primary-selection-unstable-v1
- protocol, then the regular selection is used in its
- place. Only available with the |+X11| or
+ not support the primary selection then the regular
+ selection is used in its place. Only available with
+ the |+X11| or
|+wayland_clipboard| feature. Availability can be
checked with: >
if has('unnamedplus')
diff --git a/runtime/doc/wayland.txt b/runtime/doc/wayland.txt
index 7f1b4894e..b01f031e7 100644
--- a/runtime/doc/wayland.txt
+++ b/runtime/doc/wayland.txt
@@ -1,4 +1,4 @@
-*wayland.txt* For Vim version 9.1. Last change: 2025 Nov 09
+*wayland.txt* For Vim version 9.1. Last change: 2025 Nov 25
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -16,7 +16,8 @@ Wayland Protocol Support
*wayland*
Functionality such as the clipboard for Wayland requires a seat to use. A
Wayland seat can consist of a keyboard, pointer, and touch device(s). The
seat to use can be set with the 'wlseat' option. Only useful if you use
-multiple Wayland seats in the same Wayland session.
+multiple Wayland seats in the same Wayland session. If you don't know what
+this is means, then it likely does not matter for you.
*wayland-gui*
See |gui-wayland|. Please note that when using the GUI, Vim uses the toolkit
@@ -63,11 +64,18 @@ should be bundled with libwayland on your system: >
If you don't get any match, then please see |wayland-focus-steal| for more
information.
+Some compositors that are known to support either or both protocols:
+ 1. KWin (KDE)
+ 2. wlroots based (Sway, Labwc)
+ 3. Niri
+ 4. Hyprland
+ 5. Wayfire
+
If you come from X11, then the regular Wayland selection is equivalent to the
CLIPBOARD selection in X11, and the primary Wayland selection equates to the
-X11 primary selection. Accessing these selections is the same as X11 in Vim,
+X11 PRIMARY selection. Accessing these selections is the same as X11 in Vim,
in which the + register is the regular selection, and the * register is the
-primary selection, note that your compositor may not support primary
+primary selection. Note that your compositor may not support primary
selections, see |wayland-primary-selection| for more details.
*wayland-persist*
diff --git a/src/clipboard.c b/src/clipboard.c
index 13fcae606..af3fee308 100644
--- a/src/clipboard.c
+++ b/src/clipboard.c
@@ -100,10 +100,6 @@ typedef struct {
clip_wl_selection_T regular;
clip_wl_selection_T primary;
-
- // Array of file descriptors of clients we are sending data to. These
should
- // be polled for POLLOUT and have the respective callback called for each.
- garray_T write_fds;
} clip_wl_T;
// Mime types we support sending and receiving
@@ -172,22 +168,6 @@ skip:
}
}
- static void
-clip_init_single(Clipboard_T *cb, int can_use)
-{
- // No need to init again if cbd is already available
- if (can_use && cb->available)
- return;
-
- cb->available = can_use;
- cb->owned = FALSE;
- cb->start.lnum = 0;
- cb->start.col = 0;
- cb->end.lnum = 0;
- cb->end.col = 0;
- cb->state = SELECT_CLEARED;
-}
-
/*
* Check whether the VIsual area has changed, and if so try to become the owner
* of the selection, and free any old converted selection we may still have
@@ -2428,7 +2408,7 @@ adjust_clip_reg(int *rp)
if ((!clip_star.available && *rp == '*') ||
(!clip_plus.available && *rp == '+'))
{
- msg_warn_missing_clipboard(!clip_plus.available, !clip_star.available);
+ msg_warn_missing_clipboard();
*rp = 0;
}
}
@@ -2874,6 +2854,8 @@ clip_init_wayland(void)
if (wayland_ct == NULL)
return FAIL;
+ memset(&clip_wl, 0, sizeof(clip_wl));
+
clip_wl.seat = vwl_connection_get_seat(wayland_ct, (char *)p_wse);
if (clip_wl.seat == NULL)
@@ -2891,12 +2873,14 @@ clip_init_wayland(void)
clip_wl.regular.available = true;
else
{
+ // Shouldn't happen
vwl_data_device_manager_discard(clip_wl.regular.manager);
clip_wl.regular.manager = NULL;
+ return FAIL;
}
}
- // If we still don't support the primary selection, find one for it
+ // If we still don't support the primary selection, try finding one for it
// specifically.
if (!(supported & WAYLAND_SELECTION_PRIMARY))
{
@@ -2917,10 +2901,12 @@ clip_init_wayland(void)
}
}
}
- else if (clip_wl.regular.available)
+
+ if (clip_wl.regular.available && !clip_wl.primary.available)
{
// The protocol supports both regular and primary selections, just use
- // one data device manager and one data device.
+ // one data device manager and one data device. Or the primary selection
+ // is not supported, make it point to the regular selection instead.
clip_wl.primary.available = true;
clip_wl.primary.manager = clip_wl.regular.manager;
clip_wl.primary.device = clip_wl.regular.device;
@@ -3435,7 +3421,7 @@ clip_wl_owner_exists(Clipboard_T *cbd)
* depending on the order of values in str.
*/
static clipmethod_T
-get_clipmethod(char_u *str, bool *plus UNUSED, bool *star UNUSED)
+get_clipmethod(char_u *str)
{
int len = (int)STRLEN(str) + 1;
char_u *buf = alloc(len);
@@ -3460,11 +3446,7 @@ get_clipmethod(char_u *str, bool *plus UNUSED, bool
*star UNUSED)
{
#ifdef FEAT_WAYLAND_CLIPBOARD
if (clip_wl.regular.available || clip_wl.primary.available)
- {
method = CLIPMETHOD_WAYLAND;
- *plus = clip_wl.regular.available;
- *star = clip_wl.primary.available;
- }
#endif
}
}
@@ -3485,7 +3467,6 @@ get_clipmethod(char_u *str, bool *plus UNUSED, bool *star
UNUSED)
// xterm_dpy will be set to NULL.
xterm_update();
method = CLIPMETHOD_X11;
- *plus = *star = TRUE;
}
#endif
}
@@ -3534,8 +3515,7 @@ clipmethod_to_str(clipmethod_T method)
char *
choose_clipmethod(void)
{
- bool regular = false, primary = false;
- clipmethod_T method = get_clipmethod(p_cpm, ®ular, &primary);
+ clipmethod_T method = get_clipmethod(p_cpm);
if (method == CLIPMETHOD_FAIL)
return e_invalid_argument;
@@ -3569,10 +3549,8 @@ choose_clipmethod(void)
// If we have a clipmethod that works now, then initialize clipboard
else if (clipmethod == CLIPMETHOD_NONE && method != CLIPMETHOD_NONE)
{
- clip_init_single(&clip_plus, regular);
- clip_init_single(&clip_star, primary);
- clip_plus.did_warn = false;
- clip_star.did_warn = false;
+ clip_init(TRUE);
+ did_warn_clipboard = false;
}
// Disown clipboard if we are switching to a new method
else if (clipmethod != CLIPMETHOD_NONE && method != clipmethod)
@@ -3590,8 +3568,8 @@ lose_sel_exit:
if (!gui.in_use)
#endif
{
- clip_init_single(&clip_plus, regular);
- clip_init_single(&clip_star, primary);
+ clip_init(TRUE);
+ did_warn_clipboard = false;
}
}
diff --git a/src/globals.h b/src/globals.h
index bd2b5f91a..7e72ea744 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -2067,6 +2067,9 @@ EXTERN char_u showcmd_buf[SHOWCMD_BUFLEN];
EXTERN int p_tgc_set INIT(= FALSE);
#endif
+// If we've already warned about missing/unavailable clipboard
+EXTERN bool did_warn_clipboard INIT(= FALSE);
+
#ifdef FEAT_CLIPBOARD
EXTERN clipmethod_T clipmethod INIT(= CLIPMETHOD_NONE);
#endif
@@ -2079,6 +2082,9 @@ EXTERN char *wayland_display_name INIT(= NULL);
// Special mime type used to identify selection events that came from us
setting
// the selection. Is in format of "application/x-vim-instance-<pid>" where
<pid>
// is the PID of the Vim process. Set in main.c
+//
+// This is more reliable than just checking if our data source is non-NULL, as
+// that may be subject to data races in the Wayland protocol.
EXTERN char wayland_vim_special_mime[
sizeof("application/x-vim-instance-") + NUMBUFLEN - 1]; // Includes NUL
diff --git a/src/message.c b/src/message.c
index a6dd888b9..88af7bc1d 100644
--- a/src/message.c
+++ b/src/message.c
@@ -4177,37 +4177,17 @@ msg_advance(int col)
* Warn about missing Clipboard Support
*/
void
-msg_warn_missing_clipboard(bool plus UNUSED, bool star UNUSED)
+msg_warn_missing_clipboard(void)
{
-#ifndef FEAT_CLIPBOARD
- static bool did_warn;
-
- if (!global_busy && !did_warn)
+ if (!global_busy && !did_warn_clipboard)
{
- msg(_("W24: Clipboard register not available. See :h W24"));
- did_warn = true;
- }
+#ifdef FEAT_CLIPBOARD
+ msg(_("W23: Clipboard register not available, using register 0"));
#else
- if (!global_busy)
- {
- if (plus && star && !clip_plus.did_warn && !clip_star.did_warn)
- {
- msg(_("W23: Clipboard register not available, using register 0"));
- clip_plus.did_warn = true;
- clip_star.did_warn = true;
- }
- else if (plus && !clip_plus.did_warn)
- {
- msg(_("W23: Clipboard register + not available, using register 0"));
- clip_plus.did_warn = true;
- }
- else if (star && !clip_star.did_warn)
- {
- msg(_("W23: Clipboard register * not available, using register 0"));
- clip_star.did_warn = true;
- }
- }
+ msg(_("W24: Clipboard register not available. See :h W24"));
#endif
+ did_warn_clipboard = TRUE;
+ }
}
#if defined(FEAT_CON_DIALOG)
diff --git a/src/po/vim.pot b/src/po/vim.pot
index ddac4a363..9289cc6b7 100644
--- a/src/po/vim.pot
+++ b/src/po/vim.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim
"
"Report-Msgid-Bugs-To: [email protected]
"
-"POT-Creation-Date: 2025-11-01 16:14+0000
"
+"POT-Creation-Date: 2025-11-25 22:02+0000
"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
"Language-Team: LANGUAGE <[email protected]>
"
@@ -2220,16 +2220,10 @@ msgstr ""
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr ""
-msgid "W24: Clipboard register not available. See :h W24"
-msgstr ""
-
msgid "W23: Clipboard register not available, using register 0"
msgstr ""
-msgid "W23: Clipboard register + not available, using register 0"
-msgstr ""
-
-msgid "W23: Clipboard register * not available, using register 0"
+msgid "W24: Clipboard register not available. See :h W24"
msgstr ""
msgid "Question"
@@ -9957,6 +9951,9 @@ msgstr ""
msgid "definition of what comment lines look like"
msgstr ""
+msgid "template for comments; used to put the marker in"
+msgstr ""
+
msgid "list of flags that tell how automatic formatting works"
msgstr ""
@@ -10155,9 +10152,6 @@ msgstr ""
msgid "minimum number of screen lines for a fold to be closed"
msgstr ""
-msgid "template for comments; used to put the marker in"
-msgstr ""
-
msgid ""
"folding type: \"manual\", \"indent\", \"expr\", \"marker\",
"
"\"syntax\" or \"diff\""
diff --git a/src/proto/message.pro b/src/proto/message.pro
index 5b6c80b4d..34b381866 100644
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -74,7 +74,7 @@ void give_warning(char_u *message, int hl);
void give_warning_with_source(char_u *message, int hl, int with_source);
void give_warning2(char_u *message, char_u *a1, int hl);
void msg_advance(int col);
-void msg_warn_missing_clipboard(bool plus, bool star);
+void msg_warn_missing_clipboard(void);
int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int
dfltbutton, char_u *textfield, int ex_cmd);
int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt);
int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt);
diff --git a/src/register.c b/src/register.c
index 1b3f60ec5..524ada4ca 100644
--- a/src/register.c
+++ b/src/register.c
@@ -204,7 +204,7 @@ valid_yank_reg(
else if (regname == '*' || regname == '+')
{
// Warn about missing clipboard support once
- msg_warn_missing_clipboard(true, true);
+ msg_warn_missing_clipboard();
return FALSE;
}
#endif
@@ -1189,7 +1189,7 @@ op_yank(oparg_T *oap, int deleting, int mess)
(!clip_plus.available && oap->regname == '+'))
{
oap->regname = 0;
- msg_warn_missing_clipboard(!clip_plus.available, !clip_star.available);
+ msg_warn_missing_clipboard();
}
#endif
diff --git a/src/version.c b/src/version.c
index b34018b85..1c0186ccb 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1927,
/**/
1926,
/**/
diff --git a/src/vim.h b/src/vim.h
index 2b37da2af..bc1a1d47f 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2364,8 +2364,6 @@ typedef struct
# ifdef FEAT_GUI_HAIKU
// No clipboard at the moment. TODO?
# endif
- // If we've already warned about missing/unavailable clipboard
- bool did_warn;
} Clipboard_T;
#else
typedef int Clipboard_T; // This is required for the prototypes.
diff --git a/src/wayland.c b/src/wayland.c
index 36ccf6668..bd2cdefea 100644
--- a/src/wayland.c
+++ b/src/wayland.c
@@ -849,8 +849,6 @@ ex_wlrestore(exarg_T *eap)
smsg(_("restoring Wayland display %s"), wayland_display_name);
#ifdef FEAT_WAYLAND_CLIPBOARD
- clip_plus.did_warn = false;
- clip_star.did_warn = false;
clip_init_wayland();
#endif
}
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1vOdwj-004uLn-9O%40256bit.org.