Skip to content

Commit

Permalink
Fix mouse input on HiDPI monitors (space-wizards#927)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowCommander authored and PJB3005 committed Jan 8, 2020
1 parent 3faa52e commit 5037ace
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 4 deletions.
68 changes: 68 additions & 0 deletions OpenToolkit.GraphicsLibraryFramework/GLFW.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,49 @@ public static unsafe void GetWindowFrameSize(
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.
Expand Down Expand Up @@ -4422,6 +4465,31 @@ public static unsafe IntPtr SetWindowIconifyCallback(
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,
Expand Down
11 changes: 10 additions & 1 deletion OpenToolkit.GraphicsLibraryFramework/GLFWCallbacks.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// GLFWCallbacks.cs
//
// Copyright (C) 2019 OpenTK
Expand Down Expand Up @@ -167,5 +167,14 @@ public static unsafe class GLFWCallbacks
/// </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);
}
}
8 changes: 7 additions & 1 deletion OpenToolkit.GraphicsLibraryFramework/GLFWNative.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Runtime.InteropServices;

namespace OpenToolkit.GraphicsLibraryFramework
Expand Down Expand Up @@ -103,6 +103,9 @@ static GLFWNative()
[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);

Expand Down Expand Up @@ -340,6 +343,9 @@ static GLFWNative()
[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);

Expand Down
16 changes: 14 additions & 2 deletions Robust.Client/Graphics/Clyde/Clyde.Windowing.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -36,13 +36,15 @@ internal unsafe partial class Clyde
private GLFWCallbacks.ScrollCallback _scrollCallback;
private GLFWCallbacks.WindowCloseCallback _windowCloseCallback;
private GLFWCallbacks.WindowSizeCallback _windowSizeCallback;
private GLFWCallbacks.WindowContentScaleCallback _windowContentScaleCallback;

private bool _glfwInitialized = false;

private GraphicsContext _graphicsContext;
private Window* _glfwWindow;

private Vector2i _screenSize;
private Vector2 _windowScale;
private Thread _mainThread;

private Vector2 _lastMousePos;
Expand Down Expand Up @@ -118,6 +120,7 @@ private void InitWindow()
GLFW.SetWindowSizeCallback(_glfwWindow, _windowSizeCallback);
GLFW.SetScrollCallback(_glfwWindow, _scrollCallback);
GLFW.SetMouseButtonCallback(_glfwWindow, _mouseButtonCallback);
GLFW.SetWindowContentScaleCallback(_glfwWindow, _windowContentScaleCallback);

GLFW.MakeContextCurrent(_glfwWindow);

Expand All @@ -126,6 +129,9 @@ private void InitWindow()
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.
Expand Down Expand Up @@ -218,7 +224,7 @@ private void OnGlfwChar(Window* window, uint codepoint)

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;

Expand Down Expand Up @@ -288,6 +294,11 @@ private void OnGlfwWindowSize(Window* window, int width, int height)
OnWindowResized?.Invoke(new WindowResizedEventArgs(oldSize, _screenSize));
}

private void OnGlfwWindownContentScale(Window *window, float xScale, float yScale)
{
_windowScale = (xScale, yScale);
}

private void StoreCallbacks()
{
_errorCallback = OnGlfwError;
Expand All @@ -298,6 +309,7 @@ private void StoreCallbacks()
_scrollCallback = OnGlfwScroll;
_windowCloseCallback = OnGlfwWindowClose;
_windowSizeCallback = OnGlfwWindowSize;
_windowContentScaleCallback = OnGlfwWindownContentScale;
}

public override void SetWindowTitle(string title)
Expand Down

0 comments on commit 5037ace

Please sign in to comment.