tMove terminal-related selection logic into st.c - st - [fork] customized build… | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit bcb5d3adbe57ead05a829e5144c2ba1dc465865f | |
parent 5683b1f80c5ac274adf98517ce2217b4d4896243 | |
Author: Devin J. Pohly <[email protected]> | |
Date: Wed, 21 Feb 2018 23:29:41 -0600 | |
Move terminal-related selection logic into st.c | |
The front-end determines information about mouse clicks and motion, and | |
tthe terminal handles the actual selection start/extend/dirty logic by | |
row and column. | |
While we're in the neighborhood, we'll also rename getbuttoninfo() to | |
mousesel() which is, at least, less wrong. | |
Signed-off-by: Devin J. Pohly <[email protected]> | |
Diffstat: | |
M st.c | 37 +++++++++++++++++++++++++++++… | |
M st.h | 3 ++- | |
M x.c | 55 +++++++++--------------------… | |
3 files changed, 54 insertions(+), 41 deletions(-) | |
--- | |
diff --git a/st.c b/st.c | |
t@@ -140,6 +140,7 @@ static void tscrollup(int, int); | |
static void tscrolldown(int, int); | |
static void tsetattr(int *, int); | |
static void tsetchar(Rune, Glyph *, int, int); | |
+static void tsetdirt(int, int); | |
static void tsetscroll(int, int); | |
static void tswapscreen(void); | |
static void tsetmode(int, int, int *, int); | |
t@@ -385,6 +386,42 @@ tlinelen(int y) | |
} | |
void | |
+selstart(int col, int row, int snap) | |
+{ | |
+ selclear(); | |
+ sel.mode = SEL_EMPTY; | |
+ sel.type = SEL_REGULAR; | |
+ sel.snap = snap; | |
+ sel.oe.x = sel.ob.x = col; | |
+ sel.oe.y = sel.ob.y = row; | |
+ selnormalize(); | |
+ | |
+ if (sel.snap != 0) | |
+ sel.mode = SEL_READY; | |
+ tsetdirt(sel.nb.y, sel.ne.y); | |
+} | |
+ | |
+void | |
+selextend(int col, int row, int type) | |
+{ | |
+ int oldey, oldex, oldsby, oldsey, oldtype; | |
+ oldey = sel.oe.y; | |
+ oldex = sel.oe.x; | |
+ oldsby = sel.nb.y; | |
+ oldsey = sel.ne.y; | |
+ oldtype = sel.type; | |
+ | |
+ sel.alt = IS_SET(MODE_ALTSCREEN); | |
+ sel.oe.x = col; | |
+ sel.oe.y = row; | |
+ selnormalize(); | |
+ sel.type = type; | |
+ | |
+ if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type) | |
+ tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); | |
+} | |
+ | |
+void | |
selnormalize(void) | |
{ | |
int i; | |
diff --git a/st.h b/st.h | |
t@@ -172,7 +172,6 @@ void toggleprinter(const Arg *); | |
int tattrset(int); | |
void tnew(int, int); | |
void tresize(int, int); | |
-void tsetdirt(int, int); | |
void tsetdirtattr(int); | |
void ttynew(char *, char *, char **); | |
size_t ttyread(void); | |
t@@ -184,6 +183,8 @@ void resettitle(void); | |
void selclear(void); | |
void selinit(void); | |
+void selstart(int, int, int); | |
+void selextend(int, int, int); | |
void selnormalize(void); | |
int selected(int, int); | |
char *getsel(void); | |
diff --git a/x.c b/x.c | |
t@@ -157,7 +157,7 @@ static void selnotify(XEvent *); | |
static void selclear_(XEvent *); | |
static void selrequest(XEvent *); | |
static void setsel(char *, Time); | |
-static void getbuttoninfo(XEvent *); | |
+static void mousesel(XEvent *); | |
static void mousereport(XEvent *); | |
static char *kmap(KeySym, uint); | |
static int match(uint, uint); | |
t@@ -313,24 +313,19 @@ y2row(int y) | |
} | |
void | |
-getbuttoninfo(XEvent *e) | |
+mousesel(XEvent *e) | |
{ | |
- int type; | |
+ int type, seltype = SEL_REGULAR; | |
uint state = e->xbutton.state & ~(Button1Mask | forceselmod); | |
- sel.alt = IS_SET(MODE_ALTSCREEN); | |
- | |
- sel.oe.x = x2col(e->xbutton.x); | |
- sel.oe.y = y2row(e->xbutton.y); | |
- selnormalize(); | |
- | |
- sel.type = SEL_REGULAR; | |
for (type = 1; type < LEN(selmasks); ++type) { | |
if (match(selmasks[type], state)) { | |
- sel.type = type; | |
+ seltype = type; | |
break; | |
} | |
} | |
+ | |
+ selextend(x2col(e->xbutton.x), y2row(e->xbutton.y), seltype); | |
} | |
void | |
t@@ -402,6 +397,7 @@ bpress(XEvent *e) | |
{ | |
struct timespec now; | |
MouseShortcut *ms; | |
+ int snap; | |
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { | |
mousereport(e); | |
t@@ -417,33 +413,22 @@ bpress(XEvent *e) | |
} | |
if (e->xbutton.button == Button1) { | |
- clock_gettime(CLOCK_MONOTONIC, &now); | |
- | |
- /* Clear previous selection, logically and visually. */ | |
- selclear_(NULL); | |
- sel.mode = SEL_EMPTY; | |
- sel.type = SEL_REGULAR; | |
- sel.oe.x = sel.ob.x = x2col(e->xbutton.x); | |
- sel.oe.y = sel.ob.y = y2row(e->xbutton.y); | |
- | |
/* | |
* If the user clicks below predefined timeouts specific | |
* snapping behaviour is exposed. | |
*/ | |
+ clock_gettime(CLOCK_MONOTONIC, &now); | |
if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { | |
- sel.snap = SNAP_LINE; | |
+ snap = SNAP_LINE; | |
} else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { | |
- sel.snap = SNAP_WORD; | |
+ snap = SNAP_WORD; | |
} else { | |
- sel.snap = 0; | |
+ snap = 0; | |
} | |
- selnormalize(); | |
- | |
- if (sel.snap != 0) | |
- sel.mode = SEL_READY; | |
- tsetdirt(sel.nb.y, sel.ne.y); | |
xsel.tclick2 = xsel.tclick1; | |
xsel.tclick1 = now; | |
+ | |
+ selstart(x2col(e->xbutton.x), y2row(e->xbutton.y), snap); | |
} | |
} | |
t@@ -649,20 +634,17 @@ brelease(XEvent *e) | |
selpaste(NULL); | |
} else if (e->xbutton.button == Button1) { | |
if (sel.mode == SEL_READY) { | |
- getbuttoninfo(e); | |
+ mousesel(e); | |
setsel(getsel(), e->xbutton.time); | |
} else | |
selclear_(NULL); | |
sel.mode = SEL_IDLE; | |
- tsetdirt(sel.nb.y, sel.ne.y); | |
} | |
} | |
void | |
bmotion(XEvent *e) | |
{ | |
- int oldey, oldex, oldsby, oldsey; | |
- | |
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { | |
mousereport(e); | |
return; | |
t@@ -672,14 +654,7 @@ bmotion(XEvent *e) | |
return; | |
sel.mode = SEL_READY; | |
- oldey = sel.oe.y; | |
- oldex = sel.oe.x; | |
- oldsby = sel.nb.y; | |
- oldsey = sel.ne.y; | |
- getbuttoninfo(e); | |
- | |
- if (oldey != sel.oe.y || oldex != sel.oe.x) | |
- tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); | |
+ mousesel(e); | |
} | |
void |