+
     i$  c                   s    R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
Ht RtRt/ t/ t ! R R4      t ! R	 R
]4      tR t ! R R]4      tR tR# )a  Non-blocking abstraction of unix domain sockets.

>>> server = Server('foo')
>>> client = Client('foo')

>>> server.send(1)
>>> client.poll()
>>> client.recv()

>>> client.send(2)
>>> server.poll()
>>> server.recv()

I seems harder to sniff on a socket than using pipes for other non-root
processes, but it doesn't guarantee security. As long as the GUI is open
and not running as root user, it is most likely possible to somehow log
keycodes by looking into the memory of the gui process (just like with most
other applications because they end up receiving keyboard input as well).
It still appears to be a bit overkill to use a socket considering pipes
are much easier to handle.
N)Union)	PathUtils)loggers   UUUZutf8c                   sf   a  ] tR t^Nt o RtR tR tR tR tR t	R t
R tR	 tV 3R
 lR ltRtV tR# )Basez*Abstract base class for Socket and Client.c                s    Wn         . V n        . V n        \        P                  ! \
        P                  P                  V4      4       R V n        R V n	        ^ V n
        V P                  4        R # N)_path_unreadunsentr   ZmkdirospathZdirname
connectionsocket_created_atreset)selfr	   s   &&=/usr/lib/python3.14/site-packages/inputremapper/ipc/socket.py__init__ZBase.__init__Q   sM    
-.

    c                sZ    V P                  4        \        P                  ! 4       V n        R# )zIgnore older messages than now.N)connecttimer   r      &r   r   Z
Base.reset[   s     	99;r   c                    \         h)z:Returns True if connected, and if not attempts to connect.ZNotImplementedErrorr   r   r   r   ZBase.connecta       !!r   c                r   z%For compatibility with select.select.r   r   r   r   filenoZBase.filenoe   r   r   c                r   )zTry to make a new connection.r   r   r   r   	reconnectZBase.reconnecti   r   r   c                s   V P                  4       '       g   \        P                  ! R 4       R# Rp^ p  V P                  P	                  R4      ^ ,          pW,          p\        V4      ^ 8X  d+   V^,          pV^8X  g   V P                  4       '       g   R# Kf  Kh    \        P                  \        3 d     Mi ; iTP                  \        4      pT F  p\        T4      ^ 8  g   K  \        P                  ! TP                  \        4      4      pT^ ,          T P                   8  d   \        P                  ! RT4       Ko  T P"                  P%                  T^,          4       K  	  R# )Not connectedNr   i   zIgnoring old message %s)r   r   debugr
   Zrecvmsglenr   r   ZtimeoutZBlockingIOErrorsplitENDjsonZloadsZdecodeENCODINGr   r   append)r   ZmessagesZattemptsZchunkr   messageZparseds   &      r   _receive_new_messagesZBase._receive_new_messagesm   s   ||~~LL)//5a8!u:?
 MH1}DNN,<,< -= # NNO4  s#G7|aGNN8$<=!9t/// LL!:FC##F1I. s   AB B98B9c                s    V P                  4        \        V P                  4      ^ 8X  d   R# V P                  P                  ^ 4      # )zGet the next message or None if nothing to read.

Doesn't transmit pickles, to avoid injection attacks on the
privileged reader-service. Only messages that can be converted to json
are allowed.
N)r%   r   r   popr   r   r   recvZ	Base.recv   s9     	""$t||!||""r   c                s    \        V P                  4      ^ 8  d   R# V P                  4        \        V P                  4      ^ 8  # )z(Check if a message to read is available.T)r   r   r%   r   r   r   pollZ	Base.poll   s6    t||q ""$4<< 1$$r   c                sF   < V ^8  d   QhRS[ S[S[S[S[S[S[3,          /# )i   r$   )r    ZstrZintZfloatZdictZlistZtuple)Zformat__classdict__s   "r   Z__annotate__ZBase.__annotate__   s&     $ $E#sE4u"DE $r   c                s  a  \        \        P                  ! \        P                  ! 4       V34      \        4      pS P
                  P                  V4       S P                  4       '       g   \        P                  ! R4       R# V 3R lp V! 4        R#   \         d    S P                  4       '       g9   \        P                  ! R\        S 4      P                  S P                  4        R#  T! 4         R#   \         dC   p\        P                  ! R\        S 4      P                  S P                  T4        Rp? R# Rp?ii ; ii ; i)z Send json-serializable messages.r   Nc                  s   < \        SP                  4      ^ 8  dW   SP                  ^ ,          p SP                  P                  V \        ,           4       SP                  P                  ^ 4       Kp  R# )i    N)r   r   r
   Zsendallr    r&   )r   r   s    r   send_allZBase.send.<locals>.send_all   sL    dkk"Q&Q''5"	 'r   z&%s: The other side of "%s" disappearedz%s: Failed to send via "%s": %s)Zbytesr!   Zdumpsr   r"   r   r#   r   r   r   ZBrokenPipeErrorr   errorZtype__name__r   )r   r$   Zdumpr*   r+   s   f&   r   sendZ	Base.send   s    TZZg 67B4 ||~~LL)	#	J 	>>##<J''JJ
 
" 5J''JJ	 	s6   B  E	55E	.C88E6E 9E	 EE	)r   r   r   r
   r   r   N)r,   
__module____qualname____firstlineno____doc__r   r   r   r   r   r%   r'   r(   r-   __static_attributes____classdictcell__r)      @r   r   r   N   s;     4'"""#/J#%$ $r   r   c                   s6   a  ] tR t^t o RtR tR tR tRtV t	R# )_Clientz.A socket that can be written to and read from.c                s   V P                   e   R#  \         P                   ! \         P                  4      pVP                  V P                  4       \        P
                  ! RV P                  4       VP                  R4       Yn         Yn        T \        T P                  &   R#   \         d.   p\        P
                  ! RT P                  T4        R p?R# R p?ii ; i)NTzConnected to socket: "%s"FzFailed to connect to "%s": "%s")
r   AF_UNIXr   r   r   r   setblockingZ	Exceptionr
   existing_clients)r   _socketr+   s   &  r   r   Z_Client.connect   s    ;;"	mmFNN3GOODJJ'LL4djjA&
 !'+$  	LL:DJJN	s   A1B$ $C/"CCc                V    V P                  4        V P                  P                  4       # r   )r   r   r   r   r   r   r   Z_Client.fileno   s    {{!!##r   c                s>    R V n         R V n        V P                  4       # r   )r
   r   r   r   r   r   r   Z_Client.reconnect   s    ||~r   r
   r   N
r,   r.   r/   r0   r1   r   r   r   r2   r3   r4   r5   r   r6   r6      s     8$$
 r   r6   c                 ~    V \         9   d)   \         V ,          P                  4        \         V ,          # \        V 4      # r   )r9   r   r6   r	   r   r   Clientr@      1    $$&%%4=r   c                   s6   a  ] tR t^t o RtR tR tR tRtV t	R# )_ServerzA socket that can be written to and read from.

It accepts one connection at a time, and drops old connections if
a new one is in sight.
c                s   V P                   Ef$   \        P                  P                  V P                  4      '       d!   \        P
                  ! V P                  4       \         P                   ! \         P                  \         P                  4      pVP                  V P                  4       VP                  ^4       \        P                  ! V P                  4       \        P                  ! RV P                  4       Wn         V P                   P                  R4       V \        V P                  &   \!        \"        P"                  ! V P                   .. . ^ 4      ^ ,          4      ^ 8g  pV'       g   V P$                  f   R# V'       g   V P$                  e   R# V'       dd   \        P                  ! RV P                  4       V P                   P'                  4       ^ ,          pW0n        V P$                  P                  R4       R# )NzCreated socket: "%s"FTzIncoming connection: "%s")r   r   r	   Zexistsr   Zremover7   ZSOCK_STREAMZbindZlistenr   Zchownr   r   r8   existing_serversr   selectr
   Zaccept)r   r:   Zincomingr
   s   &   r   r   Z_Server.connect   s@   ;;ww~~djj))		$**%mmFNNF4F4FGGLL$NN1OODJJ'LL/<!KKK##E*+/TZZ(v}}dkk]BA>qABaGDOO3DOO7LL4djjA++-a0J(OOO''.r   c                r;   r   )r   r
   r   r   r   r   r   Z_Server.fileno  s    %%''r   c                s0    R V n         V P                  4       # r   )r
   r   r   r   r   r   Z_Server.reconnect$  s    ||~r   r<   Nr=   r4   r5   r   rB   rB      s     @(
 r   rB   c                 r>   r   )rC   r   rB   r?   r   r   ServerrE   )  rA   r   )r1   r!   r   rD   r   r   Ztypingr    Zinputremapper.configs.pathsr   Zinputremapper.logging.loggerr   r    r"   rC   r9   r   r6   r@   rB   rE   ) r   r   <module>rF      sp   *@  	     1 /
    ~ ~Bd @.d .br   