@@ -8,21 +8,48 @@ const debug = sysinput.core.debug;
88pub fn getCaretPosition () api.POINT {
99 var pt = api.POINT { .x = 0 , .y = 0 };
1010
11- // Try getting actual caret position
11+ // First try using GUI thread info which is more reliable
1212 const focus_hwnd = api .getFocus ();
1313 if (focus_hwnd != null ) {
14- // First try to get caret position directly
14+ // Get thread ID for the window
15+ const thread_id = api .getWindowThreadProcessId (focus_hwnd .? , null );
16+
17+ // Initialize GUITHREADINFO structure
18+ var gui_info = api.GUITHREADINFO {
19+ .cbSize = @sizeOf (api .GUITHREADINFO ),
20+ .flags = 0 ,
21+ .hwndActive = null ,
22+ .hwndFocus = null ,
23+ .hwndCapture = null ,
24+ .hwndMenuOwner = null ,
25+ .hwndMoveSize = null ,
26+ .hwndCaret = null ,
27+ .rcCaret = api.RECT { .left = 0 , .top = 0 , .right = 0 , .bottom = 0 },
28+ };
29+
30+ // Try to get GUI thread info
31+ if (api .getGUIThreadInfo (thread_id , & gui_info ) != 0 ) {
32+ if (gui_info .hwndCaret != null ) {
33+ // Use caret rectangle from GUI thread info
34+ pt .x = gui_info .rcCaret .left ;
35+ pt .y = gui_info .rcCaret .bottom ; // Use bottom for better positioning
36+
37+ // Convert to screen coordinates - properly handle the optional
38+ _ = api .clientToScreen (gui_info .hwndCaret .? , & pt );
39+ debug .debugPrint ("Got caret position from GUITHREADINFO: {d},{d}\n " , .{ pt .x , pt .y });
40+ return applyPositionOffset (pt );
41+ }
42+ }
43+
44+ // If GUI thread info failed, try direct caret position
1545 if (api .getCaretPos (& pt ) != 0 ) {
1646 // Convert from client to screen coordinates
1747 _ = api .clientToScreen (focus_hwnd .? , & pt );
1848 debug .debugPrint ("Got caret position directly: {d},{d}\n " , .{ pt .x , pt .y });
19-
20- // Add slight offset below caret
21- pt .y += 20 ;
22- return pt ;
49+ return applyPositionOffset (pt );
2350 }
2451
25- // If that fails, try getting position from selection
52+ // Try using EM_POSFROMCHAR as a fallback for Edit controls
2653 const selection = api .sendMessage (focus_hwnd .? , api .EM_GETSEL , 0 , 0 );
2754 const sel_u64 : u64 = @bitCast (selection );
2855 const sel_end : u32 = @truncate ((sel_u64 >> 16 ) & 0xFFFF );
@@ -35,20 +62,23 @@ pub fn getCaretPosition() api.POINT {
3562 pt .y = @intCast ((char_pos >> 16 ) & 0xFFFF );
3663 _ = api .clientToScreen (focus_hwnd .? , & pt );
3764 debug .debugPrint ("Got caret position from selection: {d},{d}\n " , .{ pt .x , pt .y });
38-
39- // Add slight offset below caret
40- pt .y += 20 ;
41- return pt ;
65+ return applyPositionOffset (pt );
4266 }
4367 }
4468
4569 // Fall back to cursor position if everything else fails
4670 _ = api .getCursorPos (& pt );
4771 debug .debugPrint ("Falling back to cursor position: {d},{d}\n " , .{ pt .x , pt .y });
72+ return applyPositionOffset (pt );
73+ }
74+
75+ fn applyPositionOffset (pt : api.POINT ) api.POINT {
76+ var result = pt ;
77+
78+ // Simple fixed offset
79+ result .y += 20 ;
4880
49- // Add offset to position suggestions below cursor
50- pt .y += 20 ;
51- return pt ;
81+ return result ;
5282}
5383
5484/// Calculate suggestion window size based on suggestions
0 commit comments