From 62154d8e7b95e25df85c084a048d729bb2752e2a Mon Sep 17 00:00:00 2001 From: Peter Hofmann Date: Sun, 16 Jun 2024 06:01:56 +0200 Subject: [PATCH] Clipboard: Make both selections available and fix inconsistencies Previously, C-y pasted the "primary" selection on X11 and the "clipboard" selection on Wayland. That's inconsistent and confusing, especially when you're switching back and forth between the two. This commit does two things: 1. It makes C-y always paste the "clipboard" selection. 2. It adds a key bind C-Y to paste the "primary" selection. I suspect that most bemenu users are on Wayland, so this commit tries to not break things for them. It does, however, change the behavior on X11. --- README.md | 2 +- lib/bemenu.h | 3 ++- lib/menu.c | 13 +++++++++++-- lib/renderers/wayland/wayland.c | 5 ++++- lib/renderers/x11/x11.c | 5 ++++- man/bemenu.1.scd.in | 4 ++-- 6 files changed, 24 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 19d1b16..21b1eb8 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ All dependencies below are searched with `pkg-config` | x11 | x11, xinerama, cairo, pango, pangocairo | | Wayland | wayland-client, wayland-protocols, cairo, pango, pangocairo, xkbcommon | -Currently, pasting from clipboard is done at runtime with `wl-paste -t text/plain` and `xclip -t text/plain -out`, attempted in that order. +Currently, pasting from clipboard is done at runtime with `wl-paste` and `xclip`, attempted in that order. ### Installing the dependencies diff --git a/lib/bemenu.h b/lib/bemenu.h index 3081649..740783a 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -256,7 +256,8 @@ enum bm_key { BM_KEY_LINE_DELETE_LEFT, BM_KEY_LINE_DELETE_RIGHT, BM_KEY_WORD_DELETE, - BM_KEY_PASTE, + BM_KEY_PASTE_PRIMARY, + BM_KEY_PASTE_CLIPBOARD, BM_KEY_TAB, BM_KEY_SHIFT_TAB, BM_KEY_ESCAPE, diff --git a/lib/menu.c b/lib/menu.c index 0c94ff0..5b2f87f 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -1150,9 +1150,18 @@ bm_menu_run_with_key(struct bm_menu *menu, enum bm_key key, uint32_t unicode) } break; - case BM_KEY_PASTE: + case BM_KEY_PASTE_PRIMARY: + case BM_KEY_PASTE_CLIPBOARD: { - char *paster[] = {"wl-paste -t text/plain", "xclip -t text/plain -out"}; + char *paster[2] = {NULL, NULL}; + if (key == BM_KEY_PASTE_PRIMARY) { + paster[0] = "wl-paste -t text/plain -p"; + paster[1] = "xclip -t text/plain -out"; + } else { + paster[0] = "wl-paste -t text/plain"; + paster[1] = "xclip -t text/plain -out -selection clipboard"; + } + for (size_t paster_i = 0; paster_i < sizeof paster / sizeof paster[0]; paster_i++) { FILE *clipboard = popen(paster[paster_i], "r"); if (clipboard == NULL) { diff --git a/lib/renderers/wayland/wayland.c b/lib/renderers/wayland/wayland.c index 2da88b9..d765ebc 100644 --- a/lib/renderers/wayland/wayland.c +++ b/lib/renderers/wayland/wayland.c @@ -203,7 +203,10 @@ poll_key(const struct bm_menu *menu, unsigned int *unicode) return (mods & MOD_CTRL ? BM_KEY_RETURN : BM_KEY_UNICODE); case XKB_KEY_y: - return (mods & MOD_CTRL ? BM_KEY_PASTE : BM_KEY_UNICODE); + return (mods & MOD_CTRL ? BM_KEY_PASTE_CLIPBOARD : BM_KEY_UNICODE); + + case XKB_KEY_Y: + return (mods & MOD_CTRL ? BM_KEY_PASTE_PRIMARY : BM_KEY_UNICODE); case XKB_KEY_1: if ((mods & MOD_ALT)) return BM_KEY_CUSTOM_1; diff --git a/lib/renderers/x11/x11.c b/lib/renderers/x11/x11.c index b25d82f..6a62693 100644 --- a/lib/renderers/x11/x11.c +++ b/lib/renderers/x11/x11.c @@ -150,7 +150,10 @@ poll_key(const struct bm_menu *menu, unsigned int *unicode) return (mods & MOD_CTRL ? BM_KEY_WORD_DELETE : BM_KEY_UNICODE); case XK_y: - return (mods & MOD_CTRL ? BM_KEY_PASTE : BM_KEY_UNICODE); + return (mods & MOD_CTRL ? BM_KEY_PASTE_CLIPBOARD : BM_KEY_UNICODE); + + case XK_Y: + return (mods & MOD_CTRL ? BM_KEY_PASTE_PRIMARY : BM_KEY_UNICODE); case XK_j: return (mods & MOD_ALT ? BM_KEY_DOWN : BM_KEY_UNICODE); diff --git a/man/bemenu.1.scd.in b/man/bemenu.1.scd.in index 6442677..e1e4256 100644 --- a/man/bemenu.1.scd.in +++ b/man/bemenu.1.scd.in @@ -298,8 +298,8 @@ In the following examples, *C-x* means **, *M-x* means ** and *C-w* Clear the filter. -*C-y* - Paste the clipboard. +*C-y, C-Y* + Paste selection (*C-y* for "clipboard", *C-Y* for "primary"). *M-[1-9]* Print selected items and exit with a custom error code 10 (*M-1*)