拖动移动闪烁位置window

Drag move flickers position of window

我正在实施 Rust 替代 .NET 的 DragMove 方法,但是结果导致应用程序在两个相对位置之间闪烁。

screencast and sample project

我用来执行拖动移动的代码:

let mut mouse_down = false;
let mut last_pos: Option<PhysicalPosition<f64>> = None;
event_loop.run(move |event, _, control_flow| match event {
Event::WindowEvent {
        event: WindowEvent::CursorMoved {
            position,
            ..
        },
        ..
    } => {
        let gl_window = display.gl_window();
        let window = gl_window.window();
        if mouse_down {
            if last_pos.is_some() {
                let previous_pos = last_pos.unwrap();
                let delta_x = previous_pos.x - position.x;
                let delta_y = previous_pos.y - position.y;
                window.set_outer_position(PhysicalPosition::new(position.x + delta_x, position.y + delta_y));
            }
            last_pos = Some(position);
        }
    }
    Event::WindowEvent {
        event: WindowEvent::MouseInput{
            state,
            button,
            ..
        },
        ..
    } => {
        mouse_down = button == MouseButton::Left && state == ElementState::Pressed;
        if !mouse_down {
            last_pos = None;
        }
    }
    _ => {}
});

CursorMoved 报道

(x,y) coords in pixels relative to the top-left corner of the window.

当您稍后将该位置用于 set_outer_position 时,您实际上是在将 window 相对坐标重新解释为屏幕相对坐标。

您应该将偏移量应用于从 outer_position 返回的位置。

虽然这解决了眼前的问题,但我不确定这是否足以解释 window 运动。当您处理 next CursorMoved 事件时,坐标仍然是 window 相对的,但是 window 已经移动了。这可能会在整个过程中产生伪影。

更稳健的解决方案是在拖动移动操作开始时存储 window 的位置,并用累积的增量偏移该位置。