]> git.mdlowis.com Git - projs/tide.git/commitdiff
further button press refactoring
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 9 May 2019 02:29:02 +0000 (22:29 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 9 May 2019 02:29:02 +0000 (22:29 -0400)
inc/win.h
inc/x11.h
src/lib/x11.c
src/tframe.c
src/tide.c

index e8b74f35452d1d19eb426a078fa29326e34c0f85..e0ced7fa278007934c540a63ca3ffebda0aff3d8 100644 (file)
--- a/inc/win.h
+++ b/inc/win.h
@@ -12,20 +12,6 @@ typedef struct {
     short y;
 } XGlyphSpec;
 
-/* Key modifier masks */
-enum {
-    ModNone       = 0,
-    ModShift      = (1 << 0),
-    ModCapsLock   = (1 << 1),
-    ModCtrl       = (1 << 2),
-    ModAlt        = (1 << 3),
-    ModNumLock    = (1 << 4),
-    ModScrollLock = (1 << 5),
-    ModWindows    = (1 << 6),
-    ModOneOrMore  = (ModCtrl|ModAlt),
-    ModAny        = -1
-};
-
 enum {
     MouseLeft    = 1,
     MouseMiddle  = 2,
@@ -41,14 +27,7 @@ typedef enum {
     FOCUSED  = 2
 } WinRegion;
 
-typedef struct {
-    int mods;
-    Rune key;
-    void (*fn)(char*);
-    char* arg;
-} KeyBinding;
-
-void win_init(KeyBinding* bindings);
+void win_init(void);
 void win_title(char* path);
 void win_font(char* font);
 void win_prop_set(char* xname, char* ename, char* value);
index 90901e3df86324ee27e0efcc31ad946e6ba4a098..9331416ce836d4c5ec5e8404e07c1158ecdbf363 100644 (file)
--- a/inc/x11.h
+++ b/inc/x11.h
@@ -23,6 +23,7 @@ typedef struct XConf {
     XIM xim;
     GC gc;
     void (*eventfns[LASTEvent])(struct XConf*, XEvent*);
+    Time now;
 } XConf;
 
 /* Selection identifiers */
@@ -103,6 +104,26 @@ enum Keys {
     KEY_CTRL_UNDERSCORE  = 0x1F,
 };
 
+/* Key modifier masks */
+enum {
+    ModNone       = 0,
+    ModShift      = (1 << 0),
+    ModCapsLock   = (1 << 1),
+    ModCtrl       = (1 << 2),
+    ModAlt        = (1 << 3),
+    ModNumLock    = (1 << 4),
+    ModScrollLock = (1 << 5),
+    ModWindows    = (1 << 6),
+    ModOneOrMore  = (ModCtrl|ModAlt),
+    ModAny        = -1
+};
+
+typedef struct {
+    int mods;
+    uint32_t key;
+    void (*fn)(char*);
+    char* arg;
+} KeyBinding;
 
 int x11_init(XConf* x);
 void x11_error_clear(void);
@@ -114,6 +135,7 @@ int x11_process_events(XConf* x);
 void x11_event_loop(XConf* x, void (*redraw)(XConf* x));
 int x11_getptr(XConf* x, int* ptrx, int* ptry);
 uint32_t x11_getkey(XConf* x, XEvent* e);
+uint32_t x11_process_key(XConf* x, XEvent* e, KeyBinding* keys);
 
 void x11_centerwin(XConf* x);
 void x11_init_gc(XConf* x);
index e56b48094cc235c1ef854aa8c26e943544a5f4dc..1f15a2109168b35427fb7c1050e75c5696e13c39 100644 (file)
@@ -68,6 +68,15 @@ void x11_mkdialog(XConf* x, int width, int height, int evmask) {
     XChangeProperty(x->display, x->self, WindowType, XA_ATOM, 32, PropModeReplace, (unsigned char*)&DialogType, 1);
 }
 
+static void update_time(XConf* x, XEvent* e) {
+    if (
+        (e->type == KeyPress) || (e->type == ButtonPress) ||
+        (e->type == ButtonRelease) || (e->type == MotionNotify)
+    ) {
+        x->now = e->xkey.time;
+    }
+}
+
 int x11_process_events(XConf* x) {
     int nqueued, nevents, dirty = false;
     /* reap zombie background processes */
@@ -78,6 +87,7 @@ int x11_process_events(XConf* x) {
         XGetMotionEvents(x->display, x->self, CurrentTime, CurrentTime, &nevents);
         for (XEvent e; XPending(x->display);) {
             XNextEvent(x->display, &e);
+            update_time(x, &e);
             if (e.type == Expose) dirty = 1;
             if (!XFilterEvent(&e, None) && x->eventfns[e.type])
                 (x->eventfns[e.type])(x, &e);
@@ -139,3 +149,23 @@ uint32_t x11_getkey(XConf* x, XEvent* e) {
     /* translate special key codes into unicode codepoints */
     return special_keys(key);
 }
+
+uint32_t x11_process_key(XConf* x, XEvent* e, KeyBinding* keys) {
+    uint32_t key = x11_getkey(x, e);
+    if (key == RUNE_ERR) return key;
+    int mods = e->xkey.state & (ModCtrl|ModShift|ModAlt);
+    int32_t mkey = tolower(key);
+    for (KeyBinding* bind = keys; bind && bind->key; bind++) {
+        bool match   = (mkey == (int32_t)bind->key);
+        bool exact   = (bind->mods == mods);
+        bool any     = (bind->mods == ModAny);
+        bool oneplus = ((bind->mods == ModOneOrMore) && (mods & ModOneOrMore));
+        if (match && (exact || oneplus || any)) {
+            bind->fn(bind->arg);
+            return RUNE_ERR;
+        }
+    }
+    /* fallback to just inserting the rune if it doesn't fall in the private use area.
+     * the private use area is used to encode special keys */
+    return (key < 0xE000 || key > 0xF8FF ? key : RUNE_ERR);
+}
index 67419ae8eb5dfd7cbff5fccdc0d6264d163f284e..8c955598d5a0888eeee9615dd73915269e8e7771 100644 (file)
@@ -66,23 +66,8 @@ static void xexpose(XConf* x, XEvent* e) {
 }
 
 static void xkeypress(XConf* x, XEvent* e) {
-    uint32_t key = x11_getkey(x, e);
-    if (key == RUNE_ERR) return;
-//    int mods = e->xkey.state & (ModCtrl|ModShift|ModAlt);
-//    int32_t mkey = tolower(key);
-//    for (KeyBinding* bind = Keys; bind && bind->key; bind++) {
-//        bool match   = (mkey == bind->key);
-//        bool exact   = (bind->mods == mods);
-//        bool any     = (bind->mods == ModAny);
-//        bool oneplus = ((bind->mods == ModOneOrMore) && (mods & ModOneOrMore));
-//        if (match && (exact || oneplus || any)) {
-//            bind->fn(bind->arg);
-//            return;
-//        }
-//    }
-    /* fallback to just inserting the rune if it doesn't fall in the private use area.
-     * the private use area is used to encode special keys */
-    if (key < 0xE000 || key > 0xF8FF)
+    uint32_t key = x11_process_key(x, e, NULL);
+    if (key != RUNE_ERR)
         view_insert(&Tags, key);
 }
 
@@ -110,8 +95,7 @@ static void xupdate(Job* job) {
     XFlush(X.display);
 }
 
-void win_init(KeyBinding* bindings) {
-    (void)bindings;
+void win_init(void) {
     signal(SIGPIPE, SIG_IGN); // Ignore the SIGPIPE signal
     setlocale(LC_CTYPE, "");
     XSetLocaleModifiers("");
@@ -175,7 +159,7 @@ void win_quit(void) {
  ******************************************************************************/
 int main(void) {
     /* create the window */
-    win_init(NULL);
+    win_init();
 
     /* Initialize the views */
     view_init(&Tags, NULL);
index 2a0f2fba9dc090cc2b3f52937d7101a900a5b1e6..60b9ffa48ae50e098523a218405936075a2125e0 100644 (file)
@@ -34,12 +34,11 @@ typedef struct {
 
 char* ARGV0;
 static Tag Builtins[18];
-static Time Now;
+static KeyBinding Bindings[];
 static struct XConf X;
 static int KeyBtnState;
 static WinRegion Focused = EDIT;
 static View Regions[NREGIONS];
-static KeyBinding* Keys = NULL;
 static int Divider;
 static int FontSel;
 static bool SyncMouse = false;
@@ -90,8 +89,8 @@ 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 = ((Now - before) <= (uint64_t)ClickTime ? count+1 : 1);
-    before = Now;
+    count = ((X.now - before) <= (uint64_t)ClickTime ? count+1 : 1);
+    before = X.now;
     if (PRESSED(MouseRight)) {
         puts("fetch tag");
     }  else if (PRESSED(MouseMiddle)) {
@@ -172,47 +171,27 @@ size_t glyph_width(View* view, int c) {
 }
 
 static void xkeypress(XConf* x, XEvent* e) {
-    (void)x;
-    Now = e->xkey.time;
+    uint32_t key = x11_process_key(x, e, Bindings);
     Focused = (e->xkey.y <= Divider ? TAGS : EDIT);
-    uint32_t key = x11_getkey(x, e);
-    if (key == RUNE_ERR) return;
     KeyBtnState = e->xkey.state;
-    int mods = KeyBtnState & (ModCtrl|ModShift|ModAlt);
-    int32_t mkey = tolower(key);
-    for (KeyBinding* bind = Keys; bind && bind->key; bind++) {
-        bool match   = (mkey == bind->key);
-        bool exact   = (bind->mods == mods);
-        bool any     = (bind->mods == ModAny);
-        bool oneplus = ((bind->mods == ModOneOrMore) && (mods & ModOneOrMore));
-        if (match && (exact || oneplus || any)) {
-            bind->fn(bind->arg);
-            return;
-        }
-    }
-    /* fallback to just inserting the rune if it doesn't fall in the private use area.
-     * the private use area is used to encode special keys */
-    if (key < 0xE000 || key > 0xF8FF)
+    if (key != RUNE_ERR)
         view_insert(win_view(FOCUSED), key);
 }
 
 static void xbtnpress(XConf* x, XEvent* e) {
     (void)x;
-    Now = e->xbutton.time;
     KeyBtnState = (e->xbutton.state | (1 << (e->xbutton.button + 7)));
     mouse_click(e->xbutton.button, true, e->xbutton.x,  e->xbutton.y);
 }
 
 static void xbtnrelease(XConf* x, XEvent* e) {
     (void)x;
-    Now = e->xbutton.time;
     KeyBtnState = (KeyBtnState & ~(1 << (e->xbutton.button + 7)));
     mouse_click(e->xbutton.button, false, e->xbutton.x,  e->xbutton.y);
 }
 
 static void xbtnmotion(XConf* x, XEvent* e) {
     while (XCheckTypedEvent(x->display, MotionNotify, e));
-    Now = e->xbutton.time;
     size_t row, col;
     KeyBtnState = e->xbutton.state;
     int xpos = e->xbutton.x, ypos = e->xbutton.y;
@@ -251,8 +230,7 @@ static void xupdate(Job* job) {
     XFlush(X.display);
 }
 
-void win_init(KeyBinding* bindings) {
-    Keys = bindings;
+void win_init(void) {
     signal(SIGPIPE, SIG_IGN); // Ignore the SIGPIPE signal
     setlocale(LC_CTYPE, "");
     XSetLocaleModifiers("");
@@ -327,7 +305,7 @@ void win_loop(void) {
 
 void win_quit(void) {
     static uint64_t before = 0;
-    if ((win_buf(EDIT)->status != MODIFIED) || (Now - before) <= (uint64_t)ClickTime) {
+    if ((win_buf(EDIT)->status != MODIFIED) || (X.now - before) <= (uint64_t)ClickTime) {
         tide_send("DEL");
         X.eventfns[SelectionClear] = x11_sel_quit;
         XUnmapWindow(X.display, X.self);
@@ -337,7 +315,7 @@ void win_quit(void) {
             if (fork()) exit(0); /* fork into background if we still have selection */
         }
     }
-    before = Now;
+    before = X.now;
 }
 
 void win_togglefocus(void) {
@@ -881,7 +859,7 @@ int main(int argc, char** argv) {
     if (!ShellCmd[0]) ShellCmd[0] = "/bin/sh";
 
     /* create the window */
-    win_init(Bindings);
+    win_init();
 
     /* Initialize the views */
     view_init(&Regions[TAGS], NULL);