<s> import os <EOL> import socket <EOL> import selectors <EOL> import threading <EOL> from argparse import ArgumentParser <EOL> import i3ipc <EOL> SOCKET_FILE = '<STR_LIT>' <EOL> MAX_WIN_HISTORY = <NUM_LIT:15> <EOL> class FocusWatcher : <EOL> def __init__ ( self ) : <EOL> self . i3 = i3ipc . Connection ( ) <EOL> self . i3 . on ( '<STR_LIT>' , self . on_window_focus ) <EOL> self . listening_socket = socket . socket ( socket . AF_UNIX , <EOL> socket . SOCK_STREAM ) <EOL> if os . path . exists ( SOCKET_FILE ) : <EOL> os . remove ( SOCKET_FILE ) <EOL> self . listening_socket . bind ( SOCKET_FILE ) <EOL> self . listening_socket . listen ( <NUM_LIT:1> ) <EOL> self . window_list = [ ] <EOL> self . window_list_lock = threading . RLock ( ) <EOL> def on_window_focus ( self , i3conn , event ) : <EOL> with self . window_list_lock : <EOL> window_id = event . container . props . id <EOL> if window_id in self . window_list : <EOL> self . window_list . remove ( window_id ) <EOL> self . window_list . insert ( <NUM_LIT:0> , window_id ) <EOL> if len ( self . window_list ) > MAX_WIN_HISTORY : <EOL> del self . window_list [ MAX_WIN_HISTORY : ] <EOL> def launch_i3 ( self ) : <EOL> self . i3 . main ( ) <EOL> def launch_server ( self ) : <EOL> selector = selectors . DefaultSelector ( ) <EOL> def accept ( sock ) : <EOL> conn , addr = sock . accept ( ) <EOL> selector . register ( conn , selectors . EVENT_READ , read ) <EOL> def read ( conn ) : <EOL> data = conn . recv ( <NUM_LIT> ) <EOL> if data == b'<STR_LIT>' : <EOL> with self . window_list_lock : <EOL> tree = self . i3 . get_tree ( ) <EOL> windows = set ( w . id for w in tree . leaves ( ) ) <EOL> for window_id in self . window_list [ <NUM_LIT:1> : ] : <EOL> if window_id not in windows : <EOL> self . window_list . remove ( window_id ) <EOL> else : <EOL> self . i3 . command ( '<STR_LIT>' % window_id ) <EOL> break <EOL> elif not data : <EOL> selector . unregister ( conn ) <EOL> conn . close ( ) <EOL> selector . register ( self . listening_socket , selectors . EVENT_READ , accept ) <EOL> while True : <EOL> for key , event in selector . select ( ) : <EOL> callback = key . data <EOL> callback ( key . fileobj ) <EOL> def run ( self ) : <EOL> t_i3 = threading . Thread ( target = self . launch_i3 ) <EOL> t_server = threading . Thread ( target = self . launch_server ) <EOL> for t in ( t_i3 , t_server ) : <EOL> t . start ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> parser = ArgumentParser ( prog = '<STR_LIT>' , <EOL> description = '''<STR_LIT>''' ) <EOL> parser . add_argument ( '<STR_LIT>' , dest = '<STR_LIT>' , action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' , default = False ) <EOL> args = parser . parse_args ( ) <EOL> if not args . switch : <EOL> focus_watcher = FocusWatcher ( ) <EOL> focus_watcher . run ( ) <EOL> else : <EOL> client_socket = socket . socket ( socket . AF_UNIX , socket . SOCK_STREAM ) <EOL> client_socket . connect ( SOCKET_FILE ) <EOL> client_socket . send ( b'<STR_LIT>' ) <EOL> client_socket . close ( ) </s>
