]> git.mdlowis.com Git - projs/tide.git/commitdiff
rework mouse handling
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 10 May 2019 03:15:59 +0000 (23:15 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 10 May 2019 03:15:59 +0000 (23:15 -0400)
Makefile
inc/edit.h
src/lib/mouse.c [new file with mode: 0644]
src/tide.c

index 60f0f8f3ca702da6c2d3ed8a632cd55940ec24ee..71764a07ad41f2ce37024cf2523557c6b4c748e4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ LIBEDIT_OBJS = \
        src/lib/view.o \
        src/lib/draw.o \
        src/lib/shortcuts.o \
+       src/lib/mouse.o \
        src/lib/x11.o \
        src/lib/x11_gc.o \
        src/lib/x11_sel.o
index 8e9fe616780e3acc31873f2855599e69912f94e5..434cb325625bef9f877dfb75508cdb2050a8d9e1 100644 (file)
@@ -209,3 +209,19 @@ void undo(char* arg);
 void redo(char* arg);
 void newline(char* arg);
 void highlight(char* arg);
+
+enum {
+    MouseActNone,
+    MouseActSel,
+    MouseActSelCtx,
+    MouseActSelWord,
+    MouseActCut,
+    MouseActPaste,
+    MouseActExec,
+    MouseActExecArg,
+    MouseActFetch,
+    MouseActScrollUp,
+    MouseActScrollDn,
+};
+
+int process_mouse(int btn, bool pressed);
diff --git a/src/lib/mouse.c b/src/lib/mouse.c
new file mode 100644 (file)
index 0000000..3382573
--- /dev/null
@@ -0,0 +1,63 @@
+#include <utf.h>
+#include <x11.h>
+#include <edit.h>
+#include <win.h>
+#include "config.h"
+
+#define PRESSED(mods, btn) \
+    ((mods & (1 << (btn + 7))) == (1 << (btn + 7)))
+
+static int ExecRequest = 0;
+
+static int mouse_left(bool pressed) {
+    static int count = 0;
+    static Time before = 0;
+    if (!pressed) return MouseActNone;
+    count = ((X.now - before) <= (uint64_t)ClickTime ? count+1 : 1);
+    before = X.now;
+    if (PRESSED(X.mods, MouseRight)) {
+        return MouseActNone;
+    }  else if (PRESSED(X.mods, MouseMiddle)) {
+        ExecRequest = 0;
+        return MouseActExecArg;
+    } else  if (count == 1) {
+        return MouseActSel;
+    } else if (count == 2) {
+        return MouseActSelCtx;
+    } else if (count == 3) {
+        return MouseActSelWord;
+    } else {
+        return MouseActNone;
+    }
+}
+
+static int mouse_middle(bool pressed) {
+    if (pressed) { ExecRequest = 1; return MouseActNone; }
+    if (PRESSED(X.mods, MouseLeft)) {
+        return MouseActCut;
+    } else if (ExecRequest) {
+        return MouseActExec;
+    } else {
+        return MouseActNone;
+    }
+}
+
+static int mouse_right(bool pressed) {
+    if (pressed) return MouseActNone;
+    if (PRESSED(X.mods, MouseLeft)) {
+        return MouseActPaste;
+    } else {
+        return MouseActFetch;
+    }
+}
+
+int process_mouse(int btn, bool pressed) {
+    switch(btn) {
+        case MouseLeft:    return mouse_left(pressed);
+        case MouseMiddle:  return mouse_middle(pressed);
+        case MouseRight:   return mouse_right(pressed);
+        case MouseWheelUp: return (pressed ? MouseActScrollUp : MouseActNone);
+        case MouseWheelDn: return (pressed ? MouseActScrollDn : MouseActNone);
+    }
+    return MouseActNone;
+}
index e1e337357062551126d9b9e327007b8bcd3dcc31..854f3c5fe4fe95e56560ffa27f729f273ddc4ca2 100644 (file)
@@ -42,7 +42,6 @@ static int FontSel;
 static bool SyncMouse = false;
 static int SearchDir = DOWN;
 static char* SearchTerm = NULL;
-static int ExecRequest = 0;
 
 #define PRESSED(mods, btn) \
     ((mods & (1 << (btn + 7))) == (1 << (btn + 7)))
@@ -83,80 +82,6 @@ static void tide_send(char* type) {
     }
 }
 
-static void mouse_left(WinRegion id, bool pressed, size_t row, size_t col) {
-    static int count = 0;
-    static Time before = 0;
-    if (!pressed) return;
-    count = ((X.now - before) <= (uint64_t)ClickTime ? count+1 : 1);
-    before = X.now;
-    if (PRESSED(X.mods, MouseRight)) {
-        puts("fetch tag");
-    }  else if (PRESSED(X.mods, MouseMiddle)) {
-        /* if we didnt get an arg, find one in the selection */
-        char* arg = NULL;
-        if (!arg || !*arg) arg = view_getstr(win_view(EDIT));
-        if (!arg || !*arg) arg = view_getstr(win_view(TAGS));
-        char* str = view_fetch(win_view(id), row, col, riscmd);
-        if (str) exec(str, arg);
-        free(str);
-        free(arg);
-        ExecRequest = 0;
-    } else {
-        if (count == 1)
-            view_setcursor(win_view(id), row, col, win_keymodsset(ModShift));
-        else if (count == 2)
-            view_select(win_view(id), row, col);
-        else if (count == 3)
-            view_selword(win_view(id), row, col);
-    }
-}
-
-static void mouse_middle(WinRegion id, bool pressed, size_t row, size_t col) {
-    if (pressed) { ExecRequest = 1; return; }
-    if (PRESSED(X.mods, MouseLeft)) {
-        cut(NULL);
-    } else if (ExecRequest) {
-        char* str = view_fetch(win_view(id), row, col, riscmd);
-        if (str) exec(str, NULL);
-        free(str);
-    }
-}
-
-static void mouse_right(WinRegion id, bool pressed, size_t row, size_t col) {
-    if (pressed) return;
-    if (PRESSED(X.mods, MouseLeft)) {
-        paste(NULL);
-    } else {
-        FetchCmd[2] = view_fetch(win_view(id), row, col, risfile);
-        if (job_run(FetchCmd) != 0) {
-            SearchDir *= (win_keymodsset(ModShift) ? -1 : +1);
-            free(SearchTerm);
-            SearchTerm = view_fetch(win_view(id), row, col, risfile);
-            view_findstr(win_view(EDIT), SearchDir, SearchTerm);
-            SyncMouse = true;
-        }
-        free(FetchCmd[2]);
-    }
-}
-
-static void mouse_scroll(WinRegion id, bool pressed, int amount) {
-    if (!pressed)
-        view_scroll(win_view(id), amount);
-}
-
-static void mouse_click(int btn, bool pressed, int x, int y) {
-    size_t row, col;
-    Focused = (y <= Divider ? TAGS : EDIT);
-    get_position(Focused, x, y, &row, &col);
-    switch(btn) {
-        case MouseLeft:    mouse_left(Focused, pressed, row, col);    break;
-        case MouseMiddle:  mouse_middle(Focused, pressed, row, col);  break;
-        case MouseRight:   mouse_right(Focused, pressed, row, col);   break;
-        case MouseWheelUp: mouse_scroll(Focused, pressed, -ScrollBy); break;
-        case MouseWheelDn: mouse_scroll(Focused, pressed, +ScrollBy); break;
-    }
-}
-
 size_t glyph_width(View* view, int c) {
     FcChar32 rune = (FcChar32)c;
     XGlyphInfo extents;
@@ -175,14 +100,65 @@ static void xkeypress(XConf* x, XEvent* e) {
         view_insert(win_view(FOCUSED), key);
 }
 
-static void xbtnpress(XConf* x, XEvent* e) {
-    (void)x;
-    mouse_click(e->xbutton.button, true, e->xbutton.x,  e->xbutton.y);
-}
-
-static void xbtnrelease(XConf* x, XEvent* e) {
+static void xmousebtn(XConf* x, XEvent* e) {
     (void)x;
-    mouse_click(e->xbutton.button, false, e->xbutton.x,  e->xbutton.y);
+    size_t row, col;
+    Focused = (e->xbutton.y <= Divider ? TAGS : EDIT);
+    get_position(Focused, e->xbutton.x,  e->xbutton.y, &row, &col);
+    switch (process_mouse(e->xbutton.button, (e->type == ButtonPress))) {
+        case MouseActNone:
+            break;
+        case MouseActSel:
+            view_setcursor(win_view(Focused), row, col, win_keymodsset(ModShift));
+            break;
+        case MouseActSelCtx:
+            view_select(win_view(Focused), row, col);
+            break;
+        case MouseActSelWord:
+            view_selword(win_view(Focused), row, col);
+            break;
+        case MouseActCut:
+            cut(NULL);
+            break;
+        case MouseActPaste:
+            paste(NULL);
+            break;
+        case MouseActExec: {
+            char* str = view_fetch(win_view(Focused), row, col, riscmd);
+            if (str) exec(str, NULL);
+            free(str);
+            break;
+        }
+        case MouseActExecArg: {
+            /* if we didnt get an arg, find one in the selection */
+            char* arg = NULL;
+            if (!arg || !*arg) arg = view_getstr(win_view(EDIT));
+            if (!arg || !*arg) arg = view_getstr(win_view(TAGS));
+            char* str = view_fetch(win_view(Focused), row, col, riscmd);
+            if (str) exec(str, arg);
+            free(str);
+            free(arg);
+            break;
+        }
+        case MouseActFetch: {
+            FetchCmd[2] = view_fetch(win_view(Focused), row, col, risfile);
+            if (job_run(FetchCmd) != 0) {
+                SearchDir *= (win_keymodsset(ModShift) ? -1 : +1);
+                free(SearchTerm);
+                SearchTerm = view_fetch(win_view(Focused), row, col, risfile);
+                view_findstr(win_view(EDIT), SearchDir, SearchTerm);
+                SyncMouse = true;
+            }
+            free(FetchCmd[2]);
+            break;
+        }
+        case MouseActScrollUp:
+            view_scroll(win_view(Focused), -ScrollBy);
+            break;
+        case MouseActScrollDn:
+            view_scroll(win_view(Focused), +ScrollBy);
+            break;
+    }
 }
 
 static void xbtnmotion(XConf* x, XEvent* e) {
@@ -223,8 +199,9 @@ static void xredraw(XConf* x) {
 }
 
 static void xupdate(Job* job) {
-    /* redraw if we have changes */
-    if (!x11_process_events(&X, xredraw) && job) return;
+    /* redraw if we have changes or if we have input from a job */
+    if (!x11_process_events(&X, xredraw) && !job)
+        xredraw(&X);
 }
 
 void win_init(void) {
@@ -258,8 +235,8 @@ void win_init(void) {
 #endif
     /* register event handlers */
     X.eventfns[KeyPress] = xkeypress;
-    X.eventfns[ButtonPress] = xbtnpress;
-    X.eventfns[ButtonRelease] = xbtnrelease;
+    X.eventfns[ButtonPress] = xmousebtn;
+    X.eventfns[ButtonRelease] = xmousebtn;
     X.eventfns[MotionNotify] = xbtnmotion;
     X.eventfns[ClientMessage] = xclientmsg;
 }
@@ -396,9 +373,6 @@ static void exec(char* cmd, char* arg) {
     }
 }
 
-/* Keyboard Editing Handlers
- ******************************************************************************/
-
 /* Keyboard and Tag Handlers
  ******************************************************************************/
 static void change_focus(char* arg) {