Files
qwen-code/WEBVIEW_PIN_FEATURE.md
yiliang114 732220e651 wip(vscode-ide-companion): 实现 quick win 功能
- 将 WebView 调整到编辑器右侧
- 添加 ChatHeader 组件,实现会话下拉菜单
- 替换模态框为紧凑型下拉菜单
- 更新会话切换逻辑,显示当前标题
- 清理旧的会话选择器样式
基于 Claude Code v2.0.43 UI 分析实现。
2025-11-19 00:16:45 +08:00

8.8 KiB
Raw Blame History

WebView 固定功能实现说明

更新时间: 2025-11-18 功能: WebView 右侧固定 + Pin Tab 防止意外关闭


已实现的功能

1. WebView 固定在右侧

位置: src/WebViewProvider.ts:82-85

this.panel = vscode.window.createWebviewPanel(
  'qwenCode.chat',
  'Qwen Code Chat',
  {
    viewColumn: vscode.ViewColumn.Beside, // 在编辑器右侧打开
    preserveFocus: true, // 不抢夺编辑器焦点
  },
  // ...
);

功能说明:

  • viewColumn: vscode.ViewColumn.Beside - WebView 始终在当前编辑器的右侧打开
  • preserveFocus: true - 打开 WebView 时不会夺取焦点,用户可以继续编辑代码

用户体验:

  • 打开 WebView 时,编辑器保持焦点
  • WebView 在右侧独立列中打开
  • 可以同时查看代码和聊天界面

2. WebView Tab 自动固定

位置: src/WebViewProvider.ts:100-107

// Pin the webview tab to prevent accidental closure
// Note: This is done after panel creation to ensure it takes effect
setTimeout(() => {
  if (this.panel) {
    // Execute VSCode command to pin the active editor
    vscode.commands.executeCommand('workbench.action.pinEditor');
  }
}, 100);

功能说明:

  • 创建 WebView 后自动执行 pin 命令
  • 使用 100ms 延迟确保 panel 完全创建
  • 防止用户意外关闭 WebView tab

用户体验:

  • WebView tab 会显示 pin 图标(📌
  • 关闭其他 tab 时WebView 不会被关闭
  • 需要明确点击关闭按钮才能关闭 WebView

3. WebView 重新打开时保持位置

位置: src/WebViewProvider.ts:74-76

if (this.panel) {
  this.panel.reveal(vscode.ViewColumn.Beside, true); // preserveFocus = true
  return;
}

功能说明:

  • 如果 WebView 已存在,调用 reveal() 显示
  • 参数 vscode.ViewColumn.Beside 确保在右侧显示
  • 参数 true (preserveFocus) 不夺取焦点

用户体验:

  • 关闭后重新打开WebView 仍然在右侧
  • 多次打开不会创建多个 WebView
  • 保持用户的工作流程

🎯 与 Claude Code 的对比

功能 Claude Code 当前实现 状态
右侧打开 完全对标
不抢焦点 完全对标
Pin Tab 完全对标
记住位置 完全对标

📊 技术实现细节

ViewColumn.Beside 的行为

vscode.ViewColumn.Beside;

说明:

  • 如果当前有活动编辑器,在其右侧创建新列
  • 如果当前没有活动编辑器,在 ViewColumn.One 中打开
  • 如果已经有多列,在最右侧列的右边打开

实际效果:

┌─────────────┬─────────────┐
│             │             │
│   Code      │  WebView    │
│   Editor    │  (Pinned)   │
│   (Focus)   │             │
│             │             │
└─────────────┴─────────────┘

preserveFocus 的作用

{
  viewColumn: vscode.ViewColumn.Beside,
  preserveFocus: true  // ← 关键参数
}

功能:

  • true: 创建 WebView 时不夺取焦点,编辑器保持活动
  • false: 创建 WebView 时自动切换焦点到 WebView

用户场景:

  • 用户正在编辑代码时打开聊天,焦点仍在编辑器
  • 用户可以继续输入代码,不会被打断
  • 想要与 AI 交互时,手动点击 WebView 即可

Pin Editor 命令的作用

vscode.commands.executeCommand('workbench.action.pinEditor');

功能:

  • 固定当前活动的 editor tab
  • 防止被 workbench.action.closeOtherEditors 等命令关闭
  • 在 tab 上显示 pin 图标

VSCode 原生行为:

  • Pinned tab 会在非 pinned tab 的左侧显示
  • 关闭"其他编辑器"时pinned 的不会被关闭
  • Pinned tab 的颜色/样式可能有所不同(取决于主题)

🧪 测试建议

测试场景 1: 首次打开

步骤:

  1. 打开一个代码文件
  2. 执行命令 qwenCode.openChat
  3. 观察 WebView 位置

预期结果:

  • WebView 在右侧打开
  • 代码编辑器保持焦点
  • WebView tab 显示 pin 图标(📌

测试场景 2: 关闭后重新打开

步骤:

  1. 关闭 WebView tab
  2. 再次执行命令 qwenCode.openChat
  3. 观察 WebView 位置

预期结果:

  • WebView 再次在右侧打开
  • WebView 再次被 pin
  • 代码编辑器保持焦点

测试场景 3: 关闭其他编辑器

步骤:

  1. 打开多个代码文件和 WebView
  2. 右键点击任意 tab
  3. 选择 "关闭其他编辑器"

预期结果:

  • 其他非 pinned tab 被关闭
  • WebView (pinned) 保持打开
  • 当前 tab 和 WebView 仍然可见

测试场景 4: 切换焦点

步骤:

  1. WebView 打开后,焦点在编辑器
  2. 点击 WebView 中的输入框
  3. 输入一些文本
  4. 按 Ctrl/Cmd + 1 切换回编辑器

预期结果:

  • WebView 输入框获得焦点
  • 可以正常输入
  • 快捷键可以切换焦点
  • WebView 保持在右侧

测试场景 5: 分屏编辑器

步骤:

  1. 已经有左右分屏的编辑器
  2. 焦点在左侧编辑器
  3. 打开 WebView

预期结果:

  • WebView 在右侧编辑器的右边打开(第三列)
  • 左侧编辑器保持焦点
  • WebView 被 pin

🔧 故障排查

问题 1: WebView 没有被 pin

可能原因:

  • setTimeout 延迟不够
  • panel 还未完全创建

解决方案:

// 增加延迟到 200ms
setTimeout(() => {
  if (this.panel) {
    vscode.commands.executeCommand('workbench.action.pinEditor');
  }
}, 200);

问题 2: WebView 不在右侧打开

可能原因:

  • 没有活动编辑器
  • ViewColumn 参数错误

解决方案: 确保使用正确的参数格式:

{
  viewColumn: vscode.ViewColumn.Beside,  // ← 必须是对象属性
  preserveFocus: true
}

问题 3: WebView 抢夺焦点

可能原因:

  • preserveFocus 设置为 false 或未设置
  • reveal() 方法没有传递 preserveFocus 参数

解决方案:

// 创建时
{ viewColumn: ..., preserveFocus: true }

// 重新显示时
this.panel.reveal(vscode.ViewColumn.Beside, true);
//                                           ↑
//                                   preserveFocus

📝 代码改动总结

修改的文件

  • src/WebViewProvider.ts (修改 ~30 行)

主要改动

  1. show() 方法 (line 73-107)

    • 修改 createWebviewPanel 参数格式
    • 添加 preserveFocus: true
    • 添加自动 pin 逻辑
    • 修改 reveal() 调用参数
  2. 构造函数 (line 27-33)

    • 修复 TypeScript 警告
    • private context 改为普通参数

新增代码

  • 添加 10 行pin 逻辑和注释)

🚀 后续优化建议

优先级 P2 - 可选增强

1. 添加配置选项

建议:

// 在 package.json 中添加配置
"qwenCode.webview.autoPin": {
  "type": "boolean",
  "default": true,
  "description": "Automatically pin the WebView tab"
}

// 在代码中使用配置
const config = vscode.workspace.getConfiguration('qwenCode');
const autoPin = config.get<boolean>('webview.autoPin', true);

if (autoPin) {
  setTimeout(() => {
    vscode.commands.executeCommand('workbench.action.pinEditor');
  }, 100);
}

好处:

  • 用户可以选择是否自动 pin
  • 更灵活的用户体验

2. 记住 WebView 大小

建议:

// 在 workspace state 中保存大小
context.workspaceState.update('webview.size', {
  width: panel.viewColumn,
  height: panel.visible,
});

// 恢复时使用保存的大小
const savedSize = context.workspaceState.get('webview.size');

好处:

  • 用户调整的 WebView 大小会被记住
  • 下次打开时恢复到相同大小

3. 添加键盘快捷键

建议:

// package.json
"keybindings": [
  {
    "command": "qwenCode.openChat",
    "key": "ctrl+shift+q",
    "mac": "cmd+shift+q"
  },
  {
    "command": "qwenCode.focusChat",
    "key": "ctrl+shift+c",
    "mac": "cmd+shift+c"
  }
]

好处:

  • 快速打开/切换到 WebView
  • 提高工作效率

验收标准

功能验收

  • WebView 在右侧打开
  • 不夺取编辑器焦点
  • Tab 自动被 pin
  • 重新打开时保持位置
  • 构建无错误

用户体验验收

  • 符合用户预期
  • 不干扰编码流程
  • Pin 图标可见
  • 关闭其他编辑器时不受影响

文档版本: v1.0 创建时间: 2025-11-18 状态: 实现完成, 等待测试