Compare commits

...

5 Commits

Author SHA1 Message Date
886372caac build: add cache to ./configure with -C flag
All checks were successful
CI Code / Check spelling (pull_request) Successful in 23s
CI Code / Check coding style (pull_request) Successful in 38s
CI Code / Linux (arch) (pull_request) Successful in 12m20s
CI Code / Linux (ubuntu) (pull_request) Successful in 14m59s
CI Code / Linux (debian) (pull_request) Successful in 15m18s
Add the -C flag to ./configure to enable caching, reducing redundant
resource fetching during builds when packages and the machine remain
unchanged. Caching may cause issues only if applied across different machines
or if packages are modified, neither of which is the case during the build.
2025-10-14 09:47:14 +00:00
0b0b02d6e0 build: use local libstrophe version and limit depth
`--depth 1` flag ensures that only latest version is loaded (since there is no need to sync full git)
Using local libstrophe version increases speed of fetching
2025-10-14 09:47:14 +00:00
d748ffc527 build: Add multithreading to make
nproc is a standard util that prints amount of available processes.
-j is a flag that specifies how many cores can be utilized by `make` (default is 1)
-j$(nproc) allows to use all the available machine cores, potentially significantly speeding up completion of CI actions
2025-10-14 09:47:14 +00:00
fac1e224bc fix(scroll): handle edge case of extremely long messages
All checks were successful
CI Code / Check coding style (pull_request) Successful in 34s
CI Code / Check spelling (pull_request) Successful in 45s
CI Code / Linux (arch) (pull_request) Successful in 10m43s
CI Code / Linux (ubuntu) (pull_request) Successful in 13m11s
CI Code / Linux (debian) (pull_request) Successful in 16m46s
CI Code / Check spelling (push) Successful in 18s
CI Code / Check coding style (push) Successful in 32s
CI Code / Linux (arch) (push) Successful in 12m56s
CI Code / Linux (debian) (push) Successful in 13m28s
CI Code / Linux (ubuntu) (push) Successful in 16m20s
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
2025-10-08 13:00:32 +02:00
6ad8a19053 fix(buffer): use dynamic buffer size to prevent unnecessary buffer cleanups
All checks were successful
CI Code / Check spelling (pull_request) Successful in 22s
CI Code / Check coding style (pull_request) Successful in 38s
CI Code / Linux (arch) (pull_request) Successful in 13m4s
CI Code / Linux (debian) (pull_request) Successful in 13m32s
CI Code / Linux (ubuntu) (pull_request) Successful in 16m23s
CI Code / Check spelling (push) Successful in 19s
CI Code / Check coding style (push) Successful in 37s
CI Code / Linux (arch) (push) Successful in 13m8s
CI Code / Linux (ubuntu) (push) Successful in 16m2s
CI Code / Linux (debian) (push) Successful in 16m26s
Refactor buffer trimming logic to use dynamic line counts (_lines per entry)
against PAD_SIZE (10k) instead of fixed entry count (MAX_BUFFER_SIZE=200). This
prevents premature cleanups for short messages, reduces scrolling disruptions
during history loads, and scales better with rendered content size.

Delete oldest/newest entry from opposite end only when total lines approach
ncurses pad limit, minimizing unnecessary deletions.
Simplify overflow warning log by removing unused MAX_BUFFER_SIZE reference.

Update buffer.c header for improved DX:
- Add detailed module overview explaining role (in-memory UI buffer vs. DB
persistence), key features (trimming, metadata), and integration (ncurses).
- Shorten copyright/license boilerplate to concise pointer (LICENSE ref).
- Add fork notice; preserve original copyrights per GPLv3.

Partially addresses #36 (stuck scroll mitigation via fewer cleanups)
Related to #36
2025-10-07 15:12:20 +02:00
7 changed files with 55 additions and 52 deletions

View File

@@ -5,6 +5,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
autoconf \
autoconf-archive \
automake \
ca-certificates \
expect \
gcc \
git \
@@ -36,7 +37,7 @@ RUN mkdir -p /usr/src/{stabber,libstrophe,profanity}
WORKDIR /usr/src
#RUN git clone https://github.com/boothj5/stabber
RUN git clone -c http.sslverify=false https://github.com/strophe/libstrophe
RUN git clone --depth 1 https://git.jabber.space/devs/libstrophe-gh.git libstrophe
#WORKDIR /usr/src/stabber
#RUN ./bootstrap.sh
@@ -47,7 +48,7 @@ RUN git clone -c http.sslverify=false https://github.com/strophe/libstrophe
WORKDIR /usr/src/libstrophe
RUN ./bootstrap.sh
RUN ./configure --prefix=/usr
RUN make
RUN make -j$(nproc)
RUN make install
WORKDIR /usr/src/profanity

View File

@@ -9,6 +9,7 @@ RUN dnf install -y \
autoconf-archive \
automake \
awk \
ca-certificates \
expect-devel \
gcc \
git \
@@ -56,11 +57,11 @@ WORKDIR /usr/src
WORKDIR /usr/src
RUN mkdir -p /usr/src/libstrophe
RUN git clone -c http.sslverify=false https://github.com/strophe/libstrophe
RUN git clone --depth 1 https://git.jabber.space/devs/libstrophe-gh.git libstrophe
WORKDIR /usr/src/libstrophe
RUN ./bootstrap.sh
RUN ./configure --prefix=/usr
RUN make
RUN make -j$(nproc)
RUN make install
RUN mkdir -p /usr/src/profanity

View File

@@ -6,6 +6,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
autoconf \
autoconf-archive \
automake \
ca-certificates \
expect \
gcc \
git \
@@ -37,7 +38,7 @@ RUN mkdir -p /usr/src/{stabber,libstrophe,profanity}
WORKDIR /usr/src
#RUN git clone https://github.com/boothj5/stabber
RUN git clone -c http.sslverify=false https://github.com/strophe/libstrophe
RUN git clone --depth 1 https://git.jabber.space/devs/libstrophe-gh.git libstrophe
# TODO: Re-enable once libmicrohttpd-dev has been updated.
#WORKDIR /usr/src/stabber
@@ -49,7 +50,7 @@ RUN git clone -c http.sslverify=false https://github.com/strophe/libstrophe
WORKDIR /usr/src/libstrophe
RUN ./bootstrap.sh
RUN ./configure --prefix=/usr
RUN make
RUN make -j$(nproc)
RUN make install
WORKDIR /usr/src/profanity

View File

@@ -121,11 +121,11 @@ esac
case "$ARCH" in
linux*)
echo
echo "--> Building with ./configure ${tests[0]} --enable-valgrind $*"
echo "--> Building with ./configure -C ${tests[0]} --enable-valgrind $*"
echo
# shellcheck disable=SC2086
./configure ${tests[0]} --enable-valgrind $*
./configure -C ${tests[0]} --enable-valgrind $*
$MAKE CC="${CC}"
if grep '^ID=' /etc/os-release | grep -q -e debian; then
@@ -140,11 +140,11 @@ esac
for features in "${tests[@]}"
do
echo
echo "--> Building with ./configure ${features} $*"
echo "--> Building with ./configure -C ${features} $*"
echo
# shellcheck disable=SC2086
./configure $features $*
./configure -C $features $*
$MAKE CC="${CC}"
$MAKE check

View File

@@ -1,40 +1,36 @@
/*
* buffer.c
* vim: expandtab:ts=4:sts=4:sw=4
*
* Message buffer implementation for CProof.
*
* This module provides an in-memory buffer for managing active chat entries in the
* console-based XMPP client. Separate from persistent SQLite storage, it holds
* messages and metadata solely for UI rendering, ensuring responsive scrolling and
* display without exceeding ncurses pad limits (10k lines). By tracking rendered
* line counts per entry, it proactively trims content to prevent overflow, enabling
* seamless integration with ncurses for position-aware rendering.
*
* Key features and operations:
* - Append/prepend entries (messages) with automatic line-based cleanup.
* - Track cumulative lines for overflow prevention and efficient buffer sizing.
* - Remove entries by ID or index; mark delivery receipts as received.
* - Retrieve entries by index or ID for rendering and history queries.
* - Store metadata including timestamps, senders, themes, and ncurses y-positions.
*
* CProof. Fork of Profanity (since 2025).
*
* Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
* Copyright (C) 2019 - 2025 Michael Vetter <jubalh@iodoru.org>
* Copyright (C) 2025 CProof Developers
*
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <https://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two.
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL. If you modify file(s) with this exception, you
* may extend this exception to your version of the file(s), but you are not
* obligated to do so. If you do not wish to do so, delete this exception
* statement from your version. If you delete this exception statement from all
* source files in the program, then also delete it here.
* Licensed under the GNU General Public License, version 3,
* with the OpenSSL exception. See LICENSE for details.
*
* vim: expandtab:ts=4:sts=4:sw=4
*/
#include "config.h"
#include "ui/window_list.h"
#include <stdlib.h>
#include <string.h>
@@ -54,15 +50,8 @@
#include "ui/window.h"
#include "ui/buffer.h"
#define MAX_BUFFER_SIZE 200
#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);
@@ -108,23 +97,24 @@ _buffer_add(ProfBuff buffer, const char* show_char, int pad_indent, GDateTime* t
buffer->lines += e->_lines;
while (g_slist_length(buffer->entries) >= MAX_BUFFER_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, message buffer size: %d, rendered lines buffer size: %d",
from_jid, y_start_pos, id, append ? "TRUE" : "FALSE", g_slist_length(buffer->entries), MAX_BUFFER_SIZE, 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);

View File

@@ -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();

View File

@@ -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;
}
}