From dd8a6fdd4db044d9ca3c7a3d7c0e5b65059ac1e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 24 Jan 2021 20:31:22 +0100 Subject: [PATCH 1/2] =?UTF-8?q?search:=20don=E2=80=99t=20re-scan=20the=20s?= =?UTF-8?q?crollback=20unless=20the=20search=20string=20actually=20has=20c?= =?UTF-8?q?hanged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- search.c | 118 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 36 deletions(-) diff --git a/search.c b/search.c index 25793018..4e870cb4 100644 --- a/search.c +++ b/search.c @@ -574,8 +574,11 @@ from_clipboard_done(void *user) static bool execute_binding(struct seat *seat, struct terminal *term, - enum bind_action_search action, uint32_t serial) + enum bind_action_search action, uint32_t serial, + bool *update_search_result, bool *redraw) { + *update_search_result = *redraw = false; + switch (action) { case BIND_ACTION_SEARCH_NONE: return false; @@ -611,7 +614,8 @@ execute_binding(struct seat *seat, struct terminal *term, term->search.match.row = new_row; } } - return false; + *update_search_result = *redraw = true; + return true; case BIND_ACTION_SEARCH_FIND_NEXT: if (term->search.match_len > 0) { @@ -627,41 +631,58 @@ execute_binding(struct seat *seat, struct terminal *term, term->search.match.col = new_col; term->search.match.row = new_row; term->search.direction = SEARCH_FORWARD; - } + } } - return false; + *update_search_result = *redraw = true; + return true; case BIND_ACTION_SEARCH_EDIT_LEFT: - if (term->search.cursor > 0) + if (term->search.cursor > 0) { term->search.cursor--; - return false; + *redraw = true; + } + return true; case BIND_ACTION_SEARCH_EDIT_LEFT_WORD: { size_t diff = distance_prev_word(term); term->search.cursor -= diff; xassert(term->search.cursor <= term->search.len); - return false; + + if (diff > 0) + *redraw = true; + return true; } case BIND_ACTION_SEARCH_EDIT_RIGHT: - if (term->search.cursor < term->search.len) + if (term->search.cursor < term->search.len) { term->search.cursor++; - return false; + *redraw = true; + } + return true; case BIND_ACTION_SEARCH_EDIT_RIGHT_WORD: { size_t diff = distance_next_word(term); term->search.cursor += diff; xassert(term->search.cursor <= term->search.len); - return false; + + if (diff > 0) + *redraw = true; + return true; } case BIND_ACTION_SEARCH_EDIT_HOME: - term->search.cursor = 0; - return false; + if (term->search.cursor != 0) { + term->search.cursor = 0; + *redraw = true; + } + return true; case BIND_ACTION_SEARCH_EDIT_END: - term->search.cursor = term->search.len; - return false; + if (term->search.cursor != term->search.len) { + term->search.cursor = term->search.len; + *redraw = true; + } + return true; case BIND_ACTION_SEARCH_DELETE_PREV: if (term->search.cursor > 0) { @@ -671,21 +692,25 @@ execute_binding(struct seat *seat, struct terminal *term, (term->search.len - term->search.cursor) * sizeof(wchar_t)); term->search.cursor--; term->search.buf[--term->search.len] = L'\0'; + *update_search_result = *redraw = true; } - return false; + return true; case BIND_ACTION_SEARCH_DELETE_PREV_WORD: { size_t diff = distance_prev_word(term); size_t old_cursor = term->search.cursor; size_t new_cursor = old_cursor - diff; - memmove(&term->search.buf[new_cursor], - &term->search.buf[old_cursor], - (term->search.len - old_cursor) * sizeof(wchar_t)); + if (diff > 0) { + memmove(&term->search.buf[new_cursor], + &term->search.buf[old_cursor], + (term->search.len - old_cursor) * sizeof(wchar_t)); - term->search.len -= diff; - term->search.cursor = new_cursor; - return false; + term->search.len -= diff; + term->search.cursor = new_cursor; + *update_search_result = *redraw = true; + } + return true; } case BIND_ACTION_SEARCH_DELETE_NEXT: @@ -695,42 +720,50 @@ execute_binding(struct seat *seat, struct terminal *term, &term->search.buf[term->search.cursor + 1], (term->search.len - term->search.cursor - 1) * sizeof(wchar_t)); term->search.buf[--term->search.len] = L'\0'; + *update_search_result = *redraw = true; } - return false; + return true; case BIND_ACTION_SEARCH_DELETE_NEXT_WORD: { size_t diff = distance_next_word(term); size_t cursor = term->search.cursor; - memmove(&term->search.buf[cursor], - &term->search.buf[cursor + diff], - (term->search.len - (cursor + diff)) * sizeof(wchar_t)); + if (diff > 0) { + memmove(&term->search.buf[cursor], + &term->search.buf[cursor + diff], + (term->search.len - (cursor + diff)) * sizeof(wchar_t)); - term->search.len -= diff; - return false; + term->search.len -= diff; + *update_search_result = *redraw = true; + } + return true; } case BIND_ACTION_SEARCH_EXTEND_WORD: search_match_to_end_of_word(term, false); - return false; + *update_search_result = *redraw = true; + return true; case BIND_ACTION_SEARCH_EXTEND_WORD_WS: search_match_to_end_of_word(term, true); - return false; + *update_search_result = *redraw = true; + return true; case BIND_ACTION_SEARCH_CLIPBOARD_PASTE: text_from_clipboard( seat, term, &from_clipboard_cb, &from_clipboard_done, term); - return false; + *update_search_result = *redraw = true; + return true; case BIND_ACTION_SEARCH_PRIMARY_PASTE: text_from_primary( seat, term, &from_clipboard_cb, &from_clipboard_done, term); - return false; + *update_search_result = *redraw = true; + return true; case BIND_ACTION_SEARCH_COUNT: xassert(false); - return false; + return true; } xassert(false); @@ -746,6 +779,9 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key, enum xkb_compose_status compose_status = xkb_compose_state_get_status( seat->kbd.xkb_compose_state); + bool update_search_result = false; + bool redraw = false; + /* Key bindings */ tll_foreach(seat->kbd.bindings.search, it) { if (it->item.bind.mods != mods) @@ -753,16 +789,22 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key, /* Match symbol */ if (it->item.bind.sym == sym) { - if (!execute_binding(seat, term, it->item.action, serial)) + if (execute_binding(seat, term, it->item.action, serial, + &update_search_result, &redraw)) + { goto update_search; + } return; } /* Match raw key code */ tll_foreach(it->item.bind.key_codes, code) { if (code->item == key) { - if (!execute_binding(seat, term, it->item.action, serial)) + if (execute_binding(seat, term, it->item.action, serial, + &update_search_result, &redraw)) + { goto update_search; + } return; } } @@ -782,6 +824,8 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key, seat->kbd.xkb_state, key, (char *)buf, sizeof(buf)); } + update_search_result = redraw = count > 0; + if (count == 0) return; @@ -789,6 +833,8 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key, update_search: LOG_DBG("search: buffer: %ls", term->search.buf); - search_find_next(term); - render_refresh_search(term); + if (update_search_result) + search_find_next(term); + if (redraw) + render_refresh_search(term); } From dd1df60160e5e02c82701647b64de31916000da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 25 Jan 2021 10:05:51 +0100 Subject: [PATCH 2/2] changelog: high cpu usage while holding down e.g. arrow keys in search mode --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0d4d8b1..509a1972 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,8 @@ * Crash on keyboard input when repeat rate was zero (i.e. no repeat). * Wrong button encoding of mouse buttons 6 and 7 in mouse events. * Scrollback search not matching composed characters. +* High CPU usage when holding down e.g. arrow keys while in scrollback + search mode. ### Security