dmenu-mousesupporthoverbgcol-20210123-1a13d04.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       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