aboutsummaryrefslogtreecommitdiff
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
parent23ed12857f113603b689521d3f6e40ff954d25bb (diff)
downloadst-42fa1f5ce46593a9d6c2f9196c1aae1a60ca07d1.tar.gz
st-42fa1f5ce46593a9d6c2f9196c1aae1a60ca07d1.tar.bz2
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.
-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 *);
static void xresettitle(void);
static void xsetpointermotion(int);
static void xseturgency(int);
-static void xsetsel(char *);
+static void xsetsel(char *, Time);
static void xtermclear(int, int, int, int);
static void xunloadfont(Font *);
static void xunloadfonts(void);
@@ -449,7 +449,7 @@ static void selinit(void);
static void selnormalize(void);
static inline bool selected(int, int);
static char *getsel(void);
-static void selcopy(void);
+static void selcopy(Time);
static void selscroll(int, int);
static void selsnap(int, int *, int *, int);
static int x2col(int);
@@ -984,8 +984,8 @@ getsel(void) {
}
void
-selcopy(void) {
- xsetsel(getsel());
+selcopy(Time t) {
+ xsetsel(getsel(), t);
}
void
@@ -997,7 +997,7 @@ selnotify(XEvent *e) {
XSelectionEvent *xsev;
ofs = 0;
- xsev = (XSelectionEvent *)e;
+ xsev = &e->xselection;
if (xsev->property == None)
return;
do {
@@ -1083,6 +1083,9 @@ selrequest(XEvent *e) {
xev.selection = xsre->selection;
xev.target = xsre->target;
xev.time = xsre->time;
+ if (xsre->property == None)
+ xsre->property = xsre->target;
+
/* reject */
xev.property = None;
@@ -1125,11 +1128,13 @@ selrequest(XEvent *e) {
}
void
-xsetsel(char *str) {
+xsetsel(char *str, Time t) {
free(sel.primary);
sel.primary = str;
- XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, CurrentTime);
+ XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t);
+ if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win)
+ selclear(0);
}
void
@@ -1146,7 +1151,7 @@ brelease(XEvent *e) {
selclear(NULL);
} else {
getbuttoninfo(e);
- selcopy();
+ selcopy(e->xbutton.time);
}
sel.mode = 0;
tsetdirt(sel.nb.y, sel.ne.y);