mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-18 09:16:22 +00:00
fix(scroll): handle edge case of extremely long messages
Prior commit (6ad8a190) did not properly handle overflow by long (9000 lines) message,
to address this issue, multiple changes were made:
- Add lines recalculation on win_redraw
- Move `prof_buff_t` struct to header file so its lines could be externally changed
- Call win_redraw once overflow is detected: it allows to recalculate sizes in lines and apply changes to the buffer
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "ui/window_list.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -51,12 +52,6 @@
|
||||
|
||||
#define STRDUP_OR_NULL(str) ((str) ? strdup(str) : NULL)
|
||||
|
||||
struct prof_buff_t
|
||||
{
|
||||
GSList* entries;
|
||||
int lines;
|
||||
};
|
||||
|
||||
static void _free_entry(ProfBuffEntry* entry);
|
||||
static ProfBuffEntry* _create_entry(const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos);
|
||||
static void _buffer_add(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* time, int flags, theme_item_t theme_item, const char* const display_from, const char* const from_jid, const char* const message, DeliveryReceipt* receipt, const char* const id, int y_start_pos, int y_end_pos, gboolean append);
|
||||
@@ -102,23 +97,24 @@ _buffer_add(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* t
|
||||
|
||||
buffer->lines += e->_lines;
|
||||
|
||||
while (buffer->lines >= PAD_SIZE) {
|
||||
// With 10% margin to ensure overflow prevention
|
||||
while (buffer->lines >= PAD_SIZE - (PAD_SIZE / 10) && g_slist_length(buffer->entries) > 1) {
|
||||
// Delete message from the opposite size to free buffer
|
||||
GSList* buffer_entry_to_delete = append ? buffer->entries : g_slist_last(buffer->entries);
|
||||
ProfBuffEntry* entry_to_delete = (ProfBuffEntry*)buffer_entry_to_delete->data;
|
||||
// log_debug("(Messages left in buffer: %d) DELETING: %s", g_slist_length(buffer->entries), entry_to_delete->id);
|
||||
buffer->lines -= entry_to_delete->_lines;
|
||||
_free_entry(entry_to_delete);
|
||||
buffer->entries = g_slist_delete_link(buffer->entries, buffer_entry_to_delete);
|
||||
}
|
||||
|
||||
if (from_jid && y_end_pos == y_start_pos) {
|
||||
log_warning("Ncurses Overflow! From: %s, position: %d, ID: %s, append: %s, used message buffer size: %d, rendered lines buffer size: %d",
|
||||
from_jid, y_start_pos, id, append ? "TRUE" : "FALSE", g_slist_length(buffer->entries), PAD_SIZE);
|
||||
// At this point we have a message that caused overflow of the render buffer.
|
||||
// Ideally, we want to clean other messages to rerender everything properly. To do so,
|
||||
// first we need to determine the size of the message that we are trying to display,
|
||||
// then we need to print the message.
|
||||
// However, _buffer_add is too late in the code to do this, therefore it has to be done in the win_print_old_history.
|
||||
// win_redraw will redraw with entries above removed,
|
||||
// it will also recalculate actual size of the message that caused overflow
|
||||
int old_lines = buffer->lines;
|
||||
win_redraw(wins_get_current());
|
||||
log_debug("Ncurses Overflow! From: %s, position: %d, ID: %s, append: %s, used message buffer size: %d, rendered lines: (old: %d/ actual: %d/ max: %d)",
|
||||
from_jid, y_start_pos, id, append ? "TRUE" : "FALSE", g_slist_length(buffer->entries), old_lines, buffer->lines, PAD_SIZE);
|
||||
}
|
||||
|
||||
buffer->entries = append ? g_slist_append(buffer->entries, e) : g_slist_prepend(buffer->entries, e);
|
||||
|
||||
@@ -68,6 +68,12 @@ typedef struct prof_buff_entry_t
|
||||
char* id;
|
||||
} ProfBuffEntry;
|
||||
|
||||
struct prof_buff_t
|
||||
{
|
||||
GSList* entries;
|
||||
int lines;
|
||||
};
|
||||
|
||||
typedef struct prof_buff_t* ProfBuff;
|
||||
|
||||
ProfBuff buffer_create();
|
||||
|
||||
@@ -2003,6 +2003,10 @@ win_redraw(ProfWin* window)
|
||||
_win_print_internal(window, e->show_char, e->pad_indent, e->time, e->flags, e->theme_item, e->display_from, e->message, e->receipt);
|
||||
}
|
||||
e->y_end_pos = getcury(window->layout->win);
|
||||
// Recalculate lines (might be incorrect in case of NCurses overflow)
|
||||
window->layout->buffer->lines -= e->_lines;
|
||||
e->_lines = e->y_end_pos - e->y_start_pos;
|
||||
window->layout->buffer->lines += e->_lines;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user