본문 바로가기
리눅스

Ghostty 터미널 Copy-to-clipboard 메시지 패치.

by 다움위키 2025. 2. 11.

새로운 ghostty 터미널도 나름의 장점을 갖고 있기 때문에, 계속 사용해 보려고 시도 중입니다.

 

그런데, 터미널에 출력된 메지시를 마우스로 드래그를 하면, 터미널 하단 중앙부에 'copy-to-clipboard' 메시지가 아주 많이 출력되어서 명령이 제래도 입력되고 있는지 확인하기가 힘듭니다.

 

이 문제는 이미 알려져 있고, 패치가 제공되었습니다. 아마도 1.1.1 정도에 적용될 것으로 기대됩니다.

패치 형태가 필요하신 분들은 ...

--- aaa/src/Surface.zig.dist	2025-02-10 23:07:33.387763638 +0900
+++ bbb/src/Surface.zig	2025-02-10 23:11:14.667208314 +0900
@@ -1396,67 +1396,7 @@
 ///
 /// This must be called with the renderer mutex held.
 fn setSelection(self: *Surface, sel_: ?terminal.Selection) !void {
-    const prev_ = self.io.terminal.screen.selection;
     try self.io.terminal.screen.select(sel_);
-
-    // If copy on select is false then exit early.
-    if (self.config.copy_on_select == .false) return;
-
-    // Set our selection clipboard. If the selection is cleared we do not
-    // clear the clipboard. If the selection is set, we only set the clipboard
-    // again if it changed, since setting the clipboard can be an expensive
-    // operation.
-    const sel = sel_ orelse return;
-    if (prev_) |prev| if (sel.eql(prev)) return;
-
-    const buf = self.io.terminal.screen.selectionString(self.alloc, .{
-        .sel = sel,
-        .trim = self.config.clipboard_trim_trailing_spaces,
-    }) catch |err| {
-        log.err("error reading selection string err={}", .{err});
-        return;
-    };
-    defer self.alloc.free(buf);
-
-    // Set the clipboard. This is not super DRY but it is clear what
-    // we're doing for each setting without being clever.
-    switch (self.config.copy_on_select) {
-        .false => unreachable, // handled above with an early exit
-
-        // Both standard and selection clipboards are set.
-        .clipboard => {
-            const clipboards: []const apprt.Clipboard = &.{ .standard, .selection };
-            for (clipboards) |clipboard| self.rt_surface.setClipboardString(
-                buf,
-                clipboard,
-                false,
-            ) catch |err| {
-                log.err(
-                    "error setting clipboard string clipboard={} err={}",
-                    .{ clipboard, err },
-                );
-            };
-        },
-
-        // The selection clipboard is set if supported, otherwise the standard.
-        .true => {
-            const clipboard: apprt.Clipboard = if (self.rt_surface.supportsClipboard(.selection))
-                .selection
-            else
-                .standard;
-
-            self.rt_surface.setClipboardString(
-                buf,
-                clipboard,
-                false,
-            ) catch |err| {
-                log.err(
-                    "error setting clipboard string clipboard={} err={}",
-                    .{ clipboard, err },
-                );
-            };
-        },
-    }
 }
 
 /// Change the cell size for the terminal grid. This can happen as
@@ -2882,6 +2822,64 @@
         }
     }
 
+    // Set the clipboard if configured with copy_on_select
+    if (button == .left and
+        action == .release and
+        self.config.copy_on_select != .false)
+    set_clipboard: {
+        self.renderer_state.mutex.lock();
+        defer self.renderer_state.mutex.unlock();
+
+        // Only update clipboard if something is actually selected.
+        const selection = self.io.terminal.screen.selection orelse break :set_clipboard;
+
+        const buf = self.io.terminal.screen.selectionString(self.alloc, .{
+            .sel = selection,
+            .trim = self.config.clipboard_trim_trailing_spaces,
+        }) catch |err| {
+            log.err("error reading selection string err={}", .{err});
+            break :set_clipboard;
+        };
+        defer self.alloc.free(buf);
+
+        switch (self.config.copy_on_select) {
+            .false => unreachable, // should not be in this block at all
+            // Both standard and selection clipboards are set.
+            .clipboard => {
+                const clipboards: []const apprt.Clipboard = &.{ .standard, .selection };
+                for (clipboards) |clipboard| self.rt_surface.setClipboardString(
+                    buf,
+                    clipboard,
+                    false,
+                ) catch |err| {
+                    log.err(
+                        "error setting clipboard string clipboard={} err={}",
+                        .{ clipboard, err },
+                    );
+                    break :set_clipboard;
+                };
+            },
+            .true => {
+                const clipboard: apprt.Clipboard = if (self.rt_surface.supportsClipboard(.selection))
+                    .selection
+                else
+                    .standard;
+
+                self.rt_surface.setClipboardString(
+                    buf,
+                    clipboard,
+                    false,
+                ) catch |err| {
+                    log.err(
+                        "error setting clipboard string clipboard={} err={}",
+                        .{ clipboard, err },
+                    );
+                    break :set_clipboard;
+                };
+            },
+        }
+    }
+
     // Report mouse events if enabled
     {
         self.renderer_state.mutex.lock();