winemac: Improve positioning of input method candidate window.
This commit is contained in:
parent
450617ecfc
commit
939d9a906f
@ -370,6 +370,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
|
|||||||
[[window queue] postEvent:event];
|
[[window queue] postEvent:event];
|
||||||
|
|
||||||
macdrv_release_event(event);
|
macdrv_release_event(event);
|
||||||
|
|
||||||
|
[[self inputContext] invalidateCharacterCoordinates];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,10 +416,32 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
|
|||||||
|
|
||||||
- (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
- (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||||
{
|
{
|
||||||
|
macdrv_query* query;
|
||||||
|
WineWindow* window = (WineWindow*)[self window];
|
||||||
|
NSRect ret;
|
||||||
|
|
||||||
aRange = NSIntersectionRange(aRange, NSMakeRange(0, [markedText length]));
|
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)
|
if (actualRange)
|
||||||
*actualRange = aRange;
|
*actualRange = aRange;
|
||||||
return NSMakeRect(100, 100, aRange.length ? 1 : 0, 12);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) characterIndexForPoint:(NSPoint)aPoint
|
- (NSUInteger) characterIndexForPoint:(NSPoint)aPoint
|
||||||
@ -1211,6 +1235,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
|
|||||||
event->window_frame_changed.frame = NSRectToCGRect(frame);
|
event->window_frame_changed.frame = NSRectToCGRect(frame);
|
||||||
[queue postEvent:event];
|
[queue postEvent:event];
|
||||||
macdrv_release_event(event);
|
macdrv_release_event(event);
|
||||||
|
|
||||||
|
[[[self contentView] inputContext] invalidateCharacterCoordinates];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)windowShouldClose:(id)sender
|
- (BOOL)windowShouldClose:(id)sender
|
||||||
|
@ -136,6 +136,10 @@ static void macdrv_query_event(HWND hwnd, const macdrv_event *event)
|
|||||||
TRACE("QUERY_DRAG_OPERATION\n");
|
TRACE("QUERY_DRAG_OPERATION\n");
|
||||||
success = query_drag_operation(query);
|
success = query_drag_operation(query);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_IME_CHAR_RECT:
|
||||||
|
TRACE("QUERY_IME_CHAR_RECT\n");
|
||||||
|
success = query_ime_char_rect(query);
|
||||||
|
break;
|
||||||
case QUERY_PASTEBOARD_DATA:
|
case QUERY_PASTEBOARD_DATA:
|
||||||
TRACE("QUERY_PASTEBOARD_DATA\n");
|
TRACE("QUERY_PASTEBOARD_DATA\n");
|
||||||
success = query_pasteboard_data(hwnd, query->pasteboard_data.type);
|
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)
|
if (event->im_set_text.complete)
|
||||||
IME_NotifyComplete(himc);
|
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_cursor_pos(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_im_set_text(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 */
|
#endif /* __WINE_MACDRV_H */
|
||||||
|
@ -259,6 +259,7 @@ enum {
|
|||||||
QUERY_DRAG_DROP,
|
QUERY_DRAG_DROP,
|
||||||
QUERY_DRAG_EXITED,
|
QUERY_DRAG_EXITED,
|
||||||
QUERY_DRAG_OPERATION,
|
QUERY_DRAG_OPERATION,
|
||||||
|
QUERY_IME_CHAR_RECT,
|
||||||
QUERY_PASTEBOARD_DATA,
|
QUERY_PASTEBOARD_DATA,
|
||||||
NUM_QUERY_TYPES
|
NUM_QUERY_TYPES
|
||||||
};
|
};
|
||||||
@ -283,6 +284,11 @@ typedef struct macdrv_query {
|
|||||||
uint32_t accepted_op;
|
uint32_t accepted_op;
|
||||||
CFTypeRef pasteboard;
|
CFTypeRef pasteboard;
|
||||||
} drag_operation;
|
} drag_operation;
|
||||||
|
struct {
|
||||||
|
void *data;
|
||||||
|
CFRange range;
|
||||||
|
CGRect rect;
|
||||||
|
} ime_char_rect;
|
||||||
struct {
|
struct {
|
||||||
CFStringRef type;
|
CFStringRef type;
|
||||||
} pasteboard_data;
|
} pasteboard_data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user