From 543ca83524a7e7aa3c7d87227c2ac8dbff2033ff Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 19 Jun 2017 14:03:41 +0200 Subject: [PATCH 1/1] Initial import --- .gitignore | 1 + Makefile | 41 +++++++++++++++++++++++++++++++++++++++++ README.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ dump_selections.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ xowner.c | 27 +++++++++++++++++++++++++++ 5 files changed, 155 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.txt create mode 100755 dump_selections.sh create mode 100644 xowner.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07f01a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +xowner diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d6ea625 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +CFLAGS ?= -std=c99 -pedantic -pedantic-errors -Wall -g3 -O2 -D_ANSI_SOURCE_ +CFLAGS += -fno-common \ + -Wall \ + -Wdeclaration-after-statement \ + -Wextra \ + -Wformat=2 \ + -Winit-self \ + -Winline \ + -Wpacked \ + -Wp,-D_FORTIFY_SOURCE=2 \ + -Wpointer-arith \ + -Wlarger-than-65500 \ + -Wmissing-declarations \ + -Wmissing-format-attribute \ + -Wmissing-noreturn \ + -Wmissing-prototypes \ + -Wnested-externs \ + -Wold-style-definition \ + -Wredundant-decls \ + -Wsign-compare \ + -Wstrict-aliasing=2 \ + -Wstrict-prototypes \ + -Wundef \ + -Wunreachable-code \ + -Wunused-variable \ + -Wwrite-strings + +ifneq ($(CC),clang) + CFLAGS += -Wunsafe-loop-optimizations +endif + +EXECUTABLE := xowner +LDLIBS := -lX11 + +$(EXECUTABLE): + +clean: + rm -f *~ *.o $(EXECUTABLE) + +test: $(EXECUTABLE) + valgrind --leak-check=full --show-reachable=yes ./$(EXECUTABLE) PRIMARY diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..9dad622 --- /dev/null +++ b/README.txt @@ -0,0 +1,42 @@ +Some simple tools to analyze X selection buffers to understand what is going +on when text is selected with the mouse in X11. + + +BACK STORY +========== + +When vim is compiled with the +clipboad and +xterm_clipboard functionalities, +and setmouse=a is set, using vim in combination with xterm allows this +workflow: + + 1. Select something with the mouse; + 2. exit vim; + 3. paste the previously selected text with the middle mouse click. + +Moving from xterm to gnome-terminal this workflow is not possible by default. + +It turns out this is not a missing feature of vte or gtk, but rather some +extra functionality offered only by the combination of vim and xterm. + +Vim copies to the CUT_BUFFER0 selection when it exits and xterm is able to +paste from CUT_BUFFER0 when it receives a middle click. + +To make the workflow from above possible again it is possible to have vim +preserve the PRIMARY selection when it exits with a command like the following +in ~/.vimrc: + + autocmd VimLeave * call system("xsel -ip", getreg('*')) + +All the details of how the issue have been debugged can be found at +https://bugzilla.gnome.org/show_bug.cgi?id=783828 + + +REFERENCES +========== + +https://www.jwz.org/doc/x-cut-and-paste.html +https://www.uninformativ.de/blog/postings/2017-04-02/0/POSTING-en.html +https://stackoverflow.com/questions/6453595/prevent-vim-from-clearing-the-clipboard-on-exit +https://vi.stackexchange.com/questions/3769/can-vim-add-to-the-x11-clipboard-or-primary-buffers-without-an-external-utility#comment5354_3769 +https://groups.google.com/forum/#!topic/vim_dev/nlyA7AN9mfQ +https://groups.google.com/forum/#!topic/vim_use/NtprNch2ZkQ diff --git a/dump_selections.sh b/dump_selections.sh new file mode 100755 index 0000000..1f9da7b --- /dev/null +++ b/dump_selections.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +[ -x ./xowner ] || make + +get_owner() { + echo -n "$1" + OWNER=$(./xowner $1) + if [ $OWNER != "0x0" ]; + then + xwininfo -id $OWNER > /dev/null 2>&1; + if [ $? -eq 0 ]; + then + OWNER_NAME=$(xprop -id $OWNER WM_NAME | cut -d ' ' -f 3-) + if [ -z "$OWNER_NAME" ]; + then + OWNER_NAME="$OWNER" + fi + echo -n " owned by $OWNER_NAME" + fi + fi + + echo ":" +} + + +get_owner "PRIMARY" +xclip -out -selection primary 2> /dev/null +echo +echo + +get_owner "SECONDARY" +xclip -out -selection secondary 2> /dev/null +echo +echo + +get_owner "CLIPBOARD" +xclip -out -selection clipboard 2> /dev/null +echo +echo + +get_owner "CUT_BUFFER0" +xcb -p 0 +echo +echo diff --git a/xowner.c b/xowner.c new file mode 100644 index 0000000..5cbfefd --- /dev/null +++ b/xowner.c @@ -0,0 +1,27 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + Display *dpy; + Window owner; + Atom sel; + + if (argc < 2) { + fprintf(stderr, "usage: xowner \n"); + return 1; + } + + dpy = XOpenDisplay(NULL); + if (!dpy) { + fprintf(stderr, "Could not open X display\n"); + return 1; + } + + sel = XInternAtom(dpy, argv[1], False); + owner = XGetSelectionOwner(dpy, sel); + printf("0x%lX\n", owner); + + XCloseDisplay(dpy); + return 0; +} -- 2.1.4