From e489f54ef0efef37d61d70853ec3387788c76d9e Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sat, 14 Mar 2026 20:27:59 -0500 Subject: [PATCH] More optimizing. --- dvx/dvxApp.c | 29 ++++++++++-------------- dvx/dvxComp.c | 16 ++++++------- dvx/dvxWidget.h | 3 +++ dvx/widgets/widgetAnsiTerm.c | 20 +++++++++++++---- dvx/widgets/widgetButton.c | 2 +- dvx/widgets/widgetCanvas.c | 2 +- dvx/widgets/widgetCheckbox.c | 2 +- dvx/widgets/widgetComboBox.c | 10 ++++----- dvx/widgets/widgetDropdown.c | 4 ++-- dvx/widgets/widgetEvent.c | 14 ++++++------ dvx/widgets/widgetImage.c | 2 +- dvx/widgets/widgetImageButton.c | 2 +- dvx/widgets/widgetListBox.c | 4 ++-- dvx/widgets/widgetOps.c | 34 ++++++++++++++++++++++++++++ dvx/widgets/widgetRadio.c | 6 ++--- dvx/widgets/widgetSlider.c | 2 +- dvx/widgets/widgetTextInput.c | 40 ++++++++++++++++----------------- 17 files changed, 118 insertions(+), 74 deletions(-) diff --git a/dvx/dvxApp.c b/dvx/dvxApp.c index 9c00903..88ef97a 100644 --- a/dvx/dvxApp.c +++ b/dvx/dvxApp.c @@ -137,8 +137,6 @@ static void compositeAndFlush(AppContextT *ctx) { RectT popIsect; if (rectIntersect(dr, &popRect, &popIsect)) { - setClipRect(d, dr->x, dr->y, dr->w, dr->h); - // Find the window and menu for (int32_t j = 0; j < ws->count; j++) { if (ws->windows[j]->id == ctx->popup.windowId) { @@ -202,8 +200,6 @@ static void compositeAndFlush(AppContextT *ctx) { RectT smIsect; if (rectIntersect(dr, &smRect, &smIsect)) { - setClipRect(d, dr->x, dr->y, dr->w, dr->h); - BevelStyleT smBevel; smBevel.highlight = ctx->colors.windowHighlight; smBevel.shadow = ctx->colors.windowShadow; @@ -465,10 +461,10 @@ static void dispatchEvents(AppContextT *ctx) { if (mx != ctx->prevMouseX || my != ctx->prevMouseY) { dirtyCursorArea(ctx, ctx->prevMouseX, ctx->prevMouseY); dirtyCursorArea(ctx, mx, my); - } - // Update cursor shape based on what the mouse is hovering over - updateCursorShape(ctx); + // Update cursor shape based on what the mouse is hovering over + updateCursorShape(ctx); + } // Handle active drag if (ctx->stack.dragWindow >= 0) { @@ -1380,9 +1376,16 @@ static void pollAnsiTermWidgetsWalk(AppContextT *ctx, WidgetT *w, WindowT *win) static void pollKeyboard(AppContextT *ctx) { __dpmi_regs r; - // Check if key is available (INT 16h, enhanced function 11h) + // Read shift state once per poll (INT 16h, AH=12h) + memset(&r, 0, sizeof(r)); + r.x.ax = 0x1200; + __dpmi_int(0x16, &r); + int32_t shiftFlags = r.x.ax & 0xFF; + bool shiftHeld = (shiftFlags & 0x03) != 0; // left or right shift + + // Process buffered keys while (1) { - memset(&r, 0, sizeof(r)); + // Check if key is available (INT 16h, enhanced function 11h) r.x.ax = 0x1100; __dpmi_int(0x16, &r); @@ -1392,7 +1395,6 @@ static void pollKeyboard(AppContextT *ctx) { } // Read the key (INT 16h, enhanced function 10h) - memset(&r, 0, sizeof(r)); r.x.ax = 0x1000; __dpmi_int(0x16, &r); @@ -1406,13 +1408,6 @@ static void pollKeyboard(AppContextT *ctx) { ascii = 0; } - // Read shift state (INT 16h, AH=12h — enhanced shift flags) - memset(&r, 0, sizeof(r)); - r.x.ax = 0x1200; - __dpmi_int(0x16, &r); - int32_t shiftFlags = r.x.ax & 0xFF; - bool shiftHeld = (shiftFlags & 0x03) != 0; // left or right shift - // Alt+Tab / Shift+Alt+Tab — cycle windows // Alt+Tab: scancode=0xA5, ascii=0x00 if (ascii == 0 && scancode == 0xA5) { diff --git a/dvx/dvxComp.c b/dvx/dvxComp.c index 9998b69..9185c6f 100644 --- a/dvx/dvxComp.c +++ b/dvx/dvxComp.c @@ -77,12 +77,15 @@ void dirtyListMerge(DirtyListT *dl) { return; } - bool merged = true; + // Single-pass O(N²): for each rect, try to merge it into an + // earlier rect. When a merge succeeds the merged rect may now + // overlap others, so restart the inner scan for that slot. + for (int32_t i = 0; i < dl->count; i++) { + bool merged = true; - while (merged) { - merged = false; + while (merged) { + merged = false; - for (int32_t i = 0; i < dl->count; i++) { for (int32_t j = i + 1; j < dl->count; j++) { if (rectsOverlapOrAdjacent(&dl->rects[i], &dl->rects[j], DIRTY_MERGE_GAP)) { rectUnion(&dl->rects[i], &dl->rects[j], &dl->rects[i]); @@ -104,15 +107,12 @@ void dirtyListMerge(DirtyListT *dl) { void flushRect(DisplayT *d, const RectT *r) { int32_t bpp = d->format.bytesPerPixel; + // Caller (compositeAndFlush) already clips to screen bounds int32_t x = r->x; int32_t y = r->y; int32_t w = r->w; int32_t h = r->h; - if (__builtin_expect(x < 0, 0)) { w += x; x = 0; } - if (__builtin_expect(y < 0, 0)) { h += y; y = 0; } - if (__builtin_expect(x + w > d->width, 0)) { w = d->width - x; } - if (__builtin_expect(y + h > d->height, 0)) { h = d->height - y; } if (__builtin_expect(w <= 0 || h <= 0, 0)) { return; } int32_t rowBytes = w * bpp; diff --git a/dvx/dvxWidget.h b/dvx/dvxWidget.h index 3682425..40a796f 100644 --- a/dvx/dvxWidget.h +++ b/dvx/dvxWidget.h @@ -576,6 +576,9 @@ int32_t wgtAnsiTermRepaint(WidgetT *w, int32_t *outY, int32_t *outH); // Mark a widget (and ancestors) for relayout and repaint void wgtInvalidate(WidgetT *w); +// Repaint only — skip measure/layout (use for visual-only changes) +void wgtInvalidatePaint(WidgetT *w); + // Set/get widget text (label, button, textInput, etc.) void wgtSetText(WidgetT *w, const char *text); const char *wgtGetText(const WidgetT *w); diff --git a/dvx/widgets/widgetAnsiTerm.c b/dvx/widgets/widgetAnsiTerm.c index 7ea9fe5..4cb5ce2 100644 --- a/dvx/widgets/widgetAnsiTerm.c +++ b/dvx/widgets/widgetAnsiTerm.c @@ -1553,7 +1553,7 @@ void widgetAnsiTermOnKey(WidgetT *w, int32_t key, int32_t mod) { if (ansiTermHasSelection(w)) { ansiTermCopySelection(w); ansiTermClearSelection(w); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1563,7 +1563,7 @@ void widgetAnsiTermOnKey(WidgetT *w, int32_t key, int32_t mod) { // Ctrl+V: paste from clipboard to terminal if (key == 0x16 && (mod & KEY_MOD_CTRL)) { ansiTermPasteToComm(w); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1645,7 +1645,7 @@ void widgetAnsiTermOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.ansiTerm.commWrite(w->as.ansiTerm.commCtx, buf, len); } - wgtInvalidate(w); + wgtInvalidatePaint(w); } @@ -1822,8 +1822,18 @@ void widgetAnsiTermPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const Bit // Determine if viewing live terminal or scrollback bool viewingLive = (w->as.ansiTerm.scrollPos == sbCount); - // Render character cells row by row using bulk renderer + // Render character cells row by row using bulk renderer. + // Only repaint rows marked dirty; 0xFFFFFFFF means all rows. + uint32_t dirty = w->as.ansiTerm.dirtyRows; + if (dirty == 0) { + dirty = 0xFFFFFFFF; + } + for (int32_t row = 0; row < rows; row++) { + if (row < 32 && !(dirty & (1U << row))) { + continue; + } + int32_t lineIndex = w->as.ansiTerm.scrollPos + row; const uint8_t *lineData = ansiTermGetLine(w, lineIndex); @@ -1838,6 +1848,8 @@ void widgetAnsiTermPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const Bit ansiTermPaintSelRow(w, d, ops, font, row, baseX, baseY); } + w->as.ansiTerm.dirtyRows = 0; + // Draw scrollbar int32_t sbX = baseX + cols * cellW; int32_t sbY = baseY; diff --git a/dvx/widgets/widgetButton.c b/dvx/widgets/widgetButton.c index b6c18f5..a1bfae7 100644 --- a/dvx/widgets/widgetButton.c +++ b/dvx/widgets/widgetButton.c @@ -59,7 +59,7 @@ void widgetButtonOnKey(WidgetT *w, int32_t key, int32_t mod) { if (key == ' ' || key == 0x0D) { w->as.button.pressed = true; sKeyPressedBtn = w; - wgtInvalidate(w); + wgtInvalidatePaint(w); } } diff --git a/dvx/widgets/widgetCanvas.c b/dvx/widgets/widgetCanvas.c index 3db5fc9..bd36cb6 100644 --- a/dvx/widgets/widgetCanvas.c +++ b/dvx/widgets/widgetCanvas.c @@ -709,7 +709,7 @@ void widgetCanvasOnMouse(WidgetT *hit, WidgetT *root, int32_t vx, int32_t vy) { hit->as.canvas.lastX = cx; hit->as.canvas.lastY = cy; - wgtInvalidate(hit); + wgtInvalidatePaint(hit); } diff --git a/dvx/widgets/widgetCheckbox.c b/dvx/widgets/widgetCheckbox.c index 2f32a7b..4ce1ac1 100644 --- a/dvx/widgets/widgetCheckbox.c +++ b/dvx/widgets/widgetCheckbox.c @@ -64,7 +64,7 @@ void widgetCheckboxOnKey(WidgetT *w, int32_t key, int32_t mod) { w->onChange(w); } - wgtInvalidate(w); + wgtInvalidatePaint(w); } } diff --git a/dvx/widgets/widgetComboBox.c b/dvx/widgets/widgetComboBox.c index 481cd6f..3b3096e 100644 --- a/dvx/widgets/widgetComboBox.c +++ b/dvx/widgets/widgetComboBox.c @@ -154,7 +154,7 @@ void widgetComboBoxOnKey(WidgetT *w, int32_t key, int32_t mod) { } } - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -167,7 +167,7 @@ void widgetComboBoxOnKey(WidgetT *w, int32_t key, int32_t mod) { } } - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -194,7 +194,7 @@ void widgetComboBoxOnKey(WidgetT *w, int32_t key, int32_t mod) { w->onChange(w); } - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } } @@ -213,7 +213,7 @@ void widgetComboBoxOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.comboBox.listScrollPos = w->as.comboBox.hoverIdx; } - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -426,7 +426,7 @@ void widgetComboBoxPaintPopup(WidgetT *w, DisplayT *d, const BlitOpsT *ops, cons rectFill(d, ops, popX + 2, iy, textW + TEXT_INPUT_PAD * 2, font->charHeight, ibg); } - drawText(d, ops, font, textX, iy, items[idx], ifg, ibg, idx == hoverIdx); + drawText(d, ops, font, textX, iy, items[idx], ifg, ibg, false); } } diff --git a/dvx/widgets/widgetDropdown.c b/dvx/widgets/widgetDropdown.c index 6c535a9..ffd7bca 100644 --- a/dvx/widgets/widgetDropdown.c +++ b/dvx/widgets/widgetDropdown.c @@ -166,7 +166,7 @@ void widgetDropdownOnKey(WidgetT *w, int32_t key, int32_t mod) { } } - wgtInvalidate(w); + wgtInvalidatePaint(w); } @@ -280,6 +280,6 @@ void widgetDropdownPaintPopup(WidgetT *w, DisplayT *d, const BlitOpsT *ops, cons rectFill(d, ops, popX + 2, iy, textW + TEXT_INPUT_PAD * 2, font->charHeight, ibg); } - drawText(d, ops, font, textX, iy, items[idx], ifg, ibg, idx == hoverIdx); + drawText(d, ops, font, textX, iy, items[idx], ifg, ibg, false); } } diff --git a/dvx/widgets/widgetEvent.c b/dvx/widgets/widgetEvent.c index 8da293a..2a2ef46 100644 --- a/dvx/widgets/widgetEvent.c +++ b/dvx/widgets/widgetEvent.c @@ -192,21 +192,21 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) { sDrawingCanvas->as.canvas.lastX = -1; sDrawingCanvas->as.canvas.lastY = -1; sDrawingCanvas = NULL; - wgtInvalidate(root); + wgtInvalidatePaint(root); return; } // Handle canvas drawing (mouse move while pressed) if (sDrawingCanvas && (buttons & 1)) { widgetCanvasOnMouse(sDrawingCanvas, root, x, y); - wgtInvalidate(root); + wgtInvalidatePaint(root); return; } // Handle slider drag release if (sDragSlider && !(buttons & 1)) { sDragSlider = NULL; - wgtInvalidate(root); + wgtInvalidatePaint(root); return; } @@ -242,7 +242,7 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) { sDragSlider->onChange(sDragSlider); } - wgtInvalidate(root); + wgtInvalidatePaint(root); } } @@ -272,7 +272,7 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) { } } - wgtInvalidate(sPressedButton); + wgtInvalidatePaint(sPressedButton); sPressedButton = NULL; return; } @@ -302,7 +302,7 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) { sPressedButton->as.button.pressed = over; } - wgtInvalidate(sPressedButton); + wgtInvalidatePaint(sPressedButton); } return; @@ -376,7 +376,7 @@ void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons) { } sOpenPopup = NULL; - wgtInvalidate(root); + wgtInvalidatePaint(root); // Fall through to normal click handling } diff --git a/dvx/widgets/widgetImage.c b/dvx/widgets/widgetImage.c index 9c1fd10..1af41a9 100644 --- a/dvx/widgets/widgetImage.c +++ b/dvx/widgets/widgetImage.c @@ -141,7 +141,7 @@ void widgetImageOnMouse(WidgetT *w, WidgetT *root, int32_t vx, int32_t vy) { (void)vx; (void)vy; w->as.image.pressed = true; - wgtInvalidate(w); + wgtInvalidatePaint(w); if (w->onClick) { w->onClick(w); diff --git a/dvx/widgets/widgetImageButton.c b/dvx/widgets/widgetImageButton.c index 2452b45..5303d3d 100644 --- a/dvx/widgets/widgetImageButton.c +++ b/dvx/widgets/widgetImageButton.c @@ -77,7 +77,7 @@ void widgetImageButtonOnKey(WidgetT *w, int32_t key, int32_t mod) { if (key == ' ' || key == 0x0D) { w->as.imageButton.pressed = true; sKeyPressedBtn = w; - wgtInvalidate(w); + wgtInvalidatePaint(w); } } diff --git a/dvx/widgets/widgetListBox.c b/dvx/widgets/widgetListBox.c index 82834b3..c6bcee2 100644 --- a/dvx/widgets/widgetListBox.c +++ b/dvx/widgets/widgetListBox.c @@ -156,7 +156,7 @@ void widgetListBoxOnKey(WidgetT *w, int32_t key, int32_t mod) { w->onChange(w); } - wgtInvalidate(w); + wgtInvalidatePaint(w); } @@ -292,7 +292,7 @@ void widgetListBoxPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const Bitm rectFill(d, ops, w->x + LISTBOX_BORDER, iy, contentW, font->charHeight, ibg); } - drawText(d, ops, font, innerX, iy, w->as.listBox.items[idx], ifg, ibg, idx == w->as.listBox.selectedIdx); + drawText(d, ops, font, innerX, iy, w->as.listBox.items[idx], ifg, ibg, false); } // Draw scrollbar diff --git a/dvx/widgets/widgetOps.c b/dvx/widgets/widgetOps.c index 9a9c35d..ba5873c 100644 --- a/dvx/widgets/widgetOps.c +++ b/dvx/widgets/widgetOps.c @@ -250,6 +250,40 @@ void wgtInvalidate(WidgetT *w) { } +// ============================================================ +// wgtInvalidatePaint +// ============================================================ +// +// Lightweight repaint — skips measure/layout/scrollbar management. +// Use when only visual state changed (slider value, cursor blink, +// selection highlight, checkbox toggle) but widget sizes are stable. + +void wgtInvalidatePaint(WidgetT *w) { + if (!w || !w->window) { + return; + } + + WidgetT *root = w; + + while (root->parent) { + root = root->parent; + } + + AppContextT *ctx = (AppContextT *)root->userData; + + if (!ctx) { + return; + } + + // Repaint without measure/layout + RectT fullRect = {0, 0, w->window->contentW, w->window->contentH}; + widgetOnPaint(w->window, &fullRect); + w->window->contentDirty = true; + + dvxInvalidateWindow(ctx, w->window); +} + + // ============================================================ // wgtPaint // ============================================================ diff --git a/dvx/widgets/widgetRadio.c b/dvx/widgets/widgetRadio.c index f3af09d..b88b65d 100644 --- a/dvx/widgets/widgetRadio.c +++ b/dvx/widgets/widgetRadio.c @@ -92,7 +92,7 @@ void widgetRadioOnKey(WidgetT *w, int32_t key, int32_t mod) { } } - wgtInvalidate(w); + wgtInvalidatePaint(w); } else if (key == (0x50 | 0x100) || key == (0x4D | 0x100)) { // Down or Right — next radio in group if (w->parent && w->parent->type == WidgetRadioGroupE) { @@ -115,7 +115,7 @@ void widgetRadioOnKey(WidgetT *w, int32_t key, int32_t mod) { next->parent->onChange(next->parent); } - wgtInvalidate(next); + wgtInvalidatePaint(next); } } } else if (key == (0x48 | 0x100) || key == (0x4B | 0x100)) { @@ -139,7 +139,7 @@ void widgetRadioOnKey(WidgetT *w, int32_t key, int32_t mod) { prev->parent->onChange(prev->parent); } - wgtInvalidate(prev); + wgtInvalidatePaint(prev); } } } diff --git a/dvx/widgets/widgetSlider.c b/dvx/widgets/widgetSlider.c index ff6c95b..629cdf6 100644 --- a/dvx/widgets/widgetSlider.c +++ b/dvx/widgets/widgetSlider.c @@ -119,7 +119,7 @@ void widgetSliderOnKey(WidgetT *w, int32_t key, int32_t mod) { w->onChange(w); } - wgtInvalidate(w); + wgtInvalidatePaint(w); } diff --git a/dvx/widgets/widgetTextInput.c b/dvx/widgets/widgetTextInput.c index c976876..d49fef5 100644 --- a/dvx/widgets/widgetTextInput.c +++ b/dvx/widgets/widgetTextInput.c @@ -697,7 +697,7 @@ done: } } - wgtInvalidate(w); + wgtInvalidatePaint(w); } @@ -948,7 +948,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { textAreaOffToRowCol(buf, *pLen, pRow, pCol); w->as.textArea.desiredCol = *pCol; textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -996,7 +996,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1023,7 +1023,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1067,7 +1067,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1105,7 +1105,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1144,7 +1144,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1181,7 +1181,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1197,7 +1197,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.textArea.desiredCol = *pCol; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1213,7 +1213,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.textArea.desiredCol = *pCol; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1229,7 +1229,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1245,7 +1245,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1256,7 +1256,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.textArea.desiredCol = 0; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1267,7 +1267,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.textArea.desiredCol = *pCol; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1284,7 +1284,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { *pCol = w->as.textArea.desiredCol < lineL ? w->as.textArea.desiredCol : lineL; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1301,7 +1301,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { *pCol = w->as.textArea.desiredCol < lineL ? w->as.textArea.desiredCol : lineL; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1313,7 +1313,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.textArea.desiredCol = 0; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1324,7 +1324,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { w->as.textArea.desiredCol = *pCol; SEL_END(); textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -1361,7 +1361,7 @@ void widgetTextAreaOnKey(WidgetT *w, int32_t key, int32_t mod) { } textAreaEnsureVisible(w, visRows, visCols); - wgtInvalidate(w); + wgtInvalidatePaint(w); return; } @@ -2520,5 +2520,5 @@ adjustScroll: } } - wgtInvalidate(w); + wgtInvalidatePaint(w); }