From 6809b92e34bb038f8e0486dcd7dd471384aafccb Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 10 Jan 2024 10:16:09 +0200 Subject: [PATCH] Disable synthetic drag on drag and drop Otherwise, conflicting MouseMove events are generated and page regions start to flicker. --- crates/gpui/src/platform/mac/window.rs | 27 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 2beac528c1..6d03a3b5cd 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -338,6 +338,7 @@ struct MacWindowState { ime_state: ImeState, // Retains the last IME Text ime_text: Option, + external_files_dragged: bool, } impl MacWindowState { @@ -567,6 +568,7 @@ impl MacWindow { previous_modifiers_changed_event: None, ime_state: ImeState::None, ime_text: None, + external_files_dragged: false, }))); (*native_window).set_ivar( @@ -1223,15 +1225,20 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) { .. }, ) => { - lock.synthetic_drag_counter += 1; - let executor = lock.executor.clone(); - executor - .spawn(synthetic_drag( - weak_window_state, - lock.synthetic_drag_counter, - event.clone(), - )) - .detach(); + // Synthetic drag is used for selecting long buffer contents while buffer is being scrolled. + // External file drag and drop is able to emit its own synthetic mouse events which will conflict + // with these ones. + if !lock.external_files_dragged { + lock.synthetic_drag_counter += 1; + let executor = lock.executor.clone(); + executor + .spawn(synthetic_drag( + weak_window_state, + lock.synthetic_drag_counter, + event.clone(), + )) + .detach(); + } } InputEvent::MouseMove(_) if !(is_active || lock.kind == WindowKind::PopUp) => return, @@ -1675,6 +1682,7 @@ extern "C" fn dragging_entered(this: &Object, _: Sel, dragging_info: id) -> NSDr let paths = external_paths_from_event(dragging_info); InputEvent::FileDrop(FileDropEvent::Entered { position, paths }) }) { + window_state.lock().external_files_dragged = true; NSDragOperationCopy } else { NSDragOperationNone @@ -1697,6 +1705,7 @@ extern "C" fn dragging_updated(this: &Object, _: Sel, dragging_info: id) -> NSDr extern "C" fn dragging_exited(this: &Object, _: Sel, _: id) { let window_state = unsafe { get_window_state(this) }; send_new_event(&window_state, InputEvent::FileDrop(FileDropEvent::Exited)); + window_state.lock().external_files_dragged = false; } extern "C" fn perform_drag_operation(this: &Object, _: Sel, dragging_info: id) -> BOOL {