Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to open context menu in drag and drop demo by right-click #2471

Open
rafree opened this issue Dec 17, 2022 · 2 comments
Open

Not able to open context menu in drag and drop demo by right-click #2471

rafree opened this issue Dec 17, 2022 · 2 comments
Labels
bug Something is broken

Comments

@rafree
Copy link

rafree commented Dec 17, 2022

Describe the bug
I am using code inspired by the drag and drop demo, and since updating from egui 0.19.0 to the most recent version, the context menu of the items seems not to work as expected anymore. I re-created this on egui.rs (accessed 2022-12-17). When right-clicking on Item B (see video below, mouse pointer unfortunately not visible in the recording), a context menu with a Remove button as per

if ui.button("Remove").clicked() {
should appear, but instead the New Item option appears.

Screencast.from.2022-12-17.10-56-00.webm

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://www.egui.rs/
  2. Open the drag and drop demo
  3. Right click on any of the items
@rafree rafree added the bug Something is broken label Dec 17, 2022
@YgorSouza
Copy link
Contributor

I think these are the relevant parts of the code:

This sets the drag flag on pointer down:

PointerEvent::Pressed { .. } => {
if hovered {
if sense.click && memory.interaction.click_id.is_none() {
// potential start of a click
memory.interaction.click_id = Some(id);
response.is_pointer_button_down_on = true;
}
// HACK: windows have low priority on dragging.
// This is so that if you drag a slider in a window,
// the slider will steal the drag away from the window.
// This is needed because we do window interaction first (to prevent frame delay),
// and then do content layout.
if sense.drag
&& (memory.interaction.drag_id.is_none()
|| memory.interaction.drag_is_window)
{
// potential start of a drag
memory.interaction.drag_id = Some(id);
memory.interaction.drag_is_window = false;
memory.window_interaction = None; // HACK: stop moving windows (if any)
response.is_pointer_button_down_on = true;
response.dragged = true;

And this whole block handles interactions on overlapping widgets:

// This solves the problem of overlapping widgets.
// Whichever widget is added LAST (=on top) gets the input:
if interact_rect.is_positive() && sense.interactive() {
if self.style().debug.show_interactive_widgets {
Self::layer_painter(self, LayerId::debug()).rect(
interact_rect,
0.0,
Color32::YELLOW.additive().linear_multiply(0.005),
Stroke::new(1.0, Color32::YELLOW.additive().linear_multiply(0.05)),
);
}
self.write(|ctx| {
ctx.layer_rects_this_frame
.entry(layer_id)
.or_default()
.push((id, interact_rect));
if hovered {
let pointer_pos = ctx.input.pointer.interact_pos();
if let Some(pointer_pos) = pointer_pos {
if let Some(rects) = ctx.layer_rects_prev_frame.get(&layer_id) {
for &(prev_id, prev_rect) in rects.iter().rev() {
if prev_id == id {
break; // there is no other interactive widget covering us at the pointer position.
}
if prev_rect.contains(pointer_pos) {
// Another interactive widget is covering us at the pointer position,
// so we aren't hovered.
if ctx.memory.options.style.debug.show_blocking_widget {
Self::layer_painter(self, LayerId::debug()).debug_rect(
interact_rect,
Color32::GREEN,
"Covered",
);
Self::layer_painter(self, LayerId::debug()).debug_rect(
prev_rect,
Color32::LIGHT_BLUE,
"On top",
);
}
hovered = false;
break;
}
}
}
}
}
});
}
self.interact_with_hovered(layer_id, id, rect, sense, enabled, hovered)
}

I feel like the drag should start when you move the pointer with the primary button down, and not when you press any button, but when I make the change, it doesn't fix the context menu in the drag and drop demo. I think the problem is that the drag_source adds another layer on top of the widget to check for interactions on it, and then it blocks interactions with the widget itself.

@mankinskin
Copy link
Contributor

This seems to be related to #578, I remember this working at one point, but I haven't worked on this for quite some time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
None yet
Development

No branches or pull requests

3 participants