Skip to content

Commit 87c92f3

Browse files
gpui: Reset external_files_dragged after successful drag-drop on macOS (#48727)
after a successful file drag-drop, conclude_drag_operation did not reset external_files_dragged to false. since dragging_exited (the only place that resets this flag) is never called for successful drops (only for cancelled ones), the flag stayed true permanently. this caused synthetic drags (used for text selection during buffer scrolling) to be suppressed for the lifetime of the window. Release Notes: - N/A --------- Co-authored-by: MrSubidubi <finn@zed.dev>
1 parent f1f8c55 commit 87c92f3

1 file changed

Lines changed: 26 additions & 27 deletions

File tree

crates/gpui/src/platform/mac/window.rs

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,11 +2454,9 @@ extern "C" fn dragging_entered(this: &Object, _: Sel, dragging_info: id) -> NSDr
24542454
let window_state = unsafe { get_window_state(this) };
24552455
let position = drag_event_position(&window_state, dragging_info);
24562456
let paths = external_paths_from_event(dragging_info);
2457-
if let Some(event) =
2458-
paths.map(|paths| PlatformInput::FileDrop(FileDropEvent::Entered { position, paths }))
2459-
&& send_new_event(&window_state, event)
2457+
if let Some(event) = paths.map(|paths| FileDropEvent::Entered { position, paths })
2458+
&& send_file_drop_event(window_state, event)
24602459
{
2461-
window_state.lock().external_files_dragged = true;
24622460
return NSDragOperationCopy;
24632461
}
24642462
NSDragOperationNone
@@ -2467,10 +2465,7 @@ extern "C" fn dragging_entered(this: &Object, _: Sel, dragging_info: id) -> NSDr
24672465
extern "C" fn dragging_updated(this: &Object, _: Sel, dragging_info: id) -> NSDragOperation {
24682466
let window_state = unsafe { get_window_state(this) };
24692467
let position = drag_event_position(&window_state, dragging_info);
2470-
if send_new_event(
2471-
&window_state,
2472-
PlatformInput::FileDrop(FileDropEvent::Pending { position }),
2473-
) {
2468+
if send_file_drop_event(window_state, FileDropEvent::Pending { position }) {
24742469
NSDragOperationCopy
24752470
} else {
24762471
NSDragOperationNone
@@ -2479,21 +2474,13 @@ extern "C" fn dragging_updated(this: &Object, _: Sel, dragging_info: id) -> NSDr
24792474

24802475
extern "C" fn dragging_exited(this: &Object, _: Sel, _: id) {
24812476
let window_state = unsafe { get_window_state(this) };
2482-
send_new_event(
2483-
&window_state,
2484-
PlatformInput::FileDrop(FileDropEvent::Exited),
2485-
);
2486-
window_state.lock().external_files_dragged = false;
2477+
send_file_drop_event(window_state, FileDropEvent::Exited);
24872478
}
24882479

24892480
extern "C" fn perform_drag_operation(this: &Object, _: Sel, dragging_info: id) -> BOOL {
24902481
let window_state = unsafe { get_window_state(this) };
24912482
let position = drag_event_position(&window_state, dragging_info);
2492-
send_new_event(
2493-
&window_state,
2494-
PlatformInput::FileDrop(FileDropEvent::Submit { position }),
2495-
)
2496-
.to_objc()
2483+
send_file_drop_event(window_state, FileDropEvent::Submit { position }).to_objc()
24972484
}
24982485

24992486
fn external_paths_from_event(dragging_info: *mut Object) -> Option<ExternalPaths> {
@@ -2515,10 +2502,7 @@ fn external_paths_from_event(dragging_info: *mut Object) -> Option<ExternalPaths
25152502

25162503
extern "C" fn conclude_drag_operation(this: &Object, _: Sel, _: id) {
25172504
let window_state = unsafe { get_window_state(this) };
2518-
send_new_event(
2519-
&window_state,
2520-
PlatformInput::FileDrop(FileDropEvent::Exited),
2521-
);
2505+
send_file_drop_event(window_state, FileDropEvent::Exited);
25222506
}
25232507

25242508
async fn synthetic_drag(
@@ -2544,11 +2528,26 @@ async fn synthetic_drag(
25442528
}
25452529
}
25462530

2547-
fn send_new_event(window_state_lock: &Mutex<MacWindowState>, e: PlatformInput) -> bool {
2548-
let window_state = window_state_lock.lock().event_callback.take();
2549-
if let Some(mut callback) = window_state {
2550-
callback(e);
2551-
window_state_lock.lock().event_callback = Some(callback);
2531+
/// Sends the specified FileDropEvent using `PlatformInput::FileDrop` to the window
2532+
/// state and updates the window state according to the event passed.
2533+
fn send_file_drop_event(
2534+
window_state: Arc<Mutex<MacWindowState>>,
2535+
file_drop_event: FileDropEvent,
2536+
) -> bool {
2537+
let mut window_state = window_state.lock();
2538+
let window_event_callback = window_state.event_callback.as_mut();
2539+
if let Some(mut callback) = window_event_callback {
2540+
let external_files_dragged = match file_drop_event {
2541+
FileDropEvent::Entered { .. } => Some(true),
2542+
FileDropEvent::Exited => Some(false),
2543+
_ => None,
2544+
};
2545+
2546+
callback(PlatformInput::FileDrop(file_drop_event));
2547+
2548+
if let Some(external_files_dragged) = external_files_dragged {
2549+
window_state.external_files_dragged = external_files_dragged;
2550+
}
25522551
true
25532552
} else {
25542553
false

0 commit comments

Comments
 (0)