From 820ca1a966bd2cb0b77d7e36d979645b527a1b2b Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 25 Jan 2023 21:18:13 -0500 Subject: [PATCH] motif: Don't query widget width every timer update. Turns out that just getting the widget width from Xt represents the vast majority of the time spent on the timer update. It is very simple to query the width only when it changes, instead, and save that result for later rendering. --- src/xcounter.c | 23 +++++++++++++++-------- src/xcounter.h | 5 +++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/xcounter.c b/src/xcounter.c index e8e5d17..47fdf5b 100644 --- a/src/xcounter.c +++ b/src/xcounter.c @@ -1,6 +1,6 @@ /* * Helpers for implementing a rapid-update counter display in Motif. - * Copyright © 2022 Nick Bowler + * Copyright © 2022-2023 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,6 +48,10 @@ struct xcounter { Pixmap pixmap; uint_least32_t render_mask; + + /* Cached width of the widget */ + uint_least16_t render_width; + unsigned char seq[23], num_strings; /* @@ -80,7 +84,7 @@ xc_alloc(Widget w, XmRenderTable rt, XmString *strings, int nstr) xc->widget = w; for (i = 0; i < nstr; i++) { - unsigned w, h; + unsigned h; if ((h = XmStringHeight(rt, strings[i])) > height) height = h + 2*MARGIN; @@ -209,13 +213,10 @@ static void xc_redraw(struct xcounter *xc, uint_fast32_t mask) Drawable d = XtWindow(xc->widget); unsigned out_x = MARGIN, src_x, w; - Dimension max_w, h; + Dimension max_w; int i; - XtVaGetValues(xc->widget, XmNwidth, &max_w, - (char *)NULL); - max_w = MAX(MARGIN, max_w) - MARGIN; - + max_w = MAX(MARGIN, xc->render_width) - MARGIN; xc_foreach_seq(xc, i, out_x, src_x, w, mask) { if (out_x + w > max_w) { w = max_w - out_x; @@ -339,7 +340,13 @@ void xcounter_expose(struct xcounter *xc, XExposeEvent *e) void xcounter_resize_cb(Widget w, void *data, void *cb_data) { - xc_queue_render(data, XC_RESIZING); + struct xcounter *xc = data; + Dimension width; + + XtVaGetValues(xc->widget, XmNwidth, &width, (char *)NULL); + xc->render_width = width; + + xc_queue_render(xc, XC_RESIZING); } void xcounter_expose_cb(Widget w, void *data, void *cb_data) diff --git a/src/xcounter.h b/src/xcounter.h index e08b8a8..112d485 100644 --- a/src/xcounter.h +++ b/src/xcounter.h @@ -1,6 +1,6 @@ /* * Helpers for implementing a rapid-update counter display in Motif. - * Copyright © 2022 Nick Bowler + * Copyright © 2022-2023 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -94,7 +94,8 @@ void xcounter_resize_cb(Widget w, void *data, void *cb_data); void xcounter_expose_cb(Widget w, void *data, void *cb_data); /* - * Clear the margins of the counter after resizing the widget. + * Call after the widget is resized to update the internal dimensions, + * and clear the margins. * * Since the pre-rendered text never changes, this is all that is needed: * existing portions of the window do not need to be redrawn (except when -- 2.43.2