Skip to content

Commit 11834d5

Browse files
committed
improve responsiveness with large workspaces
1 parent d2c967a commit 11834d5

File tree

8 files changed

+62
-53
lines changed

8 files changed

+62
-53
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- fix menu state init
55
- save and restore more view settings
66
- add "Merge column" and "Merge tab" submenus
7+
- update interface during recomp, update regions during drag
78

89
## 9.0.9 2025/05/28
910

src/imageui.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,14 @@ imageui_drag_begin(GtkEventControllerMotion *self,
11811181
}
11821182
}
11831183

1184+
static void
1185+
imageui_regionview_update(Imageui *imageui, Regionview *regionview)
1186+
{
1187+
regionview->draw_area = regionview->our_area;
1188+
regionview->draw_type = regionview->type;
1189+
imageui_queue_draw(imageui);
1190+
}
1191+
11841192
static void
11851193
imageui_drag_update(GtkEventControllerMotion *self,
11861194
gdouble offset_x, gdouble offset_y, gpointer user_data)
@@ -1206,6 +1214,13 @@ imageui_drag_update(GtkEventControllerMotion *self,
12061214
imageui->tilesource->image_width, imageui->tilesource->image_height,
12071215
offset_x / zoom, offset_y / zoom);
12081216

1217+
/* Refresh immediately .. gives immediate feedback during drag in large
1218+
* workspaces, especially on windows.
1219+
*/
1220+
imageui_regionview_update(imageui, imageui->grabbed);
1221+
1222+
/* And nudge background recomp.
1223+
*/
12091224
regionview_model_update(imageui->grabbed);
12101225

12111226
break;
@@ -1214,13 +1229,7 @@ imageui_drag_update(GtkEventControllerMotion *self,
12141229
regionview_resize(imageui->floating, imagewindow_get_modifiers(win),
12151230
imageui->tilesource->image_width, imageui->tilesource->image_height,
12161231
offset_x / zoom, offset_y / zoom);
1217-
1218-
// fine to do an immediate redraw, since we don't rely on calc for
1219-
// position
1220-
imageui->floating->draw_area = imageui->floating->our_area;
1221-
imageui->floating->draw_type = imageui->floating->type;
1222-
imageui_queue_draw(imageui);
1223-
1232+
imageui_regionview_update(imageui, imageui->floating);
12241233
break;
12251234

12261235
case IMAGEUI_SCROLL:
@@ -1312,6 +1321,7 @@ imageui_drag_end(GtkEventControllerMotion *self,
13121321
break;
13131322

13141323
case IMAGEUI_SELECT:
1324+
regionview_model_update(imageui->grabbed);
13151325
VIPS_UNREF(imageui->grabbed);
13161326
break;
13171327

src/progress.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,4 @@ progress_end(void)
325325
ProgressEvent *event = progress_event_new(SIG_END, 0, 0, "");
326326
progress_event_signal(event);
327327
}
328+

src/reduce.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,9 @@ reduce_spine(Reduce *rc, PElement *out)
11021102
reduce_start:
11031103
reduce_total_recomputations += 1;
11041104
if ((reduce_total_recomputations % 100000) == 0) {
1105+
// helps keep the interface live
1106+
process_events();
1107+
11051108
if (progress_update_expr(reduce_current_expr)) {
11061109
error_top(_("Cancelled"));
11071110
error_sub(_("evaluation cancelled"));

src/regionview.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ regionview_model_update(Regionview *regionview)
200200

201201
if (classmodel) {
202202
classmodel_update_view(classmodel);
203-
204203
symbol_recalculate_all();
205204
}
206205

src/row.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,8 @@ row_recomp_all(Row *top_row)
15961596

15971597
/* Rebuild all dirty rows.
15981598
*/
1599-
while (!top_row->err && top_row->recomp) {
1599+
while (!top_row->err &&
1600+
top_row->recomp) {
16001601
Row *dirty_row = ROW(top_row->recomp->data);
16011602

16021603
#ifdef DEBUG_ROW
@@ -1630,6 +1631,10 @@ row_recomp_all(Row *top_row)
16301631
printf("row_recomp_all: after row recomp, top value now ");
16311632
pgraph(&top_row->expr->root);
16321633
#endif /*DEBUG*/
1634+
1635+
/* So we don't stall updates for too long.
1636+
*/
1637+
process_events();
16331638
}
16341639

16351640
workspace_error_sanity(top_row->ws);
@@ -1685,7 +1690,7 @@ row_recomp(Row *row)
16851690
*/
16861691
row_recomp_all(top_row);
16871692

1688-
/* Our workspace may have been closed in a callback: bail out.
1693+
/* Our workspace may have been closed in a callback.
16891694
*/
16901695
if (!top_row->sym)
16911696
return;
@@ -1740,7 +1745,7 @@ row_recomp(Row *row)
17401745
*/
17411746
row_recomp_all(top_row);
17421747

1743-
/* Our workspace may have been closed in a callback: bail out.
1748+
/* Our workspace may have been closed in a callback.
17441749
*/
17451750
if (!top_row->sym)
17461751
return;

src/symbol.c

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -942,11 +942,11 @@ symbol_recalculate_sub(Symbol *sym)
942942
gboolean result = TRUE;
943943

944944
#ifdef DEBUG_TIME
945-
static GTimer *timer = NULL;
945+
static GTimer *timer = NULL;
946946

947-
if (!timer)
948-
timer = g_timer_new();
949-
g_timer_reset(timer);
947+
if (!timer)
948+
timer = g_timer_new();
949+
g_timer_reset(timer);
950950
#endif /*DEBUG_TIME*/
951951

952952
g_assert(is_value(sym));
@@ -972,9 +972,9 @@ symbol_recalculate_sub(Symbol *sym)
972972
}
973973

974974
#ifdef DEBUG_TIME
975-
printf("symbol_recalculate_sub: ");
976-
symbol_name_scope_print(sym);
977-
printf(" %g\n", g_timer_elapsed(timer, NULL));
975+
printf("symbol_recalculate_sub: ");
976+
symbol_name_scope_print(sym);
977+
printf(" %g\n", g_timer_elapsed(timer, NULL));
978978
#endif /*DEBUG_TIME*/
979979

980980
return result;
@@ -1009,7 +1009,8 @@ symbol_get_last_calc(void)
10091009
*/
10101010
static gboolean symbol_running = FALSE;
10111011

1012-
/* Recalc a symbol ... with error checks.
1012+
/* Recalc a symbol with error checks. This can succeed, stop with a timeout,
1013+
* or fail with an error.
10131014
*/
10141015
static void *
10151016
symbol_recalculate_leaf_sub(Symbol *sym)
@@ -1034,6 +1035,7 @@ symbol_recalculate_leaf_sub(Symbol *sym)
10341035

10351036
return sym;
10361037
}
1038+
10371039
if (!sym->dirty)
10381040
return NULL;
10391041
if (!is_value(sym)) {
@@ -1045,14 +1047,19 @@ symbol_recalculate_leaf_sub(Symbol *sym)
10451047

10461048
reduce_context->heap->filled = FALSE;
10471049
symbol_running = TRUE;
1048-
progress_begin();
10491050
symbol_note_calc_name(sym);
1050-
if (!symbol_recalculate_sub(sym) ||
1051+
progress_begin();
1052+
1053+
// false for error, true for success or timeout
1054+
gboolean result = symbol_recalculate_sub(sym);
1055+
1056+
symbol_running = FALSE;
1057+
progress_end();
1058+
1059+
if (!result ||
10511060
reduce_context->heap->filled) {
10521061
if (sym->expr)
10531062
expr_error_set(sym->expr);
1054-
symbol_running = FALSE;
1055-
progress_end();
10561063

10571064
#ifdef DEBUG_RECALC
10581065
if (sym->expr)
@@ -1063,11 +1070,9 @@ symbol_recalculate_leaf_sub(Symbol *sym)
10631070

10641071
return sym;
10651072
}
1066-
symbol_running = FALSE;
1067-
progress_end();
10681073

1069-
/* Have we discovered any dirty children? If not, we've cleaned this
1070-
* sym.
1074+
/* Any dirty children? If not, we've cleaned this sym and it can come
1075+
* off the leaf set.
10711076
*/
10721077
if (!sym->ndirtychildren) {
10731078
symbol_dirty_clear(sym);
@@ -1124,11 +1129,11 @@ symbol_recalculate_leaf(void)
11241129
/* We can get errors during backtracking, don't report here.
11251130
*/
11261131

1127-
/* Note a pending GC.
1132+
/* Queue a GC.
11281133
*/
11291134
(void) heap_gc_request(reduce_context->heap);
11301135

1131-
/* We have recalculated a symbol.
1136+
/* We have made some progress.
11321137
*/
11331138
recalculated = TRUE;
11341139
}
@@ -1143,10 +1148,6 @@ static gint symbol_idle_id = 0;
11431148
static gboolean
11441149
symbol_recalculate_idle(void *user_data)
11451150
{
1146-
static GTimer *timer = NULL;
1147-
1148-
gboolean run_again;
1149-
11501151
#ifdef DEBUG_RECALC
11511152
printf("symbol_recalculate_idle:\n");
11521153
#endif /*DEBUG_RECALC*/
@@ -1158,34 +1159,22 @@ symbol_recalculate_idle(void *user_data)
11581159
*/
11591160
return TRUE;
11601161

1161-
if (!timer)
1162-
timer = g_timer_new();
1163-
1164-
g_timer_reset(timer);
1165-
1166-
run_again = TRUE;
1167-
1168-
if (!mainwindow_auto_recalc)
1169-
/* Auto-calc has been turned off during a recomp.
1170-
*/
1171-
run_again = FALSE;
1172-
else
1173-
while (g_timer_elapsed(timer, NULL) < 0.1)
1174-
if (!symbol_recalculate_leaf()) {
1175-
run_again = FALSE;
1176-
break;
1177-
}
1162+
if (mainwindow_auto_recalc)
1163+
while (symbol_recalculate_leaf())
1164+
;
11781165

1179-
if (!run_again) {
1166+
if (!symbol_leaf_next()) {
11801167
#ifdef DEBUG_RECALC
11811168
printf("symbol_recalculate_idle: bg recalc done\n");
11821169
#endif /*DEBUG_RECALC*/
11831170

11841171
symbol_idle_id = 0;
11851172
progress_end();
1186-
}
11871173

1188-
return run_again;
1174+
return FALSE;
1175+
}
1176+
else
1177+
return TRUE;
11891178
}
11901179

11911180
/* Recalculate ... either nudge the idle recomp, or in batch mode, do a recomp

src/symbol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ void *symbol_strip(Symbol *sym);
177177
void symbol_state_change(Symbol *sym);
178178

179179
const char *symbol_get_last_calc(void);
180+
gboolean symbol_recalculate_timeout(void);
180181
gboolean symbol_recalculate_check(Symbol *sym);
181182
void symbol_recalculate_all_force(gboolean now);
182183
void symbol_recalculate_all(void);

0 commit comments

Comments
 (0)