Skip to content

Commit 486142e

Browse files
MrLeninclaude
andcommitted
Simplify old_value: remove arrow-vs-jump heuristic and bookkeeping
Stage 2 step E: old_value is reduced to a single-purpose change gate in adjustment_changed (skip the handler body when value didn't change). All other uses are removed: - Arrow-vs-jump heuristic (±1 = arrow → immediate, else → 20ms debounce): replaced with unconditional queue_draw. The distinction was a GTK2/3 optimization; GTK4 queue_draw is already frame-deferred. - Bookkeeping adjustments (old_value ± ent_lines after insert/remove): deleted. With scroll_anchor as source of truth, an extra adjustment_changed firing is harmless (re-captures the same anchor). - Buffer-switch save/restore via old_value: replaced with restore_scroll_anchor from the persistent buf->scroll_anchor. - Seed writes in render_page_timeout and buffer_set_virtual: deleted (old_value is updated at the end of adjustment_changed, which fires on every real scroll position change). Net -29 lines. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0a023f9 commit 486142e

2 files changed

Lines changed: 24 additions & 53 deletions

File tree

src/fe-gtk/xtext.c

Lines changed: 23 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ gtk_xtext_adjustment_changed (GtkAdjustment * adj, GtkXText * xtext)
12401240
}
12411241

12421242
/* Re-read value after ensure_range + anchor restore, which may
1243-
* have shifted it. Needed for old_value update at bottom. */
1243+
* have shifted it. Needed for the change-gate update below. */
12441244
value = gtk_adjustment_get_value (xtext->adj);
12451245

12461246
/* Re-check scroll-to-top after ensure_range. When mat_first_index
@@ -1264,29 +1264,17 @@ gtk_xtext_adjustment_changed (GtkAdjustment * adj, GtkXText * xtext)
12641264
}
12651265
}
12661266

1267-
if (value + 1 == xtext->buffer->old_value ||
1268-
value - 1 == xtext->buffer->old_value) /* clicked an arrow? */
1267+
/* Queue a redraw. The old code distinguished arrow clicks (±1 line,
1268+
* immediate redraw) from jumps (thumb drag, debounced 20ms). With
1269+
* GTK4 queue_draw is already deferred to the next frame, so the
1270+
* distinction is unnecessary. Cancel any pending debounce timer
1271+
* and redraw immediately. */
1272+
if (xtext->io_tag)
12691273
{
1270-
if (xtext->io_tag)
1271-
{
1272-
g_source_remove (xtext->io_tag);
1273-
xtext->io_tag = 0;
1274-
}
1275-
/* GTK3: Queue a redraw instead of rendering directly */
1276-
gtk_widget_queue_draw (GTK_WIDGET (xtext));
1277-
} else
1278-
{
1279-
/* Invalidate pagetop cache — the scroll position jumped (thumb drag,
1280-
* page click, etc.) so the cached entry no longer matches. Without
1281-
* this, motion_notify → find_char → nth() uses the stale cache and
1282-
* returns the wrong entry, causing flicker. */
1283-
1284-
if (!xtext->io_tag)
1285-
xtext->io_tag = g_timeout_add (REFRESH_TIMEOUT,
1286-
(GSourceFunc)
1287-
gtk_xtext_adjustment_timeout,
1288-
xtext);
1274+
g_source_remove (xtext->io_tag);
1275+
xtext->io_tag = 0;
12891276
}
1277+
gtk_widget_queue_draw (GTK_WIDGET (xtext));
12901278
}
12911279
xtext->buffer->old_value = value;
12921280
}
@@ -7579,7 +7567,6 @@ gtk_xtext_remove_top (xtext_buffer *buffer)
75797567
else
75807568
buffer->text_last = NULL;
75817569

7582-
buffer->old_value -= ent_lines;
75837570
if (buffer->xtext->buffer == buffer) /* is it the current buffer? */
75847571
{
75857572
g_signal_handler_block (buffer->xtext->adj, buffer->xtext->vc_signal_tag);
@@ -8376,7 +8363,6 @@ gtk_xtext_render_page_timeout (GtkXText * xtext)
83768363
/* less than a complete page? */
83778364
if (xtext->buffer->num_lines <= gtk_adjustment_get_page_size (adj))
83788365
{
8379-
xtext->buffer->old_value = 0;
83808366
gtk_adjustment_set_value (adj, 0);
83818367
/* GTK3: Queue a redraw instead of rendering directly */
83828368
gtk_widget_queue_draw (GTK_WIDGET (xtext));
@@ -8386,7 +8372,6 @@ gtk_xtext_render_page_timeout (GtkXText * xtext)
83868372
gtk_xtext_adjustment_set (xtext->buffer, FALSE);
83878373
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
83888374
g_signal_handler_unblock (xtext->adj, xtext->vc_signal_tag);
8389-
xtext->buffer->old_value = gtk_adjustment_get_value (adj);
83908375
xtext->buffer->scroll_anchor.anchor_to_bottom = TRUE;
83918376
/* GTK3: Queue a redraw instead of rendering directly */
83928377
gtk_widget_queue_draw (GTK_WIDGET (xtext));
@@ -8686,12 +8671,6 @@ gtk_xtext_append_entry (xtext_buffer *buf, textentry * ent, time_t stamp)
86868671
buf->xtext);
86878672
}
86888673
}
8689-
if (buf->scroll_anchor.anchor_to_bottom)
8690-
{
8691-
buf->old_value = buf->num_lines - gtk_adjustment_get_page_size (buf->xtext->adj);
8692-
if (buf->old_value < 0)
8693-
buf->old_value = 0;
8694-
}
86958674
if (buf->search_flags & follow)
86968675
{
86978676
GList *gl;
@@ -8727,7 +8706,6 @@ gtk_xtext_prepend_entry (xtext_buffer *buf, textentry *ent, time_t stamp)
87278706
}
87288707

87298708
/* Adjust scroll position - we added lines at the top, so everything shifts down */
8730-
buf->old_value += new_lines;
87318709
if (buf->xtext && buf->xtext->buffer == buf)
87328710
{
87338711
buf->xtext->select_start_adj += new_lines;
@@ -8878,7 +8856,6 @@ gtk_xtext_insert_sorted_entry (xtext_buffer *buf, textentry *ent, time_t stamp)
88788856
/* Adjust scroll position if we inserted before current view */
88798857
if (inserted_before_pagetop)
88808858
{
8881-
buf->old_value += new_lines;
88828859
if (buf->xtext && buf->xtext->buffer == buf && !buf->batch_mode)
88838860
{
88848861
buf->xtext->select_start_adj += new_lines;
@@ -8892,13 +8869,8 @@ gtk_xtext_insert_sorted_entry (xtext_buffer *buf, textentry *ent, time_t stamp)
88928869
/* Don't update marker_pos for historical entries */
88938870

88948871
/* Keep scroll anchored to bottom if appropriate */
8895-
if (buf->scroll_anchor.anchor_to_bottom)
8896-
{
8897-
buf->old_value = buf->num_lines - gtk_adjustment_get_page_size (buf->xtext->adj);
8898-
if (buf->old_value < 0)
8899-
buf->old_value = 0;
8900-
}
8901-
else if (!inserted_before_pagetop && buf->xtext && buf->xtext->buffer == buf
8872+
if (!buf->scroll_anchor.anchor_to_bottom
8873+
&& !inserted_before_pagetop && buf->xtext && buf->xtext->buffer == buf
89028874
&& !buf->batch_mode)
89038875
{
89048876
/* Entry inserted after viewport (e.g., chathistory catch-up while
@@ -9846,11 +9818,8 @@ gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render)
98469818

98479819
/*printf("text_buffer_show: xtext=%p buffer=%p\n", xtext, buf);*/
98489820

9849-
/* Save the current buffer's scroll position before switching */
9850-
if (xtext->buffer != NULL)
9851-
{
9852-
xtext->buffer->old_value = gtk_adjustment_get_value (xtext->adj);
9853-
}
9821+
/* Scroll position is preserved in buf->scroll_anchor, updated by
9822+
* adjustment_changed on every value change. No explicit save needed. */
98549823

98559824
if (xtext->add_io_tag)
98569825
{
@@ -9903,9 +9872,12 @@ gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render)
99039872
buf->scroll_anchor.anchor_to_bottom = TRUE;
99049873
gtk_adjustment_set_value (xtext->adj, gtk_adjustment_get_upper (xtext->adj) - gtk_adjustment_get_page_size (xtext->adj));
99059874
}
9906-
else if (buf->old_value >= 0)
9875+
else
99079876
{
9908-
gtk_adjustment_set_value (xtext->adj, buf->old_value);
9877+
/* Restore scroll position from the persistent anchor.
9878+
* The anchor was captured in adjustment_changed when the
9879+
* user last interacted with this buffer. */
9880+
gtk_xtext_restore_scroll_anchor (buf, &buf->scroll_anchor);
99099881
}
99109882
}
99119883

@@ -10098,11 +10070,11 @@ gtk_xtext_buffer_set_virtual (xtext_buffer *buf, void *db, const char *channel,
1009810070
{
1009910071
gdouble upper = gtk_adjustment_get_upper (buf->xtext->adj);
1010010072
gdouble page = gtk_adjustment_get_page_size (buf->xtext->adj);
10073+
gdouble bottom = upper - page;
10074+
if (bottom < 0)
10075+
bottom = 0;
1010110076
buf->scroll_anchor.anchor_to_bottom = TRUE;
10102-
buf->old_value = (gfloat)(upper - page);
10103-
if (buf->old_value < 0)
10104-
buf->old_value = 0;
10105-
gtk_adjustment_set_value (buf->xtext->adj, buf->old_value);
10077+
gtk_adjustment_set_value (buf->xtext->adj, bottom);
1010610078
}
1010710079
else if (was_down)
1010810080
{
@@ -10640,7 +10612,6 @@ gtk_xtext_virt_should_materialize (xtext_buffer *buf, time_t stamp,
1064010612
g_signal_handler_block (adj, buf->xtext->vc_signal_tag);
1064110613
gtk_adjustment_configure (adj, new_val, 0, new_upper, 1, page, page);
1064210614
g_signal_handler_unblock (adj, buf->xtext->vc_signal_tag);
10643-
buf->old_value = (gfloat) new_val;
1064410615
}
1064510616

1064610617
return FALSE;

src/fe-gtk/xtext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ typedef struct {
166166
typedef struct {
167167
GtkXText *xtext; /* attached to this widget */
168168

169-
gfloat old_value; /* last known adj->value */
169+
gfloat old_value; /* last processed adj->value (change gate only) */
170170
textentry *text_first;
171171
textentry *text_last;
172172
tree234 *entry_tree; /* counted B-tree for O(log n) positional access */

0 commit comments

Comments
 (0)