Skip to content

Commit 85fe1f9

Browse files
committed
Support for restart i3 reconnection.
Search the socket path on reconnect if no user's socket_path defined.
1 parent 178a6be commit 85fe1f9

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
lines changed

i3ipc/aio/connection.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class Connection:
277277
def __init__(self, socket_path: Optional[str] = None, auto_reconnect: bool = False, *,
278278
display: Optional[str] = None):
279279
self._socket_path = socket_path
280+
self._connection_socket_path = None
280281
self._auto_reconnect = auto_reconnect
281282
self._pubsub = _AIOPubSub(self)
282283
self._subscriptions = set()
@@ -297,7 +298,7 @@ def socket_path(self) -> str:
297298
298299
:rtype: str
299300
"""
300-
return self._socket_path
301+
return self._connection_socket_path or self._socket_path
301302

302303
@property
303304
def auto_reconect(self) -> bool:
@@ -393,8 +394,10 @@ async def connect(self) -> 'Connection':
393394
if self._socket_path:
394395
logger.info('using user provided socket path: {}', self._socket_path)
395396

396-
if not self._socket_path:
397-
self._socket_path = await _find_socket_path(self._display)
397+
if self._socket_path:
398+
self._connection_socket_path = self._socket_path
399+
else:
400+
self._connection_socket_path = await _find_socket_path(self._display)
398401

399402
if not self.socket_path:
400403
raise Exception('Failed to retrieve the i3 or sway IPC socket path')
@@ -428,6 +431,7 @@ async def do_reconnect():
428431
error = None
429432
break
430433
except Exception as e:
434+
self._connection_socket_path = None
431435
error = e
432436
await asyncio.sleep(0.001)
433437

i3ipc/connection.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,24 +59,30 @@ def __init__(self, socket_path=None, auto_reconnect=False, display=None):
5959

6060
if socket_path:
6161
logger.info('using user provided socket path: %s', socket_path)
62-
else:
63-
socket_path = self._find_socket_path()
64-
65-
if not socket_path:
66-
raise Exception('Failed to retrieve the i3 or sway IPC socket path')
6762

6863
self.subscriptions = 0
6964
self._pubsub = PubSub(self)
65+
self._display = display
7066
self._socket_path = socket_path
67+
self._connection_socket_path = self._get_socket_path()
7168
self._cmd_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
72-
self._cmd_socket.connect(self._socket_path)
69+
self._cmd_socket.connect(self._connection_socket_path)
7370
self._cmd_lock = Lock()
7471
self._sub_socket = None
7572
self._sub_lock = Lock()
7673
self._auto_reconnect = auto_reconnect
7774
self._quitting = False
7875
self._synchronizer = None
79-
self._display = display
76+
77+
def _get_socket_path(self):
78+
"""Returns a current socket path."""
79+
if self._socket_path:
80+
socket_path = self._socket_path
81+
else:
82+
socket_path = self._find_socket_path()
83+
if not socket_path:
84+
raise Exception('Failed to retrieve the i3 or sway IPC socket path')
85+
return socket_path
8086

8187
def _find_socket_path(self):
8288
socket_path = os.environ.get("I3SOCK")
@@ -134,7 +140,7 @@ def socket_path(self) -> str:
134140
135141
:rtype: str
136142
"""
137-
return self._socket_path
143+
return self._connection_socket_path
138144

139145
@property
140146
def auto_reconnect(self) -> bool:
@@ -195,14 +201,13 @@ def _ipc_send(self, sock, message_type, payload):
195201

196202
def _wait_for_socket(self):
197203
# for the auto_reconnect feature only
198-
socket_path_exists = False
199204
for tries in range(0, 500):
200-
socket_path_exists = os.path.exists(self._socket_path)
201-
if socket_path_exists:
202-
break
205+
self._connection_socket_path = self._get_socket_path()
206+
if os.path.exists(self._connection_socket_path):
207+
return True
203208
time.sleep(0.001)
204209

205-
return socket_path_exists
210+
return False
206211

207212
def _message(self, message_type, payload):
208213
try:
@@ -213,13 +218,13 @@ def _message(self, message_type, payload):
213218
raise e
214219

215220
logger.info('got a connection error, reconnecting', exc_info=e)
216-
# XXX: can the socket path change between restarts?
221+
# The socket path can change between restarts.
217222
if not self._wait_for_socket():
218223
logger.info('could not reconnect')
219224
raise e
220225

221226
self._cmd_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
222-
self._cmd_socket.connect(self._socket_path)
227+
self._cmd_socket.connect(self._connection_socket_path)
223228
return self._ipc_send(self._cmd_socket, message_type, payload)
224229
finally:
225230
self._cmd_lock.release()
@@ -475,7 +480,7 @@ def _on(self, event: Union[Event, str], handler: Callable[['Connection', IpcBase
475480

476481
def _event_socket_setup(self):
477482
self._sub_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
478-
self._sub_socket.connect(self._socket_path)
483+
self._sub_socket.connect(self._connection_socket_path)
479484

480485
self._subscribe(self.subscriptions)
481486

0 commit comments

Comments
 (0)