From e0ae8703efc59644fea2ac77a1605e64de1aff4b Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Tue, 23 Jul 2024 14:45:23 -0400 Subject: [PATCH] fix highlight: no mouse move; mouse move out of panel from paging button (#60) --- page/api.ts | 20 ++++++++++++++------ page/customize.ts | 4 ++-- page/ux.ts | 10 ++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/page/api.ts b/page/api.ts index 2d69efa..290d0b3 100644 --- a/page/api.ts +++ b/page/api.ts @@ -12,6 +12,7 @@ import { hideContextmenu, getHoverBehavior, getPagingButtonsStyle, + resetMouseMoveState, resize } from './ux' import { @@ -76,10 +77,16 @@ function setWritingMode (mode: 0 | 1 | 2) { function moveHighlight (from: Element | null, to: Element | null) { from?.classList.remove('fcitx-highlighted') to?.classList.add('fcitx-highlighted') - const fromMark = from?.querySelector('.fcitx-mark') + // In vertical or scroll mode, there are multiple marks, + // but either toMark exists (for candidate) or candidateInner doesn't exist (for paging button). + // In horizontal mode, there is a unique mark. + // Don't get mark from "from" because when mouse moves from paging button to outside, + // we need to move highlight from the last hovered candidate (not paging button) to original. + const mark = hoverables?.querySelector('.fcitx-mark') const toMark = to?.querySelector('.fcitx-mark') - if (fromMark && !toMark) { - to?.querySelector('.fcitx-candidate-inner')?.prepend(fromMark) + const candidateInner = to?.querySelector('.fcitx-candidate-inner') // not paging button + if (mark && !toMark && candidateInner) { + candidateInner.prepend(mark) } } @@ -93,6 +100,7 @@ const arrowBack = common.replace('{}', '0 0 24 24').replace('{}', 'M16.62 2.99a1 const arrowForward = common.replace('{}', '0 0 24 24').replace('{}', 'M7.38 21.01c.49.49 1.28.49 1.77 0l8.31-8.31a.996.996 0 0 0 0-1.41L9.15 2.98c-.49-.49-1.28-.49-1.77 0s-.49 1.28 0 1.77L14.62 12l-7.25 7.25c-.48.48-.48 1.28.01 1.76z') function setCandidates (cands: Candidate[], highlighted: number, markText: string, pageable: boolean, hasPrev: boolean, hasNext: boolean, scrollState: SCROLL_STATE, scrollStart: boolean, scrollEnd: boolean) { + resetMouseMoveState() hideContextmenu() setScrollState(scrollState) // Clear existing candidates when scroll continues. @@ -164,7 +172,7 @@ function setCandidates (cands: Candidate[], highlighted: number, markText: strin if (scrollState === 1) { hoverables.append(divider(true)) - const expand = div('fcitx-expand', 'fcitx-hoverable-inner') + const expand = div('fcitx-expand', 'fcitx-paging-inner', 'fcitx-hoverable-inner') expand.innerHTML = arrowForward const paging = div('fcitx-paging', 'fcitx-scroll', 'fcitx-hoverable') paging.append(expand) @@ -205,9 +213,9 @@ function setCandidates (cands: Candidate[], highlighted: number, markText: strin } for (const hoverable of hoverables.querySelectorAll('.fcitx-hoverable')) { - hoverable.addEventListener('mouseenter', () => { + hoverable.addEventListener('mousemove', () => { const hoverBehavior = getHoverBehavior() - if (hoverBehavior === 'Move') { + if (hoverBehavior === 'Move' && hoverables.classList.contains('fcitx-mousemoved')) { const lastHighlighted = hoverables.querySelector('.fcitx-highlighted') moveHighlight(lastHighlighted, hoverable) } diff --git a/page/customize.ts b/page/customize.ts index 188ea03..40951e2 100644 --- a/page/customize.ts +++ b/page/customize.ts @@ -113,9 +113,9 @@ const HIGHLIGHT_ORIGINAL_MARK = `${PANEL} .fcitx-highlighted-original .fcitx-mar const PANEL_LIGHT = `.fcitx-light${PANEL}` const PANEL_LIGHT_HIGHLIGHT = `${PANEL_LIGHT} .fcitx-hoverable.fcitx-highlighted .fcitx-hoverable-inner` -const PANEL_LIGHT_HIGHLIGHT_HOVER = `${PANEL_LIGHT} .fcitx-hoverable.fcitx-highlighted:hover .fcitx-hoverable-inner` +const PANEL_LIGHT_HIGHLIGHT_HOVER = `${PANEL_LIGHT} .fcitx-mousemoved .fcitx-hoverable.fcitx-highlighted:hover .fcitx-hoverable-inner` const PANEL_LIGHT_HIGHLIGHT_PRESS = `${PANEL_LIGHT} .fcitx-hoverable.fcitx-highlighted:active .fcitx-hoverable-inner` -const PANEL_LIGHT_OTHER_HOVER = `${PANEL_LIGHT} .fcitx-hoverable:not(.fcitx-highlighted):hover .fcitx-hoverable-inner` +const PANEL_LIGHT_OTHER_HOVER = `${PANEL_LIGHT} .fcitx-mousemoved .fcitx-hoverable:not(.fcitx-highlighted):hover .fcitx-hoverable-inner` const PANEL_LIGHT_OTHER_PRESS = `${PANEL_LIGHT} .fcitx-hoverable:not(.fcitx-highlighted):active .fcitx-hoverable-inner` const TEXT_LIGHT_HIGHLIGHT = `${PANEL_LIGHT} .fcitx-candidate.fcitx-highlighted .fcitx-text` const TEXT_LIGHT_PRESS = `${PANEL_LIGHT} .fcitx-candidate:active .fcitx-candidate-inner .fcitx-text` diff --git a/page/ux.ts b/page/ux.ts index 30d947f..7b0ba80 100644 --- a/page/ux.ts +++ b/page/ux.ts @@ -21,6 +21,13 @@ let dX = 0 let dY = 0 let dragOffset = 0 +// 0: reset, 1: initial (when window is shown even if no mouse move there will be a mousemove event), 2+: moved +let mouseMoveState = 0 +export function resetMouseMoveState () { + mouseMoveState = 0 + hoverables.classList.remove('fcitx-mousemoved') +} + type ShadowBox = { anchorTop: number, anchorRight: number, @@ -167,6 +174,9 @@ document.addEventListener('mousedown', e => { }) document.addEventListener('mousemove', e => { + if (++mouseMoveState >= 2) { + hoverables.classList.add('fcitx-mousemoved') + } if (e.button !== 0 || !pressed) { return }