summaryrefslogtreecommitdiff
path: root/indra/llwindow
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llwindow')
-rw-r--r--indra/llwindow/CMakeLists.txt49
-rw-r--r--indra/llwindow/lldxhardware.cpp2
-rw-r--r--indra/llwindow/llopenglview-objc.mm7
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h2
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm137
-rw-r--r--indra/llwindow/llwindowmacosx.cpp18
-rw-r--r--indra/llwindow/llwindowmacosx.h1
-rw-r--r--indra/llwindow/llwindowwin32.cpp139
8 files changed, 199 insertions, 156 deletions
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 55befaef51..ca08e38f77 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -14,26 +14,9 @@ include(00-Common)
include(DragDrop)
include(LLCommon)
include(LLImage)
-include(LLMath)
-include(LLRender)
-include(LLFileSystem)
include(LLWindow)
-include(LLXML)
include(UI)
-
-include_directories(
- ${LLCOMMON_INCLUDE_DIRS}
- ${LLIMAGE_INCLUDE_DIRS}
- ${LLMATH_INCLUDE_DIRS}
- ${LLRENDER_INCLUDE_DIRS}
- ${LLFILESYSTEM_INCLUDE_DIRS}
- ${LLWINDOW_INCLUDE_DIRS}
- ${LLXML_INCLUDE_DIRS}
- )
-include_directories(SYSTEM
- ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
- ${LLXML_SYSTEM_INCLUDE_DIRS}
- )
+include(ViewerMiscLibs)
set(llwindow_SOURCE_FILES
llcursortypes.cpp
@@ -64,22 +47,21 @@ set(viewer_HEADER_FILES
llmousehandler.h
)
+set(llwindow_LINK_LIBRARIES
+ llcommon
+ llimage
+ llmath
+ llrender
+ llfilesystem
+ llxml
+ ll::glh_linear
+ ll::glext
+ ll::uilibraries
+ ll::SDL
+ )
# Libraries on which this library depends, needed for Linux builds
# Sort by high-level to low-level
if (LINUX)
- set(llwindow_LINK_LIBRARIES
- ${LLCOMMON_LIBRARIES}
- ${LLIMAGE_LIBRARIES}
- ${LLMATH_LIBRARIES}
- ${LLRENDER_LIBRARIES}
- ${LLFILESYSTEM_LIBRARIES}
- ${LLWINDOW_LIBRARIES}
- ${LLXML_LIBRARIES}
- ${UI_LIBRARIES} # for GTK
- ${SDL_LIBRARY}
- fontconfig # For FCInit and other FC* functions.
- )
-
list(APPEND viewer_SOURCE_FILES
llkeyboardsdl.cpp
llwindowsdl.cpp
@@ -157,9 +139,6 @@ if (SOLARIS)
)
endif (SOLARIS)
-set_source_files_properties(${llwindow_HEADER_FILES}
- PROPERTIES HEADER_FILE_ONLY TRUE)
-
if (BUILD_HEADLESS)
set(llwindowheadless_SOURCE_FILES
llwindowmesaheadless.cpp
@@ -197,10 +176,10 @@ if (SDL_FOUND)
endif (SDL_FOUND)
target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
+ target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
if (DARWIN)
include(CMakeFindFrameworks)
find_library(CARBON_LIBRARY Carbon)
target_link_libraries(llwindow ${CARBON_LIBRARY})
endif (DARWIN)
-
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index 81e938edbe..391a377280 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -1098,7 +1098,7 @@ LLSD LLDXHardware::getDisplayInfo()
}
LCleanup:
- if (ret.emptyMap())
+ if (!ret.isMap() || (ret.size() == 0))
{
LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL;
}
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 049226db65..7936245744 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -495,7 +495,12 @@ attributedStringInfo getSegments(NSAttributedString *str)
// e.g. OS Window for upload something or Input Window...
// mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit)
mModifiers = [theEvent modifierFlags];
- unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
+ NSString *str_no_modifiers = [theEvent charactersIgnoringModifiers];
+ unichar ch = 0;
+ if (str_no_modifiers.length)
+ {
+ ch = [str_no_modifiers characterAtIndex:0];
+ }
bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch);
if (acceptsText &&
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 43edc0110d..77024d3a9c 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -83,7 +83,7 @@ int createNSApp(int argc, const char **argv);
void setupCocoa();
bool pasteBoardAvailable();
bool copyToPBoard(const unsigned short *str, unsigned int len);
-const unsigned short *copyFromPBoard();
+unsigned short *copyFromPBoard();
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY);
short releaseImageCursor(CursorRef ref);
short setImageCursor(CursorRef ref);
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 5ec9b017cf..690fe058db 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -49,14 +49,12 @@ void setupCocoa()
if(!inited)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
- // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
- // when init'ing the Cocoa App window.
- [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
-
- [pool release];
+ @autoreleasepool {
+ // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
+ // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
+ // when init'ing the Cocoa App window.
+ [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
+ }
inited = true;
}
@@ -64,13 +62,13 @@ void setupCocoa()
bool copyToPBoard(const unsigned short *str, unsigned int len)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
- NSPasteboard *pboard = [NSPasteboard generalPasteboard];
- [pboard clearContents];
-
- NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil];
- [pool release];
- return [pboard writeObjects:contentsToPaste];
+ @autoreleasepool {
+ NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+ [pboard clearContents];
+
+ NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease];
+ return [pboard writeObjects:contentsToPaste];
+ }
}
bool pasteBoardAvailable()
@@ -79,39 +77,39 @@ bool pasteBoardAvailable()
return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
}
-const unsigned short *copyFromPBoard()
+unsigned short *copyFromPBoard()
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
- NSPasteboard *pboard = [NSPasteboard generalPasteboard];
- NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
- NSString *str = NULL;
- BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
- if (ok)
- {
- NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
- str = [objToPaste objectAtIndex:0];
- }
- unichar* temp = (unichar*)calloc([str length]+1, sizeof(unichar));
- [str getCharacters:temp];
- [pool release];
- return temp;
+ @autoreleasepool {
+ NSPasteboard *pboard = [NSPasteboard generalPasteboard];
+ NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
+ NSString *str = NULL;
+ BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]];
+ if (ok)
+ {
+ NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]];
+ str = [objToPaste objectAtIndex:0];
+ }
+ NSUInteger str_len = [str length];
+ unichar* temp = (unichar*)calloc(str_len+1, sizeof(unichar));
+ [str getCharacters:temp range:NSMakeRange(0, str_len)];
+ return temp;
+ }
}
CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- // extra retain on the NSCursor since we want it to live for the lifetime of the app.
- NSCursor *cursor =
- [[[NSCursor alloc]
- initWithImage:
- [[[NSImage alloc] initWithContentsOfFile:
- [NSString stringWithUTF8String:fullpath]
- ]autorelease]
- hotSpot:NSMakePoint(hotspotX, hotspotY)
- ]retain];
-
- [pool release];
+ NSCursor *cursor = nil;
+ @autoreleasepool {
+ // extra retain on the NSCursor since we want it to live for the lifetime of the app.
+ cursor =
+ [[[NSCursor alloc]
+ initWithImage:
+ [[[NSImage alloc] initWithContentsOfFile:
+ [NSString stringWithUTF8String:fullpath]
+ ] autorelease]
+ hotSpot:NSMakePoint(hotspotX, hotspotY)
+ ] retain];
+ }
return (CursorRef)cursor;
}
@@ -178,10 +176,10 @@ OSErr releaseImageCursor(CursorRef ref)
{
if( ref != NULL )
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSCursor *cursor = (NSCursor*)ref;
- [cursor release];
- [pool release];
+ @autoreleasepool {
+ NSCursor *cursor = (NSCursor*)ref;
+ [cursor autorelease];
+ }
}
else
{
@@ -195,10 +193,10 @@ OSErr setImageCursor(CursorRef ref)
{
if( ref != NULL )
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSCursor *cursor = (NSCursor*)ref;
- [cursor set];
- [pool release];
+ @autoreleasepool {
+ NSCursor *cursor = (NSCursor*)ref;
+ [cursor set];
+ }
}
else
{
@@ -217,6 +215,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height)
styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
[window makeKeyAndOrderFront:nil];
[window setAcceptsMouseMovedEvents:TRUE];
+ [window setRestorable:FALSE]; // Viewer manages state from own settings
return window;
}
@@ -419,24 +418,26 @@ void requestUserAttention()
long showAlert(std::string text, std::string title, int type)
{
- NSAlert *alert = [[NSAlert alloc] init];
-
- [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
- [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
- if (type == 0)
- {
- [alert addButtonWithTitle:@"Okay"];
- } else if (type == 1)
- {
- [alert addButtonWithTitle:@"Okay"];
- [alert addButtonWithTitle:@"Cancel"];
- } else if (type == 2)
- {
- [alert addButtonWithTitle:@"Yes"];
- [alert addButtonWithTitle:@"No"];
+ long ret = 0;
+ @autoreleasepool {
+ NSAlert *alert = [[[NSAlert alloc] init] autorelease];
+
+ [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]];
+ [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]];
+ if (type == 0)
+ {
+ [alert addButtonWithTitle:@"Okay"];
+ } else if (type == 1)
+ {
+ [alert addButtonWithTitle:@"Okay"];
+ [alert addButtonWithTitle:@"Cancel"];
+ } else if (type == 2)
+ {
+ [alert addButtonWithTitle:@"Yes"];
+ [alert addButtonWithTitle:@"No"];
+ }
+ ret = [alert runModal];
}
- long ret = [alert runModal];
- [alert dealloc];
if (ret == NSAlertFirstButtonReturn)
{
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 22a5462c7f..a0fc91399b 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -667,11 +667,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
if (cgl_err != kCGLNoError )
{
- LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL;
}
else
{
- LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
+ LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL;
}
}
makeFirstResponder(mWindow, mGLView);
@@ -1245,8 +1245,11 @@ BOOL LLWindowMacOSX::isClipboardTextAvailable()
}
BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst)
-{
- llutf16string str(copyFromPBoard());
+{
+ unsigned short* pboard_data = copyFromPBoard(); // must free returned data
+ llutf16string str(pboard_data);
+ free(pboard_data);
+
dst = utf16str_to_wstring(str);
if (dst != L"")
{
@@ -1279,7 +1282,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
{
if (!mSupportedResolutions)
{
- CFArrayRef modes = CGDisplayAvailableModes(mDisplay);
+ CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr);
if(modes != NULL)
{
@@ -1318,6 +1321,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r
}
}
}
+ CFRelease(modes);
}
}
@@ -1713,6 +1717,10 @@ void LLSplashScreenMacOSX::showImpl()
void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
{
+ if(mWindow != NULL)
+ {
+ CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
+ }
}
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index b0f339e1db..851c860017 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -228,6 +228,7 @@ protected:
BOOL mLanguageTextInputAllowed;
LLPreeditor* mPreeditor;
+public:
static BOOL sUseMultGL;
friend class LLWindowManager;
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index c487877caf..6f67b131d1 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3067,18 +3067,54 @@ 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;
+ 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);
+
+ 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;
+
+ prev_absolute_x = absolute_x;
+ prev_absolute_y = absolute_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);
+ }
}
}
}
@@ -3868,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,
@@ -4100,6 +4142,10 @@ void LLWindowWin32::handleStartCompositionMessage()
void LLWindowWin32::handleCompositionMessage(const U32 indexes)
{
+ if (!mPreeditor)
+ {
+ return;
+ }
BOOL needs_update = FALSE;
LLWString result_string;
LLWString preedit_string;
@@ -4215,7 +4261,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)
{
@@ -4395,7 +4444,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.