Distributed confirmation dialog: all GUIs open on WAIT_USER, server closes all

- Browser: OK button sends Confirm without closing dialog; Escape blocked;
  dialog closes when state leaves WAIT_USER (server-driven).
- PyQt: non-blocking QDialog replaces blocking QMessageBox; OK sends Confirm
  without closing; dialog closed by server state change or on disconnect.
- ws_client.py: remove deprecated loop= params from websockets.connect() and
  asyncio.ensure_future() (same fix already applied to ws_server.py) so the
  PyQt client can actually connect with websockets >= 10.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tqxrk8uj4M3w3d3eXm3xK8
This commit is contained in:
2026-06-25 22:21:41 +02:00
co-authored by Claude Sonnet 4.6
parent dabec1fd31
commit 0215bac13e
4 changed files with 32 additions and 12 deletions
+4 -4
View File
@@ -17,7 +17,7 @@ class WsClient:
def bg_run(self, uri):
print("bg_run: started")
asyncio.set_event_loop(self.loop)
fut = asyncio.ensure_future(self.run_client(uri), loop=self.loop)
fut = asyncio.ensure_future(self.run_client(uri))
self.loop.run_until_complete(fut)
self.stop = None
print("bg_run: terminated")
@@ -38,7 +38,7 @@ class WsClient:
async def run_client(self, uri):
try:
websocket = await websockets.connect(uri, loop=self.loop)
websocket = await websockets.connect(uri)
except Exception as exc:
print(f"Failed to connect to {uri}: {exc}.")
return
@@ -47,8 +47,8 @@ class WsClient:
await self.listener.on_connect()
try:
path = "/"
consumer_task = asyncio.ensure_future(self.handler_recv(websocket, path), loop=self.loop)
producer_task = asyncio.ensure_future(self.handler_send(websocket, path), loop=self.loop)
consumer_task = asyncio.ensure_future(self.handler_recv(websocket, path))
producer_task = asyncio.ensure_future(self.handler_send(websocket, path))
done, pending = await asyncio.wait([consumer_task, producer_task, self.stop], return_when=asyncio.FIRST_COMPLETED,)
for task in pending:
task.cancel()