mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-09-14 18:01:58 +00:00
SurfaceMouse: simplify keyToMouseShape
keyToMouseShape was initially designed with more of a transition table model in mind to handle key presses/overrides based on very specific cursor states. This never materialized, so I think it's safe to just simply the process of handling overrides and/or passing along the current cursor state from the terminal in the event of key presses. Also removed a test that is essentially a duplicate of one before it now (returning current surface shape in the event of no overrides).
This commit is contained in:
@@ -31,23 +31,10 @@ over_link: bool,
|
||||
/// True if the mouse pointer is currently hidden.
|
||||
hidden: bool,
|
||||
|
||||
/// Translates key state to mouse shape (cursor) state, based on a state
|
||||
/// machine.
|
||||
///
|
||||
/// There are 4 current states:
|
||||
///
|
||||
/// * text: starting state, displays a text bar.
|
||||
/// * default: default state when in a mouse tracking mode. (e.g. vim, etc).
|
||||
/// Displays an arrow pointer.
|
||||
/// * pointer: default state when over a link. Displays a pointing finger.
|
||||
/// * crosshair: any above state can transition to this when the rectangle
|
||||
/// select keys are pressed (ctrl/super+alt).
|
||||
///
|
||||
/// Additionally, default can transition back to text if one of the shift keys
|
||||
/// are pressed during mouse tracking mode.
|
||||
///
|
||||
/// Any secondary state transitions back to its default state when the
|
||||
/// appropriate keys are released.
|
||||
/// Translates key state to mouse shape, called during key events. This mainly
|
||||
/// handles overrides on key presses depending on whether or not we are in
|
||||
/// mouse tracking mode, however it is also responsible for resetting cursor
|
||||
/// state on any particular key releases.
|
||||
///
|
||||
/// null is returned when the mouse shape does not need changing.
|
||||
pub fn keyToMouseShape(self: SurfaceMouse) ?MouseShape {
|
||||
@@ -62,24 +49,10 @@ pub fn keyToMouseShape(self: SurfaceMouse) ?MouseShape {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set our current default state
|
||||
var current_shape_state: MouseShape = undefined;
|
||||
if (self.mouse_event != .none) {
|
||||
// In mouse tracking mode, should be default (arrow pointer)
|
||||
current_shape_state = .default;
|
||||
} else {
|
||||
// Default terminal mode, should be text (text bar)
|
||||
current_shape_state = .text;
|
||||
}
|
||||
|
||||
// Transition table.
|
||||
//
|
||||
// TODO: This could be updated eventually to be a true transition table if
|
||||
// we move to a full stateful mouse surface, e.g. very specific inputs
|
||||
// transitioning state based on previous state, versus flags like "is the
|
||||
// mouse over a link", etc.
|
||||
switch (current_shape_state) {
|
||||
.default => {
|
||||
// Handle possible overrides depending on mouse tracking state.
|
||||
switch (self.mouse_event != .none) {
|
||||
true => {
|
||||
// In mouse tracking mode
|
||||
if (isMouseModeOverrideState(self.mods) and isRectangleSelectState(self.mods)) {
|
||||
// Crosshair (rectangle select), only set if we are also
|
||||
// overriding (e.g. shift+ctrl+alt)
|
||||
@@ -87,12 +60,11 @@ pub fn keyToMouseShape(self: SurfaceMouse) ?MouseShape {
|
||||
} else if (isMouseModeOverrideState(self.mods)) {
|
||||
// Normal override state
|
||||
return .text;
|
||||
} else {
|
||||
return self.mouse_shape;
|
||||
}
|
||||
},
|
||||
|
||||
.text => {
|
||||
false => {
|
||||
// Default terminal mode
|
||||
if (isRectangleSelectState(self.mods)) {
|
||||
// Crosshair (rectangle select)
|
||||
return .crosshair;
|
||||
@@ -101,14 +73,14 @@ pub fn keyToMouseShape(self: SurfaceMouse) ?MouseShape {
|
||||
// the application cursor is not text (OSC 22). Release
|
||||
// restores mouse_shape below.
|
||||
return .text;
|
||||
} else {
|
||||
return self.mouse_shape;
|
||||
}
|
||||
},
|
||||
|
||||
// Fall back on default state
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
// No overrides means we just revert back to the stored terminal mouse
|
||||
// shape. Note that this may be different than what has been currently sent
|
||||
// to the apprt, so this will force the reset.
|
||||
return self.mouse_shape;
|
||||
}
|
||||
|
||||
fn eligibleMouseShapeKeyEvent(physical_key: input.Key) bool {
|
||||
@@ -275,22 +247,6 @@ test "keyToMouseShape" {
|
||||
try testing.expect(want == got);
|
||||
}
|
||||
|
||||
{
|
||||
// no override restores the application shape (mouse tracking)
|
||||
const m: SurfaceMouse = .{
|
||||
.physical_key = .shift_left,
|
||||
.mouse_event = .x10,
|
||||
.mouse_shape = .text,
|
||||
.mods = .{},
|
||||
.over_link = false,
|
||||
.hidden = false,
|
||||
};
|
||||
|
||||
const want: MouseShape = .text;
|
||||
const got = m.keyToMouseShape();
|
||||
try testing.expect(want == got);
|
||||
}
|
||||
|
||||
{
|
||||
// text, no mods (no mouse tracking)
|
||||
const m: SurfaceMouse = .{
|
||||
|
||||
Reference in New Issue
Block a user