Skip to content

Commit 63c8cf2

Browse files
author
Tony Crisci
committed
add logging and get socket path from binary
1 parent f89b8dd commit 63c8cf2

File tree

1 file changed

+66
-16
lines changed

1 file changed

+66
-16
lines changed

i3ipc/connection.py

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
import time
1717
import Xlib
1818
import Xlib.display
19+
from Xlib.error import DisplayError
20+
import logging
21+
from subprocess import run, PIPE
22+
23+
logger = logging.getLogger(__name__)
1924

2025

2126
class Connection:
@@ -49,20 +54,11 @@ class Connection:
4954
_struct_header_size = struct.calcsize(_struct_header)
5055

5156
def __init__(self, socket_path=None, auto_reconnect=False):
52-
if not socket_path:
53-
socket_path = os.environ.get("I3SOCK")
54-
55-
if not socket_path:
56-
socket_path = os.environ.get("SWAYSOCK")
5757

58-
if not socket_path:
59-
try:
60-
disp = Xlib.display.Display()
61-
root = disp.screen().root
62-
i3atom = disp.intern_atom("I3_SOCKET_PATH")
63-
socket_path = root.get_full_property(i3atom, Xlib.X.AnyPropertyType).value.decode()
64-
except Exception:
65-
pass
58+
if socket_path:
59+
logger.info('using user provided socket path: %s', socket_path)
60+
else:
61+
socket_path = self._find_socket_path()
6662

6763
if not socket_path:
6864
raise Exception('Failed to retrieve the i3 or sway IPC socket path')
@@ -79,6 +75,50 @@ def __init__(self, socket_path=None, auto_reconnect=False):
7975
self._quitting = False
8076
self._synchronizer = None
8177

78+
def _find_socket_path(self):
79+
socket_path = os.environ.get("I3SOCK")
80+
if socket_path:
81+
logger.info('got socket path from I3SOCK env variable: %s', socket_path)
82+
return socket_path
83+
84+
socket_path = os.environ.get("SWAYSOCK")
85+
if socket_path:
86+
logger.info('got socket path from SWAYSOCK env variable: %s', socket_path)
87+
return socket_path
88+
89+
try:
90+
disp = Xlib.display.Display()
91+
root = disp.screen().root
92+
i3atom = disp.intern_atom("I3_SOCKET_PATH")
93+
prop = root.get_full_property(i3atom, Xlib.X.AnyPropertyType)
94+
if prop and prop.value:
95+
socket_path = prop.value.decode()
96+
except DisplayError as e:
97+
logger.info('could not get i3 socket path from root atom', exc_info=e)
98+
99+
if socket_path:
100+
logger.info('got socket path from root atom: %s', socket_path)
101+
return socket_path
102+
103+
for binary in ('i3', 'sway'):
104+
try:
105+
process = run([binary, '--get-socketpath'], stdout=PIPE, stderr=PIPE)
106+
if process.returncode == 0 and process.stdout:
107+
socket_path = process.stdout.decode().strip()
108+
logger.info('got socket path from `%s` binary: %s', binary, socket_path)
109+
return socket_path
110+
else:
111+
logger.info(
112+
'could not get socket path from `%s` binary: returncode=%d, stdout=%s, stderr=%s',
113+
process.returncode, process.stdout, process.stderr)
114+
115+
except Exception as e:
116+
logger.info('could not get i3 socket path from `%s` binary', binary, exc_info=e)
117+
continue
118+
119+
logger.info('could not find i3 socket path')
120+
return None
121+
82122
def _sync(self):
83123
if self._synchronizer is None:
84124
self._synchronizer = Synchronizer()
@@ -129,19 +169,23 @@ def _ipc_recv(self, sock):
129169
data = sock.recv(14)
130170

131171
if len(data) == 0:
132-
# EOF
172+
logger.info('got EOF from ipc socket')
133173
return '', 0
134174

135175
msg_magic, msg_length, msg_type = self._unpack_header(data)
176+
logger.info('reading ipc message: type=%s, length=%s', msg_type, msg_length)
136177
msg_size = self._struct_header_size + msg_length
137178
while len(data) < msg_size:
138179
data += sock.recv(msg_length)
139-
return self._unpack(data), msg_type
180+
payload = self._unpack(data)
181+
logger.info('message payload: %s', payload)
182+
return payload, msg_type
140183

141184
def _ipc_send(self, sock, message_type, payload):
142185
"""Send and receive a message from the ipc. NOTE: this is not thread
143186
safe
144187
"""
188+
logger.info('sending to ipc socket: type=%s, payload=%s', message_type, payload)
145189
sock.sendall(self._pack(message_type, payload))
146190
data, msg_type = self._ipc_recv(sock)
147191
return data
@@ -165,8 +209,10 @@ def _message(self, message_type, payload):
165209
if not self.auto_reconnect:
166210
raise e
167211

212+
logger.info('got a connection error, reconnecting', exc_info=e)
168213
# XXX: can the socket path change between restarts?
169214
if not self._wait_for_socket():
215+
logger.info('could not reconnect')
170216
raise e
171217

172218
self._cmd_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -427,10 +473,11 @@ def _event_socket_poll(self):
427473
if self._sub_socket is None:
428474
return True
429475

476+
logger.info('getting ipc event from subscription socket')
430477
data, msg_type = self._ipc_recv(self._sub_socket)
431478

432479
if len(data) == 0:
433-
# EOF
480+
logger.info('subscription socket got EOF, shutting down')
434481
self._pubsub.emit('ipc_shutdown', None)
435482
return True
436483

@@ -486,6 +533,8 @@ def main(self, timeout: float = 0.0):
486533
self._quitting = False
487534
timer = None
488535

536+
logger.info('starting the main loop')
537+
489538
while True:
490539
try:
491540
self._event_socket_setup()
@@ -515,5 +564,6 @@ def main(self, timeout: float = 0.0):
515564

516565
def main_quit(self):
517566
"""Quits the running main loop for this connection."""
567+
logger.info('shutting down the main loop')
518568
self._quitting = True
519569
self._event_socket_teardown()

0 commit comments

Comments
 (0)