dmenu

my fork of dmenu
Index Commits Files Refs README LICENSE
patches/dmenu-mousesupporthoverbgcol-20210123-1a13d04.diff (4581B)
   1 From 51331aed8a535323702b73681c5ce2af6f8f5868 Mon Sep 17 00:00:00 2001
   2 From: Karol Kosek <krkk@krkk.ct8.pl>
   3 Date: Sat, 23 Jan 2021 20:16:19 +0100
   4 Subject: [PATCH] fix mouse hover on vertical lists with prompt text
   5 
   6 ---
   7  dmenu.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
   8  1 file changed, 158 insertions(+), 1 deletion(-)
   9 
  10 diff --git a/dmenu.c b/dmenu.c
  11 index 65f25ce..aff2768 100644
  12 --- a/dmenu.c
  13 +++ b/dmenu.c
  14 @@ -500,6 +500,156 @@ draw:
  15      drawmenu();
  16  }
  17  
  18 +static void
  19 +buttonpress(XEvent *e)
  20 +{
  21 +    struct item *item;
  22 +    XButtonPressedEvent *ev = &e->xbutton;
  23 +    int x = 0, y = 0, h = bh, w;
  24 +
  25 +    if (ev->window != win)
  26 +        return;
  27 +
  28 +    /* right-click: exit */
  29 +    if (ev->button == Button3)
  30 +        exit(1);
  31 +
  32 +    if (prompt && *prompt)
  33 +        x += promptw;
  34 +
  35 +    /* input field */
  36 +    w = (lines > 0 || !matches) ? mw - x : inputw;
  37 +
  38 +    /* left-click on input: clear input,
  39 +     * NOTE: if there is no left-arrow the space for < is reserved so
  40 +     *       add that to the input width */
  41 +    if (ev->button == Button1 &&
  42 +       ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
  43 +       ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
  44 +       (lines > 0 && ev->y >= y && ev->y <= y + h))) {
  45 +        insert(NULL, -cursor);
  46 +        drawmenu();
  47 +        return;
  48 +    }
  49 +    /* middle-mouse click: paste selection */
  50 +    if (ev->button == Button2) {
  51 +        XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
  52 +                          utf8, utf8, win, CurrentTime);
  53 +        drawmenu();
  54 +        return;
  55 +    }
  56 +    /* scroll up */
  57 +    if (ev->button == Button4 && prev) {
  58 +        sel = curr = prev;
  59 +        calcoffsets();
  60 +        drawmenu();
  61 +        return;
  62 +    }
  63 +    /* scroll down */
  64 +    if (ev->button == Button5 && next) {
  65 +        sel = curr = next;
  66 +        calcoffsets();
  67 +        drawmenu();
  68 +        return;
  69 +    }
  70 +    if (ev->button != Button1)
  71 +        return;
  72 +    /* disabled below, needs to be fixed */
  73 +    /*
  74 +    if (ev->state & ~ControlMask)
  75 +        return;
  76 +    */
  77 +    if (lines > 0) {
  78 +        /* vertical list: (ctrl)left-click on item */
  79 +        w = mw - x;
  80 +        for (item = curr; item != next; item = item->right) {
  81 +            y += h;
  82 +            if (ev->y >= y && ev->y <= (y + h)) {
  83 +                puts(item->text);
  84 +                if (!(ev->state & ControlMask))
  85 +                    exit(0);
  86 +                sel = item;
  87 +                if (sel) {
  88 +                    sel->out = 1;
  89 +                    drawmenu();
  90 +                }
  91 +                return;
  92 +            }
  93 +        }
  94 +    } else if (matches) {
  95 +        /* left-click on left arrow */
  96 +        x += inputw;
  97 +        w = TEXTW("<");
  98 +        if (prev && curr->left) {
  99 +            if (ev->x >= x && ev->x <= x + w) {
 100 +                sel = curr = prev;
 101 +                calcoffsets();
 102 +                drawmenu();
 103 +                return;
 104 +            }
 105 +        }
 106 +        /* horizontal list: (ctrl)left-click on item */
 107 +        for (item = curr; item != next; item = item->right) {
 108 +            x += w;
 109 +            w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
 110 +            if (ev->x >= x && ev->x <= x + w) {
 111 +                puts(item->text);
 112 +                if (!(ev->state & ControlMask))
 113 +                    exit(0);
 114 +                sel = item;
 115 +                if (sel) {
 116 +                    sel->out = 1;
 117 +                    drawmenu();
 118 +                }
 119 +                return;
 120 +            }
 121 +        }
 122 +        /* left-click on right arrow */
 123 +        w = TEXTW(">");
 124 +        x = mw - w;
 125 +        if (next && ev->x >= x && ev->x <= x + w) {
 126 +            sel = curr = next;
 127 +            calcoffsets();
 128 +            drawmenu();
 129 +            return;
 130 +        }
 131 +    }
 132 +}
 133 +
 134 +static void
 135 +mousemove(XEvent *e)
 136 +{
 137 +    struct item *item;
 138 +    XPointerMovedEvent *ev = &e->xmotion;
 139 +    int x = 0, y = 0, h = bh, w;
 140 +
 141 +    if (lines > 0) {
 142 +        w = mw - x;
 143 +        for (item = curr; item != next; item = item->right) {
 144 +            y += h;
 145 +            if (ev->y >= y && ev->y <= (y + h)) {
 146 +                sel = item;
 147 +                calcoffsets();
 148 +                drawmenu();
 149 +                return;
 150 +            }
 151 +        }
 152 +    } else if (matches) {
 153 +        x += inputw + promptw;
 154 +        w = TEXTW("<");
 155 +        for (item = curr; item != next; item = item->right) {
 156 +            x += w;
 157 +            w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
 158 +            if (ev->x >= x && ev->x <= x + w) {
 159 +                sel = item;
 160 +                calcoffsets();
 161 +                drawmenu();
 162 +                return;
 163 +            }
 164 +        }
 165 +    }
 166 +}
 167 +
 168  static void
 169  paste(void)
 170  {
 171 @@ -561,6 +711,12 @@ run(void)
 172                  break;
 173              cleanup();
 174              exit(1);
 175 +        case ButtonPress:
 176 +            buttonpress(&ev);
 177 +            break;
 178 +        case MotionNotify:
 179 +            mousemove(&ev);
 180 +            break;
 181          case Expose:
 182              if (ev.xexpose.count == 0)
 183                  drw_map(drw, win, 0, 0, mw, mh);
 184 @@ -658,7 +814,8 @@ setup(void)
 185      /* create menu window */
 186      swa.override_redirect = True;
 187      swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
 188 -    swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
 189 +    swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
 190 +                     ButtonPressMask | PointerMotionMask;
 191      win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
 192                          CopyFromParent, CopyFromParent, CopyFromParent,
 193                          CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
 194 -- 
 195 2.30.0
 196