Implement system-scaled HiDPI support (SDL_WINDOW_ALLOW_HIGHDPI - Wayland, macOS, etc)

This commit is contained in:
unrelentingtech 2022-09-12 08:18:08 +00:00 committed by psi29a
parent 622f906855
commit 1c8fd2ecdb
6 changed files with 56 additions and 14 deletions

View file

@ -54,8 +54,13 @@ bool GraphicsWindowSDL2::setWindowRectangleImplementation(int x, int y, int widt
{
if(!mWindow) return false;
int w,h;
SDL_GetWindowSize(mWindow, &w, &h);
int dw,dh;
SDL_GL_GetDrawableSize(mWindow, &dw, &dh);
SDL_SetWindowPosition(mWindow, x, y);
SDL_SetWindowSize(mWindow, width, height);
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
return true;
}

View file

@ -36,12 +36,23 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
Uint32 flags = SDL_GetWindowFlags(mSDLWindow);
mWindowHasFocus = (flags & SDL_WINDOW_INPUT_FOCUS);
mMouseInWindow = (flags & SDL_WINDOW_MOUSE_FOCUS);
_setWindowScale();
}
InputWrapper::~InputWrapper()
{
}
void InputWrapper::_setWindowScale()
{
int w,h;
SDL_GetWindowSize(mSDLWindow, &w, &h);
int dw,dh;
SDL_GL_GetDrawableSize(mSDLWindow, &dw, &dh);
mScaleX = dw / w;
mScaleY = dh / h;
}
void InputWrapper::capture(bool windowEventsOnly)
{
mViewer->getEventQueue()->frame(0.f);
@ -231,7 +242,7 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
int w,h;
SDL_GetWindowSize(mSDLWindow, &w, &h);
SDL_GL_GetDrawableSize(mSDLWindow, &w, &h);
int x,y;
SDL_GetWindowPosition(mSDLWindow, &x,&y);
mViewer->getCamera()->getGraphicsContext()->resized(x,y,w,h);
@ -241,6 +252,8 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
if (mWindowListener)
mWindowListener->windowResized(w, h);
_setWindowScale();
break;
case SDL_WINDOWEVENT_RESIZED:
@ -383,16 +396,16 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt)
{
MouseMotionEvent pack_evt = {};
pack_evt.x = mMouseX;
pack_evt.y = mMouseY;
pack_evt.x = mMouseX * mScaleX;
pack_evt.y = mMouseY * mScaleY;
pack_evt.z = mMouseZ;
if(evt.type == SDL_MOUSEMOTION)
{
pack_evt.x = mMouseX = evt.motion.x;
pack_evt.y = mMouseY = evt.motion.y;
pack_evt.xrel = evt.motion.xrel;
pack_evt.yrel = evt.motion.yrel;
pack_evt.x = mMouseX = evt.motion.x * mScaleX;
pack_evt.y = mMouseY = evt.motion.y * mScaleY;
pack_evt.xrel = evt.motion.xrel * mScaleX;
pack_evt.yrel = evt.motion.yrel * mScaleY;
pack_evt.type = SDL_MOUSEMOTION;
if (mFirstMouseMove)
{

View file

@ -49,6 +49,7 @@ namespace SDLUtil
bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
void _setWindowScale();
SDL_Window* mSDLWindow;
osg::ref_ptr<osgViewer::Viewer> mViewer;
@ -79,6 +80,9 @@ namespace SDLUtil
bool mWindowHasFocus;
bool mMouseInWindow;
Uint16 mScaleX;
Uint16 mScaleY;
};
}

View file

@ -76,18 +76,23 @@ namespace SDLUtil
if (SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED)
SDL_RestoreWindow(mWindow);
int w,h;
SDL_GetWindowSize(mWindow, &w, &h);
int dw,dh;
SDL_GL_GetDrawableSize(mWindow, &dw, &dh);
if (windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen)
{
SDL_DisplayMode mode;
SDL_GetWindowDisplayMode(mWindow, &mode);
mode.w = width;
mode.h = height;
mode.w = width / (dw / w);
mode.h = height / (dh / h);
SDL_SetWindowDisplayMode(mWindow, &mode);
SDL_SetWindowFullscreen(mWindow, windowMode == Settings::WindowMode::Fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP);
}
else
{
SDL_SetWindowSize(mWindow, width, height);
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE);
centerWindow();