
    i/              	          d dl Z d dlZd dlZd dlZd dl d dlZd dlZd dlZd dlm	Z	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZ  e j(                  e      Z e       Zd Zd Zd	 Zd
 Zd#dZd$dZd%dZd&dZd Z de!fdZ"de!fdZ#de!fdZ$de!fdZ%d'de&de!fdZ'de&de!fdZ(de&fdZ)d(de&de&dee&   de!fdZ*d e+de!fd!Z,d e+de!fd"Z-y))    N)*)NSWindowNSBorderlessWindowMaskNSBackingStoreBufferedNSColorNSTimer)
Controller)Optional)MacElementNodec                      t        j                         } t        j                  |       }t        j                  |       }||fS )z5Return (width, height) of the main display in pixels.)QuartzCGMainDisplayIDCGDisplayPixelsWideCGDisplayPixelsHigh)
display_idwidthheights      A/Users/mibo/.openclaw/workspace/data/TuriX-CUA/src/mac/actions.py_get_screen_sizer      s:    '')J&&z2E''
3F&=    c                  >    t        j                         } | d   | d   fS )zNReturn the current mouse cursor position as a (x, y) tuple in absolute pixels.r      )	pyautoguiposition)poss    r   _get_current_mouse_positionr   "   s%    
 


CFCFr   c                 .    t        j                  |        y)z
    Instantly move the system mouse pointer to `position` (a (x, y) tuple in absolute pixels).
    Note this jump is potentially visible unless you hide the cursor or restore quickly.
    N)r   CGWarpMouseCursorPosition)r   s    r   _warp_cursorr   *   s    
 $$X.r   c                     t        j                  d|| |f|      }t        j                  t         j                  |       y)zRCreate and post a mouse event of type `event_type` at absolute coordinates (x, y).N)r   CGEventCreateMouseEventCGEventPostkCGSessionEventTap)xy
event_typebuttonevents        r   _post_mouse_eventr)   1   s:    **	
A	E v00%8r   c                 L  K   t        j                         \  }}||z
  }	 t        j                  | |z
  ||z
  |dz  |dz        }t	        j
                         j                  |t        t        d      }|j                  t        j                         |j                  d       |j                  t        j                                |j                  d       |j!                         j#                  d       t        j$                  j'                         }|j)                  |j!                         j+                                |j-                  |       |j/                  d       |j1                  t        j2                  dddd             |j!                         j'                         j5                  |       |j7                          t9        j:                  ||dd d       t9        j:                  |dz   |dd d       t=        j>                  t        j@                  |d	z   d       y w)
N   FTr   r   z	orderOut:g?closeg?)!r   sizer   
CGRectMaker   alloc,initWithContentRect_styleMask_backing_defer_r   r   	setLevel_kCGOverlayWindowLevel
setOpaque_setBackgroundColor_r   
clearColorsetIgnoresMouseEvents_contentViewsetWantsLayer_CALayerlayer	setFrame_boundssetCornerRadius_setBorderWidth_setBorderColor_CGColorCreateGenericRGBaddSublayer_orderFrontRegardlessr   @scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_CFCFRunLoopRunInModekCFRunLoopDefaultMode)	r$   r%   radiusdurationscreen_widthscreen_heightframewinr:   s	            r   flash_click_highlightrM   ;   s    "+.."2L-AGa&j!f*fQhqIENNII+-CULCMM&../NN5G..01t$OO$$T*NN  "E	OOCOO%,,./	6"	!	&88Aq!DEOO**51 LLsKu6LL3W$7 &662uMs   H"H$c                   K   t        j                  t        | |             |dk(  r1t        j                  }t        j
                  }t        j                  }n0t        j                  }t        j                  }t        j                  }t               }t        j                  dt        j                  | |f|      }t        j                  t        j                  |       t        j                  d       d{    t        j                  d|| |f|      }t        j                  t        j                   |       t        j                  d|| |f|      }	t        j                  t        j                   |	       y7 w)z
    Perform a press-and-release click at (x, y) without leaving
    the cursor there. The pointer returns to its old position.
    `button` can be 'left' or 'right'.
    leftNgQ?)asynciocreate_taskrM   r   kCGEventLeftMouseDownkCGEventLeftMouseUpkCGMouseButtonLeftkCGEventRightMouseDownkCGEventRightMouseUpkCGMouseButtonRightr   r!   kCGEventMouseMovedr"   r#   sleepkCGHIDEventTap)
r$   r%   r'   	down_typeup_type	cg_buttonold_posmove
event_downevent_ups
             r   _click_invisiblerb   Z   s'     -a3400	..--	11	//..	)+G ))$&,&?&?'(!fi9D v00$7
--
//i!QSJ
v,,j9 --dGaVYOH
v,,h7 s   C4E:6E87BE:c                 v  K   t        t              }t        |t        | |ft              }t        |t        d       t        t        |       ||z  }	t        d|dz         D ]  }
| || z
  |
z  |z  z   }|||z
  |
z  |z  z   }t        |t        ||ft              }t        |t        d       t        |t        t        j                                      t        t        |       t        j                   |	       d {     t        |t"        ||ft              }t        |t        d       t        t        |       y 7 @w)Nr   r   )CGEventSourceCreate!kCGEventSourceStateHIDSystemStater!   rR   rT   CGEventSetIntegerValueFieldkCGMouseEventClickStater"   rZ   rangekCGEventLeftMouseDraggedCGEventSetTimestampinttimetime_nsrP   rY   rS   )x1y1x2y2rH   stepsr'   srcdownstep_tinxnydragups                  r   _drag_invisibler{   |   s&    
?
@C"3#8$&8#57D   7<%e^F1eAg2b5!)E/!2b5!)E/!&s'?(*Bx'9; 	$D$;Q	@D#dlln"56ND)mmF###  
!!4"$b!3
5B   7<# 	$s   C4D96D77AD9c                 0  K   | dkD  rdnd}t        t        |             D ]p  }t        j                  d t        j                  d|      }t        j
                  t        j                  |       t        j                  d       d {    |dk(  sp y  y 7 w)Nr   r   g~jth?   )	rh   absr   CGEventCreateScrollWheelEventkCGScrollEventUnitLiner"   r#   rP   rY   )lines	direction_r(   s       r   _scroll_invisibler      s     QYBI3u:44))	
 	644e<mmE"""b5  	#s   BBB	BBc                    K   | dz  } |dz  }t               \  }}| |z  } ||z  }t        | |f       t        |       d{    y7 w)z
    Temporarily warp the cursor to (x, y), scroll by `lines` lines 
    (positive=up, negative=down), then warp back. 
    This avoids permanently moving the user's pointer.
    g     @@NT)r   r   r   )r$   r%   r   screen_wscreen_hs        r   _scroll_invisible_at_positionr      s[      	
&A	&A)+HhMAMA!Q
E
""" #s   =AA Areturnc                    K   t               \  }}| d   dkD  r| d   dkD  r| d   dz  |z  }| d   dz  |z  }n| d   |z  }| d   |z  }t        ||d       d{    t        j                  d| d| d	       y
7 !w)zGLeft-click the specified (x, y) in normalized screen coords, invisibly.r   r     rO   r'   Nu1   ✅ Successfully left-clicked pixel at absolute [, ]Tr   rb   loggerdebugr   r   r   abs_xabs_ys        r   left_click_pixelr      s     )+Hh{Q8A;?D 8+D 8+h&h&
5%
777
LLDUG2eWTUVW 8   AA<A:"A<c                    K   t               \  }}| d   dkD  r| d   dkD  r| d   dz  |z  }| d   dz  |z  }n| d   |z  }| d   |z  }t        ||d       d{    t        j                  d| d| d	       y
7 !w)zHRight-click the specified (x, y) in normalized screen coords, invisibly.r   r   r   rightr   Nu2   ✅ Successfully right-clicked pixel at absolute [r   r   Tr   r   s        r   right_click_pixelr      s     )+Hh{Q8A;?D 8+D 8+h&h&
5%
888
LLEeWBugUVWX 9r   c                   K   t               \  }}| d   dkD  r| d   dkD  r| d   dz  |z  }| d   dz  |z  }n| d   |z  }| d   |z  }t        j                  dt        j                  ||ft        j                        }t        j
                  t        j                  |       t        j                  d| d| d       yw)	u,  
    Move the system cursor to `position` (normalized coords) instantly. 
    NOTE: This physically moves the user's cursor in one jump, which can be visible.
    If you want no visible move at all, you typically do not call 'move_to'—just 
    post mouse events at the target coords directly.
    r   r   r   Nu+   ✅ Successfully moved cursor to absolute [r   r   T)	r   r   r!   rX   rT   r"   r#   r   r   )r   r   r   r   r   r_   s         r   move_tor      s      *+Hh{Q8A;?D 8+D 8+h&h& ))$&,&?&?',enf6O6OQD v00$7
LL>ugRwaPQs   B<B>c                 x  K   t               \  }}| d   dkD  rE| d   dkD  r=|d   dkD  r5|d   dkD  r-| d   dz  |z  }| d   dz  |z  }|d   dz  |z  }|d   dz  |z  }n | d   |z  }| d   |z  }|d   |z  }|d   |z  }t        ||||d       d{    t        j                  d| d| d	| d| d
	       y7 'w)z
    Click and drag from `start` to `end` (each in normalized coords).
    This uses left-mouse drag invisibly, restoring cursor after the operation.
    r   r   r   rO   r   Nu   ✅ Successfully dragged from [r   z] to [r   T)r   r{   r   r   )startendr   r   rn   ro   rp   rq   s           r   
drag_pixelr      s    
 *+HhQx!|a1Q!A
1Xd]X%1Xd]X%VD[8#VD[8#1X 1X VhVh
"b"b
888
LL22$bF2$bANO 9s   BB:B8(B:keyc                 f   K   t        j                  |        t        j                  d|         yw)z
    Press a single key using PyAutoGUI. 
    (Alternatively, you could use pynput or Quartz events for keyboard as well.)
    u   ✅ Successfully pressed key: T)r   pressr   info)r   s    r   r   r     s+     
 OOC
KK067s   /1charrt   c                    K   t        | j                  d            dz  }t        j                  d d|      }t        j                  |||        t        j
                  t        j                  |       y w)Nz	utf-16-ler+   r   )lenencoder   CGEventCreateKeyboardEventCGEventKeyboardSetUnicodeStringr"   r#   )r   rt   unitsevs       r   _unicode_eventr     sZ     K()Q.E		*	*4D	9B
**2ud;
v00"5s   A1A3textc                    K   | D ]*  }t        |d       d {    t        |d       d {    , t        j                  d       y7 07 w)NTFu    ✅ Successfully typed the text!)r   r   r   )r   chs     r   	type_intor     sK     R&&&R'''  KK23 	''s   AAAA
A
Akey1key2key3c                 (  K   |t        j                  |        t        j                  |       t        j                  |       t        j                  |       t        j                  |       t        j                  |        t        j	                  d|  d| d|        yt        j                  |        t        j                  |       t        j                  |       t        j                  |        t        j	                  d|  d|        yw)zg
    Press a combination of keys (e.g., Command + Shift + 3).
    Uses PyAutoGUI for convenience. 
    u*   ✅ Successfully pressed the combination: z + T)r   keyDownkeyUpr   r   )r   r   r   s      r   press_combinationr     s     
 $$$@c$sSWRXYZ  	$$@c$PQs   DDamountc                 x   K   | dkD  rd} t        |        d{    t        j                  d|  d       y7 w)z
    Scroll up `amount` lines. Clamped to max of 25 for demonstration.
    Uses native Quartz scrolling (kCGScrollEventUnitLine).
    r~   r   Nu    ✅ Successfully scrolled up by  lines!Tr   r   r   r   s    r   	scroll_upr   3  s@     
 {
&
)))
KK26('BC *s   :8:c                 z   K   | dkD  rd} t        |         d{    t        j                  d|  d       y7 w)z
    Scroll down `amount` lines. Clamped to max of 25 for demonstration.
    Uses native Quartz scrolling (kCGScrollEventUnitLine).
    r~   r   Nu"   ✅ Successfully scrolled down by r   Tr   r   s    r   scroll_downr   >  sB     
 {
6'
***
KK4VHGDE +s   ;9;)   g      ?)rO   )g      ?<   rO   )r   )enter)N).loggingr   rP   rl   Quartz.CoreGraphicsr   CoreFoundationrD   ApplicationServicesr   r   r   r   r   pynput.keyboardr	   typingr
   src.mac.elementr   	getLogger__name__r   kbr   r   r   r)   rM   rb   r{   r   r   boolr   r   r   r   strr   r   r   r   rk   r   r    r   r   <module>r      s(       !  #  '  *			8	$\/9N> 8D$B&  t 0D *S t 6s 6$ 6# # S  QU *	C 	D 		c 	d 	r   