remotedesktop 0.20.0__tar.gz → 0.20.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/PKG-INFO +1 -1
  2. remotedesktop-0.20.1/docs/media/client-demo.gif +0 -0
  3. remotedesktop-0.20.1/docs/media/server-demo.gif +0 -0
  4. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/__init__.py +1 -1
  5. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tools/make_demo_gifs.py +41 -10
  6. remotedesktop-0.20.0/docs/media/client-demo.gif +0 -0
  7. remotedesktop-0.20.0/docs/media/server-demo.gif +0 -0
  8. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/.github/workflows/ci.yml +0 -0
  9. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/.gitignore +0 -0
  10. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/CLAUDE.md +0 -0
  11. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/LICENSE +0 -0
  12. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/pyproject.toml +0 -0
  13. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/readme.md +0 -0
  14. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/run_claude.bat +0 -0
  15. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/run_client.bat +0 -0
  16. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/run_server.bat +0 -0
  17. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/scripts/make_coverage_badge.py +0 -0
  18. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/scripts/make_venv.bat +0 -0
  19. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/about.py +0 -0
  20. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/autostart.py +0 -0
  21. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/client.py +0 -0
  22. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/clipboard.py +0 -0
  23. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/compat.py +0 -0
  24. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/config.py +0 -0
  25. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/db.py +0 -0
  26. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/discovery.py +0 -0
  27. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/dxgi.py +0 -0
  28. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/frames.py +0 -0
  29. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/icon.py +0 -0
  30. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/input_injection.py +0 -0
  31. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/inventory.py +0 -0
  32. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/logs.py +0 -0
  33. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/modal_loop.py +0 -0
  34. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/performance.py +0 -0
  35. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/preferences.py +0 -0
  36. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/protocol.py +0 -0
  37. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/server.py +0 -0
  38. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/sharing.py +0 -0
  39. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/tls.py +0 -0
  40. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/viewer.py +0 -0
  41. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/src/remotedesktop/window_state.py +0 -0
  42. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/conftest.py +0 -0
  43. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_about.py +0 -0
  44. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_autostart.py +0 -0
  45. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_client_window.py +0 -0
  46. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_clipboard.py +0 -0
  47. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_compat.py +0 -0
  48. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_config.py +0 -0
  49. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_discovery.py +0 -0
  50. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_dxgi.py +0 -0
  51. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_frames.py +0 -0
  52. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_icon.py +0 -0
  53. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_input.py +0 -0
  54. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_input_injection.py +0 -0
  55. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_inventory.py +0 -0
  56. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_logs.py +0 -0
  57. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_modal_loop.py +0 -0
  58. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_performance.py +0 -0
  59. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_preferences.py +0 -0
  60. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_protocol.py +0 -0
  61. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_server_window.py +0 -0
  62. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_sharing.py +0 -0
  63. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_smoke.py +0 -0
  64. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_tls.py +0 -0
  65. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/tests/test_window_state.py +0 -0
  66. {remotedesktop-0.20.0 → remotedesktop-0.20.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remotedesktop
3
- Version: 0.20.0
3
+ Version: 0.20.1
4
4
  Summary: Remote desktop client/server for Windows computers on the same LAN, with autodiscovery. Provides screen, keyboard, mouse, and clipboard sharing without RDP or Microsoft authentication.
5
5
  Project-URL: Homepage, https://github.com/jamesabel/remotedesktop
6
6
  Project-URL: Repository, https://github.com/jamesabel/remotedesktop
@@ -1,3 +1,3 @@
1
1
  """Remote desktop client/server for Windows computers on the same LAN."""
2
2
 
3
- __version__ = "0.20.0"
3
+ __version__ = "0.20.1"
@@ -62,19 +62,28 @@ _CODE_LINES = [
62
62
 
63
63
  class SyntheticDesktop:
64
64
  """Draws an animated fake desktop: wallpaper, an editor window with
65
- scrolling code, a terminal appending lines, a clock, a gliding cursor."""
66
-
67
- def __init__(self) -> None:
65
+ scrolling code, a terminal appending lines, a clock, a gliding cursor.
66
+
67
+ The gradient colors distinguish the two demo servers' desktops at a
68
+ glance when the client shows one tab per server."""
69
+
70
+ def __init__(
71
+ self,
72
+ gradient: tuple[tuple[int, int, int], tuple[int, int, int]] = (
73
+ (16, 42, 84),
74
+ (52, 18, 90),
75
+ ),
76
+ ) -> None:
68
77
  self._start = time.monotonic()
69
- self._background = self._draw_background()
78
+ self._background = self._draw_background(gradient)
70
79
 
71
80
  @staticmethod
72
- def _draw_background() -> QImage:
81
+ def _draw_background(colors: tuple[tuple[int, int, int], tuple[int, int, int]]) -> QImage:
73
82
  image = QImage(SCREEN_W, SCREEN_H, QImage.Format.Format_RGB32)
74
83
  painter = QPainter(image)
75
84
  gradient = QLinearGradient(0, 0, SCREEN_W, SCREEN_H)
76
- gradient.setColorAt(0.0, QColor(16, 42, 84))
77
- gradient.setColorAt(1.0, QColor(52, 18, 90))
85
+ gradient.setColorAt(0.0, QColor(*colors[0]))
86
+ gradient.setColorAt(1.0, QColor(*colors[1]))
78
87
  painter.fillRect(0, 0, SCREEN_W, SCREEN_H, gradient)
79
88
  painter.setRenderHint(QPainter.RenderHint.Antialiasing)
80
89
  painter.setPen(Qt.PenStyle.NoPen)
@@ -237,6 +246,18 @@ def main() -> None:
237
246
  desktop = SyntheticDesktop()
238
247
  server_window.share_server._capture = desktop.grab # the test seam # ty: ignore[invalid-assignment]
239
248
 
249
+ # A second, window-less server ("LAB-PC", teal desktop) so the client
250
+ # demo shows one tab per connected server.
251
+ lab_db = db.connect(tmp_path / "lab.db")
252
+ lab_server = sharing.ShareServer(
253
+ approve_client=lambda _cid, _name: True,
254
+ credentials=credentials,
255
+ paired=PairedClients(lab_db),
256
+ )
257
+ lab_desktop = SyntheticDesktop(gradient=((10, 62, 52), (14, 34, 78)))
258
+ lab_server._capture = lab_desktop.grab # ty: ignore[invalid-assignment]
259
+ assert lab_server.listen(0)
260
+
240
261
  client_db = db.connect(tmp_path / "client.db")
241
262
  client_settings = Settings(client_db)
242
263
  client_settings.set("client_id", str(uuid.uuid4()))
@@ -249,17 +270,25 @@ def main() -> None:
249
270
  window.show()
250
271
 
251
272
  info = ServerInfo(name="DEN-PC", host="127.0.0.1", port=server_window.share_server.port)
252
- client_module.discover_servers = lambda: [info] # ty: ignore[invalid-assignment]
273
+ lab_info = ServerInfo(name="LAB-PC", host="127.0.0.1", port=lab_server.port)
274
+ client_module.discover_servers = lambda: [info, lab_info] # ty: ignore[invalid-assignment]
253
275
  client_tabs = client_window.centralWidget()
254
276
  server_tabs = server_window.centralWidget()
255
277
  assert isinstance(client_tabs, QTabWidget) and isinstance(server_tabs, QTabWidget)
256
278
 
257
279
  # The live remote-screen section is the product's whole point, so it
258
- # gets the lion's share of the runtime (~19 s of streaming before
259
- # the brief Performance-tab detour, plus the closing shot).
280
+ # gets the lion's share of the runtime: DEN-PC streams alone first,
281
+ # then LAB-PC joins (one tab per server) and the demo flips between
282
+ # the two tabs before the brief Performance detour and closing shot.
283
+ # gethostname is swapped just before the second connection so LAB-PC's
284
+ # welcome reports its own name (it is read at admission time).
260
285
  script = [
261
286
  (0.8, lambda: client_window.discovery_panel.refresh()),
262
287
  (2.0, lambda: client_window.discovery_panel.serverActivated.emit(info)),
288
+ (7.0, lambda: setattr(socket, "gethostname", lambda: "LAB-PC")),
289
+ (7.2, lambda: client_window.discovery_panel.serverActivated.emit(lab_info)),
290
+ (13.0, lambda: client_tabs.setCurrentIndex(tab_index(client_tabs, "DEN-PC"))),
291
+ (17.0, lambda: client_tabs.setCurrentIndex(tab_index(client_tabs, "LAB-PC"))),
263
292
  (21.2, lambda: client_tabs.setCurrentIndex(tab_index(client_tabs, "Performance"))),
264
293
  (21.6, lambda: server_tabs.setCurrentIndex(tab_index(server_tabs, "Performance"))),
265
294
  (23.6, lambda: client_tabs.setCurrentIndex(tab_index(client_tabs, "DEN-PC"))),
@@ -283,10 +312,12 @@ def main() -> None:
283
312
  save_gif(server_frames, out_dir / "server-demo.gif")
284
313
  client_window.close()
285
314
  server_window.close()
315
+ lab_server.close()
286
316
  app.processEvents()
287
317
  # The temp dir can't be removed while the SQLite files are open.
288
318
  client_db.close()
289
319
  server_db.close()
320
+ lab_db.close()
290
321
 
291
322
 
292
323
  if __name__ == "__main__":
File without changes
File without changes
File without changes
File without changes