From 5745b52bc92716f7353ddb42fa0fb739cba79bc4 Mon Sep 17 00:00:00 2001 From: speedie Date: Thu, 8 Jun 2023 19:40:30 +0200 Subject: [PATCH 1/3] Add work in progress support for images on Wayland This commit also adds MASSIVE speed improvements to image drawing, due to code cleanup. There are still a *few* issues to resolve, one is X11 related, and one is caused by alpha/blending. --- README.html | 1 - README.md | 1 - docs/docs.md | 1 - docs/spmenu.conf | 7 --- keybinds.h | 2 - libs/arg.c | 11 ----- libs/arg.h | 1 - libs/conf/config.h | 1 - libs/draw.c | 7 ++- libs/img.c | 117 +++++++++++++++++++++++++++++++++++---------- libs/img.h | 11 +++-- libs/libdrw/drw.c | 22 +++++++++ libs/libdrw/drw.h | 7 +++ libs/wl/wayland.h | 1 + libs/x11/client.c | 2 +- libs/x11/event.c | 12 ----- libs/x11/init.c | 2 +- meson.build | 2 +- spmenu.1 | 11 ----- spmenu.c | 3 +- spmenu.html | 85 +++++++++++++++----------------- 21 files changed, 177 insertions(+), 130 deletions(-) diff --git a/README.html b/README.html index 40db233..0f78c05 100644 --- a/README.html +++ b/README.html @@ -219,7 +219,6 @@ alt="typing" /> bliss

  • imlib2
  • libXinerama diff --git a/README.md b/README.md index 3c7ef71..47600fa 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,6 @@ can be themed to look identical to dmenu. - libXrender - For X11 support, which is optional. - imlib2 - - Only a dependency if X11 support is enabled. - Used for image support, can be disabled during compile time. - libXinerama - For X11 support, which is optional. diff --git a/docs/docs.md b/docs/docs.md index 1a5fc90..a8abd9f 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -713,7 +713,6 @@ These are the default keybinds. You can generate these yourself from a | 0 | Shift | equal | setimgsize | +100 | | 0 | Shift | minus | setimgsize | -100 | | 0 | Shift | 0 | defaultimg | 0 | -| 0 | 0 | r | rotateimg | 0 | | 0 | 0 | o | setimgpos | +1 | | 0 | Ctrl | 1 | setimggaps | -1 | | 0 | Ctrl | 2 | setimggaps | +1 | diff --git a/docs/spmenu.conf b/docs/spmenu.conf index aa59040..90d044a 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -440,13 +440,6 @@ spmenu = { function = "defaultimg"; argument = "0"; }, - // r: Rotate image - { mode = 0; - modifier = "None"; - key = "r"; - function = "rotateimg"; - argument = "0"; - }, // o: Toggle image position { mode = 0; modifier = "None"; diff --git a/keybinds.h b/keybinds.h index 7884114..8b7fde1 100644 --- a/keybinds.h +++ b/keybinds.h @@ -36,7 +36,6 @@ static Key keys[] = { { 0, Shift, XK_equal, setimgsize, {.i = +100 } }, { 0, Shift, XK_minus, setimgsize, {.i = -100 } }, { 0, Shift, XK_0, defaultimg, {0} }, - { 0, 0, XK_r, rotateimg, {0} }, { 0, 0, XK_o, setimgpos, {.i = +1 } }, { 0, Ctrl, XK_1, setimggaps, {.i = -1 } }, { 0, Ctrl, XK_2, setimggaps, {.i = +1 } }, @@ -113,7 +112,6 @@ static WlKey wl_keys[] = { { 0, WL_Shift, XKB_KEY_equal, setimgsize, {.i = +100 } }, { 0, WL_Shift, XKB_KEY_minus, setimgsize, {.i = -100 } }, { 0, WL_Shift, XKB_KEY_0, defaultimg, {0} }, - { 0, WL_None, XKB_KEY_r, rotateimg, {0} }, { 0, WL_None, XKB_KEY_o, setimgpos, {.i = +1 } }, { 0, WL_Ctrl, XKB_KEY_1, setimggaps, {.i = -1 } }, { 0, WL_Ctrl, XKB_KEY_2, setimggaps, {.i = +1 } }, diff --git a/libs/arg.c b/libs/arg.c index a996b16..33dc95f 100644 --- a/libs/arg.c +++ b/libs/arg.c @@ -415,17 +415,6 @@ void setimggaps(Arg *arg) { #endif } -void rotateimg(Arg *arg) { -#if USEIMAGE - - if (!image || hideimage) return; - - rotation += arg->i ? arg->i : 1; - - drawmenu(); -#endif -} - void toggleimg(Arg *arg) { #if USEIMAGE diff --git a/libs/arg.h b/libs/arg.h index 0848870..c54da36 100644 --- a/libs/arg.h +++ b/libs/arg.h @@ -35,7 +35,6 @@ static void setimgsize(Arg *arg); static void toggleimg(Arg *arg); static void togglefullimg(Arg *arg); static void defaultimg(Arg *arg); -static void rotateimg(Arg *arg); static void flipimg(Arg *arg); static void setimgpos(Arg *arg); static void setimggaps(Arg *arg); diff --git a/libs/conf/config.h b/libs/conf/config.h index 5aca5b1..4c1e045 100644 --- a/libs/conf/config.h +++ b/libs/conf/config.h @@ -378,7 +378,6 @@ static FuncList fl[] = { { "toggleimg", toggleimg }, { "togglefullimg", togglefullimg }, { "defaultimg", defaultimg }, - { "rotateimg", rotateimg }, { "flipimg", flipimg }, { "setimgpos", setimgpos }, { "setimgpos", setimgpos }, diff --git a/libs/draw.c b/libs/draw.c index 910af7d..1572c2a 100644 --- a/libs/draw.c +++ b/libs/draw.c @@ -286,7 +286,7 @@ int drawitem(int x, int y, int w) { // draw image first #if USEIMAGE - if (!hideimage && longestedge != 0 && !protocol) { // TODO: wayland image support + if (!hideimage && longestedge != 0) { rx = ox; rx += MAX((imagegaps * 2) + imagewidth + menumarginh, indentitems ? x : 0); } else @@ -520,10 +520,12 @@ void drawmenu(void) { wl_surface_attach(state.surface, state.buffer, 0, 0); wl_surface_damage(state.surface, 0, 0, state.width, state.height); wl_surface_commit(state.surface); + + drawimage(); } else { drawmenu_layer(); } -#else +#elif USEX drawmenu_layer(); #endif } @@ -627,6 +629,7 @@ void drawmenu_layer(void) { } #if USEX + drawimage(); drw_map(drw, win, 0, 0, mw, mh); #endif } diff --git a/libs/img.c b/libs/img.c index 7bba09e..f7729eb 100644 --- a/libs/img.c +++ b/libs/img.c @@ -12,11 +12,11 @@ void setimagesize(int width, int height) { oih = imageheight; oiw = imagewidth; + drawimage(); + imageheight = height; imagewidth = width; - drawimage(); - needredraw = 0; if (!image) { @@ -46,11 +46,6 @@ void flipimage(void) { } } -void rotateimage(void) { - rotation %= 4; - imlib_image_orientate(rotation); -} - void cleanupimage(void) { if (image) { // free image using imlib2 imlib_free_image(); @@ -77,8 +72,6 @@ void drawimage(void) { } else if ((!sel || !sel->image) && image) { // free image cleanupimage(); } if (image && longestedge && width && height) { // render the image - // rotate and flip, will return if we don't need to - rotateimage(); flipimage(); int leftmargin = imagegaps; // gaps between image and menu @@ -97,9 +90,9 @@ void drawimage(void) { wta += menumarginv; if (mh != bh + height + leftmargin * 2 - wtr && !fullscreen) { // menu height cannot be smaller than image height - resizetoimageheight(height); + resizetoimageheight(width, height); } else if (mh != bh + height + leftmargin * 2 - wtr && fullscreen) { - resizetoimageheight(height-bh); + resizetoimageheight(width-bh, height-bh); } // we're covering all the area @@ -107,20 +100,23 @@ void drawimage(void) { xta = wta = wtr = leftmargin = 0; } - // render image + drw_set_img(drw, imlib_image_get_data(), width, height); + + // render image on X11 if (!imageposition && image) { // top mode = 0 if (height > width) width = height; - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, wta+leftmargin); + + drw_img(drw, leftmargin+(imagewidth-width)/2+xta, wta+leftmargin); } else if (imageposition == 1 && image) { // bottom mode = 1 if (height > width) width = height; - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, mh-height-leftmargin); + drw_img(drw, leftmargin+(imagewidth-width)/2+xta, mh-height-leftmargin); } else if (imageposition == 2 && image) { // center mode = 2 - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, (mh-wta-height)/2+wta); + drw_img(drw, leftmargin+(imagewidth-width)/2+xta, (mh-wta-height)/2+wta); } else if (image) { // top center int minh = MIN(height, mh-bh-leftmargin*2); - imlib_render_image_on_drawable(leftmargin+(imagewidth-width)/2+xta, (minh-height)/2+wta+leftmargin); + drw_img(drw, leftmargin+(imagewidth-width)/2+xta, (minh-height)/2+wta+leftmargin); } } @@ -131,18 +127,12 @@ void drawimage(void) { } } -#if USEX void setimageopts(void) { imlib_set_cache_size(8192 * 1024); imlib_context_set_blend(1); imlib_context_set_dither(1); imlib_set_color_usage(128); - imlib_context_set_display(dpy); - imlib_context_set_visual(visual); - imlib_context_set_colormap(cmap); - imlib_context_set_drawable(win); } -#endif void createifnexist(const char *dir) { // exists, so return @@ -337,8 +327,25 @@ void jumptoindex(unsigned int index) { } } -void resizetoimageheight(int imageheight) { +void resizetoimageheight(int imagewidth, int imageheight) { + //int ih = imageheight; + int ih = imlib_image_get_height(); + #if USEX + if (!protocol) { + resizetoimageheight_x11(ih); + } else { +#if USEWAYLAND + resizetoimageheight_wl(ih); +#endif + } +#elif USEWAYLAND + resizetoimageheight_wl(ih); +#endif +} + +#if USEX +void resizetoimageheight_x11(int imageheight) { int omh = mh, olines = lines; lines = reallines; int wtr = 0; @@ -447,9 +454,69 @@ void resizetoimageheight(int imageheight) { jumptoindex(i); } - drawmenu(); -#endif + drawmenu_layer(); } +#endif + +#if USEWAYLAND +void resizetoimageheight_wl(int imageheight) { + int omh = mh, olines = lines; + lines = reallines; + int wtr = 0; + + if (lines * bh < imageheight + imagegaps * 2) { + lines = (imageheight + imagegaps * 2) / bh; + } + + if (hideprompt && hideinput && hidemode && hidematchcount) { + wtr = bh; + } + + mh = MAX((lines + 1) * bh + 2 * menumarginv, ((lines + 1) * bh) - wtr + 2 * menumarginv); + + if (mh - bh < imageheight + imagegaps * 2) { + mh = (imageheight + imagegaps * 2 + bh) - wtr + 2 * menumarginv; + } + + if (omh == mh) { + return; + } + + if (olines != lines) { + struct item *item; + unsigned int i = 1; + + // walk through all matches + for (item = matches; item && item != sel; item = item->right) + ++i; + + jumptoindex(i); + } + + state.width = mw; + state.height = mh; + + state.buffer = create_buffer(&state); + + if (drw == NULL) { + die("spmenu: drw == NULL"); + } + + if (state.buffer == NULL) { + die("state.buffer == null"); + } + + set_layer_size(&state, state.width, state.height); + drw_create_surface_wl(drw, state.data, state.width, state.height); + + drawmenu(); + + wl_surface_set_buffer_scale(state.surface, 1); + wl_surface_attach(state.surface, state.buffer, 0, 0); + wl_surface_damage(state.surface, 0, 0, state.width, state.height); + wl_surface_commit(state.surface); +} +#endif void store_image_vars(void) { longestedge = MAX(imagewidth, imageheight); diff --git a/libs/img.h b/libs/img.h index 714275f..399a8e3 100644 --- a/libs/img.h +++ b/libs/img.h @@ -7,16 +7,19 @@ #include static void setimagesize(int width, int height); -#if USEX static void setimageopts(void); -#endif static void cleanupimage(void); static void drawimage(void); -static void rotateimage(void); static void flipimage(void); static void loadimage(const char *file, int *width, int *height); static void loadimagecache(const char *file, int *width, int *height); -static void resizetoimageheight(int imageheight); +static void resizetoimageheight(int imagewidth, int imageheight); +#if USEWAYLAND +static void resizetoimageheight_wl(int imageheight); +#endif +#if USEX +static void resizetoimageheight_x11(int imageheight); +#endif static void store_image_vars(void); static Imlib_Image image = NULL; diff --git a/libs/libdrw/drw.c b/libs/libdrw/drw.c index 97acadc..f95d9ac 100644 --- a/libs/libdrw/drw.c +++ b/libs/libdrw/drw.c @@ -415,6 +415,28 @@ void drw_cur_free(Drw *drw, Cur *cursor) { #endif } +void drw_set_img(Drw *drw, void *data, int w, int h) { + if (!w || !h || !drw) { + return; + } + + drw->img_data = data; + drw->img_surface = cairo_image_surface_create_for_data(drw->img_data, CAIRO_FORMAT_ARGB32, w, h, w * 4); +} + +void drw_img(Drw *drw, int x, int y) { + if (!drw) { + return; + } + + cairo_set_operator(drw->d, CAIRO_OPERATOR_OVER); + + cairo_set_source_surface(drw->d, drw->img_surface, x, y); + cairo_paint(drw->d); + + cairo_set_source_surface(drw->d, drw->surface, drw->w, drw->h); +} + unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup) { unsigned int tmp = 0; if (drw && drw->font && text && n) diff --git a/libs/libdrw/drw.h b/libs/libdrw/drw.h index 70d0bf0..71c7beb 100644 --- a/libs/libdrw/drw.h +++ b/libs/libdrw/drw.h @@ -24,18 +24,25 @@ typedef struct { Window root; Visual *visual; unsigned int depth; + void *img_data; void *data; Colormap cmap; Drawable drawable; GC gc; Fnt *font; cairo_surface_t *surface; + cairo_surface_t *img_surface; cairo_t *d; + cairo_t *img_d; } Drw; /* Cairo color convertion */ void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha); +/* Cairo image drawing */ +void drw_img(Drw *drw, int x, int y); +void drw_set_img(Drw *drw, void *data, int w, int h); + /* Drawable abstraction */ Drw *drw_create_x11(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol); Drw *drw_create_wl(int protocol); diff --git a/libs/wl/wayland.h b/libs/wl/wayland.h index 4b361d7..3775c8f 100644 --- a/libs/wl/wayland.h +++ b/libs/wl/wayland.h @@ -145,6 +145,7 @@ static int set_exclusive_zone(struct state *state, unsigned int val); static int set_keyboard(struct state *state, int interactivity); static int add_layer_listener(struct state *state); static int set_visible_layer(struct state *state); +struct wl_buffer *create_buffer(struct state *state); /* Set to 0 if the connection was successful * You can use this for say, X11 compatibility mode. diff --git a/libs/x11/client.c b/libs/x11/client.c index 04a1a95..f283a87 100644 --- a/libs/x11/client.c +++ b/libs/x11/client.c @@ -93,7 +93,7 @@ void resizeclient_x11(void) { // resize client to image height #if USEIMAGE - if (image) resizetoimageheight(imageheight); + if (image) resizetoimageheight(imagewidth, imageheight); #endif mh = (lines + 1) * bh + 2 * menumarginv; diff --git a/libs/x11/event.c b/libs/x11/event.c index 297aa47..064c7bf 100644 --- a/libs/x11/event.c +++ b/libs/x11/event.c @@ -1,7 +1,6 @@ /* See LICENSE file for copyright and license details. */ void eventloop_x11(void) { XEvent ev; - int noimg = 0; while (!XNextEvent(dpy, &ev)) { if (XFilterEvent(&ev, None)) @@ -15,7 +14,6 @@ void eventloop_x11(void) { exit(1); case ButtonPress: buttonpress_x11(&ev); - noimg = 0; break; case MotionNotify: // currently does nothing break; @@ -35,7 +33,6 @@ void eventloop_x11(void) { } keypress_x11(&ev); - noimg = 1; break; case SelectionNotify: // paste selection if (ev.xselection.property == utf8) @@ -48,7 +45,6 @@ void eventloop_x11(void) { case KeyRelease: getcapsstate(); drawmenu(); - noimg = 0; break; } @@ -67,13 +63,5 @@ void eventloop_x11(void) { drawmenu(); } } - - // redraw image on X11 event - if (!noimg) -#if USEIMAGE - drawimage(); -#else - ; -#endif } } diff --git a/libs/x11/init.c b/libs/x11/init.c index 800e554..d047109 100644 --- a/libs/x11/init.c +++ b/libs/x11/init.c @@ -10,7 +10,7 @@ void setupdisplay_x11(void) { // resize client to image height if deemed necessary #if USEIMAGE - if (image) resizetoimageheight(imageheight); + if (image) resizetoimageheight(imagewidth, imageheight); #endif // set prompt width based on prompt size diff --git a/meson.build b/meson.build index 0cf41a5..96f1cb5 100644 --- a/meson.build +++ b/meson.build @@ -57,7 +57,7 @@ if get_option('wayland') run_command('scripts/make/generate-headers.sh', check : false) endif -if get_option('imlib2') and get_option('openssl') and get_option('x11') +if get_option('imlib2') and get_option('openssl') project_dependencies += [ dependency('imlib2') ] project_dependencies += [ dependency('openssl') ] build_args += [ '-DIMAGE' ] diff --git a/spmenu.1 b/spmenu.1 index 42aa100..8481952 100644 --- a/spmenu.1 +++ b/spmenu.1 @@ -1001,17 +1001,6 @@ T{ T}@T{ 0 T}@T{ -r -T}@T{ -rotateimg -T}@T{ -0 -T} -T{ -0 -T}@T{ -0 -T}@T{ o T}@T{ setimgpos diff --git a/spmenu.c b/spmenu.c index 6ef8998..20f3cb6 100644 --- a/spmenu.c +++ b/spmenu.c @@ -153,7 +153,6 @@ struct item { // image globals #if USEIMAGE static int flip = 0; -static int rotation = 0; static int needredraw = 1; static int longestedge = 0; static int imagew = 0; @@ -495,7 +494,7 @@ void handle(void) { } loadhistory(); // read history entries -#if USEX +#if USEIMAGE store_image_vars(); #endif diff --git a/spmenu.html b/spmenu.html index 8806d2d..7c7f0eb 100644 --- a/spmenu.html +++ b/spmenu.html @@ -1186,284 +1186,277 @@ a keybinds.h using 0 0 -r -rotateimg -0 - - -0 -0 o setimgpos +1 - + 0 Ctrl 1 setimggaps -1 - + 0 Ctrl 2 setimggaps +1 - + 0 0 1 setimggaps -10 - + 0 0 2 setimggaps +10 - + 0 Shift 1 setimggaps -100 - + 0 Shift 2 setimggaps +100 - + 0 0 t toggleimg 0 - + 0 0 f togglefullimg 0 - + 0 0 p paste 2 - + 0 0 h flipimg 1 - + 0 0 v flipimg 0 - + 0 0 k moveup 0 - + 0 0 j movedown 0 - + 0 0 h moveleft 0 - + 0 0 l moveright 0 - + 0 Ctrl u moveup 5 - + 0 Ctrl d movedown 5 - + 0 Ctrl k setlines +1 - + 0 Ctrl j setlines -1 - + 0 Ctrl+Alt+Shift k setlines +5 - + 0 Ctrl+Alt+Shift j setlines -5 - + 0 Ctrl h setcolumns +1 - + 0 Ctrl l setcolumns -1 - + 0 Ctrl+Alt+Shift h setcolumns +5 - + 0 Ctrl+Alt+Shift l setcolumns -5 - + 0 0 u togglehighlight 0 - + 0 Ctrl+Shift h viewhist 0 - + 0 0 d clear 0 - + 0 Shift d clearins 0 - + 0 0 Escape quit 0 - + 0 0 Home movestart 0 - + 0 0 End moveend 0 - + 0 0 g movestart 0 - + 0 Shift g moveend 0 - + 0 0 Next movenext 0 - + 0 0 Prior moveprev 0 - + 0 Alt p navhistory -1 - + 0 Alt n navhistory +1 - + 1 0 Escape From 148c219ec51b9dea48edab62296035f4fa001010 Mon Sep 17 00:00:00 2001 From: speedie Date: Thu, 8 Jun 2023 20:30:42 +0200 Subject: [PATCH 2/3] Fix alpha mask --- libs/img.c | 2 -- libs/libdrw/drw.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libs/img.c b/libs/img.c index f7729eb..4d7708d 100644 --- a/libs/img.c +++ b/libs/img.c @@ -129,8 +129,6 @@ void drawimage(void) { void setimageopts(void) { imlib_set_cache_size(8192 * 1024); - imlib_context_set_blend(1); - imlib_context_set_dither(1); imlib_set_color_usage(128); } diff --git a/libs/libdrw/drw.c b/libs/libdrw/drw.c index f95d9ac..a747e04 100644 --- a/libs/libdrw/drw.c +++ b/libs/libdrw/drw.c @@ -432,7 +432,7 @@ void drw_img(Drw *drw, int x, int y) { cairo_set_operator(drw->d, CAIRO_OPERATOR_OVER); cairo_set_source_surface(drw->d, drw->img_surface, x, y); - cairo_paint(drw->d); + cairo_mask_surface(drw->d, drw->img_surface, x, y); cairo_set_source_surface(drw->d, drw->surface, drw->w, drw->h); } From e6b2c0d9c954ed12bc8a377ef28b6a6e57b6ade5 Mon Sep 17 00:00:00 2001 From: speedie Date: Thu, 8 Jun 2023 22:42:25 +0200 Subject: [PATCH 3/3] Fix some bugs which had been previous undiscovered with the keysym handling --- docs/spmenu.conf | 10 +++++----- libs/x11/key.c | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/spmenu.conf b/docs/spmenu.conf index 90d044a..e1a48ef 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -422,21 +422,21 @@ spmenu = { // Shift+=: Increase image size by 100 { mode = 0; modifier = "Shift"; - key = "="; + key = "+"; // Note that + is used instead of = because Shift is held down. function = "setimgsize"; argument = "+100"; }, // Shift+-: Decrease image size by 100 { mode = 0; modifier = "Shift"; - key = "-"; + key = "_"; // Note that _ is used instead of - because Shift is held down. function = "setimgsize"; argument = "-100"; }, // Shift+0: Set image size to the default { mode = 0; modifier = "Shift"; - key = "0"; + key = ")"; // Note that ) is used instead of 0 because Shift is held down. function = "defaultimg"; argument = "0"; }, @@ -485,14 +485,14 @@ spmenu = { // Shift+1: Decrease image gaps by 100 { mode = 0; modifier = "Shift"; - key = "1"; + key = "!"; // Note that ! is used instead of 1 because Shift is held down. function = "setimggaps"; argument = "-100"; }, // Shift+2: Increase image gaps by 100 { mode = 0; modifier = "Shift"; - key = "2"; + key = "@"; // Note that @ is used instead of 2 because Shift is held down. function = "setimggaps"; argument = "+100"; }, diff --git a/libs/x11/key.c b/libs/x11/key.c index ca55272..efc9dd2 100644 --- a/libs/x11/key.c +++ b/libs/x11/key.c @@ -18,7 +18,8 @@ void keypress_x11(XEvent *e) { updatenumlockmask(); { unsigned int i; - KeySym keysym; + KeySym keysym = NoSymbol; + KeySym keysym_case = NoSymbol; XKeyEvent *ev; char buf[64]; KeySym ksym = NoSymbol; @@ -28,7 +29,8 @@ void keypress_x11(XEvent *e) { ev = &e->xkey; len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); + // keysym = XkbKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0, 0); + XConvertCase(ksym, &keysym, &keysym_case); // this makes sure we always have a way to exit if we unbind our quit key if (keysym == hkeys[0].keysym && CLEANMASK(hkeys[0].mod) == CLEANMASK(ev->state) && hkeys[0].func) hkeys[0].func(&(hkeys[0].arg));