diff options
| author | Jari Vetoniemi <mailroxas@gmail.com> | 2014-10-25 20:02:34 +0300 | 
|---|---|---|
| committer | Jari Vetoniemi <mailroxas@gmail.com> | 2014-10-25 20:02:34 +0300 | 
| commit | d3db039136ad66d2c83c1c0fbf0964bfbb5afb16 (patch) | |
| tree | 93af6d73ad168e0169183a9c4f625acd5492e08c /lib | |
| parent | 2820734ec01ad6d2e1a0611fa480c3dd533588c7 (diff) | |
| download | bemenu-d3db039136ad66d2c83c1c0fbf0964bfbb5afb16.tar.gz bemenu-d3db039136ad66d2c83c1c0fbf0964bfbb5afb16.tar.bz2 bemenu-d3db039136ad66d2c83c1c0fbf0964bfbb5afb16.zip | |
Single line mode, color customization, etc..
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/bemenu.h | 77 | ||||
| -rw-r--r-- | lib/internal.h | 48 | ||||
| -rw-r--r-- | lib/library.c | 2 | ||||
| -rw-r--r-- | lib/menu.c | 111 | ||||
| -rw-r--r-- | lib/renderers/cairo.h | 172 | ||||
| -rw-r--r-- | lib/renderers/curses/curses.c | 14 | ||||
| -rw-r--r-- | lib/renderers/wayland/wayland.c | 44 | ||||
| -rw-r--r-- | lib/renderers/wayland/wayland.h | 3 | ||||
| -rw-r--r-- | lib/renderers/wayland/window.c | 92 | 
9 files changed, 457 insertions, 106 deletions
| diff --git a/lib/bemenu.h b/lib/bemenu.h index 20574f6..c52135d 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -183,6 +183,26 @@ enum bm_key {  };  /** + * Colorable element constants. + * + * @link ::bm_color BM_COLOR_LAST @endlink is provided for enumerating colors. + */ +enum bm_color { +    BM_COLOR_BG, +    BM_COLOR_TITLE_BG, +    BM_COLOR_TITLE_FG, +    BM_COLOR_FILTER_BG, +    BM_COLOR_FILTER_FG, +    BM_COLOR_ITEM_BG, +    BM_COLOR_ITEM_FG, +    BM_COLOR_HIGHLIGHTED_BG, +    BM_COLOR_HIGHLIGHTED_FG, +    BM_COLOR_SELECTED_BG, +    BM_COLOR_SELECTED_FG, +    BM_COLOR_LAST +}; + +/**   * @name Menu Memory   * @{ */ @@ -265,10 +285,27 @@ void bm_menu_set_filter_mode(struct bm_menu *menu, enum bm_filter_mode mode);  enum bm_filter_mode bm_menu_get_filter_mode(const struct bm_menu *menu);  /** + * Set amount of max vertical lines to be shown. + * Some renderers such as ncurses may ignore this when it does not make sense. + * + * @param menu bm_menu instance where to set max vertical line amount. + * @param lines 0 for single line layout, > 0 to show that many lines. + */ +void bm_menu_set_lines(struct bm_menu *menu, uint32_t lines); + +/** + * Get amount of max vertical lines to be shown. + * + * @param menu bm_menu instance where to get max vertical line amount. + * @return uint32_t for max amount of vertical lines to be shown. + */ +uint32_t bm_menu_get_lines(struct bm_menu *menu); + +/**   * Set selection wrapping on/off.   *   * @param menu bm_menu instance where to toggle selection wrapping. - * @param bool true/false. + * @param wrap true/false.   */  void bm_menu_set_wrap(struct bm_menu *menu, bool wrap); @@ -297,6 +334,44 @@ bool bm_menu_set_title(struct bm_menu *menu, const char *title);   */  const char* bm_menu_get_title(const struct bm_menu *menu); +/** + * Set font to bm_menu instance. + * + * @param font C "string" to set as font, can be **NULL** for default (Terminus). + * @param size Size for the font, may be set 0 for default. + * @return true if set was succesful, false if out of memory. + */ +bool bm_menu_set_font(struct bm_menu *menu, const char *font, uint32_t size); + +/** + * Get font from bm_menu instance. + * + * @param menu bm_menu instance where to get font from. + * @param out_size Reference to uint32_t, will be se to size of the font. May set **NULL** for no-op. + * @return Pointer to null terminated C "string". + */ +const char* bm_menu_get_font(const struct bm_menu *menu, uint32_t *out_size); + +/** + * Set a hexadecimal color for element. + * + * @param menu bm_menu instance where to set color. + * @param color bm_color type. + * @param hex Color in hexadecimal format starting with '#'. + * @return true if set was succesful, false if out of memory. + */ +bool bm_menu_set_color(struct bm_menu *menu, enum bm_color color, const char *hex); + +/** + * Get hexadecimal color for element. + * + * @param menu bm_menu instance where to get color from. + * @param color bm_color type. + * @return Pointer to null terminated C "string". + */ +const char* bm_menu_get_color(const struct bm_menu *menu, enum bm_color color); + +  /**  @} Properties */  /** diff --git a/lib/internal.h b/lib/internal.h index 6613cef..b9b4a5e 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -134,6 +134,38 @@ struct bm_item {  };  /** + * Internal bm_hex_color struct that is not exposed to public. + * Represent a color for element. + */ +struct bm_hex_color { +    /** +     * Provided hex for the color. +     */ +    char *hex; + +    /** +     * RGB values. +     */ +    uint8_t r, g, b; +}; + +/** + * Internal bm_font struct that is not exposed to public. + * Represent a font for text. + */ +struct bm_font { +    /** +     * Name of the font. +     */ +    char *name; + +    /** +     * Size of font. +     */ +    uint32_t size; +}; + +/**   * Internal bm_menu struct that is not exposed to public.   */  struct bm_menu { @@ -169,6 +201,16 @@ struct bm_menu {      char *title;      /** +     * Font. +     */ +    struct bm_font font; + +    /** +     * Colors. +     */ +    struct bm_hex_color colors[BM_COLOR_LAST]; + +    /**       * Text used to filter matches.       */      char *filter; @@ -200,6 +242,12 @@ struct bm_menu {      uint32_t index;      /** +     * Max number of vertical lines to be shown. +     * Some renderers such as ncurses may ignore this when it does not make sense. +     */ +    uint32_t lines; + +    /**       * Current filtering method in menu instance.       */      enum bm_filter_mode filter_mode; diff --git a/lib/library.c b/lib/library.c index 7fca099..4d7e212 100644 --- a/lib/library.c +++ b/lib/library.c @@ -30,7 +30,7 @@ load(const char *file, struct bm_renderer *renderer)      const char *error = NULL;      if (!(handle = chckDlLoad(file, &error))) -        goto fail; +        goto load_fail;      const char* (*regfun)(struct render_api*);      if (!(regfun = chckDlLoadSymbol(handle, "register_renderer", &error))) @@ -1,10 +1,33 @@  #include "internal.h" +#include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <ctype.h>  #include <assert.h>  /** + * Default font. + */ +static const char *default_font = "Terminus"; + +/** + * Default hexadecimal colors. + */ +static const char *default_colors[BM_COLOR_LAST] = { +    "#121212", // BM_COLOR_BG +    "#121212", // BM_COLOR_TITLE_BG +    "#D81860", // BM_COLOR_TITLE_FG +    "#121212", // BM_COLOR_FILTER_BG +    "#CACACA", // BM_COLOR_FILTER_FG +    "#121212", // BM_COLOR_ITEM_BG +    "#CACACA", // BM_COLOR_ITEM_FG +    "#121212", // BM_COLOR_HIGHLIGHTED_BG +    "#D81860", // BM_COLOR_HIGHLIGHTED_FG +    "#121212", // BM_COLOR_SELECTED_BG +    "#D81860"  // BM_COLOR_SELECTED_FG +}; + +/**   * Filter function map.   */  static struct bm_item** (*filter_func[BM_FILTER_MODE_LAST])(struct bm_menu *menu, bool addition, uint32_t *out_nmemb) = { @@ -51,12 +74,21 @@ bm_menu_new(const char *renderer, enum bm_prioritory prioritory)              break;      } -    if (!menu->renderer) { -        bm_menu_free(menu); -        return NULL; -    } +    if (!menu->renderer) +        goto fail; +    if (!bm_menu_set_font(menu, NULL, 0)) +        goto fail; + +    for (uint32_t i = 0; i < BM_COLOR_LAST; ++i) { +        if (!bm_menu_set_color(menu, i, NULL)) +            goto fail; +    }      return menu; + +fail: +    bm_menu_free(menu); +    return NULL;  }  void @@ -71,6 +103,11 @@ bm_menu_free(struct bm_menu *menu)      free(menu->filter);      free(menu->old_filter); +    free(menu->font.name); + +    for (uint32_t i = 0; i < BM_COLOR_LAST; ++i) +        free(menu->colors[i].hex); +      bm_menu_free_items(menu);      free(menu);  } @@ -130,6 +167,20 @@ bm_menu_get_filter_mode(const struct bm_menu *menu)  }  void +bm_menu_set_lines(struct bm_menu *menu, uint32_t lines) +{ +    assert(menu); +    menu->lines = lines; +} + +uint32_t +bm_menu_get_lines(struct bm_menu *menu) +{ +    assert(menu); +    return menu->lines; +} + +void  bm_menu_set_wrap(struct bm_menu *menu, bool wrap)  {      assert(menu); @@ -165,6 +216,58 @@ bm_menu_get_title(const struct bm_menu *menu)  }  bool +bm_menu_set_font(struct bm_menu *menu, const char *font, uint32_t size) +{ +    assert(menu); + +    const char *nfont = (font ? font : default_font); + +    char *copy = NULL; +    if (!(copy = bm_strdup(nfont))) +        return false; + +    free(menu->font.name); +    menu->font.name = copy; +    menu->font.size = (size > 0 ? size : 12); +    return true; +} + +const char* bm_menu_get_font(const struct bm_menu *menu, uint32_t *out_size) +{ +    assert(menu); +    if (out_size) *out_size = menu->font.size; +    return menu->font.name; +} + +bool bm_menu_set_color(struct bm_menu *menu, enum bm_color color, const char *hex) +{ +    assert(menu); + +    const char *nhex = (hex ? hex : default_colors[color]); + +    int32_t r, g, b; +    if (sscanf(nhex,"#%2x%2x%2x", &r, &b, &g) != 3) +        return false; + +    char *copy = NULL; +    if (!(copy = bm_strdup(nhex))) +        return false; + +    free(menu->colors[color].hex); +    menu->colors[color].hex = copy; +    menu->colors[color].r = r; +    menu->colors[color].g = g; +    menu->colors[color].b = b; +    return true; +} + +const char* bm_menu_get_color(const struct bm_menu *menu, enum bm_color color) +{ +    assert(menu); +    return menu->colors[color].hex; +} + +bool  bm_menu_add_items_at(struct bm_menu *menu, struct bm_item *item, uint32_t index)  {      assert(menu); diff --git a/lib/renderers/cairo.h b/lib/renderers/cairo.h index 9c1ff5a..1dc052f 100644 --- a/lib/renderers/cairo.h +++ b/lib/renderers/cairo.h @@ -6,6 +6,10 @@  #include <assert.h>  #include <cairo/cairo.h> +#ifndef MAX +#  define MAX(a,b) (((a)>(b))?(a):(b)) +#endif +  struct cairo {      cairo_t *cr;      cairo_surface_t *surface; @@ -15,26 +19,23 @@ struct cairo_color {      float r, g, b, a;  }; -struct cairo_font { -    const char *name; -    uint32_t size; -}; -  struct cairo_paint { -    struct cairo_color color; -    struct cairo_font font; +    struct cairo_color fg; +    struct cairo_color bg; +    cairo_font_extents_t fe;  };  struct cairo_result {      cairo_text_extents_t te;  }; -__attribute__((unused)) BM_LOG_ATTR(6, 7) static bool -bm_cairo_draw_line(struct cairo *cairo, struct cairo_paint *paint, struct cairo_result *result, int32_t x, int32_t y, const char *fmt, ...) +static size_t blen = 0; +static char *buffer = NULL; + +__attribute__((unused)) BM_LOG_ATTR(3, 4) static bool +bm_cairo_get_text_extents(struct cairo *cairo, struct cairo_result *result, const char *fmt, ...)  { -    static size_t blen = 0; -    static char *buffer = NULL; -    assert(cairo && paint && result && fmt); +    assert(cairo && result && fmt);      memset(result, 0, sizeof(struct cairo_result));      va_list args; @@ -45,13 +46,33 @@ bm_cairo_draw_line(struct cairo *cairo, struct cairo_paint *paint, struct cairo_      if (!ret)          return false; -    cairo_set_source_rgba(cairo->cr, paint->color.r, paint->color.b, paint->color.g, paint->color.a); +    cairo_text_extents(cairo->cr, buffer, &result->te); +    return true; +} + +__attribute__((unused)) BM_LOG_ATTR(8, 9) static bool +bm_cairo_draw_line(struct cairo *cairo, struct cairo_paint *paint, struct cairo_result *result, uint32_t xoff, uint32_t w, int32_t x, int32_t y, const char *fmt, ...) +{ +    assert(cairo && paint && result && fmt); +    memset(result, 0, sizeof(struct cairo_result)); + +    va_list args; +    va_start(args, fmt); +    bool ret = bm_vrprintf(&buffer, &blen, fmt, args); +    va_end(args); + +    if (!ret) +        return false;      cairo_text_extents_t te; -    cairo_select_font_face(cairo->cr, paint->font.name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); -    cairo_set_font_size(cairo->cr, paint->font.size);      cairo_text_extents(cairo->cr, buffer, &te); -    cairo_move_to(cairo->cr, x, y * te.height + te.height); + +    cairo_set_source_rgba(cairo->cr, paint->bg.r, paint->bg.b, paint->bg.g, paint->bg.a); +    cairo_rectangle(cairo->cr, x - xoff, y, (w > 0 ? w : te.width) + xoff, paint->fe.height); +    cairo_fill(cairo->cr); + +    cairo_set_source_rgba(cairo->cr, paint->fg.r, paint->fg.b, paint->fg.g, paint->fg.a); +    cairo_move_to(cairo->cr, x, y + paint->fe.descent + paint->fe.height * 0.5);      cairo_show_text(cairo->cr, buffer);      memcpy(&result->te, &te, sizeof(te)); @@ -59,41 +80,108 @@ bm_cairo_draw_line(struct cairo *cairo, struct cairo_paint *paint, struct cairo_  }  __attribute__((unused)) static void +bm_cairo_color_from_menu_color(const struct bm_menu *menu, enum bm_color color, struct cairo_color *c) +{ +    assert(menu); +    c->r = (float)menu->colors[color].r / 255.0f; +    c->g = (float)menu->colors[color].g / 255.0f; +    c->b = (float)menu->colors[color].b / 255.0f; +    c->a = 1.0f; +} + +__attribute__((unused)) static uint32_t  bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, const struct bm_menu *menu)  { -    cairo_set_source_rgb(cairo->cr, 18.0f / 255.0f, 18 / 255.0f, 18.0f / 255.0f); +    assert(cairo && menu); + +    struct cairo_color c; +    bm_cairo_color_from_menu_color(menu, BM_COLOR_BG, &c); +    cairo_set_source_rgb(cairo->cr, c.r, c.g, c.b);      cairo_rectangle(cairo->cr, 0, 0, width, height);      cairo_fill(cairo->cr); -    struct cairo_result result; -    memset(&result, 0, sizeof(result)); +    cairo_select_font_face(cairo->cr, menu->font.name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); +    cairo_set_font_size(cairo->cr, menu->font.size);      struct cairo_paint paint;      memset(&paint, 0, sizeof(paint)); -    paint.font.name = "Terminus"; -    paint.font.size = 12; -    paint.color = (struct cairo_color){ 1.0, 0.0, 0.0, 1.0 }; - -    if (menu->title) -        bm_cairo_draw_line(cairo, &paint, &result, result.te.x_advance, 0, "%s ", menu->title); -    if (menu->filter) -        bm_cairo_draw_line(cairo, &paint, &result, result.te.x_advance, 0, "%s", menu->filter); - -    uint32_t count, cl = 1; -    uint32_t lines = height / paint.font.size; -    struct bm_item **items = bm_menu_get_filtered_items(menu, &count); -    for (uint32_t i = (menu->index / (lines - 1)) * (lines - 1); i < count && cl < lines; ++i) { -        bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); - -        if (highlighted) -            paint.color = (struct cairo_color){ 1.0, 0.0, 0.0, 1.0 }; -        else if (bm_menu_item_is_selected(menu, items[i])) -            paint.color = (struct cairo_color){ 1.0, 0.0, 0.0, 1.0 }; -        else -            paint.color = (struct cairo_color){ 1.0, 1.0, 1.0, 1.0 }; - -        bm_cairo_draw_line(cairo, &paint, &result, 0, cl++, "%s%s", (highlighted ? ">> " : "   "), (items[i]->text ? items[i]->text : "")); +    cairo_font_extents(cairo->cr, &paint.fe); + +    struct cairo_result result; +    memset(&result, 0, sizeof(result)); + +    if (menu->title) { +        bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_FG, &paint.fg); +        bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_BG, &paint.bg); +        bm_cairo_draw_line(cairo, &paint, &result, 0, 0, result.te.x_advance, 4, "%s", menu->title); +    } + +    bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg); +    bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg); +    bm_cairo_draw_line(cairo, &paint, &result, 0, width, result.te.x_advance, 4, "%s%s", (menu->title ? " " : ""), (menu->filter ? menu->filter : "")); + +    uint32_t displayed = 1; +    uint32_t lines = MAX(height / paint.fe.height, menu->lines); +    if (lines > 1) { +        uint32_t count, cl = 1; +        struct bm_item **items = bm_menu_get_filtered_items(menu, &count); +        for (uint32_t i = (menu->index / (lines - 1)) * (lines - 1); i < count && cl < lines; ++i) { +            bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); + +            if (highlighted) { +                bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_FG, &paint.fg); +                bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_BG, &paint.bg); +            } else if (bm_menu_item_is_selected(menu, items[i])) { +                bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_FG, &paint.fg); +                bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_BG, &paint.bg); +            } else { +                bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_FG, &paint.fg); +                bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg); +            } + +            bm_cairo_draw_line(cairo, &paint, &result, 0, width, 0, 4 + paint.fe.height * cl++, +                    "%s%s", (highlighted ? ">> " : "   "), (items[i]->text ? items[i]->text : "")); + +            ++displayed; +        } +    } else { +        uint32_t count; +        struct bm_item **items = bm_menu_get_filtered_items(menu, &count); + +        uint32_t cl = width / 4; +        if (menu->wrap || menu->index > 0) { +            bm_cairo_draw_line(cairo, &paint, &result, 0, 0, cl, 4, "<"); +            cl += result.te.x_advance + 4; +        } + +        for (uint32_t i = menu->index; i < count && cl < width; ++i) { +            bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); + +            if (highlighted) { +                bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_FG, &paint.fg); +                bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_BG, &paint.bg); +            } else if (bm_menu_item_is_selected(menu, items[i])) { +                bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_FG, &paint.fg); +                bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_BG, &paint.bg); +            } else { +                bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_FG, &paint.fg); +                bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg); +            } + +            bm_cairo_draw_line(cairo, &paint, &result, 0, 0, cl, 4, "%s", (items[i]->text ? items[i]->text : "")); +            cl += result.te.x_advance + 4; +            displayed += (cl < width); +        } + +        if (menu->wrap || menu->index + 1 < count) { +            bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg); +            bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg); +            bm_cairo_get_text_extents(cairo, &result, ">"); +            bm_cairo_draw_line(cairo, &paint, &result, 4, result.te.x_advance + 4, width - result.te.x_advance - 4, 4, ">"); +        }      } + +    return displayed;  }  #endif /* _BM_CAIRO_H */ diff --git a/lib/renderers/curses/curses.c b/lib/renderers/curses/curses.c index c40e833..5771afa 100644 --- a/lib/renderers/curses/curses.c +++ b/lib/renderers/curses/curses.c @@ -156,7 +156,6 @@ render(const struct bm_menu *menu)          init_pair(2, COLOR_RED, -1);      } -    const uint32_t lines = getmaxy(curses.stdscr);      erase();      uint32_t ncols = getmaxx(curses.stdscr); @@ -183,11 +182,14 @@ render(const struct bm_menu *menu)      }      uint32_t count, cl = 1; -    struct bm_item **items = bm_menu_get_filtered_items(menu, &count); -    for (uint32_t i = (menu->index / (lines - 1)) * (lines - 1); i < count && cl < lines; ++i) { -        bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); -        int32_t color = (highlighted ? 2 : (bm_menu_item_is_selected(menu, items[i]) ? 1 : 0)); -        draw_line(color, cl++, "%s%s", (highlighted ? ">> " : "   "), (items[i]->text ? items[i]->text : "")); +    const uint32_t lines = getmaxy(curses.stdscr); +    if (lines > 1) { +        struct bm_item **items = bm_menu_get_filtered_items(menu, &count); +        for (uint32_t i = (menu->index / (lines - 1)) * (lines - 1); i < count && cl < lines; ++i) { +            bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); +            int32_t color = (highlighted ? 2 : (bm_menu_item_is_selected(menu, items[i]) ? 1 : 0)); +            draw_line(color, cl++, "%s%s", (highlighted ? ">> " : "   "), (items[i]->text ? items[i]->text : "")); +        }      }      move(0, title_len + (menu->curses_cursor < ccols ? menu->curses_cursor : ccols)); diff --git a/lib/renderers/wayland/wayland.c b/lib/renderers/wayland/wayland.c index 0d5fcde..c6f8f8b 100644 --- a/lib/renderers/wayland/wayland.c +++ b/lib/renderers/wayland/wayland.c @@ -11,6 +11,9 @@ static void  render(const struct bm_menu *menu)  {      struct wayland *wayland = menu->renderer->internal; +    uint32_t count; +    bm_menu_get_filtered_items(menu, &count); +    wayland->window.height = ((count < menu->lines ? count : menu->lines) + 1) * menu->font.size + 4;      bm_wl_window_render(&wayland->window, menu);      wl_display_dispatch(wayland->display);  } @@ -25,6 +28,7 @@ poll_key(const struct bm_menu *menu, unsigned int *unicode)      if (wayland->input.sym == XKB_KEY_NoSymbol)          return BM_KEY_UNICODE; +    uint32_t mods = wayland->input.modifiers;      *unicode = xkb_state_key_get_utf32(wayland->input.xkb.state, wayland->input.code);      switch (wayland->input.sym) { @@ -47,16 +51,16 @@ poll_key(const struct bm_menu *menu, unsigned int *unicode)              return BM_KEY_END;          case XKB_KEY_SunPageUp: -            return BM_KEY_PAGE_UP; +            return (mods & MOD_SHIFT ? BM_KEY_SHIFT_PAGE_UP : BM_KEY_PAGE_UP);          case XKB_KEY_SunPageDown: -            return BM_KEY_PAGE_DOWN; +            return (mods & MOD_SHIFT ? BM_KEY_SHIFT_PAGE_DOWN : BM_KEY_PAGE_DOWN);          case XKB_KEY_BackSpace:              return BM_KEY_BACKSPACE;          case XKB_KEY_Delete: -            return BM_KEY_DELETE; +            return (mods & MOD_SHIFT ? BM_KEY_LINE_DELETE_LEFT : BM_KEY_DELETE);          case XKB_KEY_Tab:              return BM_KEY_TAB; @@ -65,11 +69,41 @@ poll_key(const struct bm_menu *menu, unsigned int *unicode)              return BM_KEY_SHIFT_RETURN;          case XKB_KEY_Return: -            return BM_KEY_RETURN; +            return (mods & MOD_CTRL ? BM_KEY_CONTROL_RETURN : (mods & MOD_SHIFT ? BM_KEY_SHIFT_RETURN : BM_KEY_RETURN));          case XKB_KEY_Escape:              return BM_KEY_ESCAPE; +        case XKB_KEY_p: +            return (mods & MOD_CTRL ? BM_KEY_UP : BM_KEY_UNICODE); + +        case XKB_KEY_n: +            return (mods & MOD_CTRL ? BM_KEY_DOWN : BM_KEY_UNICODE); + +        case XKB_KEY_l: +            return (mods & MOD_CTRL ? BM_KEY_LEFT : BM_KEY_UNICODE); + +        case XKB_KEY_f: +            return (mods & MOD_CTRL ? BM_KEY_RIGHT : BM_KEY_UNICODE); + +        case XKB_KEY_a: +            return (mods & MOD_CTRL ? BM_KEY_HOME : BM_KEY_UNICODE); + +        case XKB_KEY_e: +            return (mods & MOD_CTRL ? BM_KEY_END : BM_KEY_UNICODE); + +        case XKB_KEY_h: +            return (mods & MOD_CTRL ? BM_KEY_BACKSPACE : BM_KEY_UNICODE); + +        case XKB_KEY_u: +            return (mods & MOD_CTRL ? BM_KEY_LINE_DELETE_LEFT : BM_KEY_UNICODE); + +        case XKB_KEY_k: +            return (mods & MOD_CTRL ? BM_KEY_LINE_DELETE_RIGHT : BM_KEY_UNICODE); + +        case XKB_KEY_w: +            return (mods & MOD_CTRL ? BM_KEY_WORD_DELETE : BM_KEY_UNICODE); +          default: break;      } @@ -81,7 +115,7 @@ get_displayed_count(const struct bm_menu *menu)  {      struct wayland *wayland = menu->renderer->internal;      assert(wayland); -    return wayland->window.height / 12; +    return wayland->window.displayed;  }  static void diff --git a/lib/renderers/wayland/wayland.h b/lib/renderers/wayland/wayland.h index fd29405..d698218 100644 --- a/lib/renderers/wayland/wayland.h +++ b/lib/renderers/wayland/wayland.h @@ -70,9 +70,10 @@ struct window {      struct wl_shm *shm;      struct buffer buffers[2];      uint32_t width, height; +    uint32_t displayed;      struct { -        void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, const struct bm_menu *menu); +        uint32_t (*render)(struct cairo *cairo, uint32_t width, uint32_t height, const struct bm_menu *menu);      } notify;  }; diff --git a/lib/renderers/wayland/window.c b/lib/renderers/wayland/window.c index 9234ef2..21555b8 100644 --- a/lib/renderers/wayland/window.c +++ b/lib/renderers/wayland/window.c @@ -13,79 +13,79 @@  static int  set_cloexec_or_close(int fd)  { -   if (fd == -1) -      return -1; +    if (fd == -1) +        return -1; -   long flags = fcntl(fd, F_GETFD); -   if (flags == -1) -      goto err; +    long flags = fcntl(fd, F_GETFD); +    if (flags == -1) +        goto err; -   if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) -      goto err; +    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) +        goto err; -   return fd; +    return fd;  err: -   close(fd); -   return -1; +    close(fd); +    return -1;  }  static int  create_tmpfile_cloexec(char *tmpname)  { -   int fd; +    int fd;  #ifdef HAVE_MKOSTEMP -   if ((fd = mkostemp(tmpname, O_CLOEXEC)) >= 0) -      unlink(tmpname); +    if ((fd = mkostemp(tmpname, O_CLOEXEC)) >= 0) +        unlink(tmpname);  #else -   if ((fd = mkstemp(tmpname)) >= 0) { -      fd = set_cloexec_or_close(fd); -      unlink(tmpname); -   } +    if ((fd = mkstemp(tmpname)) >= 0) { +        fd = set_cloexec_or_close(fd); +        unlink(tmpname); +    }  #endif -   return fd; +    return fd;  }  static int  os_create_anonymous_file(off_t size)  { -   static const char template[] = "/bemenu-shared-XXXXXX"; -   int fd; -   int ret; - -   const char *path; -   if (!(path = getenv("XDG_RUNTIME_DIR")) || strlen(path) <= 0) { -      errno = ENOENT; -      return -1; -   } +    static const char template[] = "/bemenu-shared-XXXXXX"; +    int fd; +    int ret; + +    const char *path; +    if (!(path = getenv("XDG_RUNTIME_DIR")) || strlen(path) <= 0) { +        errno = ENOENT; +        return -1; +    } -   char *name; -   int ts = (path[strlen(path) - 1] == '/'); -   if (!(name = bm_dprintf("%s%s%s", path, (ts ? "" : "/"), template))) -      return -1; +    char *name; +    int ts = (path[strlen(path) - 1] == '/'); +    if (!(name = bm_dprintf("%s%s%s", path, (ts ? "" : "/"), template))) +        return -1; -   fd = create_tmpfile_cloexec(name); -   free(name); +    fd = create_tmpfile_cloexec(name); +    free(name); -   if (fd < 0) -      return -1; +    if (fd < 0) +        return -1;  #ifdef HAVE_POSIX_FALLOCATE -   if ((ret = posix_fallocate(fd, 0, size)) != 0) { -      close(fd); -      errno = ret; -      return -1; -   } +    if ((ret = posix_fallocate(fd, 0, size)) != 0) { +        close(fd); +        errno = ret; +        return -1; +    }  #else -   if ((ret = ftruncate(fd, size)) < 0) { -      close(fd); -      return -1; -   } +    if ((ret = ftruncate(fd, size)) < 0) { +        close(fd); +        return -1; +    }  #endif -   return fd; +    return fd;  }  static void @@ -256,7 +256,7 @@ bm_wl_window_render(struct window *window, const struct bm_menu *menu)          return;      if (window->notify.render) -        window->notify.render(&buffer->cairo, buffer->width, buffer->height, menu); +        window->displayed = window->notify.render(&buffer->cairo, buffer->width, buffer->height, menu);      wl_surface_damage(window->surface, 0, 0, buffer->width, buffer->height);      wl_surface_attach(window->surface, buffer->buffer, 0, 0); | 
