fix(ui): main window fixes - event filter, bash layer order, scrollbar styles, rename overlay

- merge duplicated eventFilter paths and gate send-by-Enter (P0-02)
- display bash task layers in reverse start-time order while reusing
  layer instances and preserving scroll/expand state (P2-01)
- add scoped 8px scrollbars with matching corner for the bash code box
  (P2-02)
- rewrite RenameOverlay as a top-level transparent tool window so it
  can cover the native WebView2 child HWND (P2-03)
This commit is contained in:
2026-09-17 16:40:04 +08:00
parent ef00f64435
commit 95024785ae
3 changed files with 592 additions and 182 deletions
+21 -9
View File
@@ -6,7 +6,10 @@
中间是可拖动分隔线(260px 宽若真做左右并排,每栏仅 ~130px,
展开区放不下「参数 + 输出」两块列表,故用上下两栏)。
若要严格左右并排:把 _SPLIT_ORIENTATION 改成 Horizontal 即可。
· 一次 bash = 一层(BashLayer),自上而下按执行先后排列
· 一次 bash = 一层(BashLayer),自上而下按【启动先后倒序】排列(P2-01
最新启动的任务在第一项;排序键恒为启动顺序,运行中→完成归位时
不按完成时间重排;已落库时间线无显式时间时,启动序号 = 消息链
顺序 + 时间线内顺序,稳定可复现)
· 单击层头 = 展开/收起;展开后分「参数」「输出」两块
· 运行中:输出为 tool_bash 的实时流(缓冲上限 200KB,超出丢弃最旧并标注)
· 已完成:输出为「进入上下文的原文」(DB messages.timeline[].result,不截断)
@@ -35,12 +38,14 @@ PANEL_W_DEFAULT = 260 # 首次运行的默认展开宽度
PANEL_W_MIN = 200 # 🆕 拖拽最小宽度(再窄「参数/输出」两块就挤坏了)
PANEL_W_MAX = 560 # 绝对上限(实际还会受「不超过主窗口 50%」约束)
_CFG_KEY = "bash_panel_width"
_CFG_PATH = os.path.join(_ROOT, "data", "config.json")
# P0-01:配置路径统一走 core.config_paths(环境变量 HAOCODE_CONFIG_FILE 优先)
from core.config_paths import config_path as _unified_config_path # noqa: E402
def _cfg_path() -> str:
"""配置文件路径(测试可用 HAOCODE_CONFIG_FILE 指向临时文件 → 绝不污染真配置)"""
return os.environ.get("HAOCODE_CONFIG_FILE") or _CFG_PATH
"""配置文件路径(P0-01 统一入口:测试可用 HAOCODE_CONFIG_FILE 指向临时文件 → 绝不污染真配置)"""
return _unified_config_path()
def load_panel_width(default: int = PANEL_W_DEFAULT) -> int:
@@ -539,7 +544,7 @@ class BashPanel(QtWidgets.QWidget):
self._session_id = None
self._db = None
self._layers = {} # call_id -> BashLayer
self._order = [] # 执行先后
self._order = [] # 稳定启动序号(0=最早启动;追加顺序 = 启动先后
self._running = set()
self._done = set()
self._saved_h = [120, 520] # 每栏收起前的高度(展开时恢复)
@@ -886,11 +891,17 @@ class BashPanel(QtWidgets.QWidget):
self._refresh()
def _refresh(self):
# P2-01:两栏都按【启动顺序倒序】显示(最新启动在第一项)。
# 排序键恒为 self._order 中的位置(稳定启动序号)——
# · 运行中→已完成 的任务仍占原启动位置(绝不按完成时间重排);
# · 已完成栏的限量窗口 = 最近启动的 LAYER_LIMIT 个(窗口成员不变,仅显示顺序反转)。
# 重排走 set_layers(复用同一批 BashLayer 实例):展开/折叠状态、实时输出、
# 代码框水平/垂直滚动值、两栏 section 滚动位置全部保持(同对象,不重建)。
run_ids = [c for c in self._order if c in self._running]
done_ids = [c for c in self._order if c in self._done]
self.sec_running.set_layers([self._layers[c] for c in run_ids])
self.sec_running.set_layers([self._layers[c] for c in reversed(run_ids)])
shown = done_ids[-LAYER_LIMIT:]
self.sec_done.set_layers([self._layers[c] for c in shown], total=len(done_ids))
self.sec_done.set_layers([self._layers[c] for c in reversed(shown)], total=len(done_ids))
self.lbl_total.setText(f"{len(self._order)}" if self._order else "")
# ---------------- 事件 ----------------
@@ -937,8 +948,9 @@ class BashPanel(QtWidgets.QWidget):
# ---------------- 测试/调试辅助 ----------------
def layer_ids(self, which="all"):
# running/done 返回真实显示顺序(启动倒序);"all" = 原始启动序号(正序)
if which == "running":
return [c for c in self._order if c in self._running]
return [c for c in self._order if c in self._running][::-1]
if which == "done":
return [c for c in self._order if c in self._done]
return [c for c in self._order if c in self._done][::-1]
return list(self._order)