Initial import
authorAntonio Ospite <ao2@ao2.it>
Mon, 19 Jun 2017 12:03:41 +0000 (14:03 +0200)
committerAntonio Ospite <ao2@ao2.it>
Mon, 19 Jun 2017 12:03:41 +0000 (14:03 +0200)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
README.txt [new file with mode: 0644]
dump_selections.sh [new file with mode: 0755]
xowner.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..07f01a6
--- /dev/null
@@ -0,0 +1 @@
+xowner
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
index 0000000..9dad622
--- /dev/null
@@ -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 (executable)
index 0000000..1f9da7b
--- /dev/null
@@ -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 (file)
index 0000000..5cbfefd
--- /dev/null
+++ b/xowner.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <X11/Xlib.h>
+
+int main(int argc, char *argv[])
+{
+       Display *dpy;
+       Window owner;
+       Atom sel;
+
+       if (argc < 2) {
+               fprintf(stderr, "usage: xowner <selection>\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;
+}