[regression]: Fix the issue where using -/= to turn pages causes the program to crash and prevents page turning.
This commit is contained in:
1 parent
476a5c7181
commit
bcaf34e1fb
6 files changed
+182
-89
No files matched your search
@@ -452,12 +452,31 @@ BOOL CCompositionProcessorEngine::IsPunctuation(WCHAR wch)
|
||||
|
||||
namespace
|
||||
{
|
||||
bool IsCommitWithFirstCandidatePunctuationInCandidateMode(WCHAR wch, CANDIDATE_MODE candidateMode)
|
||||
bool IsCommitWithFirstCandidatePunctuationInCandidateMode(UINT uCode, WCHAR wch, CANDIDATE_MODE candidateMode)
|
||||
{
|
||||
if (candidateMode == CANDIDATE_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Candidate paging keys must keep their navigation semantics even if the
|
||||
// corresponding character is also listed in CommitWithFirstCandPunc.
|
||||
switch (uCode)
|
||||
{
|
||||
case VK_PRIOR:
|
||||
case VK_NEXT:
|
||||
case VK_OEM_MINUS:
|
||||
case VK_OEM_PLUS:
|
||||
case VK_SUBTRACT:
|
||||
case VK_ADD:
|
||||
case VK_HOME:
|
||||
case VK_END:
|
||||
case VK_TAB:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return wch != 0 && Global::CommitWithFirstCandPunc.count(wch) > 0;
|
||||
}
|
||||
|
||||
@@ -1671,18 +1690,18 @@ void CCompositionProcessorEngine::SetDefaultCandidateTextFont()
|
||||
// If engine need this virtual key code, returns true. Otherwise returns false.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
UINT uCode, //
|
||||
BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
UINT uCode, //
|
||||
_In_reads_(1) WCHAR *pwch, //
|
||||
BOOL fComposing, //
|
||||
CANDIDATE_MODE candidateMode, //
|
||||
BOOL hasCandidateWithWildcard, //
|
||||
_Out_opt_ _KEYSTROKE_STATE *pKeyState //
|
||||
)
|
||||
{
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_NONE;
|
||||
)
|
||||
{
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_NONE;
|
||||
pKeyState->Function = FUNCTION_NONE;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1720,7 @@ BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (IsCommitWithFirstCandidatePunctuationInCandidateMode(pwch ? *pwch : 0, candidateMode))
|
||||
if (IsCommitWithFirstCandidatePunctuationInCandidateMode(uCode, pwch ? *pwch : 0, candidateMode))
|
||||
{
|
||||
if (pKeyState)
|
||||
{
|
||||
@@ -1986,13 +2005,13 @@ BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_UP;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_MINUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_UP;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_MINUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_UP;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_NEXT:
|
||||
if (pKeyState)
|
||||
{
|
||||
@@ -2000,13 +2019,13 @@ BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_DOWN;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_PLUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_DOWN;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_PLUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_DOWN;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_TAB:
|
||||
if (pKeyState)
|
||||
{
|
||||
@@ -2086,13 +2105,13 @@ BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_UP;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_MINUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_UP;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_MINUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_UP;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_NEXT:
|
||||
if (pKeyState)
|
||||
{
|
||||
@@ -2100,13 +2119,13 @@ BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_DOWN;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_PLUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_DOWN;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_OEM_PLUS:
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_CANDIDATE;
|
||||
pKeyState->Function = FUNCTION_MOVE_PAGE_DOWN;
|
||||
}
|
||||
return TRUE;
|
||||
case VK_TAB:
|
||||
if (pKeyState)
|
||||
{
|
||||
@@ -2180,15 +2199,15 @@ BOOL CCompositionProcessorEngine::IsVirtualKeyNeed( //
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*pwch && !IsVirtualKeyKeystrokeComposition(uCode, pKeyState, FUNCTION_NONE))
|
||||
{
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_INVOKE_COMPOSITION_EDIT_SESSION;
|
||||
pKeyState->Function = FUNCTION_FINALIZE_TEXTSTORE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
if (*pwch && !IsVirtualKeyKeystrokeComposition(uCode, pKeyState, FUNCTION_NONE))
|
||||
{
|
||||
if (pKeyState)
|
||||
{
|
||||
pKeyState->Category = CATEGORY_INVOKE_COMPOSITION_EDIT_SESSION;
|
||||
pKeyState->Function = FUNCTION_FINALIZE_TEXTSTORE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef FANY_DEBUG
|
||||
OutputDebugString(L"[msime]: Unknown keystroke.");
|
||||
|
||||
+24
-15
@@ -13,10 +13,10 @@
|
||||
#include "Ipc.h"
|
||||
#include "FanyDefines.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
std::wstring g_toggleImeFallbackBuffer;
|
||||
}
|
||||
namespace
|
||||
{
|
||||
std::wstring g_toggleImeFallbackBuffer;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -592,12 +592,21 @@ Exit:
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
HRESULT CMetasequoiaIME::_HandleCompositionArrowKey(TfEditCookie ec, _In_ ITfContext *pContext,
|
||||
KEYSTROKE_FUNCTION keyFunction)
|
||||
{
|
||||
ITfRange *pRangeComposition = nullptr;
|
||||
TF_SELECTION tfSelection;
|
||||
ULONG fetched = 0;
|
||||
HRESULT CMetasequoiaIME::_HandleCompositionArrowKey(TfEditCookie ec, _In_ ITfContext *pContext,
|
||||
KEYSTROKE_FUNCTION keyFunction)
|
||||
{
|
||||
if ((keyFunction == FUNCTION_MOVE_PAGE_UP) || (keyFunction == FUNCTION_MOVE_PAGE_DOWN) ||
|
||||
(keyFunction == FUNCTION_MOVE_PAGE_TOP) || (keyFunction == FUNCTION_MOVE_PAGE_BOTTOM))
|
||||
{
|
||||
if ((_pCandidateListUIPresenter == nullptr) || (_pCandidateListUIPresenter->_GetCount() <= 1))
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
ITfRange *pRangeComposition = nullptr;
|
||||
TF_SELECTION tfSelection;
|
||||
ULONG fetched = 0;
|
||||
|
||||
// get the selection
|
||||
if (FAILED(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
|
||||
@@ -606,11 +615,11 @@ HRESULT CMetasequoiaIME::_HandleCompositionArrowKey(TfEditCookie ec, _In_ ITfCon
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// get the composition range
|
||||
if (FAILED(_pComposition->GetRange(&pRangeComposition)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
// get the composition range
|
||||
if ((_pComposition == nullptr) || FAILED(_pComposition->GetRange(&pRangeComposition)))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// For incremental candidate list
|
||||
if (_pCandidateListUIPresenter)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "Private.h"
|
||||
#include "KeyHandlerEditSession.h"
|
||||
#include "EditSession.h"
|
||||
#include "MetasequoiaIME.h"
|
||||
#include "CompositionProcessorEngine.h"
|
||||
#include "KeyStateCategory.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#include "MetasequoiaIME.h"
|
||||
#include "CompositionProcessorEngine.h"
|
||||
#include "KeyStateCategory.h"
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ITfEditSession
|
||||
// CEditSessionBase
|
||||
@@ -19,21 +18,21 @@
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
STDAPI CKeyHandlerEditSession::DoEditSession(TfEditCookie ec)
|
||||
{
|
||||
HRESULT hResult = S_OK;
|
||||
|
||||
CKeyStateCategoryFactory *pKeyStateCategoryFactory = CKeyStateCategoryFactory::Instance();
|
||||
STDAPI CKeyHandlerEditSession::DoEditSession(TfEditCookie ec)
|
||||
{
|
||||
HRESULT hResult = S_OK;
|
||||
|
||||
CKeyStateCategoryFactory *pKeyStateCategoryFactory = CKeyStateCategoryFactory::Instance();
|
||||
CKeyStateCategory *pKeyStateCategory =
|
||||
pKeyStateCategoryFactory->MakeKeyStateCategory(_KeyState.Category, _pTextService);
|
||||
|
||||
if (pKeyStateCategory)
|
||||
{
|
||||
KeyHandlerEditSessionDTO keyHandlerEditSessioDTO(ec, _pContext, _uCode, _wch, _KeyState.Function);
|
||||
hResult = pKeyStateCategory->KeyStateHandler(_KeyState.Function, keyHandlerEditSessioDTO);
|
||||
|
||||
pKeyStateCategory->Release();
|
||||
pKeyStateCategoryFactory->Release();
|
||||
if (pKeyStateCategory)
|
||||
{
|
||||
KeyHandlerEditSessionDTO keyHandlerEditSessioDTO(ec, _pContext, _uCode, _wch, _KeyState.Function);
|
||||
hResult = pKeyStateCategory->KeyStateHandler(_KeyState.Function, keyHandlerEditSessioDTO);
|
||||
|
||||
pKeyStateCategory->Release();
|
||||
pKeyStateCategoryFactory->Release();
|
||||
}
|
||||
|
||||
return hResult;
|
||||
|
||||
@@ -236,6 +236,20 @@ HRESULT CMetasequoiaIME::_HandleCandidateArrowKey( //
|
||||
ec;
|
||||
pContext;
|
||||
|
||||
if (_pCandidateListUIPresenter == nullptr)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if ((keyFunction == FUNCTION_MOVE_PAGE_UP) || (keyFunction == FUNCTION_MOVE_PAGE_DOWN) ||
|
||||
(keyFunction == FUNCTION_MOVE_PAGE_TOP) || (keyFunction == FUNCTION_MOVE_PAGE_BOTTOM))
|
||||
{
|
||||
if (_pCandidateListUIPresenter->_GetCount() <= 1)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
_pCandidateListUIPresenter->AdviseUIChangedByArrowKey(keyFunction);
|
||||
|
||||
return S_OK;
|
||||
@@ -770,8 +784,19 @@ void CCandidateListUIPresenter::SetPageIndexWithScrollInfo( //
|
||||
_In_ CMetasequoiaImeArray<CCandidateListItem> *pCandidateList //
|
||||
)
|
||||
{
|
||||
UINT candCntInPage = _pIndexRange->Count();
|
||||
UINT bufferSize = pCandidateList->Count() / candCntInPage + 1;
|
||||
if ((pCandidateList == nullptr) || (_pIndexRange == nullptr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT candCntInPage = _pIndexRange->Count();
|
||||
if (candCntInPage == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT candidateCount = pCandidateList->Count();
|
||||
const UINT bufferSize = (candidateCount == 0) ? 0 : ((candidateCount - 1) / candCntInPage + 1);
|
||||
UINT *puPageIndex = new (std::nothrow) UINT[bufferSize];
|
||||
if (puPageIndex != nullptr)
|
||||
{
|
||||
@@ -783,7 +808,12 @@ void CCandidateListUIPresenter::SetPageIndexWithScrollInfo( //
|
||||
_candidateState.SetPageIndex(puPageIndex, bufferSize);
|
||||
delete[] puPageIndex;
|
||||
}
|
||||
_candidateState.SetScrollInfo(pCandidateList->Count(),
|
||||
else if (bufferSize == 0)
|
||||
{
|
||||
_candidateState.SetPageIndex(nullptr, 0);
|
||||
}
|
||||
|
||||
_candidateState.SetScrollInfo(candidateCount,
|
||||
candCntInPage); // nMax:range of max, nPage:number of items in page
|
||||
}
|
||||
//+---------------------------------------------------------------------------
|
||||
|
||||
@@ -75,6 +75,10 @@ class CCandidateListUIPresenter : public CTfTextLayoutSink,
|
||||
void _NotifyUI();
|
||||
void _SetText(_In_ CMetasequoiaImeArray<CCandidateListItem> *pCandidateList, BOOL isAddFindKeyCode);
|
||||
void _ClearList();
|
||||
UINT _GetCount() const
|
||||
{
|
||||
return _candidateState.GetCount();
|
||||
}
|
||||
|
||||
DWORD_PTR _GetSelectedCandidateString(_Outptr_result_maybenull_ const WCHAR **ppwchCandidateString);
|
||||
BOOL _SetSelectionInPage(int nPos)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "Private.h"
|
||||
#include "CandidateSessionState.h"
|
||||
#include <corecrt_wstring.h>
|
||||
#include <debugapi.h>
|
||||
#include "fmt/xchar.h"
|
||||
|
||||
CCandidateSessionState::CCandidateSessionState(_In_ CCandidateRange *pIndexRange)
|
||||
{
|
||||
@@ -132,13 +134,13 @@ DWORD CCandidateSessionState::GetSelectedCandidateString(
|
||||
|
||||
BOOL CCandidateSessionState::SetSelectionInPage(_In_ int nPos)
|
||||
{
|
||||
if (nPos < 0)
|
||||
if ((nPos < 0) || (_candidateList.Count() == 0) || (_pageIndex.Count() == 0) || (_pIndexRange == nullptr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT pos = static_cast<UINT>(nPos);
|
||||
if (pos >= _candidateList.Count())
|
||||
const UINT pageSize = _pIndexRange->Count();
|
||||
if (pageSize == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -149,12 +151,24 @@ BOOL CCandidateSessionState::SetSelectionInPage(_In_ int nPos)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_currentSelection = *_pageIndex.GetAt(currentPage) + nPos;
|
||||
const UINT pageStart = *_pageIndex.GetAt(currentPage);
|
||||
const UINT selection = pageStart + static_cast<UINT>(nPos);
|
||||
if ((selection >= _candidateList.Count()) || (selection >= pageStart + pageSize))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_currentSelection = selection;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CCandidateSessionState::MoveSelection(_In_ int offSet)
|
||||
{
|
||||
if (_candidateList.Count() == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_currentSelection + offSet >= _candidateList.Count())
|
||||
{
|
||||
return FALSE;
|
||||
@@ -199,6 +213,17 @@ BOOL CCandidateSessionState::MovePage(_In_ int offSet)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((_candidateList.Count() == 0) || (_pageIndex.Count() == 0) || (_pIndexRange == nullptr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const UINT pageSize = _pIndexRange->Count();
|
||||
if (pageSize == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int currentPage = 0;
|
||||
if (FAILED(GetCurrentPage(¤tPage)))
|
||||
{
|
||||
@@ -211,14 +236,21 @@ BOOL CCandidateSessionState::MovePage(_In_ int offSet)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_currentSelection % _pIndexRange->Count() == 0 && _currentSelection == *_pageIndex.GetAt(currentPage))
|
||||
if ((_currentSelection % pageSize) == 0 && _currentSelection == *_pageIndex.GetAt(currentPage))
|
||||
{
|
||||
_dontAdjustOnEmptyItemPage = TRUE;
|
||||
}
|
||||
|
||||
int selectionOffset = _currentSelection - *_pageIndex.GetAt(currentPage);
|
||||
_currentSelection = *_pageIndex.GetAt(newPage) + selectionOffset;
|
||||
_currentSelection = _candidateList.Count() > _currentSelection ? _currentSelection : _candidateList.Count() - 1;
|
||||
const UINT currentPageStart = *_pageIndex.GetAt(currentPage);
|
||||
const UINT newPageStart = *_pageIndex.GetAt(newPage);
|
||||
if (newPageStart >= _candidateList.Count())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const UINT selectionOffset = _currentSelection - currentPageStart;
|
||||
const UINT maxSelectionInPage = min(pageSize - 1, _candidateList.Count() - 1 - newPageStart);
|
||||
_currentSelection = newPageStart + min(selectionOffset, maxSelectionInPage);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user