PyWebWinUI3 1.2.5__tar.gz → 1.2.6__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 (130) hide show
  1. {pywebwinui3-1.2.5/PyWebWinUI3.egg-info → pywebwinui3-1.2.6}/PKG-INFO +1 -1
  2. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6/PyWebWinUI3.egg-info}/PKG-INFO +1 -1
  3. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/__init__.py +1 -1
  4. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/core.py +77 -134
  5. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/LICENSE +0 -0
  6. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/MANIFEST.in +0 -0
  7. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/NOTICE +0 -0
  8. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/PyWebWinUI3.egg-info/SOURCES.txt +0 -0
  9. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/PyWebWinUI3.egg-info/dependency_links.txt +0 -0
  10. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/PyWebWinUI3.egg-info/requires.txt +0 -0
  11. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/PyWebWinUI3.egg-info/top_level.txt +0 -0
  12. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/README.md +0 -0
  13. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pyproject.toml +0 -0
  14. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/event.py +0 -0
  15. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/type.py +0 -0
  16. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/util.py +0 -0
  17. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.0.woff2 +0 -0
  18. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.1.woff2 +0 -0
  19. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.10.woff2 +0 -0
  20. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.11.woff2 +0 -0
  21. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.12.woff2 +0 -0
  22. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.13.woff2 +0 -0
  23. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.14.woff2 +0 -0
  24. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.15.woff2 +0 -0
  25. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.16.woff2 +0 -0
  26. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.17.woff2 +0 -0
  27. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.18.woff2 +0 -0
  28. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.19.woff2 +0 -0
  29. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.2.woff2 +0 -0
  30. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.20.woff2 +0 -0
  31. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.21.woff2 +0 -0
  32. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.22.woff2 +0 -0
  33. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.23.woff2 +0 -0
  34. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.24.woff2 +0 -0
  35. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.25.woff2 +0 -0
  36. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.26.woff2 +0 -0
  37. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.27.woff2 +0 -0
  38. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.28.woff2 +0 -0
  39. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.29.woff2 +0 -0
  40. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.3.woff2 +0 -0
  41. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.30.woff2 +0 -0
  42. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.31.woff2 +0 -0
  43. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.32.woff2 +0 -0
  44. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.33.woff2 +0 -0
  45. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.34.woff2 +0 -0
  46. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.35.woff2 +0 -0
  47. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.36.woff2 +0 -0
  48. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.37.woff2 +0 -0
  49. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.38.woff2 +0 -0
  50. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.39.woff2 +0 -0
  51. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.4.woff2 +0 -0
  52. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.40.woff2 +0 -0
  53. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.41.woff2 +0 -0
  54. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.42.woff2 +0 -0
  55. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.43.woff2 +0 -0
  56. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.44.woff2 +0 -0
  57. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.45.woff2 +0 -0
  58. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.46.woff2 +0 -0
  59. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.47.woff2 +0 -0
  60. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.48.woff2 +0 -0
  61. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.49.woff2 +0 -0
  62. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.5.woff2 +0 -0
  63. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.50.woff2 +0 -0
  64. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.51.woff2 +0 -0
  65. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.52.woff2 +0 -0
  66. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.53.woff2 +0 -0
  67. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.54.woff2 +0 -0
  68. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.55.woff2 +0 -0
  69. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.56.woff2 +0 -0
  70. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.57.woff2 +0 -0
  71. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.58.woff2 +0 -0
  72. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.59.woff2 +0 -0
  73. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.6.woff2 +0 -0
  74. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.60.woff2 +0 -0
  75. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.61.woff2 +0 -0
  76. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.62.woff2 +0 -0
  77. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.63.woff2 +0 -0
  78. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.64.woff2 +0 -0
  79. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.65.woff2 +0 -0
  80. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.66.woff2 +0 -0
  81. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.67.woff2 +0 -0
  82. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.68.woff2 +0 -0
  83. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.69.woff2 +0 -0
  84. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.7.woff2 +0 -0
  85. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.70.woff2 +0 -0
  86. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.71.woff2 +0 -0
  87. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.72.woff2 +0 -0
  88. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.73.woff2 +0 -0
  89. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.74.woff2 +0 -0
  90. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.75.woff2 +0 -0
  91. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.76.woff2 +0 -0
  92. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.77.woff2 +0 -0
  93. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.78.woff2 +0 -0
  94. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.79.woff2 +0 -0
  95. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.8.woff2 +0 -0
  96. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.80.woff2 +0 -0
  97. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.81.woff2 +0 -0
  98. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.82.woff2 +0 -0
  99. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.83.woff2 +0 -0
  100. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.84.woff2 +0 -0
  101. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.85.woff2 +0 -0
  102. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.86.woff2 +0 -0
  103. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.87.woff2 +0 -0
  104. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.88.woff2 +0 -0
  105. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.89.woff2 +0 -0
  106. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.9.woff2 +0 -0
  107. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.90.woff2 +0 -0
  108. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/PretendardVariable.subset.91.woff2 +0 -0
  109. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/Pretendard/Variable-dynamic-subset.min.css +0 -0
  110. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/SegoeFluentIcons.ttf +0 -0
  111. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/env.js +0 -0
  112. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/assets/2.YxEoeVwz.css +0 -0
  113. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/BQhJK30C.js +0 -0
  114. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/CUVCm1Gs.js +0 -0
  115. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/Cm7LUZmC.js +0 -0
  116. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/DenSxjN0.js +0 -0
  117. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/DoXe6v-Z.js +0 -0
  118. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/GYDIE8Th.js +0 -0
  119. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/H3JtIqnJ.js +0 -0
  120. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/chunks/IoyDzpMI.js +0 -0
  121. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/entry/app.Cls2e-Vs.js +0 -0
  122. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/entry/start.D4vOV_ze.js +0 -0
  123. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/nodes/0.DieTLBBL.js +0 -0
  124. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/nodes/1.DCNy7Bof.js +0 -0
  125. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/immutable/nodes/2.D_z1tXgZ.js +0 -0
  126. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/_app/version.json +0 -0
  127. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/pywebwinui3/web/index.html +0 -0
  128. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/requirements.txt +0 -0
  129. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/setup.cfg +0 -0
  130. {pywebwinui3-1.2.5 → pywebwinui3-1.2.6}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyWebWinUI3
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: Create modern WinUI3-style desktop UIs in Python using pywebview and a Svelte frontend.
5
5
  Home-page: https://github.com/Haruna5718/PyWebWinUI3
6
6
  Author: Haruna5718
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyWebWinUI3
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: Create modern WinUI3-style desktop UIs in Python using pywebview and a Svelte frontend.
5
5
  Home-page: https://github.com/Haruna5718/PyWebWinUI3
6
6
  Author: Haruna5718
@@ -1,3 +1,3 @@
1
1
  __all__ = ["core", "event", "util", "type"]
2
2
 
3
- __version__ = '1.2.5'
3
+ __version__ = '1.2.6'
@@ -4,16 +4,10 @@ import ctypes
4
4
  import importlib
5
5
  import json
6
6
  import logging
7
- import mimetypes
8
- import os
9
- import re
10
- import shutil
11
7
  import sys
12
8
  import threading
13
- from http import HTTPStatus
14
- from http.server import BaseHTTPRequestHandler, HTTPServer
15
9
  from pathlib import Path
16
- from urllib.parse import unquote, urlparse, urlunparse
10
+ from urllib.parse import urlparse, urlunparse
17
11
  from ctypes import wintypes
18
12
 
19
13
  import webview
@@ -32,6 +26,10 @@ DEFAULT_WINDOW_MIN_WIDTH = 100
32
26
  DEFAULT_WINDOW_MIN_HEIGHT = 100
33
27
 
34
28
 
29
+ def _virtual_host_origin(root_name: str, suffix: str) -> str:
30
+ return f"https://{root_name}.{suffix}"
31
+
32
+
35
33
  class _Point(ctypes.Structure):
36
34
  _fields_ = [
37
35
  ("x", ctypes.c_long),
@@ -119,62 +117,6 @@ def _apply_menu_theme_support(theme: str | None, hwnd: int | None = None):
119
117
  return False
120
118
 
121
119
 
122
- def _default_ui_origin_host(title: str) -> str:
123
- slug = re.sub(r"[^a-z0-9]+", "-", str(title).casefold()).strip("-")
124
- if not slug:
125
- slug = "app"
126
- slug = re.sub(r"-{2,}", "-", slug)[:48].strip("-")
127
- if not slug:
128
- slug = "app"
129
- return f"{slug}.local"
130
-
131
-
132
- class _UiHttpServer(HTTPServer):
133
- allow_reuse_address = True
134
-
135
- def __init__(self, server_address, request_handler_class, main: "MainWindow"):
136
- super().__init__(server_address, request_handler_class)
137
- self.main = main
138
-
139
-
140
- class _UiRequestHandler(BaseHTTPRequestHandler):
141
- server: _UiHttpServer
142
-
143
- def do_GET(self):
144
- try:
145
- path = self.server.main._resolve_server_path(urlparse(self.path).path)
146
- if path is None or not path.is_file():
147
- self._send_error("Not found.", HTTPStatus.NOT_FOUND)
148
- return
149
-
150
- content_type = mimetypes.guess_type(path.name)[0] or "application/octet-stream"
151
- self.send_response(HTTPStatus.OK)
152
- self._send_common_headers(content_type)
153
- self.send_header("Content-Length", str(path.stat().st_size))
154
- self.end_headers()
155
- with path.open("rb") as source:
156
- shutil.copyfileobj(source, self.wfile, length=64 * 1024)
157
- except Exception:
158
- core_logger.debug("Failed to serve UI asset", exc_info=True)
159
- self._send_error("Failed to serve UI asset.", HTTPStatus.INTERNAL_SERVER_ERROR)
160
-
161
- def log_message(self, format, *args):
162
- return
163
-
164
- def _send_error(self, message: str, status: HTTPStatus):
165
- body = message.encode("utf-8")
166
- self.send_response(status)
167
- self._send_common_headers("text/plain; charset=utf-8")
168
- self.send_header("Content-Length", str(len(body)))
169
- self.end_headers()
170
- self.wfile.write(body)
171
-
172
- def _send_common_headers(self, content_type: str):
173
- self.send_header("Content-Type", content_type)
174
- self.send_header("Cache-Control", "no-store")
175
- self.send_header("Permissions-Policy", "display-capture=*")
176
-
177
-
178
120
  class _JsApi:
179
121
  def _init(self, main:MainWindow):
180
122
  self.init = main._init_payload
@@ -200,6 +142,8 @@ class WindowEvents:
200
142
 
201
143
 
202
144
  class MainWindow:
145
+ virtual_host_suffix = "pywebwinui"
146
+
203
147
  def __init__(self, title: str, icon: str | None = None):
204
148
  self.rootPath = Path(sys._getframe(1).f_code.co_filename).parent.resolve()
205
149
  self.packagePath = Path(__file__).parent.resolve() / "web"
@@ -218,11 +162,8 @@ class MainWindow:
218
162
  self._pending_sync: dict[str, object] = {}
219
163
  self._sync_event = threading.Event()
220
164
  self._sync_thread: threading.Thread | None = None
221
- self._ui_server: _UiHttpServer | None = None
222
- self._ui_server_thread: threading.Thread | None = None
223
- self._ui_origin = ""
224
- self._ui_bind_host = "127.0.0.1"
225
- self._ui_origin_host = getattr(self, "ui_origin_host", _default_ui_origin_host(title))
165
+ self._virtual_host_handlers: dict[str, object] = {}
166
+ self._ui_origin = _virtual_host_origin("package", self.virtual_host_suffix)
226
167
  self._resource_roots: list[tuple[str, Path]] = [
227
168
  ("root", self.rootPath),
228
169
  ("package", self.packagePath),
@@ -242,13 +183,11 @@ class MainWindow:
242
183
  }
243
184
  )
244
185
  self.values.sync = self.queue_sync_value
245
- self._start_ui_server()
246
- self._configure_webview2_origin_identity()
247
186
  _apply_menu_theme_support(self.values.get("system_theme"))
248
187
 
249
188
  self._window = webview.create_window(
250
189
  self.values.get("system_title", self._title),
251
- f"{self._ui_origin}/index.html",
190
+ "about:blank",
252
191
  js_api=self.api,
253
192
  background_color="#202020",
254
193
  text_select=True,
@@ -384,82 +323,86 @@ class MainWindow:
384
323
  raise FileNotFoundError(f"Frontend entry not found: {entry}")
385
324
  return entry
386
325
 
387
- def _start_ui_server(self):
388
- self._ui_server = _UiHttpServer((self._ui_bind_host, 0), _UiRequestHandler, self)
389
- self._ui_origin = f"http://{self._ui_origin_host}:{self._ui_server.server_port}"
390
- self._ui_server_thread = threading.Thread(target=self._ui_server.serve_forever, daemon=True)
391
- self._ui_server_thread.start()
392
-
393
- def _configure_webview2_origin_identity(self):
394
- if self._ui_origin_host == self._ui_bind_host:
395
- return
326
+ def _resource_url(self, path: Path) -> str:
327
+ path = path.resolve()
328
+ for name, base_path in sorted(self._resource_roots, key=lambda item: len(item[1].parts), reverse=True):
329
+ try:
330
+ relative = path.relative_to(base_path)
331
+ except ValueError:
332
+ continue
396
333
 
397
- parsed = urlparse(self._ui_origin)
398
- if not parsed.scheme or parsed.port is None:
399
- return
334
+ return f"{_virtual_host_origin(name, self.virtual_host_suffix)}/{relative.as_posix()}"
400
335
 
401
- required_args = [
402
- f'--host-resolver-rules="MAP {self._ui_origin_host} {self._ui_bind_host}"',
403
- f"--unsafely-treat-insecure-origin-as-secure={parsed.scheme}://{self._ui_origin_host}:{parsed.port}",
404
- ]
405
- existing = os.environ.get("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "").strip()
406
- missing = [arg for arg in required_args if arg not in existing]
407
- if missing:
408
- os.environ["WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS"] = " ".join(
409
- [value for value in [existing, *missing] if value]
410
- ).strip()
411
-
412
- def _stop_ui_server(self):
413
- if self._ui_server is None:
414
- return
415
- try:
416
- self._ui_server.shutdown()
417
- self._ui_server.server_close()
418
- except Exception:
419
- core_logger.debug("Failed to stop UI server", exc_info=True)
420
- finally:
421
- self._ui_server = None
422
- self._ui_server_thread = None
423
-
424
- def _resolve_path_under(self, base_path: Path, relative_path: str) -> Path | None:
425
- candidate = (base_path / relative_path).resolve()
426
- try:
427
- candidate.relative_to(base_path)
428
- except ValueError:
429
- return None
430
- return candidate
336
+ raise ValueError(f"Path is outside of registered resource roots: {path}")
431
337
 
432
- def _resolve_server_path(self, raw_path: str) -> Path | None:
433
- path = unquote(raw_path or "/")
434
- if path in {"", "/"}:
435
- return self._entry_path()
338
+ def _map_virtual_hosts(self, core_webview):
339
+ parameter = core_webview.GetType().GetMethod("SetVirtualHostNameToFolderMapping").GetParameters()[2]
340
+ access_kind = next(
341
+ value for value in parameter.ParameterType.GetEnumValues()
342
+ if str(value) == "DenyCors"
343
+ )
436
344
 
437
345
  for name, base_path in self._resource_roots:
438
- if name == "package":
439
- continue
346
+ core_webview.SetVirtualHostNameToFolderMapping(
347
+ f"{name}.{self.virtual_host_suffix}",
348
+ str(base_path),
349
+ access_kind,
350
+ )
440
351
 
441
- prefix = f"/__{name}__/"
442
- if path.startswith(prefix):
443
- return self._resolve_path_under(base_path, path[len(prefix) :])
352
+ def _configure_virtual_host_window(self, window, target_url: str, *, show: bool = False):
353
+ native = getattr(window, "native", None)
354
+ browser = getattr(native, "browser", None)
355
+ webview_control = getattr(browser, "webview", None)
356
+ if native is None or browser is None or webview_control is None:
357
+ core_logger.debug("WebView2 is unavailable for virtual host mapping")
358
+ return
444
359
 
445
- return self._resolve_path_under(self.packagePath, path.lstrip("/"))
360
+ def load_mapped_url(core_webview):
361
+ self._map_virtual_hosts(core_webview)
362
+ browser.load_url(target_url)
363
+ if show:
364
+ window.show()
446
365
 
447
- def _resource_url(self, path: Path) -> str:
448
- path = path.resolve()
449
- for name, base_path in self._resource_roots:
366
+ def on_initialized(_, args):
450
367
  try:
451
- relative = path.relative_to(base_path)
452
- except ValueError:
453
- continue
368
+ if not args.IsSuccess:
369
+ core_logger.error("WebView2 initialization failed before virtual host mapping")
370
+ return
371
+ load_mapped_url(webview_control.CoreWebView2)
372
+ except Exception:
373
+ core_logger.error("Failed to configure WebView2 virtual host mapping", exc_info=True)
374
+ finally:
375
+ try:
376
+ webview_control.CoreWebView2InitializationCompleted -= on_initialized
377
+ except Exception:
378
+ pass
379
+ self._virtual_host_handlers.pop(window.uid, None)
454
380
 
455
- if name == "package":
456
- return f"{self._ui_origin}/{relative.as_posix()}"
457
- return f"{self._ui_origin}/__{name}__/{relative.as_posix()}"
381
+ def configure():
382
+ try:
383
+ core_webview = webview_control.CoreWebView2
384
+ except Exception:
385
+ core_webview = None
386
+ if core_webview is not None:
387
+ load_mapped_url(core_webview)
388
+ return
389
+ self._virtual_host_handlers[window.uid] = on_initialized
390
+ webview_control.CoreWebView2InitializationCompleted += on_initialized
458
391
 
459
- raise ValueError(f"Path is outside of registered resource roots: {path}")
392
+ try:
393
+ self._invoke_native_sync(native, configure)
394
+ except Exception:
395
+ core_logger.error("Failed to configure WebView2 virtual host mapping", exc_info=True)
396
+
397
+ def createResourceWindow(self, title: str, url: str, **kwargs):
398
+ keep_hidden = bool(kwargs.pop("hidden", False))
399
+ window = webview.create_window(title, "about:blank", hidden=True, **kwargs)
400
+ self._configure_virtual_host_window(window, url, show=not keep_hidden)
401
+ return window
460
402
 
461
403
  def _before_show(self):
462
404
  try:
405
+ self._configure_virtual_host_window(self._window, self._resource_url(self._entry_path()))
463
406
  hwnd = self._window.native.Handle.ToInt64()
464
407
  _apply_menu_theme_support(self.values.get("system_theme"), hwnd)
465
408
  if self._defer_window_chrome:
@@ -604,7 +547,7 @@ class MainWindow:
604
547
  with self._sync_lock:
605
548
  self._pending_sync.clear()
606
549
  self._sync_event.set()
607
- self._stop_ui_server()
550
+ self._virtual_host_handlers.clear()
608
551
  self.events.closed.set()
609
552
 
610
553
  def _dispatch_sync_values(self, values: dict[str, object]):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes