User selects any text and push ctrl+c. How to autorun command after this action?
I need solutions for:
- How to get notification/check about the state of the clipboard
- After notification/check will autorun command
I haven't idea.
User selects any text and push ctrl+c. How to autorun command after this action?
I need solutions for:
I haven't idea.
X11 clipboards can be monitored. This only applies to X11 and not console copy and paste nor tmux nor anything else. So portability might be dubious and you may need to monitor all three clipboards, depending on what your needs are.
// whenclipchange.c
// Run something when a X11 clipboard changes. Note that PRIMARY tends
// to be the traditional default, while certain software instead uses
// CLIPBOARD for I don't know what incompatible reason. There is also
// SECONDARY to make your life more interesting.
#define WHATCLIP "PRIMARY"
#include <sys/wait.h>
#include <assert.h>
#include <err.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xfixes.h>
void WatchSelection(Display *display, Window window, const char *bufname,
char *argv[]);
int
main(int argc, char *argv[])
{
#ifdef __OpenBSD__
if (pledge("exec inet proc rpath stdio unix", NULL) == -1)
err(1, "pledge failed");
#endif
if (argc < 2) err(1, "need a command to run");
argv++; // skip past command name of this program
Display *display = XOpenDisplay(NULL);
unsigned long color = BlackPixel(display, DefaultScreen(display));
Window window = XCreateSimpleWindow(display, DefaultRootWindow(display),
0, 0, 1, 1, 0, color, color);
WatchSelection(display, window, WHATCLIP, argv);
/* NOTREACHED */
XDestroyWindow(display, window);
XCloseDisplay(display);
exit(EXIT_FAILURE);
}
void
WatchSelection(Display *display, Window window, const char *bufname,
char *argv[])
{
int event_base, error_base;
XEvent event;
Atom bufid = XInternAtom(display, bufname, False);
assert(XFixesQueryExtension(display, &event_base, &error_base));
XFixesSelectSelectionInput(display, DefaultRootWindow(display), bufid,
XFixesSetSelectionOwnerNotifyMask);
while (1) {
XNextEvent(display, &event);
if (event.type == event_base + XFixesSelectionNotify &&
((XFixesSelectionNotifyEvent *) &event)->selection ==
bufid) {
pid_t pid = fork();
if (pid < 0) err(1, "fork failed");
if (pid) {
// NOTE this will block until the
// command finishes... so it might miss
// clipboard events?
int status;
wait(&status);
} else {
execvp(*argv, argv);
exit(EXIT_FAILURE);
}
}
}
}
Compile and run with something like...
$ cc -std=c99 -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXft -lXfixes -o whenclipchange whenclipchange.c
$ ./whenclipchange echo clipboard changed