mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #162 from mitchellh/mouse
Shift-Click Overrides "Grabbed" Mouse Events
This commit is contained in:
@ -1300,6 +1300,13 @@ pub fn scrollCallback(self: *Surface, xoff: f64, yoff: f64) !void {
|
|||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
|
||||||
|
// If we have an active mouse reporting mode, clear the selection.
|
||||||
|
// The selection can occur if the user uses the shift mod key to
|
||||||
|
// override mouse grabbing from the window.
|
||||||
|
if (self.io.terminal.modes.mouse_event != .none) {
|
||||||
|
self.io.terminal.screen.selection = null;
|
||||||
|
}
|
||||||
|
|
||||||
// If we're in alternate screen with alternate scroll enabled, then
|
// If we're in alternate screen with alternate scroll enabled, then
|
||||||
// we convert to cursor keys. This only happens if we're:
|
// we convert to cursor keys. This only happens if we're:
|
||||||
// (1) alt screen (2) no explicit mouse reporting and (3) alt
|
// (1) alt screen (2) no explicit mouse reporting and (3) alt
|
||||||
@ -1575,22 +1582,41 @@ pub fn mouseButtonCallback(
|
|||||||
self.mouse.click_state[@intCast(usize, @intFromEnum(button))] = action;
|
self.mouse.click_state[@intCast(usize, @intFromEnum(button))] = action;
|
||||||
self.mouse.mods = @bitCast(input.Mods, mods);
|
self.mouse.mods = @bitCast(input.Mods, mods);
|
||||||
|
|
||||||
// Shift-click continues the previous mouse state. cursorPosCallback
|
// Shift-click continues the previous mouse state if we have a selection.
|
||||||
// will also do a mouse report so we don't need to do any the logic
|
// cursorPosCallback will also do a mouse report so we don't need to do any
|
||||||
// below.
|
// of the logic below.
|
||||||
if (button == .left and action == .press) {
|
if (button == .left and action == .press) {
|
||||||
if (mods.shift and self.mouse.left_click_count > 0) {
|
if (mods.shift and self.mouse.left_click_count > 0) {
|
||||||
|
// Checking for selection requires the renderer state mutex which
|
||||||
|
// sucks but this should be pretty rare of an event so it won't
|
||||||
|
// cause a ton of contention.
|
||||||
|
const selection = selection: {
|
||||||
|
self.renderer_state.mutex.lock();
|
||||||
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
break :selection self.io.terminal.screen.selection != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (selection) {
|
||||||
const pos = try self.rt_surface.getCursorPos();
|
const pos = try self.rt_surface.getCursorPos();
|
||||||
try self.cursorPosCallback(pos);
|
try self.cursorPosCallback(pos);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
|
||||||
// Report mouse events if enabled
|
// Report mouse events if enabled
|
||||||
if (self.io.terminal.modes.mouse_event != .none) {
|
if (self.io.terminal.modes.mouse_event != .none) report: {
|
||||||
|
// Shift overrides mouse "grabbing" in the window, taken from Kitty.
|
||||||
|
if (mods.shift) break :report;
|
||||||
|
|
||||||
|
// In any other mouse button scenario without shift pressed we
|
||||||
|
// clear the selection since the underlying application can handle
|
||||||
|
// that in any way (i.e. "scrolling").
|
||||||
|
self.io.terminal.screen.selection = null;
|
||||||
|
|
||||||
const pos = try self.rt_surface.getCursorPos();
|
const pos = try self.rt_surface.getCursorPos();
|
||||||
|
|
||||||
const report_action: MouseReportAction = switch (action) {
|
const report_action: MouseReportAction = switch (action) {
|
||||||
@ -1708,7 +1734,10 @@ pub fn cursorPosCallback(
|
|||||||
defer self.renderer_state.mutex.unlock();
|
defer self.renderer_state.mutex.unlock();
|
||||||
|
|
||||||
// Do a mouse report
|
// Do a mouse report
|
||||||
if (self.io.terminal.modes.mouse_event != .none) {
|
if (self.io.terminal.modes.mouse_event != .none) report: {
|
||||||
|
// Shift overrides mouse "grabbing" in the window, taken from Kitty.
|
||||||
|
if (self.mouse.mods.shift) break :report;
|
||||||
|
|
||||||
// We use the first mouse button we find pressed in order to report
|
// We use the first mouse button we find pressed in order to report
|
||||||
// since the spec (afaict) does not say...
|
// since the spec (afaict) does not say...
|
||||||
const button: ?input.MouseButton = button: for (self.mouse.click_state, 0..) |state, i| {
|
const button: ?input.MouseButton = button: for (self.mouse.click_state, 0..) |state, i| {
|
||||||
|
Reference in New Issue
Block a user