From 2fcfea1bf149f839cdbcba5c1efc7c4ce31f6d95 Mon Sep 17 00:00:00 2001 From: Christoph Lohmann <20h@r-36.net> Date: Sat, 14 Mar 2015 07:41:59 +0100 Subject: [PATCH] Add Mod + Shift + c/v and no selclear. Thanks to Alex Pilon ! Now there is a distinction between the primary and clipboard selection. With Mod + Shift + c/v the clipboard is handled. The old Insert behavious does reside. --- config.def.h | 2 ++ st.c | 69 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/config.def.h b/config.def.h index 8a8236c..56bae2d 100644 --- a/config.def.h +++ b/config.def.h @@ -119,6 +119,8 @@ static Shortcut shortcuts[] = { { MODKEY|ShiftMask, XK_Home, xzoomreset, {.i = 0} }, { ShiftMask, XK_Insert, selpaste, {.i = 0} }, { MODKEY|ShiftMask, XK_Insert, clippaste, {.i = 0} }, + { MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} }, + { MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} }, { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, }; diff --git a/st.c b/st.c index 39a6836..4b98b27 100644 --- a/st.c +++ b/st.c @@ -290,7 +290,7 @@ typedef struct { int x, y; } nb, ne, ob, oe; - char *clip; + char *primary, *clipboard; Atom xtarget; bool alt; struct timespec tclick1; @@ -312,6 +312,7 @@ typedef struct { } Shortcut; /* function definitions used in config.h */ +static void clipcopy(const Arg *); static void clippaste(const Arg *); static void numlock(const Arg *); static void selpaste(const Arg *); @@ -479,7 +480,11 @@ static void (*handler[LASTEvent])(XEvent *) = { [MotionNotify] = bmotion, [ButtonPress] = bpress, [ButtonRelease] = brelease, - [SelectionClear] = selclear, +/* + * Uncomment if you want the selection to disappear when you select something + * different in another window. + */ +/* [SelectionClear] = selclear, */ [SelectionNotify] = selnotify, [SelectionRequest] = selrequest, }; @@ -640,7 +645,8 @@ selinit(void) { memset(&sel.tclick2, 0, sizeof(sel.tclick2)); sel.mode = 0; sel.ob.x = -1; - sel.clip = NULL; + sel.primary = NULL; + sel.clipboard = NULL; sel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); if(sel.xtarget == None) sel.xtarget = XA_STRING; @@ -985,12 +991,15 @@ selnotify(XEvent *e) { int format; uchar *data, *last, *repl; Atom type; + XSelectionEvent *xsev; ofs = 0; + xsev = (XSelectionEvent *)e; do { - if(XGetWindowProperty(xw.dpy, xw.win, XA_PRIMARY, ofs, BUFSIZ/4, - False, AnyPropertyType, &type, &format, - &nitems, &rem, &data)) { + if(XGetWindowProperty(xw.dpy, xw.win, xsev->property, ofs, + BUFSIZ/4, False, AnyPropertyType, + &type, &format, &nitems, &rem, + &data)) { fprintf(stderr, "Clipboard allocation failed\n"); return; } @@ -1025,12 +1034,26 @@ selpaste(const Arg *dummy) { xw.win, CurrentTime); } +void +clipcopy(const Arg *dummy) { + Atom clipboard; + + if(sel.clipboard != NULL) + free(sel.clipboard); + + if(sel.primary != NULL) { + sel.clipboard = xstrdup(sel.primary); + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); + } +} + void clippaste(const Arg *dummy) { Atom clipboard; clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XConvertSelection(xw.dpy, clipboard, sel.xtarget, XA_PRIMARY, + XConvertSelection(xw.dpy, clipboard, sel.xtarget, clipboard, xw.win, CurrentTime); } @@ -1046,7 +1069,8 @@ void selrequest(XEvent *e) { XSelectionRequestEvent *xsre; XSelectionEvent xev; - Atom xa_targets, string; + Atom xa_targets, string, clipboard; + char *seltext; xsre = (XSelectionRequestEvent *) e; xev.type = SelectionNotify; @@ -1065,11 +1089,25 @@ selrequest(XEvent *e) { XA_ATOM, 32, PropModeReplace, (uchar *) &string, 1); xev.property = xsre->property; - } else if(xsre->target == sel.xtarget && sel.clip != NULL) { - XChangeProperty(xsre->display, xsre->requestor, xsre->property, - xsre->target, 8, PropModeReplace, - (uchar *) sel.clip, strlen(sel.clip)); - xev.property = xsre->property; + } else if(xsre->target == sel.xtarget) { + clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); + if(xsre->selection == XA_PRIMARY) { + seltext = sel.primary; + } else if(xsre->selection == clipboard) { + seltext = sel.clipboard; + } else { + fprintf(stderr, + "Unhandled clipboard selection 0x%lx\n", + xsre->selection); + return; + } + if(seltext != NULL) { + XChangeProperty(xsre->display, xsre->requestor, + xsre->property, xsre->target, + 8, PropModeReplace, + (uchar *)seltext, strlen(seltext)); + xev.property = xsre->property; + } } /* all done, send a notification to the listener */ @@ -1079,8 +1117,9 @@ selrequest(XEvent *e) { void xsetsel(char *str) { - free(sel.clip); - sel.clip = str; + free(sel.primary); + sel.primary = str; + XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, CurrentTime); }