Files
ykxmz/_build/fix_image_center.py
T
xmz7891 b62ac865ea ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性
被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
2026-10-06 19:01:05 +08:00

138 lines
4.8 KiB
Python

# -*- coding: utf-8 -*-
"""投图窗口按「外框」在「工作区」里居中。
原来的写法:
x = (winfo_screenwidth() - width) // 2
y = (winfo_screenheight() - height) // 2
win.geometry(f"{width}x{height}+{x}+{y}")
两个问题:
1. winfo_reqwidth/height 是**客户区**尺寸,真正的窗口还带标题栏和边框,
所以外框会往下多出一截,看起来不是居中。
2. 用的是整屏高度,没扣任务栏 —— 任务栏常显时窗口会被挤下去。
改成:先量出真实外框,再在工作区(扣掉任务栏)里居中。
"""
from __future__ import annotations
import sys
from pathlib import Path
ACTIONS = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\windows"
r"\lanremote\actions.py")
OLD = ''' # 摆到屏幕正中间 —— 普通窗口,有标题栏和关闭按钮
win.update_idletasks()
width = win.winfo_reqwidth()
height = win.winfo_reqheight()
x = max(0, (win.winfo_screenwidth() - width) // 2)
y = max(0, (win.winfo_screenheight() - height) // 2)
win.geometry(f"{width}x{height}+{x}+{y}")
win.lift()
win.focus_force()'''
NEW = ''' # 摆到屏幕正中间 —— 普通窗口,有标题栏和关闭按钮
_place_centered(win, win.winfo_reqwidth(),
win.winfo_reqheight())'''
HELPER_ANCHOR = "class Actions:"
HELPER = '''def work_area() -> tuple:
"""屏幕工作区 (left, top, width, height) —— 已经扣掉任务栏。
直接读 SPI_GETWORKAREA,比自己猜任务栏多高靠谱。
"""
try:
import ctypes.wintypes
rect = ctypes.wintypes.RECT()
ok = ctypes.windll.user32.SystemParametersInfoW(
0x0030, 0, ctypes.byref(rect), 0) # SPI_GETWORKAREA
if ok and rect.right > rect.left and rect.bottom > rect.top:
return (rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top)
except Exception: # noqa: BLE001
pass
try:
import tkinter as tk
root = tk._default_root # noqa: SLF001
if root is not None:
return (0, 0, root.winfo_screenwidth(),
root.winfo_screenheight())
except Exception: # noqa: BLE001
pass
return (0, 0, 1920, 1080)
def _outer_size(win) -> tuple:
"""窗口的真实外框尺寸(含标题栏和边框)。
客户区尺寸不等于窗口占的地方 —— 不按外框算,看起来就不居中。
"""
try:
import ctypes
import ctypes.wintypes
hwnd = int(win.frame(), 0) # '0x00012345'
rect = ctypes.wintypes.RECT()
if ctypes.windll.user32.GetWindowRect(hwnd, ctypes.byref(rect)):
return (rect.right - rect.left, rect.bottom - rect.top,
rect.left, rect.top)
except Exception: # noqa: BLE001
pass
return (win.winfo_width(), win.winfo_height(), 0, 0)
def _place_centered(win, client_w: int, client_h: int) -> None:
"""在工作区正中间摆好这个窗口(按外框算)。"""
client_w = max(1, int(client_w))
client_h = max(1, int(client_h))
# 先放到 0,0,好量出真实外框
win.geometry(f"{client_w}x{client_h}+0+0")
win.update_idletasks()
outer_w, outer_h, outer_x, outer_y = _outer_size(win)
# 外框相对客户区多出来的部分(左边框 / 标题栏+上边框)
chrome_w = max(0, outer_w - client_w)
chrome_h = max(0, outer_h - client_h)
area_x, area_y, area_w, area_h = work_area()
x = area_x + max(0, (area_w - outer_w) // 2) + chrome_w // 2
y = area_y + max(0, (area_h - outer_h) // 2) + chrome_h - chrome_h // 2
win.geometry(f"{client_w}x{client_h}+{x}+{y}")
win.update_idletasks()
win.lift()
win.focus_force()
''' + HELPER_ANCHOR
def main() -> int:
text = ACTIONS.read_text(encoding="utf-8")
if "_place_centered" in text:
print(" 已经改过")
return 0
if OLD not in text:
print(" [失败] 定位锚点没找到")
return 1
text = text.replace(OLD, NEW, 1)
if HELPER_ANCHOR not in text:
print(" [失败] 找不到 class Actions")
return 1
text = text.replace(HELPER_ANCHOR, HELPER, 1)
ACTIONS.write_text(text, encoding="utf-8")
print(" 已改成按外框在工作区居中")
import ast
try:
ast.parse(ACTIONS.read_text(encoding="utf-8"))
print(" actions.py: 语法 OK")
except SyntaxError as exc:
print(f" actions.py: 语法错误 {exc}")
return 1
return 0
if __name__ == "__main__":
sys.exit(main())