Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support EditSession in filterKeyDown/filterKeyUp #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 48 additions & 37 deletions TextService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ void TextService::onDeactivate() {
}

// virtual
bool TextService::filterKeyDown(KeyEvent& keyEvent) {
bool TextService::filterKeyDown(KeyEvent& keyEvent, EditSession* session) {
return false;
}

Expand All @@ -498,7 +498,7 @@ bool TextService::onKeyDown(KeyEvent& keyEvent, EditSession* session) {
}

// virtual
bool TextService::filterKeyUp(KeyEvent& keyEvent) {
bool TextService::filterKeyUp(KeyEvent& keyEvent, EditSession *session) {
return false;
}

Expand Down Expand Up @@ -861,34 +861,33 @@ STDMETHODIMP TextService::OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPA
*pfEaten = FALSE;
else {
KeyEvent keyEvent(WM_KEYDOWN, wParam, lParam);
*pfEaten = (BOOL)filterKeyDown(keyEvent);
HRESULT sessionResult;
KeyEditSession* session = new KeyEditSession(this, pContext, keyEvent, true);
pContext->RequestEditSession(clientId_, session, TF_ES_SYNC | TF_ES_READWRITE, &sessionResult);
*pfEaten = session->result_; // tell TSF if we handled the key
session->Release();
}
return S_OK;
}

STDMETHODIMP TextService::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) {
// Some applications do not trigger OnTestKeyDown()
// So we need to test it again here! Windows TSF sucks!
if(isKeyboardDisabled(pContext) || !isKeyboardOpened())
*pfEaten = FALSE;
else {
KeyEvent keyEvent(WM_KEYDOWN, wParam, lParam);
*pfEaten = (BOOL)filterKeyDown(keyEvent);
if(*pfEaten) { // we want to eat the key
HRESULT sessionResult;
// ask TSF for an edit session. If editing is approved by TSF,
// KeyEditSession::DoEditSession will be called, which in turns
// call back to TextService::doKeyEditSession().
// So the real key handling is relayed to TextService::doKeyEditSession().
KeyEditSession* session = new KeyEditSession(this, pContext, keyEvent);

// We use TF_ES_SYNC here, so the request becomes synchronus and blocking.
// KeyEditSession::DoEditSession() and TextService::doKeyEditSession() will be
// called before RequestEditSession() returns.
pContext->RequestEditSession(clientId_, session, TF_ES_SYNC|TF_ES_READWRITE, &sessionResult);
*pfEaten = session->result_; // tell TSF if we handled the key
session->Release();
}
HRESULT sessionResult;
// ask TSF for an edit session. If editing is approved by TSF,
// KeyEditSession::DoEditSession will be called, which in turns
// call back to TextService::doKeyEditSession().
// So the real key handling is relayed to TextService::doKeyEditSession().
KeyEditSession* session = new KeyEditSession(this, pContext, keyEvent, false);

// We use TF_ES_SYNC here, so the request becomes synchronus and blocking.
// KeyEditSession::DoEditSession() and TextService::doKeyEditSession() will be
// called before RequestEditSession() returns.
pContext->RequestEditSession(clientId_, session, TF_ES_SYNC|TF_ES_READWRITE, &sessionResult);
*pfEaten = session->result_; // tell TSF if we handled the key
session->Release();
}
return S_OK;
}
Expand All @@ -897,8 +896,12 @@ STDMETHODIMP TextService::OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARA
if(isKeyboardDisabled(pContext) || !isKeyboardOpened())
*pfEaten = FALSE;
else {
KeyEvent keyEvent(WM_KEYDOWN, wParam, lParam);
*pfEaten = (BOOL)filterKeyUp(keyEvent);
KeyEvent keyEvent(WM_KEYUP, wParam, lParam);
HRESULT sessionResult;
KeyEditSession* session = new KeyEditSession(this, pContext, keyEvent, true);
pContext->RequestEditSession(clientId_, session, TF_ES_SYNC | TF_ES_READWRITE, &sessionResult);
*pfEaten = session->result_; // tell TSF if we handled the key
session->Release();
}
return S_OK;
}
Expand All @@ -910,14 +913,11 @@ STDMETHODIMP TextService::OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lP
*pfEaten = FALSE;
else {
KeyEvent keyEvent(WM_KEYUP, wParam, lParam);
*pfEaten = (BOOL)filterKeyUp(keyEvent);
if(*pfEaten) {
HRESULT sessionResult;
KeyEditSession* session = new KeyEditSession(this, pContext, keyEvent);
pContext->RequestEditSession(clientId_, session, TF_ES_SYNC|TF_ES_READWRITE, &sessionResult);
*pfEaten = session->result_; // tell TSF if we handled the key
session->Release();
}
HRESULT sessionResult;
KeyEditSession* session = new KeyEditSession(this, pContext, keyEvent, false);
pContext->RequestEditSession(clientId_, session, TF_ES_SYNC|TF_ES_READWRITE, &sessionResult);
*pfEaten = session->result_; // tell TSF if we handled the key
session->Release();
}
return S_OK;
}
Expand Down Expand Up @@ -1005,7 +1005,7 @@ STDMETHODIMP TextService::OnActivated(REFCLSID clsid, REFGUID guidProfile, BOOL
// edit session handling
STDMETHODIMP TextService::KeyEditSession::DoEditSession(TfEditCookie ec) {
EditSession::DoEditSession(ec);
return textService_->doKeyEditSession(ec, this);
return textService_->doKeyEditSession(ec, this, testOnly_);
}

// edit session handling
Expand All @@ -1021,11 +1021,22 @@ STDMETHODIMP TextService::EndCompositionEditSession::DoEditSession(TfEditCookie
}

// callback from edit session of key events
HRESULT TextService::doKeyEditSession(TfEditCookie cookie, KeyEditSession* session) {
if(session->keyEvent_.type() == WM_KEYDOWN)
session->result_ = onKeyDown(session->keyEvent_, session);
else if(session->keyEvent_.type() == WM_KEYUP)
session->result_ = onKeyUp(session->keyEvent_, session);
HRESULT TextService::doKeyEditSession(TfEditCookie cookie, KeyEditSession* session, bool testOnly) {
// Some applications do not trigger OnTestKeyDown()
// So we need to test it again here! Windows TSF sucks!

UINT type = session->keyEvent_.type();
if (type == WM_KEYDOWN)
session->result_ = filterKeyDown(session->keyEvent_, session);
else if (type == WM_KEYUP)
session->result_ = filterKeyUp(session->keyEvent_, session);

if (session->result_ && !testOnly) {
if (type == WM_KEYDOWN)
session->result_ = onKeyDown(session->keyEvent_, session);
else if (type == WM_KEYUP)
session->result_ = onKeyUp(session->keyEvent_, session);
}
return S_OK;
}

Expand Down
10 changes: 6 additions & 4 deletions TextService.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ class TextService:
virtual void onSetFocus();
virtual void onKillFocus();

virtual bool filterKeyDown(KeyEvent& keyEvent);
virtual bool filterKeyDown(KeyEvent& keyEvent, EditSession* session);
virtual bool onKeyDown(KeyEvent& keyEvent, EditSession* session);

virtual bool filterKeyUp(KeyEvent& keyEvent);
virtual bool filterKeyUp(KeyEvent& keyEvent, EditSession* session);
virtual bool onKeyUp(KeyEvent& keyEvent, EditSession* session);

virtual bool onPreservedKey(const GUID& guid);
Expand Down Expand Up @@ -240,14 +240,16 @@ class TextService:
// edit session classes, used with TSF
class KeyEditSession: public EditSession {
public:
KeyEditSession(TextService* service, ITfContext* context, KeyEvent& keyEvent):
KeyEditSession(TextService* service, ITfContext* context, KeyEvent& keyEvent, bool testOnly):
EditSession(service, context),
keyEvent_(keyEvent),
testOnly_(testOnly),
result_(false) {
}
STDMETHODIMP DoEditSession(TfEditCookie ec);

KeyEvent keyEvent_;
bool testOnly_;
bool result_;
};

Expand All @@ -267,7 +269,7 @@ class TextService:
STDMETHODIMP DoEditSession(TfEditCookie ec);
};

HRESULT doKeyEditSession(TfEditCookie cookie, KeyEditSession* session);
HRESULT doKeyEditSession(TfEditCookie cookie, KeyEditSession* session, bool testOnly);
HRESULT doStartCompositionEditSession(TfEditCookie cookie, StartCompositionEditSession* session);
HRESULT doEndCompositionEditSession(TfEditCookie cookie, EndCompositionEditSession* session);

Expand Down