mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1059643 nsIMM32Handler should handle NOTIFY_IME_OF_MOUSE_BUTTON_EVENT r=emk
This commit is contained in:
parent
43e13298d1
commit
2c3997d15c
@ -204,6 +204,8 @@ IMEHandler::NotifyIME(nsWindow* aWindow,
|
||||
case NOTIFY_IME_OF_COMPOSITION_UPDATE:
|
||||
nsIMM32Handler::OnUpdateComposition(aWindow);
|
||||
return NS_OK;
|
||||
case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
|
||||
return nsIMM32Handler::OnMouseButtonEvent(aWindow, aIMENotification);
|
||||
#ifdef NS_ENABLE_TSF
|
||||
case NOTIFY_IME_OF_BLUR:
|
||||
// If a plugin gets focus while TSF has focus, we need to notify TSF of
|
||||
|
@ -142,7 +142,9 @@ nsIMM32Handler::GetKeyboardCodePage()
|
||||
nsIMEUpdatePreference
|
||||
nsIMM32Handler::GetIMEUpdatePreference()
|
||||
{
|
||||
return nsIMEUpdatePreference(nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE);
|
||||
return nsIMEUpdatePreference(
|
||||
nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE |
|
||||
nsIMEUpdatePreference::NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR);
|
||||
}
|
||||
|
||||
// used for checking the lParam of WM_IME_COMPOSITION
|
||||
@ -303,18 +305,6 @@ nsIMM32Handler::ProcessMessage(nsWindow* aWindow, UINT msg,
|
||||
|
||||
aResult.mResult = 0;
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN: {
|
||||
// We don't need to create the instance of the handler here.
|
||||
if (!gIMM32Handler) {
|
||||
return false;
|
||||
}
|
||||
return gIMM32Handler->OnMouseEvent(aWindow, lParam,
|
||||
msg == WM_LBUTTONDOWN ? IMEMOUSE_LDOWN :
|
||||
msg == WM_MBUTTONDOWN ? IMEMOUSE_MDOWN :
|
||||
IMEMOUSE_RDOWN, aResult);
|
||||
}
|
||||
case WM_INPUTLANGCHANGE:
|
||||
return ProcessInputLangChangeMessage(aWindow, wParam, lParam, aResult);
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
@ -2045,37 +2035,60 @@ nsIMM32Handler::ResolveIMECaretPos(nsIWidget* aReferenceWidget,
|
||||
aOutRect.MoveBy(-aNewOriginWidget->WidgetToScreenOffset());
|
||||
}
|
||||
|
||||
bool
|
||||
nsIMM32Handler::OnMouseEvent(nsWindow* aWindow, LPARAM lParam, int aAction,
|
||||
MSGResult& aResult)
|
||||
/* static */ nsresult
|
||||
nsIMM32Handler::OnMouseButtonEvent(nsWindow* aWindow,
|
||||
const IMENotification& aIMENotification)
|
||||
{
|
||||
aResult.mConsumed = false; // always call next wndprc
|
||||
|
||||
if (!sWM_MSIME_MOUSE || !mIsComposing ||
|
||||
!ShouldDrawCompositionStringOurselves()) {
|
||||
return false;
|
||||
// We don't need to create the instance of the handler here.
|
||||
if (!gIMM32Handler) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIntPoint cursor(LOWORD(lParam), HIWORD(lParam));
|
||||
WidgetQueryContentEvent charAtPt(true, NS_QUERY_CHARACTER_AT_POINT, aWindow);
|
||||
aWindow->InitEvent(charAtPt, &cursor);
|
||||
aWindow->DispatchWindowEvent(&charAtPt);
|
||||
if (!charAtPt.mSucceeded ||
|
||||
charAtPt.mReply.mOffset == WidgetQueryContentEvent::NOT_FOUND ||
|
||||
charAtPt.mReply.mOffset < mCompositionStart ||
|
||||
charAtPt.mReply.mOffset >
|
||||
mCompositionStart + mCompositionString.Length()) {
|
||||
return false;
|
||||
if (!sWM_MSIME_MOUSE || !IsComposingOnOurEditor() ||
|
||||
!ShouldDrawCompositionStringOurselves()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We need to handle only mousedown event.
|
||||
if (aIMENotification.mMouseButtonEventData.mEventMessage !=
|
||||
NS_MOUSE_BUTTON_DOWN) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the character under the cursor is not in the composition string,
|
||||
// we don't need to notify IME of it.
|
||||
uint32_t compositionStart = gIMM32Handler->mCompositionStart;
|
||||
uint32_t compositionEnd =
|
||||
compositionStart + gIMM32Handler->mCompositionString.Length();
|
||||
if (aIMENotification.mMouseButtonEventData.mOffset < compositionStart ||
|
||||
aIMENotification.mMouseButtonEventData.mOffset >= compositionEnd) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BYTE button;
|
||||
switch (aIMENotification.mMouseButtonEventData.mButton) {
|
||||
case WidgetMouseEventBase::eLeftButton:
|
||||
button = IMEMOUSE_LDOWN;
|
||||
break;
|
||||
case WidgetMouseEventBase::eMiddleButton:
|
||||
button = IMEMOUSE_MDOWN;
|
||||
break;
|
||||
case WidgetMouseEventBase::eRightButton:
|
||||
button = IMEMOUSE_RDOWN;
|
||||
break;
|
||||
default:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// calcurate positioning and offset
|
||||
// char : JCH1|JCH2|JCH3
|
||||
// offset: 0011 1122 2233
|
||||
// positioning: 2301 2301 2301
|
||||
nsIntRect cursorInTopLevel, cursorRect(cursor, nsIntSize(0, 0));
|
||||
ResolveIMECaretPos(aWindow, cursorRect,
|
||||
aWindow->GetTopLevelWindow(false), cursorInTopLevel);
|
||||
int32_t cursorXInChar = cursorInTopLevel.x - charAtPt.mReply.mRect.x;
|
||||
nsIntPoint cursorPos =
|
||||
aIMENotification.mMouseButtonEventData.mCursorPos.AsIntPoint();
|
||||
nsIntRect charRect =
|
||||
aIMENotification.mMouseButtonEventData.mCharRect.AsIntRect();
|
||||
int32_t cursorXInChar = cursorPos.x - charRect.x;
|
||||
// The event might hit to zero-width character, see bug 694913.
|
||||
// The reason might be:
|
||||
// * There are some zero-width characters are actually.
|
||||
@ -2084,26 +2097,30 @@ nsIMM32Handler::OnMouseEvent(nsWindow* aWindow, LPARAM lParam, int aAction,
|
||||
// We should assume that user clicked on right most of the zero-width
|
||||
// character in such case.
|
||||
int positioning = 1;
|
||||
if (charAtPt.mReply.mRect.width > 0) {
|
||||
positioning = cursorXInChar * 4 / charAtPt.mReply.mRect.width;
|
||||
if (charRect.width > 0) {
|
||||
positioning = cursorXInChar * 4 / charRect.width;
|
||||
positioning = (positioning + 2) % 4;
|
||||
}
|
||||
|
||||
int offset = charAtPt.mReply.mOffset - mCompositionStart;
|
||||
int offset =
|
||||
aIMENotification.mMouseButtonEventData.mOffset - compositionStart;
|
||||
if (positioning < 2) {
|
||||
offset++;
|
||||
}
|
||||
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: OnMouseEvent, x,y=%ld,%ld, offset=%ld, positioning=%ld\n",
|
||||
cursor.x, cursor.y, offset, positioning));
|
||||
("IMM32: OnMouseButtonEvent, x,y=%ld,%ld, offset=%ld, positioning=%ld\n",
|
||||
cursorPos.x, cursorPos.y, offset, positioning));
|
||||
|
||||
// send MS_MSIME_MOUSE message to default IME window.
|
||||
HWND imeWnd = ::ImmGetDefaultIMEWnd(aWindow->GetWindowHandle());
|
||||
nsIMEContext IMEContext(aWindow->GetWindowHandle());
|
||||
return ::SendMessageW(imeWnd, sWM_MSIME_MOUSE,
|
||||
MAKELONG(MAKEWORD(aAction, positioning), offset),
|
||||
(LPARAM) IMEContext.get()) == 1;
|
||||
if (::SendMessageW(imeWnd, sWM_MSIME_MOUSE,
|
||||
MAKELONG(MAKEWORD(button, positioning), offset),
|
||||
(LPARAM) IMEContext.get()) == 1) {
|
||||
return NS_SUCCESS_EVENT_CONSUMED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
@ -110,6 +110,7 @@ protected:
|
||||
|
||||
class nsIMM32Handler
|
||||
{
|
||||
typedef mozilla::widget::IMENotification IMENotification;
|
||||
typedef mozilla::widget::MSGResult MSGResult;
|
||||
public:
|
||||
static void Initialize();
|
||||
@ -145,6 +146,11 @@ public:
|
||||
|
||||
static nsIMEUpdatePreference GetIMEUpdatePreference();
|
||||
|
||||
// Returns NS_SUCCESS_EVENT_CONSUMED if the mouse button event is consumed by
|
||||
// IME. Otherwise, NS_OK.
|
||||
static nsresult OnMouseButtonEvent(nsWindow* aWindow,
|
||||
const IMENotification& aIMENotification);
|
||||
|
||||
protected:
|
||||
static void EnsureHandlerInstance();
|
||||
|
||||
@ -176,8 +182,6 @@ protected:
|
||||
|
||||
// On*() methods return true if the caller of message handler shouldn't do
|
||||
// anything anymore. Otherwise, false.
|
||||
bool OnMouseEvent(nsWindow* aWindow, LPARAM lParam, int aAction,
|
||||
MSGResult& aResult);
|
||||
static bool OnKeyDownEvent(nsWindow* aWindow, WPARAM wParam, LPARAM lParam,
|
||||
MSGResult& aResult);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user