diff --git a/Changelog b/Changelog index 4705d75f..9584b77b 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ - One-off when pasting text. - Improve rendering of boxes (fixed height and margins) - Fix modi switcher boxes size+layout. + - Reduce work on redraws (do not always calculate new size/position), set text, etc. Cleanup: - Do not lug argc,argv around everywhere. diff --git a/source/rofi.c b/source/rofi.c index 944764e4..e2a2e0bb 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -302,6 +302,8 @@ typedef struct MenuState // Update/Refilter list. int update; int refilter; + int rchanged; + int cur_page; // Entries textbox *text; @@ -796,6 +798,7 @@ static void menu_refilter ( MenuState *state, char **lines, menu_match_cb mmc, v } state->refilter = FALSE; + state->rchanged = TRUE; } @@ -814,6 +817,10 @@ static void menu_draw ( MenuState *state ) int page = ( state->max_elements > 0 ) ? ( state->selected / state->max_elements ) : 0; offset = page * state->max_elements; state->last_offset = offset; + if ( page != state->cur_page ) { + state->cur_page = page; + state->rchanged = TRUE; + } } // Re calculate the boxes and sizes, see if we can move this in the menu_calc*rowscolumns @@ -841,27 +848,35 @@ static void menu_draw ( MenuState *state ) for ( i = max_elements; i < state->max_elements; i++ ) { textbox_hide ( state->boxes[i] ); } - // Move, resize visible boxes and show them. - for ( i = 0; i < max_elements; i++ ) { - unsigned int ex = ( ( i ) / state->max_rows ) * ( element_width + LINE_MARGIN ); - unsigned int ey = ( ( i ) % state->max_rows ) * element_height + LINE_MARGIN; - // Move it around. - textbox_moveresize ( state->boxes[i], - ex + x_offset, ey + y_offset, - element_width, element_height ); - if ( ( i + offset ) >= state->num_lines || state->filtered[i + offset] == NULL ) { - textbox_font ( state->boxes[i], NORMAL ); - textbox_text ( state->boxes[i], "" ); + if ( state->rchanged ) { + // Move, resize visible boxes and show them. + for ( i = 0; i < max_elements; i++ ) { + unsigned int ex = ( ( i ) / state->max_rows ) * ( element_width + LINE_MARGIN ); + unsigned int ey = ( ( i ) % state->max_rows ) * element_height + LINE_MARGIN; + // Move it around. + textbox_moveresize ( state->boxes[i], + ex + x_offset, ey + y_offset, + element_width, element_height ); + { + TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT; + char *text = state->filtered[i + offset]; + TextBoxFontType tbft = ( i + offset ) == state->selected ? HIGHLIGHT : type; + textbox_font ( state->boxes[i], tbft ); + textbox_text ( state->boxes[i], text ); + } + textbox_show ( state->boxes[i] ); + textbox_draw ( state->boxes[i] ); } - else{ - TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT; - char *text = state->filtered[i + offset]; - TextBoxFontType tbft = ( i + offset ) == state->selected ? HIGHLIGHT : type; + state->rchanged = FALSE; + } + else{ + // Only do basic redrawing + highlight of row. + for ( i = 0; i < max_elements; i++ ) { + TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT; + TextBoxFontType tbft = ( i + offset ) == state->selected ? HIGHLIGHT : type; textbox_font ( state->boxes[i], tbft ); - textbox_text ( state->boxes[i], text ); + textbox_draw ( state->boxes[i] ); } - textbox_show ( state->boxes[i] ); - textbox_draw ( state->boxes[i] ); } } @@ -943,6 +958,8 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom // We want to filter on the first run. .refilter = TRUE, .update = FALSE, + .rchanged = TRUE, + .cur_page = -1, .lines = lines }; unsigned int i; diff --git a/source/textbox.c b/source/textbox.c index d35ce58a..190fa0d1 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -57,9 +57,6 @@ Colormap target_colormap; PangoContext *p_context = NULL; - -void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ); - // Xft text box, optionally editable textbox* textbox_create ( Window parent, XVisualInfo *vinfo, @@ -168,6 +165,10 @@ void textbox_text ( textbox *tb, const char *text ) } } pango_layout_set_text ( tb->layout, tb->text, strlen ( tb->text ) ); + if ( tb->flags & TB_AUTOWIDTH ) { + textbox_moveresize ( tb, tb->x, tb->y, tb->w, tb->h ); + } + tb->cursor = MAX ( 0, MIN ( ( int ) strlen ( text ), tb->cursor ) ); } @@ -188,6 +189,7 @@ void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ) } if ( tb->flags & TB_AUTOWIDTH ) { + pango_layout_set_width ( tb->layout, -1 ); if ( w > 1 ) { w = MIN ( w, textbox_get_width ( tb ) ); } @@ -211,6 +213,7 @@ void textbox_moveresize ( textbox *tb, int x, int y, int w, int h ) tb->w = MAX ( 1, w ); tb->h = MAX ( 1, h ); XMoveResizeWindow ( display, tb->window, tb->x, tb->y, tb->w, tb->h ); + pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->w - 2 * SIDE_MARGIN ) ); } } @@ -272,7 +275,7 @@ void textbox_draw ( textbox *tb ) cursor_x = pos.x / PANGO_SCALE; } - pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->w - 2 * SIDE_MARGIN ) ); +// pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->w - 2 * SIDE_MARGIN ) ); // Skip the side MARGIN on the X axis.