summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscos/gui.c11
-rw-r--r--riscos/gui/status_bar.c37
2 files changed, 41 insertions, 7 deletions
diff --git a/riscos/gui.c b/riscos/gui.c
index fa1158ad5..64276b36b 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -959,10 +959,19 @@ void gui_poll(bool active)
} else {
event = wimp_poll(wimp_MASK_NULL | mask, &block, 0);
}
+
xhourglass_on();
gui_last_poll = clock();
ro_gui_handle_event(event, &block);
- schedule_run();
+
+ /* Only run scheduled callbacks on a null poll
+ * We cannot do this in the null event handler, as that may be called
+ * from gui_multitask(). Scheduled callbacks must only be run from the
+ * top-level.
+ */
+ if (event == wimp_NULL_REASON_CODE)
+ schedule_run();
+
ro_gui_window_update_boxes();
if (browser_reformat_pending && event == wimp_NULL_REASON_CODE)
diff --git a/riscos/gui/status_bar.c b/riscos/gui/status_bar.c
index 75208ff64..c28611146 100644
--- a/riscos/gui/status_bar.c
+++ b/riscos/gui/status_bar.c
@@ -45,7 +45,7 @@
struct status_bar {
wimp_w w; /**< status bar window handle */
wimp_w parent; /**< parent window handle */
- char *text; /**< status bar text */
+ const char *text; /**< status bar text */
struct progress_bar *pb; /**< progress bar */
unsigned int scale; /**< current status bar scale */
int width; /**< current status bar width */
@@ -102,6 +102,7 @@ wimp_WINDOW(1) status_bar_definition = {
static void ro_gui_status_bar_open(wimp_open *open);
static bool ro_gui_status_bar_click(wimp_pointer *pointer);
static void ro_gui_status_bar_redraw(wimp_draw *redraw);
+static void ro_gui_status_bar_redraw_callback(void *handle);
static void ro_gui_status_position_progress_bar(struct status_bar *sb);
@@ -168,8 +169,8 @@ void ro_gui_status_bar_destroy(struct status_bar *sb)
ro_gui_progress_bar_destroy(sb->pb);
- if (sb->text)
- free(sb->text);
+ /* Remove any scheduled redraw callbacks */
+ schedule_remove(ro_gui_status_bar_redraw_callback, (void *) sb);
free(sb);
}
@@ -316,9 +317,21 @@ void ro_gui_status_bar_set_text(struct status_bar *sb, const char *text)
sb->text = text;
- /* redraw the window */
- if ((sb->visible) && (text != NULL))
- xwimp_force_redraw(sb->w, 0, 0, sb->width - WIDGET_WIDTH, 65536);
+ /* Schedule a window redraw for 1cs' time.
+ *
+ * We do this to ensure that redraws as a result of text changes
+ * do not prevent other applications obtaining CPU time.
+ *
+ * The scheduled callback will be run when we receive the first
+ * null poll after 1cs has elapsed. It may then issue a redraw
+ * request to the Wimp.
+ *
+ * The scheduler ensures that only one instance of the
+ * { callback, handle } pair is registered at once.
+ */
+ if (sb->visible && text != NULL) {
+ schedule(1, ro_gui_status_bar_redraw_callback, (void *) sb);
+ }
}
@@ -489,6 +502,18 @@ void ro_gui_status_bar_redraw(wimp_draw *redraw)
}
}
+/**
+ * Callback for scheduled redraw
+ *
+ * \param handle Callback handle
+ */
+void ro_gui_status_bar_redraw_callback(void *handle)
+{
+ struct status_bar *sb = handle;
+
+ wimp_force_redraw(sb->w, 0, 0, sb->width - WIDGET_WIDTH, 65536);
+}
+
/**
* Process an mouse_click event for a status window.