Hi,

the attached patch resolves some minor issues of mouse handling and 
changes some of its behaviours:

* Fixed: double-clicking on first word of a line does not select it

* Text is only selected with Button1; pasting when Button2 is released 
  (maybe in the future: Button3 to expand the current selection like in
  xterm/rxvt-unicode)

* Support for (xterm-specific) '\E[1002' button-event-tracking: report 
  mouse motion events while some button is pressed (only if pointer is 
  moved to another character; used in e.g. `vim -c "set mouse=a 
  ttymouse=xterm2"'; the old '\E[1000' is kept working)

* When MODE_MOUSE is set: only report mouse events but do not handle 
  them inside st, selecting text in vim was kind of awkward, because it 
  was selected inside and outside of vim and caused double (i.e. no) 
  highlighting of the selected text

* Listen for MotionNotify events only when at least one button is down 
  (PointerMotionMask -> ButtonMotionMask)


Regards, Bert
--- a/st.c      2011-06-01 15:29:53.000000000 +0200
+++ b/st.c      2011-06-02 12:48:43.000000000 +0200
@@ -258,6 +258,7 @@ static CSIEscape escseq;
 static int cmdfd;
 static pid_t pid;
 static Selection sel;
+static int repmotion; /* also report mouse motion events */
 static char **opt_cmd  = NULL;
 static char *opt_title = NULL;
 static char *opt_class = NULL;
@@ -418,17 +419,27 @@ mousereport(XEvent *e) {
        int button = e->xbutton.button;
        int state = e->xbutton.state;
        char buf[] = { '\033', '[', 'M', 0, 32+x+1, 32+y+1 };
+       static int ob, ox, oy;
        
        if(!IS_SET(MODE_MOUSE))
                return;
        
        /* from urxvt */
-       if(e->xbutton.type == ButtonRelease || button == AnyButton)
+       if(e->xbutton.type == MotionNotify) {
+               if(!repmotion || (x == ox && y == oy))
+                       return;
+               button = ob + 32;
+               ox = x, oy = y;
+       } else if(e->xbutton.type == ButtonRelease || button == AnyButton) {
                button = 3;
-       else {
+       } else {
                button -= Button1;
                if(button >= 3)
                        button += 64 - 3;
+               if(e->xbutton.type == ButtonPress) {
+                       ob = button;
+                       ox = x, oy = y;
+               }
        }
        
        buf[3] = 32 + button + (state & ShiftMask ? 4 : 0)
@@ -440,10 +451,13 @@ mousereport(XEvent *e) {
 
 void
 bpress(XEvent *e) {
-       mousereport(e);
-       sel.mode = 1;
-       sel.ex = sel.bx = X2COL(e->xbutton.x);
-       sel.ey = sel.by = Y2ROW(e->xbutton.y);
+       if(IS_SET(MODE_MOUSE))
+               mousereport(e);
+       else if(e->xbutton.button == Button1) {
+               sel.mode = 1;
+               sel.ex = sel.bx = X2COL(e->xbutton.x);
+               sel.ey = sel.by = Y2ROW(e->xbutton.y);
+       }
 }
 
 void
@@ -552,17 +566,18 @@ xsetsel(char *str) {
 
 void
 brelease(XEvent *e) {
-       int b;
-
-       sel.mode = 0;
-       getbuttoninfo(e, &b, &sel.ex, &sel.ey);
-       mousereport(e);
-       if(sel.bx == sel.ex && sel.by == sel.ey) {
-               sel.bx = -1;
-               if(b == 2)
-                       selpaste();
-               else if(b == 1) {
+       if(IS_SET(MODE_MOUSE)) {
+               mousereport(e);
+               return;
+       }
+       if(e->xbutton.button == Button2)
+               selpaste();
+       else if(e->xbutton.button == Button1) {
+               sel.mode = 0;
+               getbuttoninfo(e, NULL, &sel.ex, &sel.ey);
+               if(sel.bx == sel.ex && sel.by == sel.ey) {
                        struct timeval now;
+                       sel.bx = -1;
                        gettimeofday(&now, NULL);
 
                        if(TIMEDIFF(now, sel.tclick2) <= TRIPLECLICK_TIMEOUT) {
@@ -574,18 +589,18 @@ brelease(XEvent *e) {
                        } else if(TIMEDIFF(now, sel.tclick1) <= 
DOUBLECLICK_TIMEOUT) {
                                /* double click to select word */
                                sel.bx = sel.ex;
-                               while(term.line[sel.ey][sel.bx-1].state & 
GLYPH_SET &&
+                               while(sel.bx > 0 && 
term.line[sel.ey][sel.bx-1].state & GLYPH_SET &&
                                          term.line[sel.ey][sel.bx-1].c[0] != ' 
') sel.bx--;
                                sel.b.x = sel.bx;
-                               while(term.line[sel.ey][sel.ex+1].state & 
GLYPH_SET &&
+                               while(sel.ex < term.col-1 && 
term.line[sel.ey][sel.ex+1].state & GLYPH_SET &&
                                          term.line[sel.ey][sel.ex+1].c[0] != ' 
') sel.ex++;
                                sel.e.x = sel.ex;
                                sel.b.y = sel.e.y = sel.ey;
                                selcopy();
                        }
-               }
-       } else if(b == 1)
-               selcopy();
+               } else
+                       selcopy();
+       }
        memcpy(&sel.tclick2, &sel.tclick1, sizeof(struct timeval));
        gettimeofday(&sel.tclick1, NULL);
        draw();
@@ -593,9 +608,12 @@ brelease(XEvent *e) {
 
 void
 bmotion(XEvent *e) {
+       if(IS_SET(MODE_MOUSE)) {
+               mousereport(e);
+               return;
+       }
        if(sel.mode) {
-               int oldey = sel.ey,
-                       oldex = sel.ex;
+               int oldey = sel.ey, oldex = sel.ex;
                getbuttoninfo(e, NULL, &sel.ex, &sel.ey);
 
                if(oldey != sel.ey || oldex != sel.ex) {
@@ -1117,6 +1135,7 @@ csihandle(void) {
                                term.c.state |= CURSOR_HIDE;
                                break;
                        case 1000: /* disable X11 xterm mouse reporting */
+                       case 1002:
                                term.mode &= ~MODE_MOUSE;
                                break;
                        case 1049: /* = 1047 and 1048 */
@@ -1183,7 +1202,9 @@ csihandle(void) {
                                term.c.state &= ~CURSOR_HIDE;
                                break;
                        case 1000: /* enable X11 xterm mouse reporting */
+                       case 1002:
                                term.mode |= MODE_MOUSE;
+                               repmotion = escseq.arg[0] == 1002;
                                break;
                        case 1049: /* = 1047 and 1048 */
                        case 1047:
@@ -1605,7 +1626,7 @@ xinit(void) {
        attrs.bit_gravity = NorthWestGravity;
        attrs.event_mask = FocusChangeMask | KeyPressMask
                | ExposureMask | VisibilityChangeMask | StructureNotifyMask
-               | PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
+               | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
        attrs.colormap = xw.cmap;
 
        xw.win = XCreateWindow(xw.dpy, XRootWindow(xw.dpy, xw.scr), 0, 0,

Reply via email to