mirror of https://gitlab.com/nakst/essence
remove fast scroll
This commit is contained in:
parent
20a9aecae0
commit
97f308e0a7
|
@ -2896,9 +2896,6 @@ void ScrollPane::SetPosition(int axis, double newScroll, bool sendMovedMessage)
|
|||
else if (newScroll > limit[axis]) newScroll = limit[axis];
|
||||
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];
|
||||
position[axis] = newScroll;
|
||||
if (bar[axis]) ScrollbarSetPosition(bar[axis], position[axis], false, false);
|
||||
|
@ -6500,28 +6497,16 @@ void EsElementRepaint(EsElement *element, const EsRectangle *region) {
|
|||
}
|
||||
|
||||
void EsElementRepaintForScroll(EsElement *element, EsMessage *message, EsRectangle border) {
|
||||
EsRectangle content = ES_RECT_4(border.l, element->width - border.r, border.t, element->height - border.b);
|
||||
EsRectangle repaint = content;
|
||||
int64_t delta = message->scrollbarMoved.scroll - message->scrollbarMoved.previous;
|
||||
// TODO Improved fast scroll:
|
||||
// - Set a scroll rectangle in the window.
|
||||
// - If one is already marked, then don't attempt a fast scroll.
|
||||
// - When painting, exclude anything containing in the scroll rectangle.
|
||||
// - When sending bits to the WM, give it the scroll rectangle to apply first.
|
||||
|
||||
if (message->type == ES_MSG_SCROLL_Y) {
|
||||
if (delta > 0) repaint.t = element->height - delta - border.b;
|
||||
else repaint.b = border.t - delta;
|
||||
} else if (message->type == ES_MSG_SCROLL_X) {
|
||||
if (delta > 0) repaint.l = element->width - delta - border.r;
|
||||
else repaint.r = border.l - delta;
|
||||
} else {
|
||||
EsAssert(false);
|
||||
}
|
||||
EsElementRepaint(element);
|
||||
|
||||
EsRectangle rectangle = element->GetWindowBounds(false);
|
||||
EsRectangle scrollBits = Translate(content, rectangle.l, rectangle.t);
|
||||
EsSyscall(ES_SYSCALL_WINDOW_SET_BITS, element->window->handle, (uintptr_t) &scrollBits, delta,
|
||||
message->type == ES_MSG_SCROLL_Y ? WINDOW_SET_BITS_SCROLL_VERTICAL : WINDOW_SET_BITS_SCROLL_HORIZONTAL);
|
||||
|
||||
repaint = EsRectangleIntersection(repaint, content);
|
||||
EsElementRepaint(element, &repaint);
|
||||
UIWindowPaintNow(element->window, nullptr, false);
|
||||
(void) message;
|
||||
(void) border;
|
||||
}
|
||||
|
||||
bool EsElementStartAnimating(EsElement *element) {
|
||||
|
|
|
@ -1257,7 +1257,7 @@ struct EsProcessState {
|
|||
|
||||
struct EsPainter {
|
||||
EsRectangle clip;
|
||||
int offsetX, offsetY, width, height;
|
||||
int32_t offsetX, offsetY, width, height;
|
||||
void *style;
|
||||
EsPaintTarget *target;
|
||||
}
|
||||
|
@ -2119,6 +2119,7 @@ function EsRectangle EsRectangleSubtract(EsRectangle a, EsRectangle b);
|
|||
function EsRectangle EsRectangleTranslate(EsRectangle a, EsRectangle b);
|
||||
function bool EsRectangleEquals(EsRectangle a, EsRectangle b);
|
||||
function bool EsRectangleContains(EsRectangle a, int32_t x, int32_t y);
|
||||
function bool EsRectangleContainsAll(EsRectangle parent, EsRectangle child); // Returns true iff the child rectangle is entirely contained within parent.
|
||||
function void EsSort(void *_base, size_t nmemb, size_t size, EsComparisonCallback compar, EsGeneric argument);
|
||||
function void EsSortWithSwapCallback(void *_base, size_t nmemb, size_t size, EsComparisonCallback compar, EsGeneric argument, EsSwapCallback swap);
|
||||
|
||||
|
|
|
@ -304,9 +304,11 @@ struct GlobalData {
|
|||
#define K_SYSTEM_CONFIGURATION K_SYSTEM_FOLDER "/Default.ini"
|
||||
|
||||
#define WINDOW_SET_BITS_NORMAL (0)
|
||||
#define WINDOW_SET_BITS_SCROLL_HORIZONTAL (1)
|
||||
#define WINDOW_SET_BITS_SCROLL_VERTICAL (2)
|
||||
#define WINDOW_SET_BITS_AFTER_RESIZE (3)
|
||||
#define WINDOW_SET_BITS_AFTER_RESIZE (1)
|
||||
|
||||
#define FAST_SCROLL_HORIZONTAL (1)
|
||||
#define FAST_SCROLL_VERTICAL (2)
|
||||
#define FAST_SCROLL_DO_NOT_ATTEMPT (3)
|
||||
|
||||
#define CURSOR_USE_ACCELERATION (1 << 0)
|
||||
#define CURSOR_USE_ALT_SLOW (1 << 1)
|
||||
|
|
|
@ -500,7 +500,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
|
|||
bool isEmbed = _window.type == KERNEL_OBJECT_EMBEDDED_WINDOW;
|
||||
Window *window = isEmbed ? ((EmbeddedWindow *) _window.object)->container : ((Window *) _window.object);
|
||||
|
||||
if (!window || (isEmbed && currentProcess != ((EmbeddedWindow *) _window.object)->owner)) {
|
||||
if (!window || (isEmbed && currentProcess != ((EmbeddedWindow *) _window.object)->owner) || window->closed) {
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
|
@ -511,109 +511,73 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
|
|||
region = Translate(region, insets.l, insets.t);
|
||||
}
|
||||
|
||||
if (argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL || argument3 == WINDOW_SET_BITS_SCROLL_HORIZONTAL) {
|
||||
ptrdiff_t scrollDelta = argument2;
|
||||
bool scrollVertical = argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL;
|
||||
EsRectangle originalRegion = region;
|
||||
SYSCALL_BUFFER(argument2, Width(region) * Height(region) * 4, 1, false);
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
|
||||
if (scrollVertical) {
|
||||
if (scrollDelta < 0) region.b += scrollDelta;
|
||||
else region.t += scrollDelta;
|
||||
} else {
|
||||
if (scrollDelta < 0) region.r += scrollDelta;
|
||||
else region.l += scrollDelta;
|
||||
bool resizeQueued = false;
|
||||
|
||||
if (argument3 == WINDOW_SET_BITS_AFTER_RESIZE && windowManager.resizeWindow == window) {
|
||||
if (isEmbed) windowManager.resizeReceivedBitsFromEmbed = true;
|
||||
else windowManager.resizeReceivedBitsFromContainer = true;
|
||||
|
||||
if (windowManager.resizeReceivedBitsFromContainer && windowManager.resizeReceivedBitsFromEmbed) {
|
||||
// Resize complete.
|
||||
resizeQueued = windowManager.resizeQueued;
|
||||
windowManager.resizeQueued = false;
|
||||
windowManager.resizeWindow = nullptr;
|
||||
windowManager.resizeSlow = KGetTimeInMs() - windowManager.resizeStartTimeStampMs >= RESIZE_SLOW_THRESHOLD
|
||||
|| windowManager.inspectorWindowCount /* HACK anti-flicker logic interfers with the inspector's logging */;
|
||||
// EsPrint("Resize complete in %dms%z.\n", KGetTimeInMs() - windowManager.resizeStartTimeStampMs, windowManager.resizeSlow ? " (slow)" : "");
|
||||
}
|
||||
}
|
||||
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
uintptr_t stride = Width(region) * 4;
|
||||
EsRectangle clippedRegion = EsRectangleIntersection(region, ES_RECT_2S(surface->width, surface->height));
|
||||
|
||||
if (window->closed
|
||||
|| region.l < 0 || region.r > (int32_t) surface->width
|
||||
|| region.t < 0 || region.b > (int32_t) surface->height
|
||||
|| region.l >= region.r || region.t >= region.b) {
|
||||
} else {
|
||||
surface->Scroll(region, scrollDelta, scrollVertical);
|
||||
window->Update(&originalRegion, true);
|
||||
window->queuedScrollUpdate = true;
|
||||
// Don't update the screen until the rest of the window is painted.
|
||||
}
|
||||
EsRectangle directUpdateSubRegion;
|
||||
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
|
||||
directUpdateSubRegion = ES_RECT_4(0, window->width, 0, insets.t);
|
||||
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
|
||||
directUpdateSubRegion = ES_RECT_4(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
|
||||
} else {
|
||||
bool skipUpdate = false;
|
||||
SYSCALL_BUFFER(argument2, Width(region) * Height(region) * 4, 1, false);
|
||||
KMutexAcquire(&windowManager.mutex);
|
||||
directUpdateSubRegion = ES_RECT_4(0, window->width, 0, window->height);
|
||||
}
|
||||
|
||||
bool resizeQueued = false;
|
||||
bool didDirectUpdate = false;
|
||||
|
||||
if (argument3 == WINDOW_SET_BITS_AFTER_RESIZE && windowManager.resizeWindow == window) {
|
||||
if (isEmbed) windowManager.resizeReceivedBitsFromEmbed = true;
|
||||
else windowManager.resizeReceivedBitsFromContainer = true;
|
||||
|
||||
if (windowManager.resizeReceivedBitsFromContainer && windowManager.resizeReceivedBitsFromEmbed) {
|
||||
// Resize complete.
|
||||
resizeQueued = windowManager.resizeQueued;
|
||||
windowManager.resizeQueued = false;
|
||||
windowManager.resizeWindow = nullptr;
|
||||
windowManager.resizeSlow = KGetTimeInMs() - windowManager.resizeStartTimeStampMs >= RESIZE_SLOW_THRESHOLD
|
||||
|| windowManager.inspectorWindowCount /* HACK anti-flicker logic interfers with the inspector's logging */;
|
||||
|
||||
#if 0
|
||||
EsPrint("Resize complete in %dms%z.\n", KGetTimeInMs() - windowManager.resizeStartTimeStampMs, windowManager.resizeSlow ? " (slow)" : "");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (window->closed) {
|
||||
skipUpdate = true;
|
||||
} else {
|
||||
uintptr_t stride = Width(region) * 4;
|
||||
EsRectangle clippedRegion = EsRectangleIntersection(region, ES_RECT_2S(surface->width, surface->height));
|
||||
|
||||
EsRectangle directUpdateSubRegion;
|
||||
|
||||
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
|
||||
directUpdateSubRegion = ES_RECT_4(0, window->width, 0, insets.t);
|
||||
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
|
||||
directUpdateSubRegion = ES_RECT_4(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
|
||||
} else {
|
||||
directUpdateSubRegion = ES_RECT_4(0, window->width, 0, window->height);
|
||||
}
|
||||
|
||||
if (argument3 != WINDOW_SET_BITS_AFTER_RESIZE && EsRectangleEquals(region, EsRectangleIntersection(region, directUpdateSubRegion))) {
|
||||
skipUpdate = window->UpdateDirect((K_USER_BUFFER uint32_t *) argument2, stride, clippedRegion);
|
||||
}
|
||||
if (argument3 != WINDOW_SET_BITS_AFTER_RESIZE && EsRectangleEquals(region, EsRectangleIntersection(region, directUpdateSubRegion))) {
|
||||
didDirectUpdate = window->UpdateDirect((K_USER_BUFFER uint32_t *) argument2, stride, clippedRegion);
|
||||
}
|
||||
|
||||
#define SET_BITS_REGION(...) { \
|
||||
EsRectangle subRegion = EsRectangleIntersection(clippedRegion, ES_RECT_4(__VA_ARGS__)); \
|
||||
if (ES_RECT_VALID(subRegion)) { surface->SetBits((K_USER_BUFFER const uint8_t *) argument2 \
|
||||
+ stride * (subRegion.t - clippedRegion.t) + 4 * (subRegion.l - clippedRegion.l), stride, subRegion); } }
|
||||
EsRectangle subRegion = EsRectangleIntersection(clippedRegion, ES_RECT_4(__VA_ARGS__)); \
|
||||
if (ES_RECT_VALID(subRegion)) { surface->SetBits((K_USER_BUFFER const uint8_t *) argument2 \
|
||||
+ stride * (subRegion.t - clippedRegion.t) + 4 * (subRegion.l - clippedRegion.l), stride, subRegion); } }
|
||||
|
||||
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
|
||||
SET_BITS_REGION(0, window->width, 0, insets.t);
|
||||
SET_BITS_REGION(0, insets.l, insets.t, window->height - insets.b);
|
||||
SET_BITS_REGION(window->width - insets.r, window->width, insets.t, window->height - insets.b);
|
||||
SET_BITS_REGION(0, window->width, window->height - insets.b, window->height);
|
||||
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
|
||||
SET_BITS_REGION(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
|
||||
} else {
|
||||
SET_BITS_REGION(0, window->width, 0, window->height);
|
||||
}
|
||||
}
|
||||
|
||||
window->Update(®ion, !skipUpdate);
|
||||
|
||||
if (!skipUpdate || window->queuedScrollUpdate) {
|
||||
window->queuedScrollUpdate = false;
|
||||
GraphicsUpdateScreen();
|
||||
}
|
||||
|
||||
if (resizeQueued) {
|
||||
window->Move(windowManager.resizeQueuedRectangle, ES_WINDOW_MOVE_DYNAMIC);
|
||||
}
|
||||
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
|
||||
SET_BITS_REGION(0, window->width, 0, insets.t);
|
||||
SET_BITS_REGION(0, insets.l, insets.t, window->height - insets.b);
|
||||
SET_BITS_REGION(window->width - insets.r, window->width, insets.t, window->height - insets.b);
|
||||
SET_BITS_REGION(0, window->width, window->height - insets.b, window->height);
|
||||
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
|
||||
SET_BITS_REGION(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
|
||||
} else {
|
||||
SET_BITS_REGION(0, window->width, 0, window->height);
|
||||
}
|
||||
|
||||
window->Update(®ion, !didDirectUpdate);
|
||||
|
||||
if (!didDirectUpdate) {
|
||||
GraphicsUpdateScreen();
|
||||
}
|
||||
|
||||
if (resizeQueued) {
|
||||
window->Move(windowManager.resizeQueuedRectangle, ES_WINDOW_MOVE_DYNAMIC);
|
||||
}
|
||||
|
||||
KMutexRelease(&windowManager.mutex);
|
||||
|
||||
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
// Terminology:
|
||||
// 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.
|
||||
// Fast scroll - scrolling by shifting the bits in the window's surface, rather than repainting the entire area.
|
||||
|
||||
struct EmbeddedWindow {
|
||||
void Destroy();
|
||||
|
@ -35,7 +34,7 @@ struct Window {
|
|||
// State:
|
||||
EsWindowStyle style;
|
||||
EsRectangle solidOffsets, embedInsets;
|
||||
bool solid, noClickActivate, hidden, isMaximised, alwaysOnTop, hoveringOverEmbed, queuedScrollUpdate, activationClick, noBringToFront;
|
||||
bool solid, noClickActivate, hidden, isMaximised, alwaysOnTop, hoveringOverEmbed, activationClick, noBringToFront;
|
||||
volatile bool closed;
|
||||
|
||||
// Appearance:
|
||||
|
|
|
@ -134,6 +134,10 @@ bool EsRectangleContains(EsRectangle a, int32_t x, int32_t y) {
|
|||
return ES_RECT_VALID(a) && a.l <= x && a.r > x && a.t <= y && a.b > y;
|
||||
}
|
||||
|
||||
bool EsRectangleContainsAll(EsRectangle parent, EsRectangle child) {
|
||||
return ES_RECT_VALID(parent) && child.l >= parent.l && child.r <= parent.r && child.t >= parent.t && child.b <= parent.b;
|
||||
}
|
||||
|
||||
EsRectangle EsRectangleSplit(EsRectangle *a, int32_t amount, char side, int32_t gap) {
|
||||
EsRectangle b = *a;
|
||||
if (side == 'l') a->l += amount + gap, b.r = a->l - gap;
|
||||
|
|
|
@ -491,3 +491,4 @@ _EsOpenDocumentEnumerate=489
|
|||
EsDialogGetContentArea=490
|
||||
_EsDebugCommand=491
|
||||
DateToLinear=492
|
||||
EsRectangleContainsAll=493
|
||||
|
|
Loading…
Reference in New Issue