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.
This commit is contained in:
parent
23ed12857f
commit
42fa1f5ce4
21
st.c
21
st.c
|
@ -423,7 +423,7 @@ static void xsettitle(char *);
|
||||||
static void xresettitle(void);
|
static void xresettitle(void);
|
||||||
static void xsetpointermotion(int);
|
static void xsetpointermotion(int);
|
||||||
static void xseturgency(int);
|
static void xseturgency(int);
|
||||||
static void xsetsel(char *);
|
static void xsetsel(char *, Time);
|
||||||
static void xtermclear(int, int, int, int);
|
static void xtermclear(int, int, int, int);
|
||||||
static void xunloadfont(Font *);
|
static void xunloadfont(Font *);
|
||||||
static void xunloadfonts(void);
|
static void xunloadfonts(void);
|
||||||
|
@ -449,7 +449,7 @@ static void selinit(void);
|
||||||
static void selnormalize(void);
|
static void selnormalize(void);
|
||||||
static inline bool selected(int, int);
|
static inline bool selected(int, int);
|
||||||
static char *getsel(void);
|
static char *getsel(void);
|
||||||
static void selcopy(void);
|
static void selcopy(Time);
|
||||||
static void selscroll(int, int);
|
static void selscroll(int, int);
|
||||||
static void selsnap(int, int *, int *, int);
|
static void selsnap(int, int *, int *, int);
|
||||||
static int x2col(int);
|
static int x2col(int);
|
||||||
|
@ -984,8 +984,8 @@ getsel(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
selcopy(void) {
|
selcopy(Time t) {
|
||||||
xsetsel(getsel());
|
xsetsel(getsel(), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -997,7 +997,7 @@ selnotify(XEvent *e) {
|
||||||
XSelectionEvent *xsev;
|
XSelectionEvent *xsev;
|
||||||
|
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
xsev = (XSelectionEvent *)e;
|
xsev = &e->xselection;
|
||||||
if (xsev->property == None)
|
if (xsev->property == None)
|
||||||
return;
|
return;
|
||||||
do {
|
do {
|
||||||
|
@ -1083,6 +1083,9 @@ selrequest(XEvent *e) {
|
||||||
xev.selection = xsre->selection;
|
xev.selection = xsre->selection;
|
||||||
xev.target = xsre->target;
|
xev.target = xsre->target;
|
||||||
xev.time = xsre->time;
|
xev.time = xsre->time;
|
||||||
|
if (xsre->property == None)
|
||||||
|
xsre->property = xsre->target;
|
||||||
|
|
||||||
/* reject */
|
/* reject */
|
||||||
xev.property = None;
|
xev.property = None;
|
||||||
|
|
||||||
|
@ -1125,11 +1128,13 @@ selrequest(XEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xsetsel(char *str) {
|
xsetsel(char *str, Time t) {
|
||||||
free(sel.primary);
|
free(sel.primary);
|
||||||
sel.primary = str;
|
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
|
void
|
||||||
|
@ -1146,7 +1151,7 @@ brelease(XEvent *e) {
|
||||||
selclear(NULL);
|
selclear(NULL);
|
||||||
} else {
|
} else {
|
||||||
getbuttoninfo(e);
|
getbuttoninfo(e);
|
||||||
selcopy();
|
selcopy(e->xbutton.time);
|
||||||
}
|
}
|
||||||
sel.mode = 0;
|
sel.mode = 0;
|
||||||
tsetdirt(sel.nb.y, sel.ne.y);
|
tsetdirt(sel.nb.y, sel.ne.y);
|
||||||
|
|
Loading…
Reference in New Issue