停用 grabScrollFocus:它把列表的 ScrollPane 当 Stage.addActor 的参数传进去,导致列表被搬出面板画到窗口左下角

现象:点过面板按钮后,列表(Inspector 114 行)画在窗口左下角一小块里,面板中段只剩红/绿描边。
原因(探针实测 pid 59699):
  - 面板根表格只剩 2 个子控件(按钮块 + 日志 Label),ScrollPane 不见了;
  - ScrollPane 的父级变成 do[0,0,0x0](Stage 根),绝对坐标 (57,824);
  - grabScrollFocus 在 Stage 上找「1 个 Actor 参数 + void」当 setScrollFocus,
    只排除 dl/do/eX;但编辑器的 Stage 类 dt **自己声明** D(Ldl;)V(字节码 = root.addActor),
    于是唯一候选就是 addActor,被 invoke 后 Group.addActor 先把 ScrollPane 摘下来再挂到 Stage 根。
修复(用户选方案 B):不再调用 grabScrollFocus(滚动焦点本来就靠鼠标点列表拿到)。
复验(新进程 pid 60682,同一探针):root 子控件 = 3,ScrollPane 父级 = root,
绝对坐标 (2115,830) 回到停靠框内。
This commit is contained in:
tianmo committed 2026-10-16 18:47:34 +08:00
1 parent 7f06c6744a
commit b8e84c7aa5
1 file changed
+16 -2
+16 -2
View File
@@ -820,12 +820,23 @@ public final class ObjectPanel {
/**
* 把编辑器的**滚动焦点**抢到面板的列表上(鼠标滚轮才会滚列表)。
*
* ⚠️ 2026-10-16 已停用(用户选方案 B):不再调用。原因见下面实测——
* 它在 Stage 上找"1 个 Actor 参数 + void"的方法当 setScrollFocus,只排除了声明在
* `dl`(Actor)/`do`(Group)/`eX`(WidgetGroup) 上的方法;可**编辑器的 Stage 类 `dt`
* 自己声明了** `D(Ldl;)V`(字节码就是 `root.addActor(actor)`,即 Stage.addActor),
* 于是它成了唯一候选被调用 → ScrollPane 被 Group.addActor 先摘下来再挂到 Stage 根,
* 坐标保留局部值 (57,824) → 整块列表(114 行)被画到**窗口左下角**,
* 被 ScrollPane 自己的裁剪框裁成 400x400 一小块(就是"列表里的 UI 跑到外面")。
* 日志现场:`[panel] 没找到 setScrollFocus(候选 setter 1 个 / getter 0 个)`。
* 实测焦点本来就是靠鼠标点一下列表拿到的,不需要这段。
*
* 识别方式(不猜名字、也不会误调 addActor):
* - 只在 **Stage 自己声明的**方法里找(`uk`/`dt`/`lpt6` 这些层),
* `addActor` 声明在 Group 上、不在这一层,所以不会被误选;
* - 候选 setter = 「1 个参数是 Actor 类型、返回 void」;候选 getter = 「无参、返回 Actor 类型」;
* - 调 setter 后看哪个 getter 变成了我们的面板 —— 那就是 setScrollFocus 那一对,日志会写出来。
*/
@SuppressWarnings("unused")
static void grabScrollFocus(final State state) {
try {
Object stage = SceneObjects.global(state.loader, "uk");
@@ -1376,8 +1387,11 @@ public final class ObjectPanel {
}
try {
((Runnable) route[1]).run();
Object st = LAST_STATE;
if (st instanceof State) grabScrollFocus((State) st);
// 这里以前会调 grabScrollFocus(state) 去抢滚动焦点。
// 2026-10-16 停用:它会把列表的 ScrollPane 当成 Stage.addActor 的参数传进去,
// 结果 ScrollPane 被搬出面板、挂到 Stage 根,列表就画到窗口左下角去了
// (证据:dt.D(Ldl;)V 的字节码 = root.addActor;探针实测 root 子控件只剩 2 个)。
// 滚动焦点本来就靠鼠标点一下列表拿到,不需要这段。
} catch (Throwable error) {
System.err.println("[panel] 动作失败: " + error);
error.printStackTrace(System.err);