diff --git a/Apps/Explorer/desk_server.vp b/Apps/Explorer/desk_server.vp index 066dda5..7b676a2 100644 --- a/Apps/Explorer/desk_server.vp +++ b/Apps/Explorer/desk_server.vp @@ -459,6 +459,8 @@ class DeskServer: for i in range(desk.DESK_MAX_WIN): s: desk.WinSlot* = self.slot(i) if s.used == 0: + # 槽位复用前整块清零:避免上一任窗口的 pid/几何/缓冲区偏移残留。 + string.memset(s, 0, desk.desk_slot_size()) cap_px: int = w * content_h buf_off: uint32 = desk.desk_arena_alloc(self.shm, uint32(cap_px) * uint32(4)) if buf_off == uint32(0): return -1 @@ -1202,6 +1204,10 @@ class DeskServer: buf: uint32* = uint32*(self.shm + uint64(s.fb_off)) fw: int = int(s.fb_w) fh: int = int(s.fb_h) + # 槽表被写坏时宁可跳过该窗口,也不要按越界 fb_off 读像素把整个合成器带崩。 + need_bytes: uint64 = uint64(fw) * uint64(fh) * uint64(4) + if s.fb_off < uint32(desk.DESK_OFF_ARENA) or uint64(s.fb_off) + need_bytes > uint64(desk.DESK_SHM_SIZE): + return content_y0: int = wy + th + TITLE_GAP r: int = WIN_RADIUS yy: int = y0 diff --git a/vpsdk/desk.vp b/vpsdk/desk.vp index bb0bf15..f9f0e74 100644 --- a/vpsdk/desk.vp +++ b/vpsdk/desk.vp @@ -29,7 +29,7 @@ from stdint import * # 32MB:1920×1080 全屏窗口的内容缓冲约 7.3MB,最大化需要足够 arena。 define DESK_SHM_SIZE = 33554432 define DESK_MAGIC = 0x4B534544 # 'DESK' -define DESK_VERSION = 1 +define DESK_VERSION = 2 # WinSlot 布局变更必须 +1,旧 app 拒绝挂载 define DESK_MAX_WIN = 8 define DESK_TITLE_MAX = 32 @@ -213,6 +213,9 @@ def desk_map(fd: int) -> uint64: def desk_format(base: uint64, fb_w: uint32, fb_h: uint32, fb_pitch: uint32): """explorer 专用:初始化共享区头与各环。""" + # 先清空整个控制区(头 + 窗口槽表 + 各环):共享区来自 mm.malloc,不能假设为 0。 + # 否则槽表里的随机 used/active 会被当成"多出来的窗口",合成器还会按垃圾 fb_off 取像素。 + string.memset(rawptr(base), 0, uint64(DESK_OFF_ARENA)) h: DeskHeader* = DeskHeader*(base + desk_header_off()) string.memset(h, 0, DeskHeader.__sizeof__()) h.magic = uint32(DESK_MAGIC) @@ -236,6 +239,10 @@ def desk_ready(base: uint64) -> int: h: DeskHeader* = DeskHeader*(base + desk_header_off()) if h.magic != uint32(DESK_MAGIC): return 0 + # 共享结构布局变了(WinSlot 增字段)就拒绝挂载:旧 app 按错偏移读写会把 + # 头部/槽表/别人的像素缓冲写坏,比"连不上"危险得多。 + if h.version != uint32(DESK_VERSION): + return 0 return h.ready def desk_arena_alloc(base: uint64, size: uint32) -> uint32: