aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorMarkus Wichmann <nullplan@gmx.net>2015-04-11 21:21:34 +0200
committerRoberto E. Vargas Caballero <k0ga@shike2.com>2015-04-13 22:18:45 +0200
commit42fa1f5ce46593a9d6c2f9196c1aae1a60ca07d1 (patch)
treee8a24252d06e235076593d3abe4b2398364e7ea5 /st.c
parent23ed12857f113603b689521d3f6e40ff954d25bb (diff)
downloadst-42fa1f5ce46593a9d6c2f9196c1aae1a60ca07d1.tar.gz
st-42fa1f5ce46593a9d6c2f9196c1aae1a60ca07d1.zip
Implement most ICCCM rules for selection handling.
ICCCM mandates the use of real timestamps to interact with the selection, to rule out race conditions if the clients are run at different speeds. I have implemented the low hanging fruit, putting the timestamps into text selection. Also, ICCCM mandates a check for whether XSetSelectionOwner() worked. Not sure my version is correct, though.
Diffstat (limited to 'st.c')
-rw-r--r--st.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/st.c b/st.c
index f874127..6bfa834 100644
--- a/st.c
+++ b/st.c
@@ -423,7 +423,7 @@ static void xsettitle(char *);
423static void xresettitle(void); 423static void xresettitle(void);
424static void xsetpointermotion(int); 424static void xsetpointermotion(int);
425static void xseturgency(int); 425static void xseturgency(int);
426static void xsetsel(char *); 426static void xsetsel(char *, Time);
427static void xtermclear(int, int, int, int); 427static void xtermclear(int, int, int, int);
428static void xunloadfont(Font *); 428static void xunloadfont(Font *);
429static void xunloadfonts(void); 429static void xunloadfonts(void);
@@ -449,7 +449,7 @@ static void selinit(void);
449static void selnormalize(void); 449static void selnormalize(void);
450static inline bool selected(int, int); 450static inline bool selected(int, int);
451static char *getsel(void); 451static char *getsel(void);
452static void selcopy(void); 452static void selcopy(Time);
453static void selscroll(int, int); 453static void selscroll(int, int);
454static void selsnap(int, int *, int *, int); 454static void selsnap(int, int *, int *, int);
455static int x2col(int); 455static int x2col(int);
@@ -984,8 +984,8 @@ getsel(void) {
984} 984}
985 985
986void 986void
987selcopy(void) { 987selcopy(Time t) {
988 xsetsel(getsel()); 988 xsetsel(getsel(), t);
989} 989}
990 990
991void 991void
@@ -997,7 +997,7 @@ selnotify(XEvent *e) {
997 XSelectionEvent *xsev; 997 XSelectionEvent *xsev;
998 998
999 ofs = 0; 999 ofs = 0;
1000 xsev = (XSelectionEvent *)e; 1000 xsev = &e->xselection;
1001 if (xsev->property == None) 1001 if (xsev->property == None)
1002 return; 1002 return;
1003 do { 1003 do {
@@ -1083,6 +1083,9 @@ selrequest(XEvent *e) {
1083 xev.selection = xsre->selection; 1083 xev.selection = xsre->selection;
1084 xev.target = xsre->target; 1084 xev.target = xsre->target;
1085 xev.time = xsre->time; 1085 xev.time = xsre->time;
1086 if (xsre->property == None)
1087 xsre->property = xsre->target;
1088
1086 /* reject */ 1089 /* reject */
1087 xev.property = None; 1090 xev.property = None;
1088 1091
@@ -1125,11 +1128,13 @@ selrequest(XEvent *e) {
1125} 1128}
1126 1129
1127void 1130void
1128xsetsel(char *str) { 1131xsetsel(char *str, Time t) {
1129 free(sel.primary); 1132 free(sel.primary);
1130 sel.primary = str; 1133 sel.primary = str;
1131 1134
1132 XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, CurrentTime); 1135 XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
1136 if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
1137 selclear(0);
1133} 1138}
1134 1139
1135void 1140void
@@ -1146,7 +1151,7 @@ brelease(XEvent *e) {
1146 selclear(NULL); 1151 selclear(NULL);
1147 } else { 1152 } else {
1148 getbuttoninfo(e); 1153 getbuttoninfo(e);
1149 selcopy(); 1154 selcopy(e->xbutton.time);
1150 } 1155 }
1151 sel.mode = 0; 1156 sel.mode = 0;
1152 tsetdirt(sel.nb.y, sel.ne.y); 1157 tsetdirt(sel.nb.y, sel.ne.y);