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

449 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WebView 固定功能实现说明
> **更新时间**: 2025-11-18
> **功能**: WebView 右侧固定 + Pin Tab 防止意外关闭
---
## ✅ 已实现的功能
### 1. WebView 固定在右侧 ✅
**位置**: `src/WebViewProvider.ts:82-85`
```typescript
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`
```typescript
// 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`
```typescript
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 的行为
```typescript
vscode.ViewColumn.Beside;
```
**说明**:
- 如果当前有活动编辑器,在其右侧创建新列
- 如果当前没有活动编辑器,在 ViewColumn.One 中打开
- 如果已经有多列,在最右侧列的右边打开
**实际效果**:
```
┌─────────────┬─────────────┐
│ │ │
│ Code │ WebView │
│ Editor │ (Pinned) │
│ (Focus) │ │
│ │ │
└─────────────┴─────────────┘
```
---
### preserveFocus 的作用
```typescript
{
viewColumn: vscode.ViewColumn.Beside,
preserveFocus: true // ← 关键参数
}
```
**功能**:
- `true`: 创建 WebView 时不夺取焦点,编辑器保持活动
- `false`: 创建 WebView 时自动切换焦点到 WebView
**用户场景**:
- ✅ 用户正在编辑代码时打开聊天,焦点仍在编辑器
- ✅ 用户可以继续输入代码,不会被打断
- ✅ 想要与 AI 交互时,手动点击 WebView 即可
---
### Pin Editor 命令的作用
```typescript
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 还未完全创建
**解决方案**:
```typescript
// 增加延迟到 200ms
setTimeout(() => {
if (this.panel) {
vscode.commands.executeCommand('workbench.action.pinEditor');
}
}, 200);
```
---
### 问题 2: WebView 不在右侧打开
**可能原因**:
- 没有活动编辑器
- ViewColumn 参数错误
**解决方案**:
确保使用正确的参数格式:
```typescript
{
viewColumn: vscode.ViewColumn.Beside, // ← 必须是对象属性
preserveFocus: true
}
```
---
### 问题 3: WebView 抢夺焦点
**可能原因**:
- `preserveFocus` 设置为 `false` 或未设置
- `reveal()` 方法没有传递 `preserveFocus` 参数
**解决方案**:
```typescript
// 创建时
{ 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. 添加配置选项
**建议**:
```typescript
// 在 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 大小
**建议**:
```typescript
// 在 workspace state 中保存大小
context.workspaceState.update('webview.size', {
width: panel.viewColumn,
height: panel.visible,
});
// 恢复时使用保存的大小
const savedSize = context.workspaceState.get('webview.size');
```
**好处**:
- 用户调整的 WebView 大小会被记住
- 下次打开时恢复到相同大小
---
#### 3. 添加键盘快捷键
**建议**:
```json
// 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
- 提高工作效率
---
## ✅ 验收标准
### 功能验收
- [x] WebView 在右侧打开
- [x] 不夺取编辑器焦点
- [x] Tab 自动被 pin
- [x] 重新打开时保持位置
- [x] 构建无错误
### 用户体验验收
- [ ] 符合用户预期
- [ ] 不干扰编码流程
- [ ] Pin 图标可见
- [ ] 关闭其他编辑器时不受影响
---
**文档版本**: v1.0
**创建时间**: 2025-11-18
**状态**: ✅ 实现完成,⏳ 等待测试