From 25023ae97735dc0ef7a936b4aeb27e88a2a76aff Mon Sep 17 00:00:00 2001 From: ksqsf Date: Tue, 1 Oct 2024 20:44:11 +0200 Subject: [PATCH] Fix display leftover --- include/webview_candidate_window.hpp | 3 +++ page/global.d.ts | 4 ++-- page/ux.ts | 9 ++++++--- src/webview_candidate_window.cpp | 19 +++++++++++++------ tests/global.d.ts | 2 +- tests/util.ts | 4 ++-- 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/include/webview_candidate_window.hpp b/include/webview_candidate_window.hpp index 8b4f3b9..5bace57 100644 --- a/include/webview_candidate_window.hpp +++ b/include/webview_candidate_window.hpp @@ -8,6 +8,7 @@ #else #include "webview.h" #endif +#include #include #include #include @@ -67,6 +68,8 @@ class WebviewCandidateWindow : public CandidateWindow { int accent_color_ = 0; layout_t layout_ = layout_t::horizontal; writing_mode_t writing_mode_ = writing_mode_t::horizontal_tb; + uint32_t epoch = 0; // A timestamp for async results from + // webview private: /* Platform-specific interfaces (implemented in 'platform') */ diff --git a/page/global.d.ts b/page/global.d.ts index fa6e60f..ed12b8b 100644 --- a/page/global.d.ts +++ b/page/global.d.ts @@ -34,13 +34,13 @@ declare global { _scroll: (start: number, length: number) => void _askActions: (index: number) => void _action: (index: number, id: number) => void - _resize: (dx: number, dy: number, anchorTop: number, anchorRight: number, anchorBottom: number, anchorLeft: number, panelTop: number, panelRight: number, panelBottom: number, panelLeft: number, panelRadius: number, borderWidth: number, fullWidth: number, fullHeight: number, dragging: boolean) => void + _resize: (epoch: number, dx: number, dy: number, anchorTop: number, anchorRight: number, anchorBottom: number, anchorLeft: number, panelTop: number, panelRight: number, panelBottom: number, panelLeft: number, panelRadius: number, borderWidth: number, fullWidth: number, fullHeight: number, dragging: boolean) => void // JavaScript APIs that webview_candidate_window.mm calls setCandidates: (cands: Candidate[], highlighted: number, markText: string, pageable: boolean, hasPrev: boolean, hasNext: boolean, scrollState: SCROLL_STATE, scrollStart: boolean, scrollEnd: boolean) => void setLayout: (layout: 0 | 1) => void updateInputPanel: (preeditHTML: string, auxUpHTML: string, auxDownHTML: string) => void - resize: (dx: number, dy: number, dragging: boolean, hasContextmenu: boolean) => void + resize: (new_epoch: number, dx: number, dy: number, dragging: boolean, hasContextmenu: boolean) => void setTheme: (theme: 0 | 1 | 2) => void setAccentColor: (color: number | null) => void setStyle: (style: string) => void diff --git a/page/ux.ts b/page/ux.ts index 559bc60..e3b3bac 100644 --- a/page/ux.ts +++ b/page/ux.ts @@ -12,6 +12,7 @@ import { const DRAG_THRESHOLD = 10 +let epoch = 0 let pressed = false let dragging = false let startX = 0 @@ -37,11 +38,13 @@ interface ShadowBox { } export function resize( + new_epoch: number, dx: number, dy: number, dragging: boolean, hasContextmenu: boolean, ) { + epoch = new_epoch function adaptWindowSize(reserveSpaceForContextmenu: boolean) { let { anchorTop, @@ -85,7 +88,7 @@ export function resize( const { borderRadius, borderWidth } = getComputedStyle(panel) const bWidth = Math.max(...borderWidth.split(' ').map(Number.parseFloat)) const pRadius = Math.max(...borderRadius.split(' ').map(Number.parseFloat)) - window.fcitx._resize(dx, dy, anchorTop, anchorRight, anchorBottom, anchorLeft, pRect.top, pRect.right, pRect.bottom, pRect.left, pRadius, bWidth, right, bottom, dragging) + window.fcitx._resize(epoch, dx, dy, anchorTop, anchorRight, anchorBottom, anchorLeft, pRect.top, pRect.right, pRect.bottom, pRect.left, pRadius, bWidth, right, bottom, dragging) } adaptWindowSize(hasContextmenu) if (!dragging) { @@ -165,7 +168,7 @@ export function showContextmenu(x: number, y: number, index: number, actions: Ca contextmenu.style.top = `${y}px` contextmenu.style.left = `${x}px` contextmenu.style.display = 'block' - resize(0, 0, false, true) + resize(epoch, 0, 0, false, true) } export function hideContextmenu() { @@ -207,7 +210,7 @@ receiver.addEventListener('mousemove', (e) => { dX += dx dY += dy dragOffset = Math.max(dragOffset, dX * dX + dY * dY) - resize(dx, dy, true, false) + resize(epoch, dx, dy, true, false) }) receiver.addEventListener('mouseup', (e) => { diff --git a/src/webview_candidate_window.cpp b/src/webview_candidate_window.cpp index 714da12..f762738 100644 --- a/src/webview_candidate_window.cpp +++ b/src/webview_candidate_window.cpp @@ -44,11 +44,17 @@ WebviewCandidateWindow::WebviewCandidateWindow() update_accent_color(); bind("_resize", - [this](double dx, double dy, double anchor_top, double anchor_right, - double anchor_bottom, double anchor_left, double panel_top, - double panel_right, double panel_bottom, double panel_left, - double panel_radius, double border_width, double width, - double height, bool dragging) { + [this](uint32_t result_epoch, double dx, double dy, double anchor_top, + double anchor_right, double anchor_bottom, double anchor_left, + double panel_top, double panel_right, double panel_bottom, + double panel_left, double panel_radius, double border_width, + double width, double height, bool dragging) { + // Drop results from previous epochs. This can happen + // because JS code runs in another thread and can be slow + // sometimes. + // NOTE: accept result_epoch=0 because of wrapping. + if (result_epoch != 0 && result_epoch < epoch) + return; resize(dx, dy, anchor_top, anchor_right, anchor_bottom, anchor_left, panel_top, panel_right, panel_bottom, panel_left, panel_radius, border_width, width, height, @@ -144,7 +150,8 @@ void WebviewCandidateWindow::show(double x, double y) { // warmed-up yet, and it won't be updated until user changes color. set_accent_color(); } - invoke_js("resize", 0., 0., false); + epoch += 1; + invoke_js("resize", epoch, 0., 0., false); } static void build_html_open_tags(std::stringstream &ss, int flags) { diff --git a/tests/global.d.ts b/tests/global.d.ts index 4b52455..8dfa26a 100644 --- a/tests/global.d.ts +++ b/tests/global.d.ts @@ -1,6 +1,6 @@ declare global { type CppCall = { - resize: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, boolean] + resize: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, boolean] } | { select: number } | { diff --git a/tests/util.ts b/tests/util.ts index d4c6db1..e3c7f1a 100644 --- a/tests/util.ts +++ b/tests/util.ts @@ -10,9 +10,9 @@ export async function init(page: Page) { await page.evaluate(() => { window.fcitx.setTheme(2) window.cppCalls = [] - window.fcitx._resize = (dx: number, dy: number, anchorTop: number, anchorRight: number, anchorBottom: number, anchorLeft: number, panelTop: number, panelRight: number, panelBottom: number, panelLeft: number, panelRadius: number, borderWidth: number, fullWidth: number, fullHeight: number, dragging: boolean) => { + window.fcitx._resize = (epoch: number, dx: number, dy: number, anchorTop: number, anchorRight: number, anchorBottom: number, anchorLeft: number, panelTop: number, panelRight: number, panelBottom: number, panelLeft: number, panelRadius: number, borderWidth: number, fullWidth: number, fullHeight: number, dragging: boolean) => { window.cppCalls.push({ - resize: [dx, dy, anchorTop, anchorRight, anchorBottom, anchorLeft, panelTop, panelRight, panelBottom, panelLeft, panelRadius, borderWidth, fullWidth, fullHeight, dragging], + resize: [epoch, dx, dy, anchorTop, anchorRight, anchorBottom, anchorLeft, panelTop, panelRight, panelBottom, panelLeft, panelRadius, borderWidth, fullWidth, fullHeight, dragging], }) } window.fcitx._select = (index: number) => {