fix fast scroll glitches

This commit is contained in:
nakst 2021-09-14 12:18:08 +01:00
parent 599a2786d8
commit b4dfe96d85
4 changed files with 13 additions and 4 deletions

View File

@ -2830,6 +2830,10 @@ void ScrollPane::SetPosition(int axis, double newScroll, bool sendMovedMessage)
if (newScroll < 0) newScroll = 0; if (newScroll < 0) newScroll = 0;
else if (newScroll > limit[axis]) newScroll = limit[axis]; else if (newScroll > limit[axis]) newScroll = limit[axis];
if (newScroll == position[axis]) return; if (newScroll == position[axis]) return;
// Since we might be about to fast scroll, make sure the bits we are scrolling are valid.
UIWindowPaintNow(parent->window, nullptr, false);
double previous = position[axis]; double previous = position[axis];
position[axis] = newScroll; position[axis] = newScroll;
if (bar[axis]) ScrollbarSetPosition(bar[axis], position[axis], false, false); if (bar[axis]) ScrollbarSetPosition(bar[axis], position[axis], false, false);
@ -6089,7 +6093,7 @@ void EsElementRepaint(EsElement *element, const EsRectangle *region) {
} }
void EsElementRepaintForScroll(EsElement *element, EsMessage *message) { void EsElementRepaintForScroll(EsElement *element, EsMessage *message) {
// TODO Support custom borders sizes. // TODO Support custom border sizes.
EsRectangle borders = ES_RECT_4(element->internalOffsetLeft, element->internalOffsetRight, EsRectangle borders = ES_RECT_4(element->internalOffsetLeft, element->internalOffsetRight,
element->internalOffsetTop, element->internalOffsetBottom); element->internalOffsetTop, element->internalOffsetBottom);

View File

@ -222,7 +222,11 @@ void Surface::Scroll(EsRectangle region, ptrdiff_t delta, bool vertical) {
} }
} }
} else { } else {
// TODO. for (intptr_t i = region.t; i < region.b; i++) {
for (intptr_t j = region.r - 1; j >= region.l; j--) {
((uint32_t *) bits)[j - delta + i * stride / 4] = ((uint32_t *) bits)[j + i * stride / 4];
}
}
} }
} }
} }

View File

@ -505,6 +505,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
if (argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL || argument3 == WINDOW_SET_BITS_SCROLL_HORIZONTAL) { if (argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL || argument3 == WINDOW_SET_BITS_SCROLL_HORIZONTAL) {
ptrdiff_t scrollDelta = argument2; ptrdiff_t scrollDelta = argument2;
bool scrollVertical = argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL; bool scrollVertical = argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL;
EsRectangle originalRegion = region;
if (scrollVertical) { if (scrollVertical) {
if (scrollDelta < 0) region.b += scrollDelta; if (scrollDelta < 0) region.b += scrollDelta;
@ -522,7 +523,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
|| region.l >= region.r || region.t >= region.b) { || region.l >= region.r || region.t >= region.b) {
} else { } else {
surface->Scroll(region, scrollDelta, scrollVertical); surface->Scroll(region, scrollDelta, scrollVertical);
window->Update(&region, true); window->Update(&originalRegion, true);
window->queuedScrollUpdate = true; window->queuedScrollUpdate = true;
// Don't update the screen until the rest of the window is painted. // Don't update the screen until the rest of the window is painted.
} }

View File

@ -7,7 +7,7 @@
// Terminology: // Terminology:
// Dynamic resize - flicker-free resizing in container windows with an embedded window owned by a separate process. // Dynamic resize - flicker-free resizing in container windows with an embedded window owned by a separate process.
// Direct update - paint first onto the video card's framebuffer, then onto the window manager's; used to reduce latency. // Direct update - paint first onto the video card's framebuffer, then onto the window manager's; used to reduce latency.
// Fast scroll - scrolling by shifting the bits in the window's surface, rather than repainting the entire area. TODO This is currently a bit broken. // Fast scroll - scrolling by shifting the bits in the window's surface, rather than repainting the entire area.
struct EmbeddedWindow { struct EmbeddedWindow {
void Destroy(); void Destroy();