Add Mod + Shift + c/v and no selclear. Thanks to Alex Pilon <alp@alexpilon.ca>! 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.
Christoph Lohmann 20h@r-36.net
2 files changed,
56 insertions(+),
15 deletions(-)
M
config.def.h
→
config.def.h
@@ -119,6 +119,8 @@ { MODKEY|ShiftMask, XK_Next, xzoom, {.i = -1} },
{ 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} }, };
M
st.c
→
st.c
@@ -290,7 +290,7 @@ struct {
int x, y; } nb, ne, ob, oe; - char *clip; + char *primary, *clipboard; Atom xtarget; bool alt; struct timespec tclick1;@@ -312,6 +312,7 @@ const Arg arg;
} 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 @@ [FocusOut] = focus,
[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 @@ memset(&sel.tclick1, 0, sizeof(sel.tclick1));
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 @@ ulong nitems, ofs, rem;
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; }@@ -1023,6 +1032,20 @@ void
selpaste(const Arg *dummy) { XConvertSelection(xw.dpy, XA_PRIMARY, sel.xtarget, XA_PRIMARY, 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@@ -1030,7 +1053,7 @@ 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 @@ XChangeProperty(xsre->display, xsre->requestor, xsre->property,
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 @@ }
void xsetsel(char *str) { - free(sel.clip); - sel.clip = str; + free(sel.primary); + sel.primary = str; + XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, CurrentTime); }