Move terminal-related selection logic into st.c
The front-end determines information about mouse clicks and motion, and the 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 <djpohly@gmail.com>
This commit is contained in:
		
							
								
								
									
										37
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								st.c
									
									
									
									
									
								
							| @@ -140,6 +140,7 @@ static void tscrollup(int, int); | |||||||
| static void tscrolldown(int, int); | static void tscrolldown(int, int); | ||||||
| static void tsetattr(int *, int); | static void tsetattr(int *, int); | ||||||
| static void tsetchar(Rune, Glyph *, int, int); | static void tsetchar(Rune, Glyph *, int, int); | ||||||
|  | static void tsetdirt(int, int); | ||||||
| static void tsetscroll(int, int); | static void tsetscroll(int, int); | ||||||
| static void tswapscreen(void); | static void tswapscreen(void); | ||||||
| static void tsetmode(int, int, int *, int); | static void tsetmode(int, int, int *, int); | ||||||
| @@ -384,6 +385,42 @@ tlinelen(int y) | |||||||
| 	return i; | 	return i; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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 | void | ||||||
| selnormalize(void) | selnormalize(void) | ||||||
| { | { | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								st.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								st.h
									
									
									
									
									
								
							| @@ -172,7 +172,6 @@ void toggleprinter(const Arg *); | |||||||
| int tattrset(int); | int tattrset(int); | ||||||
| void tnew(int, int); | void tnew(int, int); | ||||||
| void tresize(int, int); | void tresize(int, int); | ||||||
| void tsetdirt(int, int); |  | ||||||
| void tsetdirtattr(int); | void tsetdirtattr(int); | ||||||
| void ttynew(char *, char *, char **); | void ttynew(char *, char *, char **); | ||||||
| size_t ttyread(void); | size_t ttyread(void); | ||||||
| @@ -184,6 +183,8 @@ void resettitle(void); | |||||||
|  |  | ||||||
| void selclear(void); | void selclear(void); | ||||||
| void selinit(void); | void selinit(void); | ||||||
|  | void selstart(int, int, int); | ||||||
|  | void selextend(int, int, int); | ||||||
| void selnormalize(void); | void selnormalize(void); | ||||||
| int selected(int, int); | int selected(int, int); | ||||||
| char *getsel(void); | char *getsel(void); | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								x.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								x.c
									
									
									
									
									
								
							| @@ -157,7 +157,7 @@ static void selnotify(XEvent *); | |||||||
| static void selclear_(XEvent *); | static void selclear_(XEvent *); | ||||||
| static void selrequest(XEvent *); | static void selrequest(XEvent *); | ||||||
| static void setsel(char *, Time); | static void setsel(char *, Time); | ||||||
| static void getbuttoninfo(XEvent *); | static void mousesel(XEvent *); | ||||||
| static void mousereport(XEvent *); | static void mousereport(XEvent *); | ||||||
| static char *kmap(KeySym, uint); | static char *kmap(KeySym, uint); | ||||||
| static int match(uint, uint); | static int match(uint, uint); | ||||||
| @@ -313,24 +313,19 @@ y2row(int y) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| getbuttoninfo(XEvent *e) | mousesel(XEvent *e) | ||||||
| { | { | ||||||
| 	int type; | 	int type, seltype = SEL_REGULAR; | ||||||
| 	uint state = e->xbutton.state & ~(Button1Mask | forceselmod); | 	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) { | 	for (type = 1; type < LEN(selmasks); ++type) { | ||||||
| 		if (match(selmasks[type], state)) { | 		if (match(selmasks[type], state)) { | ||||||
| 			sel.type = type; | 			seltype = type; | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	selextend(x2col(e->xbutton.x), y2row(e->xbutton.y), seltype); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -402,6 +397,7 @@ bpress(XEvent *e) | |||||||
| { | { | ||||||
| 	struct timespec now; | 	struct timespec now; | ||||||
| 	MouseShortcut *ms; | 	MouseShortcut *ms; | ||||||
|  | 	int snap; | ||||||
|  |  | ||||||
| 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { | 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { | ||||||
| 		mousereport(e); | 		mousereport(e); | ||||||
| @@ -417,33 +413,22 @@ bpress(XEvent *e) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (e->xbutton.button == Button1) { | 	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 | 		 * If the user clicks below predefined timeouts specific | ||||||
| 		 * snapping behaviour is exposed. | 		 * snapping behaviour is exposed. | ||||||
| 		 */ | 		 */ | ||||||
|  | 		clock_gettime(CLOCK_MONOTONIC, &now); | ||||||
| 		if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { | 		if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { | ||||||
| 			sel.snap = SNAP_LINE; | 			snap = SNAP_LINE; | ||||||
| 		} else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { | 		} else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { | ||||||
| 			sel.snap = SNAP_WORD; | 			snap = SNAP_WORD; | ||||||
| 		} else { | 		} 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.tclick2 = xsel.tclick1; | ||||||
| 		xsel.tclick1 = now; | 		xsel.tclick1 = now; | ||||||
|  |  | ||||||
|  | 		selstart(x2col(e->xbutton.x), y2row(e->xbutton.y), snap); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -649,20 +634,17 @@ brelease(XEvent *e) | |||||||
| 		selpaste(NULL); | 		selpaste(NULL); | ||||||
| 	} else if (e->xbutton.button == Button1) { | 	} else if (e->xbutton.button == Button1) { | ||||||
| 		if (sel.mode == SEL_READY) { | 		if (sel.mode == SEL_READY) { | ||||||
| 			getbuttoninfo(e); | 			mousesel(e); | ||||||
| 			setsel(getsel(), e->xbutton.time); | 			setsel(getsel(), e->xbutton.time); | ||||||
| 		} else | 		} else | ||||||
| 			selclear_(NULL); | 			selclear_(NULL); | ||||||
| 		sel.mode = SEL_IDLE; | 		sel.mode = SEL_IDLE; | ||||||
| 		tsetdirt(sel.nb.y, sel.ne.y); |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| bmotion(XEvent *e) | bmotion(XEvent *e) | ||||||
| { | { | ||||||
| 	int oldey, oldex, oldsby, oldsey; |  | ||||||
|  |  | ||||||
| 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { | 	if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { | ||||||
| 		mousereport(e); | 		mousereport(e); | ||||||
| 		return; | 		return; | ||||||
| @@ -672,14 +654,7 @@ bmotion(XEvent *e) | |||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	sel.mode = SEL_READY; | 	sel.mode = SEL_READY; | ||||||
| 	oldey = sel.oe.y; | 	mousesel(e); | ||||||
| 	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)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user