aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Lohmann <20h@r-36.net>2013-02-19 19:08:41 +0100
committerChristoph Lohmann <20h@r-36.net>2013-02-19 19:08:41 +0100
commit3865e9eaaf4e1c7820b1f41ce9d0b1d7b109fb26 (patch)
tree1c54d60e09105dbc2894a5a62b85d990f8937b72
parente5295629cdffb711001f3fdffbb9aa4ef772add0 (diff)
downloadst-patched-3865e9eaaf4e1c7820b1f41ce9d0b1d7b109fb26.tar.bz2
st-patched-3865e9eaaf4e1c7820b1f41ce9d0b1d7b109fb26.tar.xz
st-patched-3865e9eaaf4e1c7820b1f41ce9d0b1d7b109fb26.zip
Implement rectangular mouse selection.
Thanks Alexander Sedov <alex0player@gmail.com>!
-rw-r--r--config.def.h12
-rw-r--r--st.c68
2 files changed, 66 insertions, 14 deletions
diff --git a/config.def.h b/config.def.h
index 07a22ed..a31a235 100644
--- a/config.def.h
+++ b/config.def.h
@@ -305,3 +305,15 @@ static Key key[] = {
305 { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0, 0}, 305 { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0, 0},
306}; 306};
307 307
308/*
309 * Selection types' masks.
310 * Use the same masks as usual.
311 * Button1Mask is always unset, to make masks match between ButtonPress.
312 * ButtonRelease and MotionNotify.
313 * If no match is found, regular selection is used.
314 */
315
316static uint selmasks[] = {
317 [SEL_RECTANGULAR] = Mod1Mask,
318};
319
diff --git a/st.c b/st.c
index 7befdc0..300e5ec 100644
--- a/st.c
+++ b/st.c
@@ -137,6 +137,11 @@ enum window_state {
137 WIN_FOCUSED = 4 137 WIN_FOCUSED = 4
138}; 138};
139 139
140enum selection_type {
141 SEL_REGULAR = 1,
142 SEL_RECTANGULAR = 2
143};
144
140/* bit macro */ 145/* bit macro */
141#undef B0 146#undef B0
142enum { B0=1, B1=2, B2=4, B3=8, B4=16, B5=32, B6=64, B7=128 }; 147enum { B0=1, B1=2, B2=4, B3=8, B4=16, B5=32, B6=64, B7=128 };
@@ -234,6 +239,7 @@ typedef struct {
234/* TODO: use better name for vars... */ 239/* TODO: use better name for vars... */
235typedef struct { 240typedef struct {
236 int mode; 241 int mode;
242 int type;
237 int bx, by; 243 int bx, by;
238 int ex, ey; 244 int ex, ey;
239 struct { 245 struct {
@@ -651,10 +657,23 @@ selected(int x, int y) {
651 || (y == sel.e.y && x <= sel.e.x)) 657 || (y == sel.e.y && x <= sel.e.x))
652 || (y == sel.b.y && x >= sel.b.x 658 || (y == sel.b.y && x >= sel.b.x
653 && (x <= sel.e.x || sel.b.y != sel.e.y)); 659 && (x <= sel.e.x || sel.b.y != sel.e.y));
660 switch(sel.type) {
661 case SEL_REGULAR:
662 return ((sel.b.y < y && y < sel.e.y)
663 || (y == sel.e.y && x <= sel.e.x))
664 || (y == sel.b.y && x >= sel.b.x
665 && (x <= sel.e.x || sel.b.y != sel.e.y));
666 case SEL_RECTANGULAR:
667 return ((sel.b.y <= y && y <= sel.e.y)
668 && (sel.b.x <= x && x <= sel.e.x));
669 };
654} 670}
655 671
656void 672void
657getbuttoninfo(XEvent *e) { 673getbuttoninfo(XEvent *e) {
674 int type;
675 uint state = e->xbutton.state &~Button1Mask;
676
658 sel.alt = IS_SET(MODE_ALTSCREEN); 677 sel.alt = IS_SET(MODE_ALTSCREEN);
659 678
660 sel.ex = x2col(e->xbutton.x); 679 sel.ex = x2col(e->xbutton.x);
@@ -664,6 +683,14 @@ getbuttoninfo(XEvent *e) {
664 sel.b.y = MIN(sel.by, sel.ey); 683 sel.b.y = MIN(sel.by, sel.ey);
665 sel.e.x = sel.by < sel.ey ? sel.ex : sel.bx; 684 sel.e.x = sel.by < sel.ey ? sel.ex : sel.bx;
666 sel.e.y = MAX(sel.by, sel.ey); 685 sel.e.y = MAX(sel.by, sel.ey);
686
687 sel.type = SEL_REGULAR;
688 for(type = 1; type < LEN(selmasks); ++type) {
689 if(match(selmasks[type], state)) {
690 sel.type = type;
691 break;
692 }
693 }
667} 694}
668 695
669void 696void
@@ -724,6 +751,7 @@ bpress(XEvent *e) {
724 draw(); 751 draw();
725 } 752 }
726 sel.mode = 1; 753 sel.mode = 1;
754 sel.type = SEL_REGULAR;
727 sel.ex = sel.bx = x2col(e->xbutton.x); 755 sel.ex = sel.bx = x2col(e->xbutton.x);
728 sel.ey = sel.by = y2row(e->xbutton.y); 756 sel.ey = sel.by = y2row(e->xbutton.y);
729 } else if(e->xbutton.button == Button4) { 757 } else if(e->xbutton.button == Button4) {
@@ -746,7 +774,8 @@ selcopy(void) {
746 ptr = str = xmalloc(bufsize); 774 ptr = str = xmalloc(bufsize);
747 775
748 /* append every set & selected glyph to the selection */ 776 /* append every set & selected glyph to the selection */
749 for(y = 0; y < term.row; y++) { 777 for(y = sel.b.y; y < sel.e.y + 1; y++) {
778 is_selected = 0;
750 gp = &term.line[y][0]; 779 gp = &term.line[y][0];
751 last = gp + term.col; 780 last = gp + term.col;
752 781
@@ -754,8 +783,11 @@ selcopy(void) {
754 /* nothing */; 783 /* nothing */;
755 784
756 for(x = 0; gp <= last; x++, ++gp) { 785 for(x = 0; gp <= last; x++, ++gp) {
757 if(!(is_selected = selected(x, y))) 786 if(!selected(x, y)) {
758 continue; 787 continue;
788 } else {
789 is_selected = 1;
790 }
759 791
760 p = (gp->state & GLYPH_SET) ? gp->c : " "; 792 p = (gp->state & GLYPH_SET) ? gp->c : " ";
761 size = utf8size(p); 793 size = utf8size(p);
@@ -907,7 +939,7 @@ brelease(XEvent *e) {
907 939
908void 940void
909bmotion(XEvent *e) { 941bmotion(XEvent *e) {
910 int starty, endy, oldey, oldex; 942 int oldey, oldex;
911 943
912 if(IS_SET(MODE_MOUSE)) { 944 if(IS_SET(MODE_MOUSE)) {
913 mousereport(e); 945 mousereport(e);
@@ -922,9 +954,7 @@ bmotion(XEvent *e) {
922 getbuttoninfo(e); 954 getbuttoninfo(e);
923 955
924 if(oldey != sel.ey || oldex != sel.ex) { 956 if(oldey != sel.ey || oldex != sel.ex) {
925 starty = MIN(oldey, sel.ey); 957 tsetdirt(sel.b.y, sel.e.y);
926 endy = MAX(oldey, sel.ey);
927 tsetdirt(starty, endy);
928 } 958 }
929} 959}
930 960
@@ -1216,14 +1246,24 @@ selscroll(int orig, int n) {
1216 sel.bx = -1; 1246 sel.bx = -1;
1217 return; 1247 return;
1218 } 1248 }
1219 if(sel.by < term.top) { 1249 switch(sel.type) {
1220 sel.by = term.top; 1250 case SEL_REGULAR:
1221 sel.bx = 0; 1251 if(sel.by < term.top) {
1222 } 1252 sel.by = term.top;
1223 if(sel.ey > term.bot) { 1253 sel.bx = 0;
1224 sel.ey = term.bot; 1254 }
1225 sel.ex = term.col; 1255 if(sel.ey > term.bot) {
1226 } 1256 sel.ey = term.bot;
1257 sel.ex = term.col;
1258 }
1259 break;
1260 case SEL_RECTANGULAR:
1261 if(sel.by < term.top)
1262 sel.by = term.top;
1263 if(sel.ey > term.bot)
1264 sel.ey = term.bot;
1265 break;
1266 };
1227 sel.b.y = sel.by, sel.b.x = sel.bx; 1267 sel.b.y = sel.by, sel.b.x = sel.bx;
1228 sel.e.y = sel.ey, sel.e.x = sel.ex; 1268 sel.e.y = sel.ey, sel.e.x = sel.ex;
1229 } 1269 }