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];
|
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);
|
||||||
|
@ -6500,28 +6497,16 @@ void EsElementRepaint(EsElement *element, const EsRectangle *region) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EsElementRepaintForScroll(EsElement *element, EsMessage *message, EsRectangle border) {
|
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);
|
// TODO Improved fast scroll:
|
||||||
EsRectangle repaint = content;
|
// - Set a scroll rectangle in the window.
|
||||||
int64_t delta = message->scrollbarMoved.scroll - message->scrollbarMoved.previous;
|
// - 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) {
|
EsElementRepaint(element);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
EsRectangle rectangle = element->GetWindowBounds(false);
|
(void) message;
|
||||||
EsRectangle scrollBits = Translate(content, rectangle.l, rectangle.t);
|
(void) border;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsElementStartAnimating(EsElement *element) {
|
bool EsElementStartAnimating(EsElement *element) {
|
||||||
|
|
|
@ -1257,7 +1257,7 @@ struct EsProcessState {
|
||||||
|
|
||||||
struct EsPainter {
|
struct EsPainter {
|
||||||
EsRectangle clip;
|
EsRectangle clip;
|
||||||
int offsetX, offsetY, width, height;
|
int32_t offsetX, offsetY, width, height;
|
||||||
void *style;
|
void *style;
|
||||||
EsPaintTarget *target;
|
EsPaintTarget *target;
|
||||||
}
|
}
|
||||||
|
@ -2119,6 +2119,7 @@ function EsRectangle EsRectangleSubtract(EsRectangle a, EsRectangle b);
|
||||||
function EsRectangle EsRectangleTranslate(EsRectangle a, EsRectangle b);
|
function EsRectangle EsRectangleTranslate(EsRectangle a, EsRectangle b);
|
||||||
function bool EsRectangleEquals(EsRectangle a, EsRectangle b);
|
function bool EsRectangleEquals(EsRectangle a, EsRectangle b);
|
||||||
function bool EsRectangleContains(EsRectangle a, int32_t x, int32_t y);
|
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 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);
|
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 K_SYSTEM_CONFIGURATION K_SYSTEM_FOLDER "/Default.ini"
|
||||||
|
|
||||||
#define WINDOW_SET_BITS_NORMAL (0)
|
#define WINDOW_SET_BITS_NORMAL (0)
|
||||||
#define WINDOW_SET_BITS_SCROLL_HORIZONTAL (1)
|
#define WINDOW_SET_BITS_AFTER_RESIZE (1)
|
||||||
#define WINDOW_SET_BITS_SCROLL_VERTICAL (2)
|
|
||||||
#define WINDOW_SET_BITS_AFTER_RESIZE (3)
|
#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_ACCELERATION (1 << 0)
|
||||||
#define CURSOR_USE_ALT_SLOW (1 << 1)
|
#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;
|
bool isEmbed = _window.type == KERNEL_OBJECT_EMBEDDED_WINDOW;
|
||||||
Window *window = isEmbed ? ((EmbeddedWindow *) _window.object)->container : ((Window *) _window.object);
|
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);
|
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,109 +511,73 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_WINDOW_SET_BITS) {
|
||||||
region = Translate(region, insets.l, insets.t);
|
region = Translate(region, insets.l, insets.t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL || argument3 == WINDOW_SET_BITS_SCROLL_HORIZONTAL) {
|
SYSCALL_BUFFER(argument2, Width(region) * Height(region) * 4, 1, false);
|
||||||
ptrdiff_t scrollDelta = argument2;
|
KMutexAcquire(&windowManager.mutex);
|
||||||
bool scrollVertical = argument3 == WINDOW_SET_BITS_SCROLL_VERTICAL;
|
|
||||||
EsRectangle originalRegion = region;
|
|
||||||
|
|
||||||
if (scrollVertical) {
|
bool resizeQueued = false;
|
||||||
if (scrollDelta < 0) region.b += scrollDelta;
|
|
||||||
else region.t += scrollDelta;
|
if (argument3 == WINDOW_SET_BITS_AFTER_RESIZE && windowManager.resizeWindow == window) {
|
||||||
} else {
|
if (isEmbed) windowManager.resizeReceivedBitsFromEmbed = true;
|
||||||
if (scrollDelta < 0) region.r += scrollDelta;
|
else windowManager.resizeReceivedBitsFromContainer = true;
|
||||||
else region.l += scrollDelta;
|
|
||||||
|
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
|
EsRectangle directUpdateSubRegion;
|
||||||
|| 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.
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
bool skipUpdate = false;
|
directUpdateSubRegion = ES_RECT_4(0, window->width, 0, window->height);
|
||||||
SYSCALL_BUFFER(argument2, Width(region) * Height(region) * 4, 1, false);
|
}
|
||||||
KMutexAcquire(&windowManager.mutex);
|
|
||||||
|
|
||||||
bool resizeQueued = false;
|
bool didDirectUpdate = false;
|
||||||
|
|
||||||
if (argument3 == WINDOW_SET_BITS_AFTER_RESIZE && windowManager.resizeWindow == window) {
|
if (argument3 != WINDOW_SET_BITS_AFTER_RESIZE && EsRectangleEquals(region, EsRectangleIntersection(region, directUpdateSubRegion))) {
|
||||||
if (isEmbed) windowManager.resizeReceivedBitsFromEmbed = true;
|
didDirectUpdate = window->UpdateDirect((K_USER_BUFFER uint32_t *) argument2, stride, clippedRegion);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_BITS_REGION(...) { \
|
#define SET_BITS_REGION(...) { \
|
||||||
EsRectangle subRegion = EsRectangleIntersection(clippedRegion, ES_RECT_4(__VA_ARGS__)); \
|
EsRectangle subRegion = EsRectangleIntersection(clippedRegion, ES_RECT_4(__VA_ARGS__)); \
|
||||||
if (ES_RECT_VALID(subRegion)) { surface->SetBits((K_USER_BUFFER const uint8_t *) argument2 \
|
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); } }
|
+ stride * (subRegion.t - clippedRegion.t) + 4 * (subRegion.l - clippedRegion.l), stride, subRegion); } }
|
||||||
|
|
||||||
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
|
if (window->style == ES_WINDOW_CONTAINER && !isEmbed) {
|
||||||
SET_BITS_REGION(0, window->width, 0, insets.t);
|
SET_BITS_REGION(0, window->width, 0, insets.t);
|
||||||
SET_BITS_REGION(0, insets.l, insets.t, window->height - insets.b);
|
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(window->width - insets.r, window->width, insets.t, window->height - insets.b);
|
||||||
SET_BITS_REGION(0, window->width, window->height - insets.b, window->height);
|
SET_BITS_REGION(0, window->width, window->height - insets.b, window->height);
|
||||||
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
|
} else if (window->style == ES_WINDOW_CONTAINER && isEmbed) {
|
||||||
SET_BITS_REGION(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
|
SET_BITS_REGION(insets.l, window->width - insets.r, insets.t, window->height - insets.b);
|
||||||
} else {
|
} else {
|
||||||
SET_BITS_REGION(0, window->width, 0, window->height);
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
SYSCALL_RETURN(ES_SUCCESS, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
struct EmbeddedWindow {
|
struct EmbeddedWindow {
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
@ -35,7 +34,7 @@ struct Window {
|
||||||
// State:
|
// State:
|
||||||
EsWindowStyle style;
|
EsWindowStyle style;
|
||||||
EsRectangle solidOffsets, embedInsets;
|
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;
|
volatile bool closed;
|
||||||
|
|
||||||
// Appearance:
|
// 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;
|
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 EsRectangleSplit(EsRectangle *a, int32_t amount, char side, int32_t gap) {
|
||||||
EsRectangle b = *a;
|
EsRectangle b = *a;
|
||||||
if (side == 'l') a->l += amount + gap, b.r = a->l - gap;
|
if (side == 'l') a->l += amount + gap, b.r = a->l - gap;
|
||||||
|
|
|
@ -491,3 +491,4 @@ _EsOpenDocumentEnumerate=489
|
||||||
EsDialogGetContentArea=490
|
EsDialogGetContentArea=490
|
||||||
_EsDebugCommand=491
|
_EsDebugCommand=491
|
||||||
DateToLinear=492
|
DateToLinear=492
|
||||||
|
EsRectangleContainsAll=493
|
||||||
|
|
Loading…
Reference in New Issue