winemac: Improve positioning of input method candidate window.
This commit is contained in:
parent
450617ecfc
commit
939d9a906f
|
@ -370,6 +370,8 @@ - (void) setMarkedText:(id)string selectedRange:(NSRange)selectedRange replaceme
|
|||
[[window queue] postEvent:event];
|
||||
|
||||
macdrv_release_event(event);
|
||||
|
||||
[[self inputContext] invalidateCharacterCoordinates];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,10 +416,32 @@ - (NSArray*) validAttributesForMarkedText
|
|||
|
||||
- (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||
{
|
||||
macdrv_query* query;
|
||||
WineWindow* window = (WineWindow*)[self window];
|
||||
NSRect ret;
|
||||
|
||||
aRange = NSIntersectionRange(aRange, NSMakeRange(0, [markedText length]));
|
||||
|
||||
query = macdrv_create_query();
|
||||
query->type = QUERY_IME_CHAR_RECT;
|
||||
query->window = (macdrv_window)[window retain];
|
||||
query->ime_char_rect.data = [window imeData];
|
||||
query->ime_char_rect.range = CFRangeMake(aRange.location, aRange.length);
|
||||
|
||||
if ([window.queue query:query timeout:1])
|
||||
{
|
||||
aRange = NSMakeRange(query->ime_char_rect.range.location, query->ime_char_rect.range.length);
|
||||
ret = NSRectFromCGRect(query->ime_char_rect.rect);
|
||||
[[WineApplicationController sharedController] flipRect:&ret];
|
||||
}
|
||||
else
|
||||
ret = NSMakeRect(100, 100, aRange.length ? 1 : 0, 12);
|
||||
|
||||
macdrv_release_query(query);
|
||||
|
||||
if (actualRange)
|
||||
*actualRange = aRange;
|
||||
return NSMakeRect(100, 100, aRange.length ? 1 : 0, 12);
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (NSUInteger) characterIndexForPoint:(NSPoint)aPoint
|
||||
|
@ -1211,6 +1235,8 @@ - (void)windowDidResize:(NSNotification *)notification
|
|||
event->window_frame_changed.frame = NSRectToCGRect(frame);
|
||||
[queue postEvent:event];
|
||||
macdrv_release_event(event);
|
||||
|
||||
[[[self contentView] inputContext] invalidateCharacterCoordinates];
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(id)sender
|
||||
|
|
|
@ -136,6 +136,10 @@ static void macdrv_query_event(HWND hwnd, const macdrv_event *event)
|
|||
TRACE("QUERY_DRAG_OPERATION\n");
|
||||
success = query_drag_operation(query);
|
||||
break;
|
||||
case QUERY_IME_CHAR_RECT:
|
||||
TRACE("QUERY_IME_CHAR_RECT\n");
|
||||
success = query_ime_char_rect(query);
|
||||
break;
|
||||
case QUERY_PASTEBOARD_DATA:
|
||||
TRACE("QUERY_PASTEBOARD_DATA\n");
|
||||
success = query_pasteboard_data(hwnd, query->pasteboard_data.type);
|
||||
|
|
|
@ -1509,3 +1509,126 @@ void macdrv_im_set_text(const macdrv_event *event)
|
|||
if (event->im_set_text.complete)
|
||||
IME_NotifyComplete(himc);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* query_ime_char_rect
|
||||
*/
|
||||
BOOL query_ime_char_rect(macdrv_query* query)
|
||||
{
|
||||
HWND hwnd = macdrv_get_window_hwnd(query->window);
|
||||
void *himc = query->ime_char_rect.data;
|
||||
CFRange* range = &query->ime_char_rect.range;
|
||||
CGRect* rect = &query->ime_char_rect.rect;
|
||||
IMECHARPOSITION charpos;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("win %p/%p himc %p range %ld-%ld\n", hwnd, query->window, himc, range->location,
|
||||
range->length);
|
||||
|
||||
if (!himc) himc = RealIMC(FROM_MACDRV);
|
||||
|
||||
charpos.dwSize = sizeof(charpos);
|
||||
charpos.dwCharPos = range->location;
|
||||
if (ImmRequestMessageW(himc, IMR_QUERYCHARPOSITION, (ULONG_PTR)&charpos))
|
||||
{
|
||||
int i;
|
||||
|
||||
*rect = CGRectMake(charpos.pt.x, charpos.pt.y, 0, charpos.cLineHeight);
|
||||
|
||||
/* iterate over rest of length to extend rect */
|
||||
for (i = 1; i <= range->length; i++)
|
||||
{
|
||||
charpos.dwSize = sizeof(charpos);
|
||||
charpos.dwCharPos = range->location + i;
|
||||
if (!ImmRequestMessageW(himc, IMR_QUERYCHARPOSITION, (ULONG_PTR)&charpos) ||
|
||||
charpos.pt.y != rect->origin.y)
|
||||
{
|
||||
range->length = i;
|
||||
break;
|
||||
}
|
||||
|
||||
rect->size.width = charpos.pt.x - rect->origin.x;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
LPINPUTCONTEXT ic = ImmLockIMC(himc);
|
||||
|
||||
if (ic)
|
||||
{
|
||||
LPIMEPRIVATE private = ImmLockIMCC(ic->hPrivate);
|
||||
LPBYTE compdata = ImmLockIMCC(ic->hCompStr);
|
||||
LPCOMPOSITIONSTRING compstr = (LPCOMPOSITIONSTRING)compdata;
|
||||
LPWSTR str = (LPWSTR)(compdata + compstr->dwCompStrOffset);
|
||||
|
||||
if (private->hwndDefault && compstr->dwCompStrOffset &&
|
||||
IsWindowVisible(private->hwndDefault))
|
||||
{
|
||||
HDC dc = GetDC(private->hwndDefault);
|
||||
HFONT oldfont = NULL;
|
||||
SIZE size;
|
||||
|
||||
if (private->textfont)
|
||||
oldfont = SelectObject(dc, private->textfont);
|
||||
|
||||
if (range->location > compstr->dwCompStrLen)
|
||||
range->location = compstr->dwCompStrLen;
|
||||
if (range->location + range->length > compstr->dwCompStrLen)
|
||||
range->length = compstr->dwCompStrLen - range->location;
|
||||
|
||||
GetTextExtentPoint32W(dc, str, range->location, &size);
|
||||
charpos.rcDocument.left = size.cx;
|
||||
charpos.rcDocument.top = 0;
|
||||
GetTextExtentPoint32W(dc, str, range->location + range->length, &size);
|
||||
charpos.rcDocument.right = size.cx;
|
||||
charpos.rcDocument.bottom = size.cy;
|
||||
|
||||
if (ic->cfCompForm.dwStyle == CFS_DEFAULT)
|
||||
OffsetRect(&charpos.rcDocument, 10, 10);
|
||||
|
||||
LPtoDP(dc, (POINT*)&charpos.rcDocument, 2);
|
||||
MapWindowPoints(private->hwndDefault, 0, (POINT*)&charpos.rcDocument, 2);
|
||||
*rect = cgrect_from_rect(charpos.rcDocument);
|
||||
ret = TRUE;
|
||||
|
||||
if (oldfont)
|
||||
SelectObject(dc, oldfont);
|
||||
ReleaseDC(private->hwndDefault, dc);
|
||||
}
|
||||
|
||||
ImmUnlockIMCC(ic->hCompStr);
|
||||
ImmUnlockIMCC(ic->hPrivate);
|
||||
}
|
||||
|
||||
ImmUnlockIMC(himc);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
HWND focus = GetFocus();
|
||||
if (focus && (focus == hwnd || IsChild(hwnd, focus)) &&
|
||||
GetClientRect(focus, &charpos.rcDocument))
|
||||
{
|
||||
if (!GetCaretPos((POINT*)&charpos.rcDocument))
|
||||
charpos.rcDocument.left = charpos.rcDocument.top = 0;
|
||||
|
||||
charpos.rcDocument.right = charpos.rcDocument.left + 1;
|
||||
MapWindowPoints(focus, 0, (POINT*)&charpos.rcDocument, 2);
|
||||
|
||||
*rect = cgrect_from_rect(charpos.rcDocument);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret && range->length && !rect->size.width)
|
||||
rect->size.width = 1;
|
||||
|
||||
TRACE(" -> %s range %ld-%ld rect %s\n", ret ? "TRUE" : "FALSE", range->location,
|
||||
range->length, wine_dbgstr_cgrect(*rect));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -204,5 +204,6 @@ extern BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const B
|
|||
|
||||
extern void macdrv_im_set_cursor_pos(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_im_set_text(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
extern BOOL query_ime_char_rect(macdrv_query* query) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_MACDRV_H */
|
||||
|
|
|
@ -259,6 +259,7 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
QUERY_DRAG_DROP,
|
||||
QUERY_DRAG_EXITED,
|
||||
QUERY_DRAG_OPERATION,
|
||||
QUERY_IME_CHAR_RECT,
|
||||
QUERY_PASTEBOARD_DATA,
|
||||
NUM_QUERY_TYPES
|
||||
};
|
||||
|
@ -283,6 +284,11 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
uint32_t accepted_op;
|
||||
CFTypeRef pasteboard;
|
||||
} drag_operation;
|
||||
struct {
|
||||
void *data;
|
||||
CFRange range;
|
||||
CGRect rect;
|
||||
} ime_char_rect;
|
||||
struct {
|
||||
CFStringRef type;
|
||||
} pasteboard_data;
|
||||
|
|
Loading…
Reference in New Issue