tSelect and print what's under cursor on exit - xmenu - drop-down menu for X11
 (HTM) git clone git://git.z3bra.org/xmenu.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 6e984bc6d761614be9bb1da31217a40fbb587ccd
 (DIR) parent 8f3bd60df8e72fdbbcef34f94578590ccb791a38
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Tue, 19 Nov 2019 18:17:56 +0100
       
       Select and print what's under cursor on exit
       
       Diffstat:
         M font.c                              |       2 +-
         M xmenu.c                             |      53 ++++++++++++++++++++++++++++---
       
       2 files changed, 50 insertions(+), 5 deletions(-)
       ---
 (DIR) diff --git a/font.c b/font.c
       t@@ -76,7 +76,7 @@ xr_create_canvas(xcb_connection_t *dpy, xcb_drawable_t xid)
                        XCB_RENDER_CP_POLY_MODE | XCB_RENDER_CP_POLY_EDGE, val);
        
                return pic;
       -} 
       +}
        
        static xcb_render_picture_t
        xr_create_pen(xcb_connection_t *dpy, xcb_render_color_t color)
 (DIR) diff --git a/xmenu.c b/xmenu.c
       t@@ -16,6 +16,7 @@
        #define MIN(a,b) (((a)<(b))?(a):(b))
        
        int verbose = 0;
       +int current = -1;
        xcb_connection_t *dpy;
        xcb_screen_t *screen;
        xcb_window_t wid;
       t@@ -31,6 +32,31 @@ usage(FILE *fd, char *name)
        }
        
        int
       +outline(xcb_drawable_t xid, int x, int y, int w, int h)
       +{
       +        int mask, val[3];
       +        xcb_gcontext_t gc;
       +        xcb_rectangle_t r;
       +
       +        gc = xcb_generate_id(dpy);
       +
       +        mask = XCB_GC_FUNCTION | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE;
       +        val[0] = XCB_GX_INVERT;
       +        val[1] = 0;
       +        val[2] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS;
       +        xcb_create_gc(dpy, gc, xid, mask, val);
       +
       +        /* draw inverted rectangle */
       +        r.x = x;
       +        r.y = y;
       +        r.width = w;
       +        r.height = h;
       +        xcb_poly_rectangle(dpy, xid, gc, 1, &r);
       +
       +        return 0;
       +}
       +
       +int
        drawentries()
        {
                size_t i, w, h;
       t@@ -85,9 +111,11 @@ main(int argc, char *argv[])
                val[0] = background;
                val[1] = XCB_EVENT_MASK_EXPOSURE
                        | XCB_EVENT_MASK_KEY_PRESS
       +                | XCB_EVENT_MASK_LEAVE_WINDOW
                        | XCB_EVENT_MASK_BUTTON_PRESS
                        | XCB_EVENT_MASK_BUTTON_RELEASE
                        | XCB_EVENT_MASK_BUTTON_MOTION
       +                | XCB_EVENT_MASK_POINTER_MOTION
                        | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
        
                for (nent = 0; entries[nent]; nent++) {
       t@@ -100,13 +128,12 @@ main(int argc, char *argv[])
                        0, 0, width, height, 0,
                        XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, val);
        
       -
       -        //xcb_grab_key(dpy, 1, wid, XCB_NONE, 9, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
       -
                xcb_map_window(dpy, wid);
        
                int loop = 1;
                while(loop) {
       +                int last = current;
       +
                        xcb_flush(dpy);
                        ev = xcb_wait_for_event(dpy);
                        if (!ev)
       t@@ -114,7 +141,13 @@ main(int argc, char *argv[])
        
                        switch(ev->response_type & ~0x80) {
                        case XCB_KEY_PRESS:
       -                        if (((xcb_key_press_event_t *)ev)->detail == 9)
       +                        if (((xcb_key_press_event_t *)ev)->detail == 9) {
       +                                current = -1;
       +                                loop = 0;
       +                        }
       +                        break;
       +                case XCB_BUTTON_RELEASE:
       +                        if (((xcb_button_release_event_t *)ev)->event == wid)
                                        loop = 0;
                                break;
                        case XCB_CONFIGURE_NOTIFY:
       t@@ -124,9 +157,21 @@ main(int argc, char *argv[])
                        case XCB_EXPOSE:
                                drawentries();
                                break;
       +                case XCB_LEAVE_NOTIFY:
       +                        current = -1;
       +                        outline(wid, 0, (height/nent) * last, width, height/nent);
       +                        break;
       +                case XCB_MOTION_NOTIFY:
       +                        current = nent * (((xcb_motion_notify_event_t *)ev)->event_y * 1.0 / height);
       +                        outline(wid, 0, (height/nent) * last, width, height/nent);
       +                        outline(wid, 0, (height/nent) * current, width, height/nent);
       +                        break;
                        }
                }
        
       +        if (current >= 0)
       +                printf("%s\n", entries[current]);
       +
                xcb_disconnect(dpy);
                return 0;
        }