Fix mouse input on HiDPI monitors (#927)

This commit is contained in:
ShadowCommander
2020-01-08 11:50:25 +01:00
committed by Pieter-Jan Briers
parent 3faa52ee01
commit 5037ace00b
4 changed files with 99 additions and 4 deletions
@@ -1099,6 +1099,49 @@ namespace OpenToolkit.GraphicsLibraryFramework
bottom = b;
}
/// <summary>
/// <para>
/// This function retrieves the content scale for the specified window.
/// </para>
/// <para>
/// The content scale is the ratio between the current DPI and the platform's default DPI.
/// This is especially important for text and any UI elements.
/// If the pixel dimensions of your UI scaled by this look appropriate on your machine then it should
/// appear at a reasonable size on other machines regardless of their DPI and scaling settings.
/// This relies on the system DPI and scaling settings being somewhat correct.
/// </para>
///
/// <para>
/// On systems where each monitors can have its own content scale,
/// the window content scale will depend on which monitor the system considers the window to be on.
/// </para>
/// </summary>
/// <param name="window">The window to query.</param>
/// <param name="xScale">
/// Where to store the x-axis content scale, or <c>out _</c>.
/// </param>
/// <param name="yScale">
/// Where to store the y-axis content scale, or <c>out _</c>.
/// </param>
/// <remarks>
/// <para>
/// This function must only be called from the main thread.
/// </para>
/// <para>
/// Possible errors include <see cref="ErrorCode.NotInitialized"/> and <see cref="ErrorCode.PlatformError"/>.
/// </para>
/// </remarks>
public static unsafe void GetWindowContentScale(
Window* window,
out float xScale,
out float yScale)
{
float x, y;
glfwGetWindowContentScale(window, &x, &y);
xScale = x;
yScale = y;
}
/// <summary>
/// <para>
/// This function returns the opacity of the window, including any decorations.
@@ -4422,6 +4465,31 @@ namespace OpenToolkit.GraphicsLibraryFramework
return glfwSetWindowIconifyCallback(window, Marshal.GetFunctionPointerForDelegate(callback));
}
/// <summary>
/// <para>
/// This function sets the window content scale callback of the specified window,
/// which is called when the content scale of the specified window changes.
/// </para>
/// </summary>
/// <param name="window">The window whose content scale changed.</param>
/// <param name="xscale">The new x-axis content scale of the window. </param>
/// <param name="yscale">The new y-axis content scale of the window. </param>
/// <remarks>
/// <para>
/// This function must only be called from the main thread.
/// </para>
/// <para>
/// Possible errors include <see cref="ErrorCode.NotInitialized"/>.
/// </para>
/// </remarks>
/// <seealso cref="GetWindowContentScale"/>
public static unsafe IntPtr SetWindowContentScaleCallback(
Window* window,
GLFWCallbacks.WindowContentScaleCallback callback)
{
return glfwSetWindowContentScaleCallback(window, Marshal.GetFunctionPointerForDelegate(callback));
}
/// <summary>
/// <para>
/// This function sets the monitor that the window uses for full screen mode or,
@@ -1,4 +1,4 @@
//
//
// GLFWCallbacks.cs
//
// Copyright (C) 2019 OpenTK
@@ -167,5 +167,14 @@ namespace OpenToolkit.GraphicsLibraryFramework
/// </summary>
/// <param name="window">The window that needs to be refreshed.</param>
public delegate void WindowRefreshCallback(Window* window);
/// <summary>
/// This is the function pointer type for window content scale callbacks.
/// </summary>
/// <param name="window">The window whose content scale changed. </param>
/// <param name="xscale">The new x-axis content scale of the window. </param>
/// <param name="yscale">The new y-axis content scale of the window.</param>
/// <seealso cref="GLFW.SetWindowContentScaleCallback"/>
public delegate void WindowContentScaleCallback(Window* window, float xscale, float yscale);
}
}
@@ -1,4 +1,4 @@
using System;
using System;
using System.Runtime.InteropServices;
namespace OpenToolkit.GraphicsLibraryFramework
@@ -103,6 +103,9 @@ namespace OpenToolkit.GraphicsLibraryFramework
[DllImport(LibraryName)]
public static extern void glfwGetWindowFrameSize(Window* window, int* left, int* top, int* right, int* bottom);
[DllImport(LibraryName)]
public static extern void glfwGetWindowContentScale(Window* window, float* xscale, float* yscale);
[DllImport(LibraryName)]
public static extern float glfwGetWindowOpacity(Window* window);
@@ -340,6 +343,9 @@ namespace OpenToolkit.GraphicsLibraryFramework
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowIconifyCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern IntPtr glfwSetWindowContentScaleCallback(Window* window, IntPtr callback);
[DllImport(LibraryName)]
public static extern void glfwSetWindowTitle(Window* window, byte* title);
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@@ -36,6 +36,7 @@ namespace Robust.Client.Graphics.Clyde
private GLFWCallbacks.ScrollCallback _scrollCallback;
private GLFWCallbacks.WindowCloseCallback _windowCloseCallback;
private GLFWCallbacks.WindowSizeCallback _windowSizeCallback;
private GLFWCallbacks.WindowContentScaleCallback _windowContentScaleCallback;
private bool _glfwInitialized = false;
@@ -43,6 +44,7 @@ namespace Robust.Client.Graphics.Clyde
private Window* _glfwWindow;
private Vector2i _screenSize;
private Vector2 _windowScale;
private Thread _mainThread;
private Vector2 _lastMousePos;
@@ -118,6 +120,7 @@ namespace Robust.Client.Graphics.Clyde
GLFW.SetWindowSizeCallback(_glfwWindow, _windowSizeCallback);
GLFW.SetScrollCallback(_glfwWindow, _scrollCallback);
GLFW.SetMouseButtonCallback(_glfwWindow, _mouseButtonCallback);
GLFW.SetWindowContentScaleCallback(_glfwWindow, _windowContentScaleCallback);
GLFW.MakeContextCurrent(_glfwWindow);
@@ -126,6 +129,9 @@ namespace Robust.Client.Graphics.Clyde
GLFW.GetFramebufferSize(_glfwWindow, out var fbW, out var fbH);
_screenSize = (fbW, fbH);
GLFW.GetWindowContentScale(_glfwWindow, out var scaleX, out var scaleY);
_windowScale = (scaleX, scaleY);
InitGLContext();
// Initializing OTK 3 seems to mess with the current context, so ensure it's still set.
@@ -218,7 +224,7 @@ namespace Robust.Client.Graphics.Clyde
private void OnGlfwCursorPos(Window* window, double x, double y)
{
var newPos = new Vector2((float) x, (float) y);
var newPos = new Vector2((float) x, (float) y) * _windowScale;
var delta = newPos - _lastMousePos;
_lastMousePos = newPos;
@@ -288,6 +294,11 @@ namespace Robust.Client.Graphics.Clyde
OnWindowResized?.Invoke(new WindowResizedEventArgs(oldSize, _screenSize));
}
private void OnGlfwWindownContentScale(Window *window, float xScale, float yScale)
{
_windowScale = (xScale, yScale);
}
private void StoreCallbacks()
{
_errorCallback = OnGlfwError;
@@ -298,6 +309,7 @@ namespace Robust.Client.Graphics.Clyde
_scrollCallback = OnGlfwScroll;
_windowCloseCallback = OnGlfwWindowClose;
_windowSizeCallback = OnGlfwWindowSize;
_windowContentScaleCallback = OnGlfwWindownContentScale;
}
public override void SetWindowTitle(string title)