Fix webview dragging.
This commit is contained in:
@@ -395,6 +395,12 @@ pub fn grabFocus(self: *Pane) void {
|
||||
self.content.grabFocus();
|
||||
}
|
||||
|
||||
/// Whether the content is allowed to be picked as the target of a pointer or a
|
||||
/// drop. Off for the length of a pane drag — see `installDropTarget`.
|
||||
pub fn setContentTargetable(self: *Pane, targetable: bool) void {
|
||||
self.content.widget().setCanTarget(@intFromBool(targetable));
|
||||
}
|
||||
|
||||
/// The terminal this pane holds, or null if it holds something else. Callers
|
||||
/// that only make sense for a terminal — pasting a VT sequence, say — use this
|
||||
/// to opt out on a web pane.
|
||||
@@ -585,6 +591,17 @@ fn installDropTarget(self: *Pane) void {
|
||||
_ = gtk.DropTarget.signals.motion.connect(target, *Pane, &onDropMotion, self, .{});
|
||||
_ = gtk.DropTarget.signals.leave.connect(target, *Pane, &onDropLeave, self, .{});
|
||||
_ = gtk.DropTarget.signals.drop.connect(target, *Pane, &onDrop, self, .{});
|
||||
|
||||
// On the pane rather than the header, so the whole pane is a target and
|
||||
// `targetAt` has an area to pick a side from. That puts it above the
|
||||
// content in the widget tree, which is fine for a terminal — it takes no
|
||||
// drops — but a web view is a drop target in its own right and an
|
||||
// innermost one wins. Since the preview slides the dragged pane in under
|
||||
// the pointer, the drop at the end of a drag of a browser or a review pane
|
||||
// would land in that pane's own page: no `drop` here, so `endDrag` would
|
||||
// find the drag uncommitted and undo the whole move. `View.beginDrag`
|
||||
// takes every pane's content out of the picking for the length of a drag
|
||||
// so that the pane is what the drop reaches.
|
||||
self.widget().addController(target.as(gtk.EventController));
|
||||
}
|
||||
|
||||
|
||||
@@ -786,6 +786,13 @@ pub fn beginDrag(self: *View, pane: *Pane) bool {
|
||||
.origin_ratio = position.ratio,
|
||||
};
|
||||
pane.widget().addCssClass("dragging");
|
||||
|
||||
// For the length of the drag, a pane's content is not a drop target and
|
||||
// the pane itself is. Without this a web view — a browser or a review
|
||||
// pane — swallows the drop that lands on it, including the drop on the
|
||||
// dragged pane itself, which is where the preview has just put it. See
|
||||
// `Pane.installDropTarget`.
|
||||
for (self.panes.items) |p| p.setContentTargetable(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -808,6 +815,10 @@ pub fn commitDrag(self: *View) void {
|
||||
|
||||
/// End of a drag. If no drop was accepted, undo whatever the preview did.
|
||||
pub fn endDrag(self: *View) void {
|
||||
// Before the early return: a drag whose pane was closed under it has
|
||||
// already cleared `drag`, and the content would stay unpickable for good.
|
||||
for (self.panes.items) |p| p.setContentTargetable(true);
|
||||
|
||||
const drag = self.drag orelse return;
|
||||
self.drag = null;
|
||||
drag.pane.widget().removeCssClass("dragging");
|
||||
|
||||
Reference in New Issue
Block a user