PyWebWinUI3 1.2.1__tar.gz → 1.2.3__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.
- {pywebwinui3-1.2.1/PyWebWinUI3.egg-info → pywebwinui3-1.2.3}/PKG-INFO +1 -1
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3/PyWebWinUI3.egg-info}/PKG-INFO +1 -1
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/PyWebWinUI3.egg-info/SOURCES.txt +6 -6
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/__init__.py +1 -1
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/core.py +347 -30
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/event.py +3 -1
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/type.py +100 -29
- pywebwinui3-1.2.1/pywebwinui3/web/_app/immutable/assets/2.B-R7-woU.css → pywebwinui3-1.2.3/pywebwinui3/web/_app/immutable/assets/2.YxEoeVwz.css +1 -1
- pywebwinui3-1.2.1/pywebwinui3/web/_app/immutable/chunks/CDNCM73h.js → pywebwinui3-1.2.3/pywebwinui3/web/_app/immutable/chunks/D94BNvJJ.js +1 -1
- pywebwinui3-1.2.1/pywebwinui3/web/_app/immutable/entry/app.DZs-LPnH.js → pywebwinui3-1.2.3/pywebwinui3/web/_app/immutable/entry/app.B-Q6XOuJ.js +2 -2
- pywebwinui3-1.2.3/pywebwinui3/web/_app/immutable/entry/start.C1-i6FUr.js +1 -0
- pywebwinui3-1.2.1/pywebwinui3/web/_app/immutable/nodes/1.CrcwixmX.js → pywebwinui3-1.2.3/pywebwinui3/web/_app/immutable/nodes/1.a96iIGzo.js +1 -1
- pywebwinui3-1.2.3/pywebwinui3/web/_app/immutable/nodes/2.Ofs4dh3G.js +142 -0
- pywebwinui3-1.2.3/pywebwinui3/web/_app/version.json +1 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/index.html +9 -9
- pywebwinui3-1.2.1/pywebwinui3/web/_app/immutable/entry/start.BIkwzMz6.js +0 -1
- pywebwinui3-1.2.1/pywebwinui3/web/_app/immutable/nodes/2.BX-aQgy_.js +0 -99
- pywebwinui3-1.2.1/pywebwinui3/web/_app/version.json +0 -1
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/LICENSE +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/MANIFEST.in +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/NOTICE +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/PyWebWinUI3.egg-info/dependency_links.txt +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/PyWebWinUI3.egg-info/requires.txt +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/PyWebWinUI3.egg-info/top_level.txt +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/README.md +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pyproject.toml +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/util.py +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.0.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.1.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.10.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.11.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.12.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.13.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.14.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.15.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.16.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.17.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.18.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.19.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.2.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.20.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.21.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.22.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.23.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.24.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.25.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.26.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.27.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.28.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.29.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.3.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.30.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.31.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.32.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.33.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.34.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.35.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.36.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.37.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.38.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.39.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.4.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.40.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.41.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.42.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.43.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.44.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.45.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.46.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.47.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.48.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.49.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.5.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.50.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.51.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.52.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.53.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.54.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.55.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.56.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.57.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.58.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.59.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.6.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.60.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.61.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.62.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.63.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.64.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.65.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.66.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.67.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.68.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.69.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.7.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.70.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.71.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.72.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.73.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.74.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.75.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.76.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.77.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.78.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.79.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.8.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.80.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.81.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.82.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.83.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.84.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.85.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.86.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.87.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.88.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.89.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.9.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.90.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/PretendardVariable.subset.91.woff2 +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/Pretendard/Variable-dynamic-subset.min.css +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/SegoeFluentIcons.ttf +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/env.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/6pQH9Hkv.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/B-XLOWlt.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/CGGCsFu4.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/CW0wlPPy.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/CZPLFskb.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/CZuXpvpo.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/chunks/DF1x2LYX.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/pywebwinui3/web/_app/immutable/nodes/0.C49PHrK2.js +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/requirements.txt +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/setup.cfg +0 -0
- {pywebwinui3-1.2.1 → pywebwinui3-1.2.3}/setup.py +0 -0
|
@@ -112,17 +112,17 @@ pywebwinui3/web/Pretendard/PretendardVariable.subset.91.woff2
|
|
|
112
112
|
pywebwinui3/web/Pretendard/Variable-dynamic-subset.min.css
|
|
113
113
|
pywebwinui3/web/_app/env.js
|
|
114
114
|
pywebwinui3/web/_app/version.json
|
|
115
|
-
pywebwinui3/web/_app/immutable/assets/2.
|
|
115
|
+
pywebwinui3/web/_app/immutable/assets/2.YxEoeVwz.css
|
|
116
116
|
pywebwinui3/web/_app/immutable/chunks/6pQH9Hkv.js
|
|
117
117
|
pywebwinui3/web/_app/immutable/chunks/B-XLOWlt.js
|
|
118
|
-
pywebwinui3/web/_app/immutable/chunks/CDNCM73h.js
|
|
119
118
|
pywebwinui3/web/_app/immutable/chunks/CGGCsFu4.js
|
|
120
119
|
pywebwinui3/web/_app/immutable/chunks/CW0wlPPy.js
|
|
121
120
|
pywebwinui3/web/_app/immutable/chunks/CZPLFskb.js
|
|
122
121
|
pywebwinui3/web/_app/immutable/chunks/CZuXpvpo.js
|
|
122
|
+
pywebwinui3/web/_app/immutable/chunks/D94BNvJJ.js
|
|
123
123
|
pywebwinui3/web/_app/immutable/chunks/DF1x2LYX.js
|
|
124
|
-
pywebwinui3/web/_app/immutable/entry/app.
|
|
125
|
-
pywebwinui3/web/_app/immutable/entry/start.
|
|
124
|
+
pywebwinui3/web/_app/immutable/entry/app.B-Q6XOuJ.js
|
|
125
|
+
pywebwinui3/web/_app/immutable/entry/start.C1-i6FUr.js
|
|
126
126
|
pywebwinui3/web/_app/immutable/nodes/0.C49PHrK2.js
|
|
127
|
-
pywebwinui3/web/_app/immutable/nodes/1.
|
|
128
|
-
pywebwinui3/web/_app/immutable/nodes/2.
|
|
127
|
+
pywebwinui3/web/_app/immutable/nodes/1.a96iIGzo.js
|
|
128
|
+
pywebwinui3/web/_app/immutable/nodes/2.Ofs4dh3G.js
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import ctypes
|
|
3
4
|
import importlib
|
|
4
5
|
import json
|
|
5
6
|
import logging
|
|
@@ -12,9 +13,10 @@ from http import HTTPStatus
|
|
|
12
13
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from urllib.parse import unquote, urlparse, urlunparse
|
|
16
|
+
from ctypes import wintypes
|
|
15
17
|
|
|
16
18
|
import webview
|
|
17
|
-
from hPyT import title_bar
|
|
19
|
+
from hPyT import title_bar, window_dwm
|
|
18
20
|
|
|
19
21
|
from .event import Event, PathEvent
|
|
20
22
|
from .type import Status
|
|
@@ -29,6 +31,93 @@ DEFAULT_WINDOW_MIN_WIDTH = 100
|
|
|
29
31
|
DEFAULT_WINDOW_MIN_HEIGHT = 100
|
|
30
32
|
|
|
31
33
|
|
|
34
|
+
class _Point(ctypes.Structure):
|
|
35
|
+
_fields_ = [
|
|
36
|
+
("x", ctypes.c_long),
|
|
37
|
+
("y", ctypes.c_long),
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
_user32 = ctypes.WinDLL("user32", use_last_error=True)
|
|
41
|
+
_kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
|
|
42
|
+
_uxtheme = ctypes.WinDLL("uxtheme", use_last_error=True)
|
|
43
|
+
|
|
44
|
+
_kernel32.GetProcAddress.argtypes = [wintypes.HMODULE, wintypes.LPCSTR]
|
|
45
|
+
_kernel32.GetProcAddress.restype = ctypes.c_void_p
|
|
46
|
+
_user32.ReleaseCapture.argtypes = []
|
|
47
|
+
_user32.ReleaseCapture.restype = ctypes.c_bool
|
|
48
|
+
_user32.GetCursorPos.argtypes = [ctypes.POINTER(_Point)]
|
|
49
|
+
_user32.GetCursorPos.restype = ctypes.c_bool
|
|
50
|
+
_user32.GetSystemMenu.argtypes = [ctypes.c_void_p, ctypes.c_bool]
|
|
51
|
+
_user32.GetSystemMenu.restype = ctypes.c_void_p
|
|
52
|
+
_user32.IsZoomed.argtypes = [ctypes.c_void_p]
|
|
53
|
+
_user32.IsZoomed.restype = ctypes.c_bool
|
|
54
|
+
_user32.PostMessageW.argtypes = [ctypes.c_void_p, ctypes.c_uint, ctypes.c_size_t, ctypes.c_ssize_t]
|
|
55
|
+
_user32.PostMessageW.restype = ctypes.c_bool
|
|
56
|
+
_user32.SendMessageW.argtypes = [ctypes.c_void_p, ctypes.c_uint, ctypes.c_size_t, ctypes.c_ssize_t]
|
|
57
|
+
_user32.SendMessageW.restype = ctypes.c_ssize_t
|
|
58
|
+
_user32.SetForegroundWindow.argtypes = [ctypes.c_void_p]
|
|
59
|
+
_user32.SetForegroundWindow.restype = ctypes.c_bool
|
|
60
|
+
_user32.ShowWindow.argtypes = [ctypes.c_void_p, ctypes.c_int]
|
|
61
|
+
_user32.ShowWindow.restype = ctypes.c_bool
|
|
62
|
+
_user32.TrackPopupMenu.argtypes = [
|
|
63
|
+
ctypes.c_void_p,
|
|
64
|
+
ctypes.c_uint,
|
|
65
|
+
ctypes.c_int,
|
|
66
|
+
ctypes.c_int,
|
|
67
|
+
ctypes.c_int,
|
|
68
|
+
ctypes.c_void_p,
|
|
69
|
+
ctypes.c_void_p,
|
|
70
|
+
]
|
|
71
|
+
_user32.TrackPopupMenu.restype = ctypes.c_uint
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _load_ordinal_function(module, ordinal: int, restype, argtypes):
|
|
75
|
+
address = _kernel32.GetProcAddress(
|
|
76
|
+
wintypes.HMODULE(module._handle),
|
|
77
|
+
ctypes.cast(ctypes.c_void_p(ordinal), wintypes.LPCSTR),
|
|
78
|
+
)
|
|
79
|
+
if not address:
|
|
80
|
+
return None
|
|
81
|
+
function = ctypes.WINFUNCTYPE(restype, *argtypes)(address)
|
|
82
|
+
function.argtypes = argtypes
|
|
83
|
+
function.restype = restype
|
|
84
|
+
return function
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
_allow_dark_mode_for_window = (
|
|
88
|
+
_load_ordinal_function(_uxtheme, 145, ctypes.c_bool, [ctypes.c_void_p, ctypes.c_bool])
|
|
89
|
+
or _load_ordinal_function(_uxtheme, 133, ctypes.c_bool, [ctypes.c_void_p, ctypes.c_bool])
|
|
90
|
+
)
|
|
91
|
+
_set_preferred_app_mode = _load_ordinal_function(_uxtheme, 135, ctypes.c_int, [ctypes.c_int])
|
|
92
|
+
_flush_menu_themes = _load_ordinal_function(_uxtheme, 136, None, [])
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _apply_menu_theme_support(theme: str | None, hwnd: int | None = None):
|
|
96
|
+
if _set_preferred_app_mode is None:
|
|
97
|
+
return False
|
|
98
|
+
try:
|
|
99
|
+
normalized = str(theme or "system").casefold()
|
|
100
|
+
if normalized == "dark":
|
|
101
|
+
mode = 2 # ForceDark
|
|
102
|
+
allow_dark = True
|
|
103
|
+
elif normalized == "light":
|
|
104
|
+
mode = 3 # ForceLight
|
|
105
|
+
allow_dark = False
|
|
106
|
+
else:
|
|
107
|
+
mode = 1 # AllowDark
|
|
108
|
+
allow_dark = True
|
|
109
|
+
|
|
110
|
+
_set_preferred_app_mode(mode)
|
|
111
|
+
if hwnd is not None and _allow_dark_mode_for_window is not None:
|
|
112
|
+
_allow_dark_mode_for_window(hwnd, allow_dark)
|
|
113
|
+
if _flush_menu_themes is not None:
|
|
114
|
+
_flush_menu_themes()
|
|
115
|
+
return True
|
|
116
|
+
except Exception:
|
|
117
|
+
core_logger.debug("Failed to apply menu theme support", exc_info=True)
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
|
|
32
121
|
def _default_ui_origin_host(title: str) -> str:
|
|
33
122
|
slug = re.sub(r"[^a-z0-9]+", "-", str(title).casefold()).strip("-")
|
|
34
123
|
if not slug:
|
|
@@ -93,6 +182,9 @@ class _JsApi:
|
|
|
93
182
|
self.syncValue = main.syncValue
|
|
94
183
|
self.syncValues = main._sync_values
|
|
95
184
|
self.pin = main.pin
|
|
185
|
+
self.startWindowDrag = main.startWindowDrag
|
|
186
|
+
self.toggleWindowMaximize = main.toggleWindowMaximize
|
|
187
|
+
self.showWindowSystemMenu = main.showWindowSystemMenu
|
|
96
188
|
self.minimize = main.minimize
|
|
97
189
|
self.destroy = main.destroy
|
|
98
190
|
self.resolveResource = main.resolveResource
|
|
@@ -101,6 +193,7 @@ class _JsApi:
|
|
|
101
193
|
class WindowEvents:
|
|
102
194
|
def __init__(self) -> None:
|
|
103
195
|
self.windowReady = Event()
|
|
196
|
+
self.closing = Event()
|
|
104
197
|
self.closed = Event()
|
|
105
198
|
self.accentColorChange = Event()
|
|
106
199
|
self.valueChange = PathEvent()
|
|
@@ -119,6 +212,8 @@ class MainWindow:
|
|
|
119
212
|
self._setup_fired = False
|
|
120
213
|
self._minimum_width = DEFAULT_WINDOW_MIN_WIDTH
|
|
121
214
|
self._minimum_height = DEFAULT_WINDOW_MIN_HEIGHT
|
|
215
|
+
self._defer_window_chrome = False
|
|
216
|
+
self._startup_cloaked = False
|
|
122
217
|
self._sync_lock = threading.Lock()
|
|
123
218
|
self._pending_sync: dict[str, object] = {}
|
|
124
219
|
self._ui_server: _UiHttpServer | None = None
|
|
@@ -141,14 +236,16 @@ class MainWindow:
|
|
|
141
236
|
"system_settings": None,
|
|
142
237
|
"system_nofication": [],
|
|
143
238
|
"system_pin": False,
|
|
239
|
+
"system_maximized": False,
|
|
144
240
|
}
|
|
145
241
|
)
|
|
146
242
|
self.values.sync = self.queue_sync_value
|
|
147
243
|
self._start_ui_server()
|
|
148
244
|
self._configure_webview2_origin_identity()
|
|
245
|
+
_apply_menu_theme_support(self.values.get("system_theme"))
|
|
149
246
|
|
|
150
247
|
self._window = webview.create_window(
|
|
151
|
-
self.
|
|
248
|
+
self.values.get("system_title", self._title),
|
|
152
249
|
f"{self._ui_origin}/index.html",
|
|
153
250
|
js_api=self.api,
|
|
154
251
|
background_color="#202020",
|
|
@@ -158,14 +255,18 @@ class MainWindow:
|
|
|
158
255
|
min_size=(self._minimum_width, self._minimum_height),
|
|
159
256
|
on_top=bool(self.values.get("system_pin", False)),
|
|
160
257
|
)
|
|
161
|
-
self.show = self.
|
|
162
|
-
self.restore = self.
|
|
163
|
-
self.hide = self.
|
|
164
|
-
self.destroy = self.
|
|
165
|
-
self.minimize = self.
|
|
258
|
+
self.show = self._show_window
|
|
259
|
+
self.restore = self._restore_window
|
|
260
|
+
self.hide = self._hide_window
|
|
261
|
+
self.destroy = self._destroy_window
|
|
262
|
+
self.minimize = self._minimize_window
|
|
166
263
|
self.api._init(self)
|
|
167
264
|
self._window.events.before_show += self._before_show
|
|
265
|
+
self._window.events.closing += self._on_closing
|
|
168
266
|
self._window.events.closed += self._on_closed
|
|
267
|
+
self._window.events.maximized += self._on_window_maximized_state
|
|
268
|
+
self._window.events.restored += self._on_window_restored_state
|
|
269
|
+
self._window.events.restored += self._on_window_restored
|
|
169
270
|
|
|
170
271
|
core_logger.debug("Window created")
|
|
171
272
|
|
|
@@ -192,6 +293,9 @@ class MainWindow:
|
|
|
192
293
|
def onSetup(self):
|
|
193
294
|
return self._event_decorator(self.events.windowReady)
|
|
194
295
|
|
|
296
|
+
def onClosing(self):
|
|
297
|
+
return self._event_decorator(self.events.closing)
|
|
298
|
+
|
|
195
299
|
def onExit(self):
|
|
196
300
|
return self._event_decorator(self.events.closed)
|
|
197
301
|
|
|
@@ -208,6 +312,8 @@ class MainWindow:
|
|
|
208
312
|
return state
|
|
209
313
|
|
|
210
314
|
def syncValue(self, key, value):
|
|
315
|
+
if key == "system_theme":
|
|
316
|
+
_apply_menu_theme_support(value, self._window_handle())
|
|
211
317
|
return self.values.set(key, value, False)
|
|
212
318
|
|
|
213
319
|
def addSettings(self, pageFile: str | Path | None = None, pageData: dict | None = None):
|
|
@@ -219,11 +325,11 @@ class MainWindow:
|
|
|
219
325
|
def addPage(self, pageFile: str | Path | None = None, pageData: dict | None = None):
|
|
220
326
|
if pageFile and not pageData:
|
|
221
327
|
pageData = loadPage(pageFile)
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
328
|
+
page_path = str(pageData["attr"]["path"])
|
|
329
|
+
logger.debug("Page added: %s", page_path)
|
|
330
|
+
if self.values["system_pages"] is None:
|
|
331
|
+
self.values["system_pages"] = {}
|
|
332
|
+
self.values.set(f"system_pages[{json.dumps(page_path, ensure_ascii=False)}]", pageData)
|
|
227
333
|
|
|
228
334
|
def resolve_path(self, value: str | Path | None) -> Path | None:
|
|
229
335
|
if value is None:
|
|
@@ -243,8 +349,14 @@ class MainWindow:
|
|
|
243
349
|
|
|
244
350
|
return root_candidate.resolve()
|
|
245
351
|
|
|
246
|
-
def
|
|
247
|
-
|
|
352
|
+
def _window_handle(self) -> int | None:
|
|
353
|
+
try:
|
|
354
|
+
native = getattr(self._window, "native", None)
|
|
355
|
+
if native is None:
|
|
356
|
+
return None
|
|
357
|
+
return int(native.Handle.ToInt64())
|
|
358
|
+
except Exception:
|
|
359
|
+
return None
|
|
248
360
|
|
|
249
361
|
def _entry_path(self) -> Path:
|
|
250
362
|
entry = (Path(self.packagePath) / "index.html").resolve()
|
|
@@ -329,23 +441,149 @@ class MainWindow:
|
|
|
329
441
|
def _before_show(self):
|
|
330
442
|
try:
|
|
331
443
|
hwnd = self._window.native.Handle.ToInt64()
|
|
332
|
-
|
|
444
|
+
_apply_menu_theme_support(self.values.get("system_theme"), hwnd)
|
|
445
|
+
if self._defer_window_chrome:
|
|
446
|
+
window_dwm.toggle_cloak(hwnd, True)
|
|
447
|
+
self._startup_cloaked = True
|
|
448
|
+
else:
|
|
449
|
+
title_bar.hide(hwnd)
|
|
450
|
+
self._set_window_maximized_state(bool(_user32.IsZoomed(hwnd)), sync=False)
|
|
333
451
|
except Exception:
|
|
334
452
|
core_logger.debug("Failed to hide title bar", exc_info=True)
|
|
335
453
|
|
|
454
|
+
def _invoke_native(self, native, callback):
|
|
455
|
+
action_type = getattr(importlib.import_module("System"), "Action")
|
|
456
|
+
if native.InvokeRequired:
|
|
457
|
+
native.BeginInvoke(action_type(callback))
|
|
458
|
+
else:
|
|
459
|
+
callback()
|
|
460
|
+
|
|
461
|
+
def _invoke_native_sync(self, native, callback):
|
|
462
|
+
action_type = getattr(importlib.import_module("System"), "Action")
|
|
463
|
+
if native.InvokeRequired:
|
|
464
|
+
native.Invoke(action_type(callback))
|
|
465
|
+
else:
|
|
466
|
+
callback()
|
|
467
|
+
|
|
468
|
+
def _invoke_native_later(self, native, callback, delay: float):
|
|
469
|
+
timer = threading.Timer(delay, lambda: self._invoke_native(native, callback))
|
|
470
|
+
timer.daemon = True
|
|
471
|
+
timer.start()
|
|
472
|
+
|
|
473
|
+
def _on_window_maximized_state(self, *_):
|
|
474
|
+
self._set_window_maximized_state(True)
|
|
475
|
+
|
|
476
|
+
def _on_window_restored_state(self, *_):
|
|
477
|
+
self._set_window_maximized_state(False)
|
|
478
|
+
|
|
479
|
+
def _on_window_restored(self):
|
|
480
|
+
self._ensure_window_chrome()
|
|
481
|
+
self._refresh_client_layout()
|
|
482
|
+
|
|
483
|
+
def _ensure_window_chrome(self, delay: float = 0.08):
|
|
484
|
+
if not self._defer_window_chrome:
|
|
485
|
+
return
|
|
486
|
+
|
|
487
|
+
self._defer_window_chrome = False
|
|
488
|
+
native = getattr(self._window, "native", None)
|
|
489
|
+
if native is None:
|
|
490
|
+
return
|
|
491
|
+
|
|
492
|
+
def _apply():
|
|
493
|
+
try:
|
|
494
|
+
hwnd = int(native.Handle.ToInt64())
|
|
495
|
+
_apply_menu_theme_support(self.values.get("system_theme"), hwnd)
|
|
496
|
+
if self._startup_cloaked:
|
|
497
|
+
window_dwm.toggle_cloak(hwnd, False)
|
|
498
|
+
self._startup_cloaked = False
|
|
499
|
+
try:
|
|
500
|
+
title_bar.unhide(hwnd)
|
|
501
|
+
except Exception:
|
|
502
|
+
pass
|
|
503
|
+
title_bar.hide(hwnd)
|
|
504
|
+
self._set_window_maximized_state(bool(_user32.IsZoomed(hwnd)), sync=False)
|
|
505
|
+
except Exception:
|
|
506
|
+
core_logger.debug("Failed to ensure window chrome", exc_info=True)
|
|
507
|
+
|
|
508
|
+
self._invoke_native_later(native, _apply, delay)
|
|
509
|
+
|
|
510
|
+
def _refresh_client_layout(self, delay: float = 0.08):
|
|
511
|
+
native = getattr(self._window, "native", None)
|
|
512
|
+
if native is None:
|
|
513
|
+
return
|
|
514
|
+
|
|
515
|
+
forms = importlib.import_module("System.Windows.Forms")
|
|
516
|
+
|
|
517
|
+
def _apply():
|
|
518
|
+
try:
|
|
519
|
+
native.SuspendLayout()
|
|
520
|
+
webview_control = getattr(native, "webview", None)
|
|
521
|
+
if webview_control is not None:
|
|
522
|
+
webview_control.Dock = forms.DockStyle.Fill
|
|
523
|
+
webview_control.Bounds = native.ClientRectangle
|
|
524
|
+
webview_control.BringToFront()
|
|
525
|
+
webview_control.Invalidate()
|
|
526
|
+
webview_control.Update()
|
|
527
|
+
native.PerformLayout()
|
|
528
|
+
native.Invalidate(True)
|
|
529
|
+
native.Refresh()
|
|
530
|
+
except Exception:
|
|
531
|
+
core_logger.debug("Failed to refresh client layout", exc_info=True)
|
|
532
|
+
finally:
|
|
533
|
+
try:
|
|
534
|
+
native.ResumeLayout(True)
|
|
535
|
+
except Exception:
|
|
536
|
+
pass
|
|
537
|
+
|
|
538
|
+
self._invoke_native_later(native, _apply, delay)
|
|
539
|
+
|
|
540
|
+
def _show_window(self):
|
|
541
|
+
native = getattr(self._window, "native", None)
|
|
542
|
+
if native is None:
|
|
543
|
+
self._window.show()
|
|
544
|
+
else:
|
|
545
|
+
self._invoke_native_sync(native, self._window.show)
|
|
546
|
+
self._ensure_window_chrome()
|
|
547
|
+
self._refresh_client_layout()
|
|
548
|
+
|
|
549
|
+
def _restore_window(self):
|
|
550
|
+
native = getattr(self._window, "native", None)
|
|
551
|
+
if native is None:
|
|
552
|
+
self._window.restore()
|
|
553
|
+
else:
|
|
554
|
+
self._invoke_native_sync(native, self._window.restore)
|
|
555
|
+
self._ensure_window_chrome()
|
|
556
|
+
self._refresh_client_layout()
|
|
557
|
+
|
|
558
|
+
def _hide_window(self):
|
|
559
|
+
native = getattr(self._window, "native", None)
|
|
560
|
+
if native is None:
|
|
561
|
+
self._window.hide()
|
|
562
|
+
return
|
|
563
|
+
self._invoke_native_sync(native, self._window.hide)
|
|
564
|
+
|
|
565
|
+
def _destroy_window(self):
|
|
566
|
+
native = getattr(self._window, "native", None)
|
|
567
|
+
if native is None:
|
|
568
|
+
self._window.destroy()
|
|
569
|
+
return
|
|
570
|
+
self._invoke_native_sync(native, self._window.destroy)
|
|
571
|
+
|
|
572
|
+
def _minimize_window(self):
|
|
573
|
+
native = getattr(self._window, "native", None)
|
|
574
|
+
if native is None:
|
|
575
|
+
self._window.minimize()
|
|
576
|
+
return
|
|
577
|
+
self._invoke_native_sync(native, self._window.minimize)
|
|
578
|
+
|
|
579
|
+
def _on_closing(self, *_):
|
|
580
|
+
return not self.events.closing.set()
|
|
581
|
+
|
|
336
582
|
def _on_closed(self):
|
|
337
583
|
self.accent.stop()
|
|
338
584
|
self._stop_ui_server()
|
|
339
585
|
self.events.closed.set()
|
|
340
586
|
|
|
341
|
-
def _dispatch_or_defer_sync(self, key: str, value):
|
|
342
|
-
with self._sync_lock:
|
|
343
|
-
if not self._frontend_ready:
|
|
344
|
-
self._pending_sync[key] = value
|
|
345
|
-
return
|
|
346
|
-
|
|
347
|
-
self._dispatch_sync_value(key, value)
|
|
348
|
-
|
|
349
587
|
def _dispatch_sync_value(self, key: str, value):
|
|
350
588
|
if key == "system_title":
|
|
351
589
|
try:
|
|
@@ -362,7 +600,22 @@ class MainWindow:
|
|
|
362
600
|
core_logger.debug("Failed to sync value %s", key, exc_info=True)
|
|
363
601
|
|
|
364
602
|
def queue_sync_value(self, key: str, value):
|
|
365
|
-
self.
|
|
603
|
+
with self._sync_lock:
|
|
604
|
+
if not self._frontend_ready:
|
|
605
|
+
self._pending_sync[key] = value
|
|
606
|
+
return
|
|
607
|
+
|
|
608
|
+
self._dispatch_sync_value(key, value)
|
|
609
|
+
|
|
610
|
+
def _set_window_maximized_state(self, value: bool, *, sync: bool = True):
|
|
611
|
+
value = bool(value)
|
|
612
|
+
if self.values.get("system_maximized") == value:
|
|
613
|
+
return
|
|
614
|
+
self.values.set("system_maximized", value, False)
|
|
615
|
+
if sync:
|
|
616
|
+
timer = threading.Timer(0.01, lambda: self.queue_sync_value("system_maximized", value))
|
|
617
|
+
timer.daemon = True
|
|
618
|
+
timer.start()
|
|
366
619
|
|
|
367
620
|
def _init_payload(self):
|
|
368
621
|
return dict(self.values)
|
|
@@ -399,18 +652,79 @@ class MainWindow:
|
|
|
399
652
|
self._window.on_top = state
|
|
400
653
|
return
|
|
401
654
|
|
|
402
|
-
action_type = getattr(importlib.import_module("System"), "Action")
|
|
403
|
-
|
|
404
655
|
def _apply():
|
|
405
656
|
self._window.on_top = state
|
|
406
657
|
|
|
407
|
-
|
|
408
|
-
native.BeginInvoke(action_type(_apply))
|
|
409
|
-
else:
|
|
410
|
-
_apply()
|
|
658
|
+
self._invoke_native(native, _apply)
|
|
411
659
|
except Exception:
|
|
412
660
|
core_logger.debug("Failed to set window on top", exc_info=True)
|
|
413
661
|
|
|
662
|
+
def startWindowDrag(self):
|
|
663
|
+
try:
|
|
664
|
+
native = getattr(self._window, "native", None)
|
|
665
|
+
if native is None:
|
|
666
|
+
return
|
|
667
|
+
|
|
668
|
+
def _apply():
|
|
669
|
+
hwnd = int(native.Handle.ToInt64())
|
|
670
|
+
_user32.ReleaseCapture()
|
|
671
|
+
_user32.SendMessageW(hwnd, 0x00A1, 2, 0) # WM_NCLBUTTONDOWN, HTCAPTION
|
|
672
|
+
|
|
673
|
+
self._invoke_native(native, _apply)
|
|
674
|
+
except Exception:
|
|
675
|
+
core_logger.debug("Failed to start system window drag", exc_info=True)
|
|
676
|
+
|
|
677
|
+
def toggleWindowMaximize(self):
|
|
678
|
+
try:
|
|
679
|
+
native = getattr(self._window, "native", None)
|
|
680
|
+
if native is None:
|
|
681
|
+
return
|
|
682
|
+
|
|
683
|
+
def _apply():
|
|
684
|
+
hwnd = int(native.Handle.ToInt64())
|
|
685
|
+
is_zoomed = bool(_user32.IsZoomed(hwnd))
|
|
686
|
+
command = 9 if is_zoomed else 3 # SW_RESTORE / SW_MAXIMIZE
|
|
687
|
+
_user32.ShowWindow(hwnd, command)
|
|
688
|
+
|
|
689
|
+
self._invoke_native(native, _apply)
|
|
690
|
+
except Exception:
|
|
691
|
+
core_logger.debug("Failed to toggle window maximize", exc_info=True)
|
|
692
|
+
|
|
693
|
+
def showWindowSystemMenu(self):
|
|
694
|
+
try:
|
|
695
|
+
native = getattr(self._window, "native", None)
|
|
696
|
+
if native is None:
|
|
697
|
+
return
|
|
698
|
+
|
|
699
|
+
def _apply():
|
|
700
|
+
hwnd = int(native.Handle.ToInt64())
|
|
701
|
+
menu = _user32.GetSystemMenu(hwnd, False)
|
|
702
|
+
if not menu:
|
|
703
|
+
return
|
|
704
|
+
_apply_menu_theme_support(self.values.get("system_theme"), hwnd)
|
|
705
|
+
|
|
706
|
+
cursor = _Point()
|
|
707
|
+
if not _user32.GetCursorPos(ctypes.byref(cursor)):
|
|
708
|
+
return
|
|
709
|
+
|
|
710
|
+
_user32.SetForegroundWindow(hwnd)
|
|
711
|
+
command = _user32.TrackPopupMenu(
|
|
712
|
+
menu,
|
|
713
|
+
0x0100 | 0x0002, # TPM_RETURNCMD | TPM_RIGHTBUTTON
|
|
714
|
+
cursor.x,
|
|
715
|
+
cursor.y,
|
|
716
|
+
0,
|
|
717
|
+
hwnd,
|
|
718
|
+
None,
|
|
719
|
+
)
|
|
720
|
+
if command:
|
|
721
|
+
_user32.PostMessageW(hwnd, 0x0112, command, 0) # WM_SYSCOMMAND
|
|
722
|
+
_user32.PostMessageW(hwnd, 0x0000, 0, 0) # WM_NULL
|
|
723
|
+
|
|
724
|
+
self._invoke_native(native, _apply)
|
|
725
|
+
except Exception:
|
|
726
|
+
core_logger.debug("Failed to show window system menu", exc_info=True)
|
|
727
|
+
|
|
414
728
|
def get_window_size(self) -> tuple[int, int]:
|
|
415
729
|
width = int(getattr(self._window, "initial_width", DEFAULT_WINDOW_WIDTH))
|
|
416
730
|
height = int(getattr(self._window, "initial_height", DEFAULT_WINDOW_HEIGHT))
|
|
@@ -463,6 +777,7 @@ class MainWindow:
|
|
|
463
777
|
debug: bool = False,
|
|
464
778
|
*,
|
|
465
779
|
hidden: bool = False,
|
|
780
|
+
minimized: bool = False,
|
|
466
781
|
on_top: bool | None = None,
|
|
467
782
|
width: int | None = None,
|
|
468
783
|
height: int | None = None,
|
|
@@ -473,7 +788,9 @@ class MainWindow:
|
|
|
473
788
|
self._minimum_width = max(1, int(min_width))
|
|
474
789
|
self._minimum_height = max(1, int(min_height))
|
|
475
790
|
self._window.min_size = (self._minimum_width, self._minimum_height)
|
|
791
|
+
self._defer_window_chrome = bool(hidden or minimized)
|
|
476
792
|
self._window.hidden = bool(hidden)
|
|
793
|
+
self._window.minimized = bool(minimized and not hidden)
|
|
477
794
|
|
|
478
795
|
if width is not None and height is not None:
|
|
479
796
|
width = max(self._minimum_width, int(width))
|
|
@@ -12,11 +12,13 @@ class Event:
|
|
|
12
12
|
self.items: list[Callable[..., Any]] = []
|
|
13
13
|
|
|
14
14
|
def set(self, *args: Any):
|
|
15
|
+
result = False
|
|
15
16
|
for func in tuple(self.items):
|
|
16
17
|
try:
|
|
17
|
-
func(*args)
|
|
18
|
+
result = bool(func(*args)) or result
|
|
18
19
|
except Exception:
|
|
19
20
|
logger.exception("Event callback failed")
|
|
21
|
+
return result
|
|
20
22
|
|
|
21
23
|
def _add(self, item: Callable[..., Any]):
|
|
22
24
|
self.items.append(item)
|