itMove window creation and event loop outside the main() - xmenu - drop-down menu for X11 Err z3bra.org 70 hgit clone git://git.z3bra.org/xmenu.git URL:git://git.z3bra.org/xmenu.git z3bra.org 70 1Log /scm/xmenu/log.gph z3bra.org 70 1Files /scm/xmenu/files.gph z3bra.org 70 1Refs /scm/xmenu/refs.gph z3bra.org 70 i--- Err z3bra.org 70 1commit 61c19bc23c3509c5b1e32afe95f335516fd39d32 /scm/xmenu/commit/61c19bc23c3509c5b1e32afe95f335516fd39d32.gph z3bra.org 70 1parent c6811f6a13d0f8b361c2860ae1c38ac88ac341ec /scm/xmenu/commit/c6811f6a13d0f8b361c2860ae1c38ac88ac341ec.gph z3bra.org 70 hAuthor: Willy Goiffon URL:mailto:dev@z3bra.org z3bra.org 70 iDate: Wed, 20 Nov 2019 14:04:43 +0100 Err z3bra.org 70 i Err z3bra.org 70 iMove window creation and event loop outside the main() Err z3bra.org 70 i Err z3bra.org 70 iDiffstat: Err z3bra.org 70 i M xmenu.c | 132 +++++++++++++++++++------------ Err z3bra.org 70 i Err z3bra.org 70 i1 file changed, 80 insertions(+), 52 deletions(-) Err z3bra.org 70 i--- Err z3bra.org 70 1diff --git a/xmenu.c b/xmenu.c /scm/xmenu/file/xmenu.c.gph z3bra.org 70 it@@ -42,10 +42,9 @@ hilight(xcb_drawable_t xid, int x, int y, int w, int h) Err z3bra.org 70 i Err z3bra.org 70 i gc = xcb_generate_id(dpy); Err z3bra.org 70 i Err z3bra.org 70 i- mask = XCB_GC_FUNCTION | XCB_GC_LINE_WIDTH | XCB_GC_SUBWINDOW_MODE; Err z3bra.org 70 i+ mask = XCB_GC_FUNCTION | XCB_GC_SUBWINDOW_MODE; Err z3bra.org 70 i val[0] = XCB_GX_INVERT; Err z3bra.org 70 i- val[1] = 0; Err z3bra.org 70 i- val[2] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS; Err z3bra.org 70 i+ val[1] = XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS; Err z3bra.org 70 i xcb_create_gc(dpy, gc, xid, mask, val); Err z3bra.org 70 i Err z3bra.org 70 i /* draw inverted rectangle */ Err z3bra.org 70 it@@ -73,39 +72,9 @@ drawentries() Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i int Err z3bra.org 70 i-main(int argc, char *argv[]) Err z3bra.org 70 i+popwindow(int w, int h) Err z3bra.org 70 i { Err z3bra.org 70 i- char *argv0; Err z3bra.org 70 i- long dpi; Err z3bra.org 70 i int mask, val[4]; Err z3bra.org 70 i- xcb_generic_event_t *ev = NULL; Err z3bra.org 70 i- Err z3bra.org 70 i- ARGBEGIN { Err z3bra.org 70 i- case 'h': Err z3bra.org 70 i- usage(stdout, argv0); Err z3bra.org 70 i- return 0; Err z3bra.org 70 i- break; Err z3bra.org 70 i- case 'v': Err z3bra.org 70 i- verbose++; Err z3bra.org 70 i- break; Err z3bra.org 70 i- default: Err z3bra.org 70 i- usage(stderr, argv0); Err z3bra.org 70 i- return -1; Err z3bra.org 70 i- break; Err z3bra.org 70 i- } ARGEND; Err z3bra.org 70 i- Err z3bra.org 70 i- dpy = xcb_connect(NULL, NULL); Err z3bra.org 70 i- if (xcb_connection_has_error(dpy)) Err z3bra.org 70 i- return -1; Err z3bra.org 70 i- Err z3bra.org 70 i- screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; Err z3bra.org 70 i- if (!screen) Err z3bra.org 70 i- return -1; Err z3bra.org 70 i- Err z3bra.org 70 i- /* 1 inch = 25.4 millimeters */ Err z3bra.org 70 i- dpi = screen->height_in_pixels/screen->height_in_millimeters * 25.4; Err z3bra.org 70 i- Err z3bra.org 70 i- xft_loadfont(font, dpi); Err z3bra.org 70 i Err z3bra.org 70 i mask = XCB_CW_BACK_PIXEL Err z3bra.org 70 i | XCB_CW_EVENT_MASK; Err z3bra.org 70 it@@ -120,46 +89,56 @@ main(int argc, char *argv[]) Err z3bra.org 70 i | XCB_EVENT_MASK_POINTER_MOTION Err z3bra.org 70 i | XCB_EVENT_MASK_STRUCTURE_NOTIFY; Err z3bra.org 70 i Err z3bra.org 70 i- for (nent = 0; entries[nent]; nent++) { Err z3bra.org 70 i- maxwidth = MAX(xft_txtw(entries[nent]), maxwidth); Err z3bra.org 70 i- maxheight = MAX(xft_txth(entries[nent]), maxheight); Err z3bra.org 70 i- } Err z3bra.org 70 i- Err z3bra.org 70 i- width = maxwidth * 1.2; Err z3bra.org 70 i- height = maxheight * nent * 2.5; Err z3bra.org 70 i- Err z3bra.org 70 i wid = xcb_generate_id(dpy); Err z3bra.org 70 i xcb_create_window(dpy, screen->root_depth, wid, screen->root, Err z3bra.org 70 i- 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, Err z3bra.org 70 i+ 0, 0, w, h, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, Err z3bra.org 70 i screen->root_visual, mask, val); Err z3bra.org 70 i Err z3bra.org 70 i xcb_map_window(dpy, wid); Err z3bra.org 70 i+ xcb_flush(dpy); Err z3bra.org 70 i+ Err z3bra.org 70 i+ return 0; Err z3bra.org 70 i+} Err z3bra.org 70 i Err z3bra.org 70 i+int Err z3bra.org 70 i+eventloop() Err z3bra.org 70 i+{ Err z3bra.org 70 i int loop = 1; Err z3bra.org 70 i+ xcb_generic_event_t *ev; Err z3bra.org 70 i+ Err z3bra.org 70 i while(loop) { Err z3bra.org 70 i int last = current; Err z3bra.org 70 i Err z3bra.org 70 i- xcb_flush(dpy); Err z3bra.org 70 i ev = xcb_wait_for_event(dpy); Err z3bra.org 70 i if (!ev) Err z3bra.org 70 i break; Err z3bra.org 70 i Err z3bra.org 70 i switch(ev->response_type & ~0x80) { Err z3bra.org 70 i case XCB_KEY_PRESS: Err z3bra.org 70 i- if (((xcb_key_press_event_t *)ev)->detail == 9) { Err z3bra.org 70 i- current = -1; Err z3bra.org 70 i- loop = 0; Err z3bra.org 70 i- } Err z3bra.org 70 i+ if (((xcb_key_press_event_t *)ev)->detail == 9) Err z3bra.org 70 i+ return -1; Err z3bra.org 70 i break; Err z3bra.org 70 i case XCB_BUTTON_RELEASE: Err z3bra.org 70 i if (((xcb_button_release_event_t *)ev)->event == wid) Err z3bra.org 70 i- loop = 0; Err z3bra.org 70 i+ return current; Err z3bra.org 70 i break; Err z3bra.org 70 i case XCB_CONFIGURE_NOTIFY: Err z3bra.org 70 i width = ((xcb_configure_notify_event_t *)ev)->width; Err z3bra.org 70 i height = ((xcb_configure_notify_event_t *)ev)->height; Err z3bra.org 70 i break; Err z3bra.org 70 i case XCB_EXPOSE: Err z3bra.org 70 i+ /* Err z3bra.org 70 i+ * TODO: clean after someone mess up current entry Err z3bra.org 70 i+ * As the current entry is represented using an Err z3bra.org 70 i+ * XCB_GX_INVERT function, an external program Err z3bra.org 70 i+ * could mess up the display by drawing over Err z3bra.org 70 i+ * the selection using a non-inverting function. Err z3bra.org 70 i+ * Inverting a partially cleared region would Err z3bra.org 70 i+ * end up inverting the artifacts, so we must Err z3bra.org 70 i+ * find a way to clean up this mess somehow. Err z3bra.org 70 i+ * Err z3bra.org 70 i+ * Damn punks. Err z3bra.org 70 i+ */ Err z3bra.org 70 i if (last >= 0) Err z3bra.org 70 i hilight(wid, 0, (height/nent) * last, width, height/nent); Err z3bra.org 70 i drawentries(); Err z3bra.org 70 it@@ -168,7 +147,7 @@ main(int argc, char *argv[]) Err z3bra.org 70 i break; Err z3bra.org 70 i case XCB_LEAVE_NOTIFY: Err z3bra.org 70 i hilight(wid, 0, (height/nent) * current, width, height/nent); Err z3bra.org 70 i- current = last = -1; Err z3bra.org 70 i+ current = -1; Err z3bra.org 70 i break; Err z3bra.org 70 i case XCB_MOTION_NOTIFY: Err z3bra.org 70 i /* Err z3bra.org 70 it@@ -191,11 +170,60 @@ main(int argc, char *argv[]) Err z3bra.org 70 i break; Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i+ xcb_flush(dpy); Err z3bra.org 70 i free(ev); Err z3bra.org 70 i } Err z3bra.org 70 i Err z3bra.org 70 i- if (current >= 0) Err z3bra.org 70 i- printf("%s\n", entries[current]); Err z3bra.org 70 i+ return -1; Err z3bra.org 70 i+} Err z3bra.org 70 i+ Err z3bra.org 70 i+int Err z3bra.org 70 i+main(int argc, char *argv[]) Err z3bra.org 70 i+{ Err z3bra.org 70 i+ int selected = 0; Err z3bra.org 70 i+ long dpi; Err z3bra.org 70 i+ char *argv0; Err z3bra.org 70 i+ Err z3bra.org 70 i+ ARGBEGIN { Err z3bra.org 70 i+ case 'h': Err z3bra.org 70 i+ usage(stdout, argv0); Err z3bra.org 70 i+ return 0; Err z3bra.org 70 i+ break; Err z3bra.org 70 i+ case 'v': Err z3bra.org 70 i+ verbose++; Err z3bra.org 70 i+ break; Err z3bra.org 70 i+ default: Err z3bra.org 70 i+ usage(stderr, argv0); Err z3bra.org 70 i+ return -1; Err z3bra.org 70 i+ break; Err z3bra.org 70 i+ } ARGEND; Err z3bra.org 70 i+ Err z3bra.org 70 i+ dpy = xcb_connect(NULL, NULL); Err z3bra.org 70 i+ if (xcb_connection_has_error(dpy)) Err z3bra.org 70 i+ return -1; Err z3bra.org 70 i+ Err z3bra.org 70 i+ screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; Err z3bra.org 70 i+ if (!screen) Err z3bra.org 70 i+ return -1; Err z3bra.org 70 i+ Err z3bra.org 70 i+ /* 1 inch = 25.4 millimeters */ Err z3bra.org 70 i+ dpi = screen->height_in_pixels/screen->height_in_millimeters * 25.4; Err z3bra.org 70 i+ Err z3bra.org 70 i+ xft_loadfont(font, dpi); Err z3bra.org 70 i+ Err z3bra.org 70 i+ for (nent = 0; entries[nent]; nent++) { Err z3bra.org 70 i+ maxwidth = MAX(xft_txtw(entries[nent]), maxwidth); Err z3bra.org 70 i+ maxheight = MAX(xft_txth(entries[nent]), maxheight); Err z3bra.org 70 i+ } Err z3bra.org 70 i+ Err z3bra.org 70 i+ width = maxwidth * 1.2; Err z3bra.org 70 i+ height = maxheight * nent * 2.5; Err z3bra.org 70 i+ Err z3bra.org 70 i+ popwindow(width, height); Err z3bra.org 70 i+ selected = eventloop(); Err z3bra.org 70 i+ Err z3bra.org 70 i+ if (selected >= 0) Err z3bra.org 70 i+ printf("%s\n", entries[selected]); Err z3bra.org 70 i Err z3bra.org 70 i xft_unload(); Err z3bra.org 70 i xcb_disconnect(dpy); Err z3bra.org 70 .