tAdd Mod + Shift + c/v and no selclear. - st - [fork] customized build of st, t… | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 2fcfea1bf149f839cdbcba5c1efc7c4ce31f6d95 | |
parent b746816b78447b9e4a3af7333a4e992eb8d32254 | |
Author: Christoph Lohmann <[email protected]> | |
Date: Sat, 14 Mar 2015 07:41:59 +0100 | |
Add Mod + Shift + c/v and no selclear. | |
Thanks to Alex Pilon <[email protected]>! | |
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. | |
Diffstat: | |
M config.def.h | 2 ++ | |
M st.c | 69 ++++++++++++++++++++++++-----… | |
2 files changed, 56 insertions(+), 15 deletions(-) | |
--- | |
diff --git a/config.def.h b/config.def.h | |
t@@ -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 | |
t@@ -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; | |
t@@ -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 *); | |
t@@ -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, | |
}; | |
t@@ -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; | |
t@@ -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/… | |
- 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; | |
} | |
t@@ -1026,11 +1035,25 @@ selpaste(const Arg *dummy) { | |
} | |
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); | |
} | |
t@@ -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; | |
t@@ -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 */ | |
t@@ -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); | |
} | |