mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
DragImageComponent: Avoid case where image may detach from mouse when dragging between screens
When two monitors are available, both with different scale factors, then the drag-image may 'detach' from the mouse while the image's top-left coordinate was on one display, and the mouse cursor was on the other display. This happened because, on Windows, the mouse cursor moves continuously in physical (not logical!) space. In other words, the mouse may not move continuously in logical space, and the discontinuity becomes visible when components are positioned relative to the mouse in logical space. In order to display consistently, the top-left position of the image must be set relative to the physical position of the mouse.
This commit is contained in:
parent
2fcf9ebf38
commit
fc76e936d3
1 changed files with 27 additions and 4 deletions
|
|
@ -324,12 +324,35 @@ private:
|
|||
|
||||
void setNewScreenPos (Point<int> screenPos)
|
||||
{
|
||||
auto newPos = screenPos - imageOffset;
|
||||
setTopLeftPosition (std::invoke ([&]
|
||||
{
|
||||
if (auto* p = getParentComponent())
|
||||
return p->getLocalPoint (nullptr, screenPos - imageOffset);
|
||||
|
||||
if (auto* p = getParentComponent())
|
||||
newPos = p->getLocalPoint (nullptr, newPos);
|
||||
#if JUCE_WINDOWS
|
||||
// On Windows, the mouse position is continuous in physical pixels across screen boundaries.
|
||||
// i.e. if two screens are set to different scale factors, when the mouse moves horizontally
|
||||
// between those screens, the mouse's physical y coordinate will be preserved, and if
|
||||
// the mouse moves vertically between screens its physical x coordinate will be preserved.
|
||||
|
||||
setTopLeftPosition (newPos);
|
||||
// To avoid the dragged image detaching from the mouse, compute the new top left position
|
||||
// in physical coords and then convert back to logical.
|
||||
// If we were to stay in logical coordinates the whole time, the image may detach from the
|
||||
// mouse because the mouse does not move continuously in logical coordinate space.
|
||||
|
||||
const auto& displays = Desktop::getInstance().getDisplays();
|
||||
const auto physicalPos = displays.logicalToPhysical (screenPos);
|
||||
|
||||
float scale = 1.0f;
|
||||
|
||||
if (auto* p = getPeer())
|
||||
scale = (float) p->getPlatformScaleFactor();
|
||||
|
||||
return displays.physicalToLogical (physicalPos - (imageOffset * scale));
|
||||
#else
|
||||
return screenPos - imageOffset;
|
||||
#endif
|
||||
}));
|
||||
}
|
||||
|
||||
void sendDragMove (DragAndDropTarget::SourceDetails& details) const
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue