mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1218552 - Fix GTK drag-and-drop coordinate scaling on HiDPI displays (r=karlt)
This commit is contained in:
parent
946855ad65
commit
164b197f13
@ -237,8 +237,12 @@ OnSourceGrabEventAfter(GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
||||
// Update the cursor position. The last of these recorded gets used for
|
||||
// the eDragEnd event.
|
||||
nsDragService *dragService = static_cast<nsDragService*>(user_data);
|
||||
dragService->SetDragEndPoint(nsIntPoint(event->motion.x_root,
|
||||
event->motion.y_root));
|
||||
gint scale = nsScreenGtk::GetGtkMonitorScaleFactor();
|
||||
LayoutDeviceIntPoint p = {
|
||||
floor(event->motion.x_root * scale + 0.5),
|
||||
floor(event->motion.y_root * scale + 0.5)
|
||||
};
|
||||
dragService->SetDragEndPoint(p);
|
||||
} else if (sMotionEvent && (event->type == GDK_KEY_PRESS ||
|
||||
event->type == GDK_KEY_RELEASE)) {
|
||||
// Update modifier state from key events.
|
||||
@ -396,7 +400,7 @@ nsDragService::InvokeDragSessionImpl(nsISupportsArray* aArrayTransferables,
|
||||
G_CALLBACK(OnSourceGrabEventAfter), this);
|
||||
}
|
||||
// We don't have a drag end point yet.
|
||||
mEndDragPoint = nsIntPoint(-1, -1);
|
||||
mEndDragPoint = LayoutDeviceIntPoint(-1, -1);
|
||||
rv = NS_OK;
|
||||
}
|
||||
else {
|
||||
@ -1413,8 +1417,9 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
|
||||
gint x, y;
|
||||
GdkDisplay* display = gdk_display_get_default();
|
||||
if (display) {
|
||||
gint scale = nsScreenGtk::GetGtkMonitorScaleFactor();
|
||||
gdk_display_get_pointer(display, nullptr, &x, &y, nullptr);
|
||||
SetDragEndPoint(nsIntPoint(x, y));
|
||||
SetDragEndPoint(LayoutDeviceIntPoint(x * scale, y * scale));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1462,7 +1467,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext,
|
||||
}
|
||||
|
||||
// Schedule the appropriate drag end dom events.
|
||||
Schedule(eDragTaskSourceEnd, nullptr, nullptr, nsIntPoint(), 0);
|
||||
Schedule(eDragTaskSourceEnd, nullptr, nullptr, LayoutDeviceIntPoint(), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1783,7 +1788,7 @@ invisibleSourceDragEnd(GtkWidget *aWidget,
|
||||
gboolean
|
||||
nsDragService::ScheduleMotionEvent(nsWindow *aWindow,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIntPoint aWindowPoint, guint aTime)
|
||||
LayoutDeviceIntPoint aWindowPoint, guint aTime)
|
||||
{
|
||||
if (mScheduledTask == eDragTaskMotion) {
|
||||
// The drag source has sent another motion message before we've
|
||||
@ -1806,7 +1811,7 @@ nsDragService::ScheduleLeaveEvent()
|
||||
// We don't know at this stage whether a drop signal will immediately
|
||||
// follow. If the drop signal gets sent it will happen before we return
|
||||
// to the main loop and the scheduled leave task will be replaced.
|
||||
if (!Schedule(eDragTaskLeave, nullptr, nullptr, nsIntPoint(), 0)) {
|
||||
if (!Schedule(eDragTaskLeave, nullptr, nullptr, LayoutDeviceIntPoint(), 0)) {
|
||||
NS_WARNING("Drag leave after drop");
|
||||
}
|
||||
}
|
||||
@ -1814,7 +1819,7 @@ nsDragService::ScheduleLeaveEvent()
|
||||
gboolean
|
||||
nsDragService::ScheduleDropEvent(nsWindow *aWindow,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIntPoint aWindowPoint, guint aTime)
|
||||
LayoutDeviceIntPoint aWindowPoint, guint aTime)
|
||||
{
|
||||
if (!Schedule(eDragTaskDrop, aWindow,
|
||||
aDragContext, aWindowPoint, aTime)) {
|
||||
@ -1822,7 +1827,7 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffsetUntyped());
|
||||
SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset());
|
||||
|
||||
// We'll reply with gtk_drag_finish().
|
||||
return TRUE;
|
||||
@ -1831,7 +1836,7 @@ nsDragService::ScheduleDropEvent(nsWindow *aWindow,
|
||||
gboolean
|
||||
nsDragService::Schedule(DragTask aTask, nsWindow *aWindow,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIntPoint aWindowPoint, guint aTime)
|
||||
LayoutDeviceIntPoint aWindowPoint, guint aTime)
|
||||
{
|
||||
// If there is an existing leave or motion task scheduled, then that
|
||||
// will be replaced. When the new task is run, it will dispatch
|
||||
|
@ -96,12 +96,12 @@ public:
|
||||
|
||||
gboolean ScheduleMotionEvent(nsWindow *aWindow,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIntPoint aWindowPoint,
|
||||
mozilla::LayoutDeviceIntPoint aWindowPoint,
|
||||
guint aTime);
|
||||
void ScheduleLeaveEvent();
|
||||
gboolean ScheduleDropEvent(nsWindow *aWindow,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIntPoint aWindowPoint,
|
||||
mozilla::LayoutDeviceIntPoint aWindowPoint,
|
||||
guint aTime);
|
||||
|
||||
nsWindow* GetMostRecentDestWindow()
|
||||
@ -154,7 +154,7 @@ private:
|
||||
// when the scheduled task is run. mPendingWindow and mPendingDragContext
|
||||
// will be nullptr if the scheduled task is eDragTaskLeave.
|
||||
RefPtr<nsWindow> mPendingWindow;
|
||||
nsIntPoint mPendingWindowPoint;
|
||||
mozilla::LayoutDeviceIntPoint mPendingWindowPoint;
|
||||
nsCountedRef<GdkDragContext> mPendingDragContext;
|
||||
guint mPendingTime;
|
||||
|
||||
@ -162,7 +162,7 @@ private:
|
||||
// eDragTaskMotion or eDragTaskDrop task that was run or is still running.
|
||||
// mTargetWindow is cleared once the drag has completed or left.
|
||||
RefPtr<nsWindow> mTargetWindow;
|
||||
nsIntPoint mTargetWindowPoint;
|
||||
mozilla::LayoutDeviceIntPoint mTargetWindowPoint;
|
||||
// mTargetWidget and mTargetDragContext are set only while dispatching
|
||||
// motion or drop events. mTime records the corresponding timestamp.
|
||||
nsCountedRef<GtkWidget> mTargetWidget;
|
||||
@ -210,7 +210,7 @@ private:
|
||||
|
||||
gboolean Schedule(DragTask aTask, nsWindow *aWindow,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIntPoint aWindowPoint, guint aTime);
|
||||
mozilla::LayoutDeviceIntPoint aWindowPoint, guint aTime);
|
||||
|
||||
// Callback for g_idle_add_full() to run mScheduledTask.
|
||||
static gboolean TaskDispatchCallback(gpointer data);
|
||||
|
@ -3331,7 +3331,7 @@ nsWindow::ThemeChanged()
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::DispatchDragEvent(EventMessage aMsg, const nsIntPoint& aRefPoint,
|
||||
nsWindow::DispatchDragEvent(EventMessage aMsg, const LayoutDeviceIntPoint& aRefPoint,
|
||||
guint aTime)
|
||||
{
|
||||
WidgetDragEvent event(true, aMsg, this);
|
||||
@ -3340,7 +3340,7 @@ nsWindow::DispatchDragEvent(EventMessage aMsg, const nsIntPoint& aRefPoint,
|
||||
InitDragEvent(event);
|
||||
}
|
||||
|
||||
event.refPoint = LayoutDeviceIntPoint::FromUntyped(aRefPoint);
|
||||
event.refPoint = aRefPoint;
|
||||
event.time = aTime;
|
||||
event.timeStamp = GetEventTimeStamp(aTime);
|
||||
|
||||
@ -5978,9 +5978,11 @@ drag_motion_event_cb(GtkWidget *aWidget,
|
||||
|
||||
LOGDRAG(("nsWindow drag-motion signal for %p\n", (void*)innerMostWindow));
|
||||
|
||||
LayoutDeviceIntPoint point = window->GdkPointToDevicePixels({ retx, rety });
|
||||
|
||||
return nsDragService::GetInstance()->
|
||||
ScheduleMotionEvent(innerMostWindow, aDragContext,
|
||||
nsIntPoint(retx, rety), aTime);
|
||||
point, aTime);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6048,9 +6050,11 @@ drag_drop_event_cb(GtkWidget *aWidget,
|
||||
|
||||
LOGDRAG(("nsWindow drag-drop signal for %p\n", (void*)innerMostWindow));
|
||||
|
||||
LayoutDeviceIntPoint point = window->GdkPointToDevicePixels({ retx, rety });
|
||||
|
||||
return nsDragService::GetInstance()->
|
||||
ScheduleDropEvent(innerMostWindow, aDragContext,
|
||||
nsIntPoint(retx, rety), aTime);
|
||||
point, aTime);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -269,7 +269,7 @@ public:
|
||||
bool IsDestroyed() { return mIsDestroyed; }
|
||||
|
||||
void DispatchDragEvent(mozilla::EventMessage aMsg,
|
||||
const nsIntPoint& aRefPoint,
|
||||
const mozilla::LayoutDeviceIntPoint& aRefPoint,
|
||||
guint aTime);
|
||||
static void UpdateDragStatus (GdkDragContext *aDragContext,
|
||||
nsIDragService *aDragService);
|
||||
|
@ -217,7 +217,7 @@ nsBaseDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
||||
// stash the document of the dom node
|
||||
aDOMNode->GetOwnerDocument(getter_AddRefs(mSourceDocument));
|
||||
mSourceNode = aDOMNode;
|
||||
mEndDragPoint = nsIntPoint(0, 0);
|
||||
mEndDragPoint = LayoutDeviceIntPoint(0, 0);
|
||||
|
||||
// When the mouse goes down, the selection code starts a mouse
|
||||
// capture. However, this gets in the way of determining drag
|
||||
@ -413,7 +413,7 @@ nsBaseDragService::EndDragSession(bool aDoneDrag)
|
||||
mImageOffset = CSSIntPoint();
|
||||
mScreenX = -1;
|
||||
mScreenY = -1;
|
||||
mEndDragPoint = nsIntPoint(0, 0);
|
||||
mEndDragPoint = LayoutDeviceIntPoint(0, 0);
|
||||
mInputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -54,7 +54,14 @@ public:
|
||||
NS_DECL_NSIDRAGSERVICE
|
||||
NS_DECL_NSIDRAGSESSION
|
||||
|
||||
void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
|
||||
void SetDragEndPoint(nsIntPoint aEndDragPoint)
|
||||
{
|
||||
mEndDragPoint = mozilla::LayoutDeviceIntPoint::FromUntyped(aEndDragPoint);
|
||||
}
|
||||
void SetDragEndPoint(mozilla::LayoutDeviceIntPoint aEndDragPoint)
|
||||
{
|
||||
mEndDragPoint = aEndDragPoint;
|
||||
}
|
||||
|
||||
uint16_t GetInputSource() { return mInputSource; }
|
||||
|
||||
@ -171,7 +178,7 @@ protected:
|
||||
int32_t mScreenY;
|
||||
|
||||
// the screen position where the drag ended
|
||||
nsIntPoint mEndDragPoint;
|
||||
mozilla::LayoutDeviceIntPoint mEndDragPoint;
|
||||
|
||||
uint32_t mSuppressLevel;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user