Move terminal-related selection logic into st.c - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit bcb5d3adbe57ead05a829e5144c2ba1dc465865f
 (DIR) parent 5683b1f80c5ac274adf98517ce2217b4d4896243
 (HTM) Author: Devin J. Pohly <djpohly@gmail.com>
       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
       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>
       
       Diffstat:
         M st.c                                |      37 +++++++++++++++++++++++++++++++
         M st.h                                |       3 ++-
         M x.c                                 |      55 +++++++++----------------------
       
       3 files changed, 54 insertions(+), 41 deletions(-)
       ---
 (DIR) diff --git a/st.c b/st.c
       @@ -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);
       @@ -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;
 (DIR) diff --git a/st.h b/st.h
       @@ -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);
       @@ -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);
 (DIR) diff --git a/x.c b/x.c
       @@ -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);
       @@ -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
       @@ -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);
       @@ -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);
                }
        }
        
       @@ -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;
       @@ -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