mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-06 03:18:19 +00:00
core: only update selection clipboard on left mouse release
Fixes #4800, supercedes #5995 This is a rewrite of #5995 (though the solution is mostly the same since this is pretty straightforward). The main difference is the rebase on the new mouse handling we've had since, and I also continue to update the selection clipboard on non-left-mouse events.
This commit is contained in:
@@ -3094,10 +3094,27 @@ pub fn mouseButtonCallback(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (button == .left and action == .release) {
|
||||||
|
// The selection clipboard is only updated for left-click drag when
|
||||||
|
// the left button is released. This is to avoid the clipboard
|
||||||
|
// being updated on every mouse move which would be noisy.
|
||||||
|
if (self.config.copy_on_select != .false) {
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
const prev_ = self.io.terminal.screen.selection;
|
||||||
|
if (prev_) |prev| {
|
||||||
|
try self.setSelection(terminal.Selection.init(
|
||||||
|
prev.start(),
|
||||||
|
prev.end(),
|
||||||
|
false,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle link clicking. We want to do this before we do mouse
|
// Handle link clicking. We want to do this before we do mouse
|
||||||
// reporting or any other mouse handling because a successfully
|
// reporting or any other mouse handling because a successfully
|
||||||
// clicked link will swallow the event.
|
// clicked link will swallow the event.
|
||||||
if (button == .left and action == .release and self.mouse.over_link) {
|
if (self.mouse.over_link) {
|
||||||
const pos = try self.rt_surface.getCursorPos();
|
const pos = try self.rt_surface.getCursorPos();
|
||||||
if (self.processLinks(pos)) |processed| {
|
if (self.processLinks(pos)) |processed| {
|
||||||
if (processed) return true;
|
if (processed) return true;
|
||||||
@@ -3105,6 +3122,7 @@ pub fn mouseButtonCallback(
|
|||||||
log.warn("error processing links err={}", .{err});
|
log.warn("error processing links err={}", .{err});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Report mouse events if enabled
|
// Report mouse events if enabled
|
||||||
{
|
{
|
||||||
@@ -3238,12 +3256,16 @@ pub fn mouseButtonCallback(
|
|||||||
log.err("error reading time, mouse multi-click won't work err={}", .{err});
|
log.err("error reading time, mouse multi-click won't work err={}", .{err});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In all cases below, we set the selection directly rather than use
|
||||||
|
// `setSelection` because we want to avoid copying the selection
|
||||||
|
// to the selection clipboard. For left mouse clicks we only set
|
||||||
|
// the clipboard on release.
|
||||||
switch (self.mouse.left_click_count) {
|
switch (self.mouse.left_click_count) {
|
||||||
// Single click
|
// Single click
|
||||||
1 => {
|
1 => {
|
||||||
// If we have a selection, clear it. This always happens.
|
// If we have a selection, clear it. This always happens.
|
||||||
if (self.io.terminal.screen.selection != null) {
|
if (self.io.terminal.screen.selection != null) {
|
||||||
try self.setSelection(null);
|
try self.io.terminal.screen.select(null);
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3252,7 +3274,7 @@ pub fn mouseButtonCallback(
|
|||||||
2 => {
|
2 => {
|
||||||
const sel_ = self.io.terminal.screen.selectWord(pin.*);
|
const sel_ = self.io.terminal.screen.selectWord(pin.*);
|
||||||
if (sel_) |sel| {
|
if (sel_) |sel| {
|
||||||
try self.setSelection(sel);
|
try self.io.terminal.screen.select(sel);
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3264,7 +3286,7 @@ pub fn mouseButtonCallback(
|
|||||||
else
|
else
|
||||||
self.io.terminal.screen.selectLine(.{ .pin = pin.* });
|
self.io.terminal.screen.selectLine(.{ .pin = pin.* });
|
||||||
if (sel_) |sel| {
|
if (sel_) |sel| {
|
||||||
try self.setSelection(sel);
|
try self.io.terminal.screen.select(sel);
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3549,7 +3571,7 @@ pub fn mousePressureCallback(
|
|||||||
// to handle state inconsistency here.
|
// to handle state inconsistency here.
|
||||||
const pin = self.mouse.left_click_pin orelse break :select;
|
const pin = self.mouse.left_click_pin orelse break :select;
|
||||||
const sel = self.io.terminal.screen.selectWord(pin.*) orelse break :select;
|
const sel = self.io.terminal.screen.selectWord(pin.*) orelse break :select;
|
||||||
try self.setSelection(sel);
|
try self.io.terminal.screen.select(sel);
|
||||||
try self.queueRender();
|
try self.queueRender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3768,13 +3790,13 @@ fn dragLeftClickDouble(
|
|||||||
// If our current mouse position is before the starting position,
|
// If our current mouse position is before the starting position,
|
||||||
// then the selection start is the word nearest our current position.
|
// then the selection start is the word nearest our current position.
|
||||||
if (drag_pin.before(click_pin)) {
|
if (drag_pin.before(click_pin)) {
|
||||||
try self.setSelection(terminal.Selection.init(
|
try self.io.terminal.screen.select(.init(
|
||||||
word_current.start(),
|
word_current.start(),
|
||||||
word_start.end(),
|
word_start.end(),
|
||||||
false,
|
false,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
try self.setSelection(terminal.Selection.init(
|
try self.io.terminal.screen.select(.init(
|
||||||
word_start.start(),
|
word_start.start(),
|
||||||
word_current.end(),
|
word_current.end(),
|
||||||
false,
|
false,
|
||||||
@@ -3806,7 +3828,7 @@ fn dragLeftClickTriple(
|
|||||||
} else {
|
} else {
|
||||||
sel.endPtr().* = line.end();
|
sel.endPtr().* = line.end();
|
||||||
}
|
}
|
||||||
try self.setSelection(sel);
|
try self.io.terminal.screen.select(sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dragLeftClickSingle(
|
fn dragLeftClickSingle(
|
||||||
@@ -3815,7 +3837,7 @@ fn dragLeftClickSingle(
|
|||||||
drag_x: f64,
|
drag_x: f64,
|
||||||
) !void {
|
) !void {
|
||||||
// This logic is in a separate function so that it can be unit tested.
|
// This logic is in a separate function so that it can be unit tested.
|
||||||
try self.setSelection(mouseSelection(
|
try self.io.terminal.screen.select(mouseSelection(
|
||||||
self.mouse.left_click_pin.?.*,
|
self.mouse.left_click_pin.?.*,
|
||||||
drag_pin,
|
drag_pin,
|
||||||
@intFromFloat(@max(0.0, self.mouse.left_click_xpos)),
|
@intFromFloat(@max(0.0, self.mouse.left_click_xpos)),
|
||||||
|
Reference in New Issue
Block a user