fix: clicking the same char indexes in different views triggered double / triple click

pull/12514/head
Nikita Revenco 2025-01-16 16:06:13 +00:00
parent 82401d87b7
commit 056e2ffbb2
2 changed files with 21 additions and 13 deletions

View File

@ -1179,7 +1179,7 @@ impl EditorView {
let doc = doc_mut!(editor, &view!(editor, view_id).doc); let doc = doc_mut!(editor, &view!(editor, view_id).doc);
let text = doc.text().slice(..); let text = doc.text().slice(..);
let selection = match editor.mouse_clicks.register_click(pos) { let selection = match editor.mouse_clicks.register_click(pos, view_id) {
MouseClick::Single => { MouseClick::Single => {
if modifiers == KeyModifiers::ALT { if modifiers == KeyModifiers::ALT {
let selection = doc.selection(view_id).clone(); let selection = doc.selection(view_id).clone();

View File

@ -5,6 +5,7 @@ use serde::de::{self, Deserialize, Deserializer};
use std::fmt; use std::fmt;
pub use crate::keyboard::{KeyCode, KeyModifiers, MediaKeyCode, ModifierKeyCode}; pub use crate::keyboard::{KeyCode, KeyModifiers, MediaKeyCode, ModifierKeyCode};
use crate::ViewId;
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)] #[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)]
pub enum Event { pub enum Event {
@ -63,12 +64,12 @@ pub enum MouseButton {
/// Tracks the character positions where the mouse was last clicked /// Tracks the character positions where the mouse was last clicked
#[derive(Debug)] #[derive(Debug)]
pub struct MouseClicks { pub struct MouseClicks {
clicks: [Option<usize>; 2], clicks: [Option<(usize, ViewId)>; 2],
count: u8, count: u8,
} }
pub enum MouseClick { pub enum MouseClick {
/// A single click /// A click where the pressed character is different to the character previously pressed
Single, Single,
/// A click where the same character was pressed 2 times in a row /// A click where the same character was pressed 2 times in a row
Double, Double,
@ -76,6 +77,9 @@ pub enum MouseClick {
Triple, Triple,
} }
/// Stores information about the state of the mouse clicks on specific character indexes
///
/// Stores the positions of the 2 most recently clicked characters
impl MouseClicks { impl MouseClicks {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@ -85,13 +89,15 @@ impl MouseClicks {
} }
/// Registers a click for a certain character index, and returns the type of this click /// Registers a click for a certain character index, and returns the type of this click
pub fn register_click(&mut self, char_idx: usize) -> MouseClick { pub fn register_click(&mut self, char_idx: usize, view_id: ViewId) -> MouseClick {
let click_type = if self.is_triple_click(char_idx) { let click_type = if self.is_triple_click(char_idx, view_id) {
// Clicking 4th time on the same character should be the same as clicking for the 1st time
// So we reset the state
self.clicks = [None, None]; self.clicks = [None, None];
self.count = 0; self.count = 0;
return MouseClick::Triple; return MouseClick::Triple;
} else if self.is_double_click(char_idx) { } else if self.is_double_click(char_idx, view_id) {
MouseClick::Double MouseClick::Double
} else { } else {
MouseClick::Single MouseClick::Single
@ -99,16 +105,16 @@ impl MouseClicks {
match self.count { match self.count {
0 => { 0 => {
self.clicks[0] = Some(char_idx); self.clicks[0] = Some((char_idx, view_id));
self.count = 1; self.count = 1;
} }
1 => { 1 => {
self.clicks[1] = Some(char_idx); self.clicks[1] = Some((char_idx, view_id));
self.count = 2; self.count = 2;
} }
2 => { 2 => {
self.clicks[1] = self.clicks[0]; self.clicks[1] = self.clicks[0];
self.clicks[0] = Some(char_idx); self.clicks[0] = Some((char_idx, view_id));
} }
_ => unreachable!(), _ => unreachable!(),
}; };
@ -116,12 +122,14 @@ impl MouseClicks {
click_type click_type
} }
fn is_triple_click(&mut self, char_idx: usize) -> bool { /// Whether the character indexed was pressed 3 times in a row
Some(char_idx) == self.clicks[0] && Some(char_idx) == self.clicks[1] fn is_triple_click(&mut self, char_idx: usize, view_id: ViewId) -> bool {
Some((char_idx, view_id)) == self.clicks[0] && Some((char_idx, view_id)) == self.clicks[1]
} }
fn is_double_click(&mut self, char_idx: usize) -> bool { /// The 2 most recent clicks were on the same character, and the 1 click before that was on a different character
Some(char_idx) == self.clicks[0] && Some(char_idx) != self.clicks[1] fn is_double_click(&mut self, char_idx: usize, view_id: ViewId) -> bool {
Some((char_idx, view_id)) == self.clicks[0] && Some((char_idx, view_id)) != self.clicks[1]
} }
} }