@@ -28,6 +28,7 @@ import (
2828 "charm.land/glamour/v2"
2929 "charm.land/glamour/v2/styles"
3030 "charm.land/lipgloss/v2"
31+ "github.com/atotto/clipboard"
3132 "github.com/charmbracelet/x/ansi"
3233)
3334
@@ -209,6 +210,10 @@ type model struct {
209210 plan * planState
210211 planKind string // 当前 plan 来源:"todo"(Todo)/ "createplan"(CreatePlan),右栏分段显示用
211212
213+ // mousePassthrough 为 true 时,在 View() 中关掉鼠标捕获(MouseModeNone),
214+ // 让终端原生处理右键粘贴与文字选择。用 F2 切换。
215+ mousePassthrough bool
216+
212217 // 鼠标 chat 矩形选区。selecting=true 表示左键在 chat 区按下后还没松开;
213218 // selAnchor / selEnd 是选区两端 (cellPos: 显示列 + wrapped 行号)。
214219 // 松开左键时:抠出选区内文本写到系统剪贴板,然后 selecting=false 高亮自动消失。
@@ -1460,6 +1465,16 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
14601465 return m , nil
14611466 }
14621467 if msg .Button != tea .MouseLeft {
1468+ // 右键点击输入区 → 读取剪贴板文本并粘贴
1469+ if msg .Button == tea .MouseRight {
1470+ leftW , vpH := m .layout ()
1471+ inInput := msg .Y >= vpH && msg .Y < m .height && msg .X >= 0 && msg .X < leftW
1472+ if inInput {
1473+ if text , err := clipboard .ReadAll (); err == nil && text != "" {
1474+ m .input .InsertString (text )
1475+ }
1476+ }
1477+ }
14631478 return m , nil
14641479 }
14651480 leftW , vpH := m .layout ()
@@ -2477,6 +2492,17 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
24772492 // 显示/隐藏右侧状态栏(chat 铺满整宽);记忆到 meta。
24782493 m .toggleStatusPanel ()
24792494 return m , nil
2495+ case "f2" :
2496+ // 切换鼠标穿透模式:关掉 MouseMode,让终端原生处理右键粘贴和文字选择。
2497+ m .mousePassthrough = ! m .mousePassthrough
2498+ hint := "鼠标"
2499+ if m .mousePassthrough {
2500+ hint += "穿透已开启(终端原生选择/粘贴)"
2501+ } else {
2502+ hint += "捕获已恢复(deepx 选区/复制)"
2503+ }
2504+ m .appendChat ("System" , hint )
2505+ return m , nil
24802506 case "ctrl+v" :
24812507 // 剪贴板有图就落盘并插入到输入框;没图则下落到 textinput 走文本粘贴。
24822508 if data , err := readClipboardImage (); err == nil {
0 commit comments