Skip to content

Commit dd08aab

Browse files
authored
fix: browser drag completion lifecycle (#192)
1 parent 314469c commit dd08aab

7 files changed

Lines changed: 39 additions & 17 deletions

File tree

crates/gdcef/src/browser.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ pub struct DragState {
465465
pub is_drag_over: bool,
466466
pub is_dragging_from_browser: bool,
467467
pub allowed_ops: u32,
468+
pub source_position: Option<(i32, i32)>,
468469
}
469470

470471
/// Rendering mode for the CEF browser.
@@ -667,13 +668,15 @@ mod tests {
667668
app.drag_state.is_drag_over = true;
668669
app.drag_state.is_dragging_from_browser = true;
669670
app.drag_state.allowed_ops = u32::MAX;
671+
app.drag_state.source_position = Some((10, 20));
670672

671673
app.clear_runtime_state();
672674

673675
assert!(app.state.is_none());
674676
assert!(!app.drag_state.is_drag_over);
675677
assert!(!app.drag_state.is_dragging_from_browser);
676678
assert_eq!(app.drag_state.allowed_ops, 0);
679+
assert_eq!(app.drag_state.source_position, None);
677680
}
678681
}
679682

crates/gdcef/src/cef_texture/mod.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -769,17 +769,33 @@ impl CefTexture {
769769
let Some(host) = app.host() else {
770770
return;
771771
};
772+
if !app.drag_state.is_dragging_from_browser {
773+
return;
774+
}
772775
host.drag_source_ended_at(position.x as i32, position.y as i32, op);
776+
host.drag_source_system_drag_ended();
773777
app.drag_state.is_dragging_from_browser = false;
778+
app.drag_state.source_position = None;
779+
app.drag_state.allowed_ops = 0;
774780
});
775781
}
776782

777783
#[func]
778784
pub fn drag_source_system_ended(&mut self) {
779-
self.with_app(|app| {
780-
if let Some(host) = app.host() {
781-
host.drag_source_system_drag_ended();
785+
self.with_app_mut(|app| {
786+
let Some(host) = app.host() else {
787+
return;
788+
};
789+
if !app.drag_state.is_dragging_from_browser {
790+
return;
782791
}
792+
let (x, y) = app.drag_state.source_position.unwrap_or((0, 0));
793+
let op = cef::DragOperationsMask::from(cef::sys::cef_drag_operations_mask_t(0));
794+
host.drag_source_ended_at(x, y, op);
795+
host.drag_source_system_drag_ended();
796+
app.drag_state.is_dragging_from_browser = false;
797+
app.drag_state.source_position = None;
798+
app.drag_state.allowed_ops = 0;
783799
});
784800
}
785801

crates/gdcef/src/cef_texture/signals.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,17 +288,18 @@ impl CefTexture {
288288
} => {
289289
let drag_info = DragDataInfo::from_internal(drag_data);
290290
let position = Vector2::new(*x as f32, *y as f32);
291+
self.with_app_mut(|app| {
292+
app.drag_state.is_dragging_from_browser = true;
293+
app.drag_state.allowed_ops = *allowed_ops;
294+
app.drag_state.source_position = Some((*x, *y));
295+
});
291296
emit_signal_variants!(
292297
self,
293298
"drag_started",
294299
drag_info,
295300
position,
296301
*allowed_ops as i32
297302
);
298-
self.with_app_mut(|app| {
299-
app.drag_state.is_dragging_from_browser = true;
300-
app.drag_state.allowed_ops = *allowed_ops;
301-
});
302303
}
303304
DragEvent::UpdateCursor { operation } => {
304305
emit_signal_variants!(self, "drag_cursor_updated", *operation as i32);

docs/api/drag-and-drop.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ func _on_drag_entered(drag_data: DragDataInfo, mask: int):
172172

173173
### Notifying CEF When Browser Drag Ends
174174

175-
When a drag that started from the browser ends (either dropped somewhere or cancelled), you should notify CEF:
175+
When a drag that started from the browser ends, notify CEF exactly once:
176176

177177
#### `drag_source_ended(position: Vector2, operation: int)`
178178

179-
Call when a browser-initiated drag ends with a specific result.
179+
Call when a browser-initiated drag ends with a specific drop result. This completes the browser drag operation.
180180

181181
```gdscript
182182
func _on_drop_completed(drop_position: Vector2, was_accepted: bool):
@@ -187,7 +187,7 @@ func _on_drop_completed(drop_position: Vector2, was_accepted: bool):
187187

188188
#### `drag_source_system_ended()`
189189

190-
Call when the system drag operation ends (cleanup).
190+
Call when a browser-initiated drag is cancelled or ends without a drop result. This completes the browser drag operation with `DragOperation.NONE`.
191191

192192
```gdscript
193193
func _notification(what):
@@ -253,6 +253,7 @@ func _drop_data(at_position: Vector2, data):
253253
if data is DragDataInfo and data.is_link:
254254
_add_item_from_url(data.link_url)
255255
cef_texture.drag_source_ended(at_position, DragOperation.COPY)
256+
browser_drag_data = null
256257
257258
func _notification(what):
258259
if what == NOTIFICATION_DRAG_END:

docs/api/methods.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,15 +442,15 @@ func _drop_data(at_position: Vector2, data):
442442

443443
### `drag_source_ended(position: Vector2, operation: int)`
444444

445-
Notifies CEF that a browser-initiated drag has ended. Call this when handling drops from the browser into your game.
445+
Notifies CEF that a browser-initiated drag ended with a drop result. This completes the browser drag operation, so do not call `drag_source_system_ended()` afterward.
446446

447447
```gdscript
448448
cef_texture.drag_source_ended(drop_position, DragOperation.COPY)
449449
```
450450

451451
### `drag_source_system_ended()`
452452

453-
Notifies CEF that the system drag operation has ended. Call this for cleanup after browser-initiated drags.
453+
Notifies CEF that a browser-initiated drag was cancelled or ended without a drop result. This completes the browser drag operation with `DragOperation.NONE`.
454454

455455
```gdscript
456456
cef_texture.drag_source_system_ended()

docs/zh_CN/api/drag-and-drop.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ func _on_drag_entered(drag_data: DragDataInfo, mask: int):
172172

173173
### 通知 CEF 浏览器拖动结束
174174

175-
当从浏览器发起的拖动结束(被放下或取消)时,您应该通知 CEF:
175+
当从浏览器发起的拖动结束时,只通知 CEF 一次
176176

177177
#### `drag_source_ended(position: Vector2, operation: int)`
178178

179-
当浏览器发起的拖动以特定结果结束时调用
179+
当浏览器发起的拖动以特定放置结果结束时调用。此方法会完成浏览器拖动操作
180180

181181
```gdscript
182182
func _on_drop_completed(drop_position: Vector2, was_accepted: bool):
@@ -187,7 +187,7 @@ func _on_drop_completed(drop_position: Vector2, was_accepted: bool):
187187

188188
#### `drag_source_system_ended()`
189189

190-
当系统拖动操作结束时调用(清理)
190+
当浏览器发起的拖动被取消,或没有放置结果就结束时调用。此方法会以 `DragOperation.NONE` 完成浏览器拖动操作
191191

192192
```gdscript
193193
func _notification(what):
@@ -253,6 +253,7 @@ func _drop_data(at_position: Vector2, data):
253253
if data is DragDataInfo and data.is_link:
254254
_add_item_from_url(data.link_url)
255255
cef_texture.drag_source_ended(at_position, DragOperation.COPY)
256+
browser_drag_data = null
256257
257258
func _notification(what):
258259
if what == NOTIFICATION_DRAG_END:

docs/zh_CN/api/methods.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,15 +342,15 @@ func _drop_data(at_position: Vector2, data):
342342

343343
### `drag_source_ended(position: Vector2, operation: int)`
344344

345-
通知 CEF 浏览器发起的拖动已结束。在处理从浏览器拖放到游戏中时调用此方法
345+
通知 CEF 浏览器发起的拖动已用放置结果结束。此方法会完成浏览器拖动操作,因此之后不要再调用 `drag_source_system_ended()`
346346

347347
```gdscript
348348
cef_texture.drag_source_ended(drop_position, DragOperation.COPY)
349349
```
350350

351351
### `drag_source_system_ended()`
352352

353-
通知 CEF 系统拖动操作已结束。在浏览器发起的拖动后用于清理
353+
通知 CEF 浏览器发起的拖动已取消,或没有放置结果就结束。此方法会以 `DragOperation.NONE` 完成浏览器拖动操作
354354

355355
```gdscript
356356
cef_texture.drag_source_system_ended()

0 commit comments

Comments
 (0)