From ff895e96b249171644aa3fc352128fedd944248a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 13 Aug 2022 01:24:35 +0300 Subject: SL-17719 Windows support for absolute mouse positioning For virtual machines and touch screens Also raw input is not subjected to mouse speed --- indra/llwindow/llwindowwin32.cpp | 41 ++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'indra/llwindow/llwindowwin32.cpp') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 4c3aeb4695..f2dd46fee7 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3058,18 +3058,43 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LLMutexLock lock(&window_imp->mRawMouseMutex); - S32 speed; - const S32 DEFAULT_SPEED(10); - SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); - if (speed == DEFAULT_SPEED) + bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE); + + if (absolute_coordinates) { - window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; - window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP; + + S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); + S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); + + S32 absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width; + S32 absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height; + + static S32 prev_absolute_x = 0; + static S32 prev_absolute_y = 0; + S32 delta_x = absolute_x - prev_absolute_x; + S32 delta_y = absolute_y - prev_absolute_y; + prev_absolute_x = absolute_x; + prev_absolute_y = absolute_y; + + window_imp->mRawMouseDelta.mX += delta_x; + window_imp->mRawMouseDelta.mY -= delta_y; } else { - window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); - window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + S32 speed; + const S32 DEFAULT_SPEED(10); + SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); + if (speed == DEFAULT_SPEED) + { + window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; + window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + } + else + { + window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); + window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + } } } } -- cgit v1.2.3 From aa5c4d45aa36df1c4dad7b68b4e1b760420409ad Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 15 Aug 2022 20:10:17 +0300 Subject: SL-17719 Windows support for absolute mouse positioning #2 Better touch screen handling --- indra/llwindow/llwindowwin32.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'indra/llwindow/llwindowwin32.cpp') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index f2dd46fee7..6d5b42f2f1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3062,23 +3062,34 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ if (absolute_coordinates) { - bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP; + static S32 prev_absolute_x = 0; + static S32 prev_absolute_y = 0; + S32 absolute_x; + S32 absolute_y; + + if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header + { + // touch screen spams (0,0) coordinates in a number of situations + // (0,0) might need to be filtered + absolute_x = raw->data.mouse.lLastX; + absolute_y = raw->data.mouse.lLastY; + } + else + { + bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP; - S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); - S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); + S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); + S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); - S32 absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width; - S32 absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height; + absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width; + absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height; + } + + window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x; + window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y; - static S32 prev_absolute_x = 0; - static S32 prev_absolute_y = 0; - S32 delta_x = absolute_x - prev_absolute_x; - S32 delta_y = absolute_y - prev_absolute_y; prev_absolute_x = absolute_x; prev_absolute_y = absolute_y; - - window_imp->mRawMouseDelta.mX += delta_x; - window_imp->mRawMouseDelta.mY -= delta_y; } else { -- cgit v1.2.3 From a53ccb237919d4361d1625cc0b0aac338267509f Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 2 Nov 2022 19:38:01 +0200 Subject: SL-18136 fix for Japanese IME --- indra/llwindow/llwindowwin32.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llwindow/llwindowwin32.cpp') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 984afe623c..41f3042ace 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4251,7 +4251,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) if (needs_update) { - mPreeditor->resetPreedit(); + if (preedit_string.length() != 0 || result_string.length() != 0) + { + mPreeditor->resetPreedit(); + } if (result_string.length() > 0) { -- cgit v1.2.3 From d01f7afff206dd610b6c209e6bd69d646b47863f Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <118780484+maxim-productengine@users.noreply.github.com> Date: Fri, 25 Nov 2022 18:16:31 +0200 Subject: SL-18713 fix crash in handleCompositionMessage (#12) --- indra/llwindow/llwindowwin32.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llwindow/llwindowwin32.cpp') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index c487877caf..740224adf9 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4100,6 +4100,10 @@ void LLWindowWin32::handleStartCompositionMessage() void LLWindowWin32::handleCompositionMessage(const U32 indexes) { + if (!mPreeditor) + { + return; + } BOOL needs_update = FALSE; LLWString result_string; LLWString preedit_string; -- cgit v1.2.3 From 89f3bf6c13c07038c1d50ea0babb35045cba7f77 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 17 Jan 2023 22:06:22 +0200 Subject: SL-18985 Crash at std::basic_string::erase --- indra/llwindow/llwindowwin32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llwindow/llwindowwin32.cpp') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 6039aa6618..11a3c943ee 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4438,7 +4438,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); preedit -= context_offset; preedit_length = llmin(preedit_length, (S32)context.length() - preedit); - if (preedit_length && preedit >= 0) + if (preedit_length > 0 && preedit >= 0) { // IMR_DOCUMENTFEED may be called when we have an active preedit. // We should pass the context string *excluding* the preedit string. -- cgit v1.2.3 From 472ecc8088233168b25f60a100403d9c4ab832b1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Jan 2023 01:44:16 +0200 Subject: SL-18999 IME disabling should be called in window's thread For some reason positioning IME window works fine, but disabling and enabling ime works from window's thread only --- indra/llwindow/llwindowwin32.cpp | 76 ++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'indra/llwindow/llwindowwin32.cpp') diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 11a3c943ee..6f67b131d1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3904,42 +3904,48 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) sLanguageTextInputAllowed = b; - if ( sLanguageTextInputAllowed ) - { - // Allowing: Restore the previous IME status, so that the user has a feeling that the previous - // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps - // using same Input Locale (aka Keyboard Layout). - if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) - { - HIMC himc = LLWinImm::getContext(mWindowHandle); - LLWinImm::setOpenStatus(himc, TRUE); - LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode); - LLWinImm::releaseContext(mWindowHandle, himc); - } - } - else - { - // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly. - // However, do it after saving the current IME status. We need to restore the status when - // allowing language text input again. - sWinInputLocale = GetKeyboardLayout(0); - sWinIMEOpened = LLWinImm::isIME(sWinInputLocale); - if (sWinIMEOpened) - { - HIMC himc = LLWinImm::getContext(mWindowHandle); - sWinIMEOpened = LLWinImm::getOpenStatus(himc); - if (sWinIMEOpened) - { - LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); + if (sLanguageTextInputAllowed) + { + mWindowThread->post([=]() + { + // Allowing: Restore the previous IME status, so that the user has a feeling that the previous + // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps + // using same Input Locale (aka Keyboard Layout). + if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) + { + HIMC himc = LLWinImm::getContext(mWindowHandle); + LLWinImm::setOpenStatus(himc, TRUE); + LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode); + LLWinImm::releaseContext(mWindowHandle, himc); + } + }); + } + else + { + mWindowThread->post([=]() + { + // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly. + // However, do it after saving the current IME status. We need to restore the status when + // allowing language text input again. + sWinInputLocale = GetKeyboardLayout(0); + sWinIMEOpened = LLWinImm::isIME(sWinInputLocale); + if (sWinIMEOpened) + { + HIMC himc = LLWinImm::getContext(mWindowHandle); + sWinIMEOpened = LLWinImm::getOpenStatus(himc); + if (sWinIMEOpened) + { + LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); - // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's - // keyboard hooking, because Some IME reacts only on the former and some other on the latter... - LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); - LLWinImm::setOpenStatus(himc, FALSE); - } - LLWinImm::releaseContext(mWindowHandle, himc); - } - } + // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's + // keyboard hooking, because Some IME reacts only on the former and some other on the latter... + LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); + LLWinImm::setOpenStatus(himc, FALSE); + } + LLWinImm::releaseContext(mWindowHandle, himc); + } + }); + } } void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, -- cgit v1.2.3