mirror of
https://github.com/OpenMW/openmw.git
synced 2025-04-03 12:36:39 +00:00
Implement system-scaled HiDPI support (SDL_WINDOW_ALLOW_HIGHDPI - Wayland, macOS, etc)
This commit is contained in:
parent
622f906855
commit
1c8fd2ecdb
6 changed files with 56 additions and 14 deletions
|
@ -584,7 +584,7 @@ void OMW::Engine::createWindow()
|
||||||
pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen);
|
pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE;
|
Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
if(windowMode == Settings::WindowMode::Fullscreen)
|
if(windowMode == Settings::WindowMode::Fullscreen)
|
||||||
flags |= SDL_WINDOW_FULLSCREEN;
|
flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
else if (windowMode == Settings::WindowMode::WindowedFullscreen)
|
else if (windowMode == Settings::WindowMode::WindowedFullscreen)
|
||||||
|
@ -640,11 +640,21 @@ void OMW::Engine::createWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since we use physical resolution internally, we have to create the window with scaled resolution,
|
||||||
|
// but we can't get the scale before the window exists, so instead we have to resize aftewards.
|
||||||
|
int w,h;
|
||||||
|
SDL_GetWindowSize(mWindow, &w, &h);
|
||||||
|
int dw,dh;
|
||||||
|
SDL_GL_GetDrawableSize(mWindow, &dw, &dh);
|
||||||
|
if (dw != w || dh != h) {
|
||||||
|
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
|
||||||
|
}
|
||||||
|
|
||||||
setWindowIcon();
|
setWindowIcon();
|
||||||
|
|
||||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
|
||||||
SDL_GetWindowPosition(mWindow, &traits->x, &traits->y);
|
SDL_GetWindowPosition(mWindow, &traits->x, &traits->y);
|
||||||
SDL_GetWindowSize(mWindow, &traits->width, &traits->height);
|
SDL_GL_GetDrawableSize(mWindow, &traits->width, &traits->height);
|
||||||
traits->windowName = SDL_GetWindowTitle(mWindow);
|
traits->windowName = SDL_GetWindowTitle(mWindow);
|
||||||
traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS);
|
traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS);
|
||||||
traits->screenNum = SDL_GetWindowDisplayIndex(mWindow);
|
traits->screenNum = SDL_GetWindowDisplayIndex(mWindow);
|
||||||
|
|
|
@ -177,7 +177,12 @@ namespace MWGui
|
||||||
, mVersionDescription(versionDescription)
|
, mVersionDescription(versionDescription)
|
||||||
, mWindowVisible(true)
|
, mWindowVisible(true)
|
||||||
{
|
{
|
||||||
mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f);
|
int w,h;
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
int dw,dh;
|
||||||
|
SDL_GL_GetDrawableSize(window, &dw, &dh);
|
||||||
|
|
||||||
|
mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f) * (dw / w);
|
||||||
mGuiPlatform = std::make_unique<osgMyGUI::Platform>(viewer, guiRoot, resourceSystem->getImageManager(),
|
mGuiPlatform = std::make_unique<osgMyGUI::Platform>(viewer, guiRoot, resourceSystem->getImageManager(),
|
||||||
resourceSystem->getVFS(), mScalingFactor, "mygui",
|
resourceSystem->getVFS(), mScalingFactor, "mygui",
|
||||||
logpath / "MyGUI.log");
|
logpath / "MyGUI.log");
|
||||||
|
|
|
@ -54,8 +54,13 @@ bool GraphicsWindowSDL2::setWindowRectangleImplementation(int x, int y, int widt
|
||||||
{
|
{
|
||||||
if(!mWindow) return false;
|
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_SetWindowPosition(mWindow, x, y);
|
||||||
SDL_SetWindowSize(mWindow, width, height);
|
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,23 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
|
||||||
Uint32 flags = SDL_GetWindowFlags(mSDLWindow);
|
Uint32 flags = SDL_GetWindowFlags(mSDLWindow);
|
||||||
mWindowHasFocus = (flags & SDL_WINDOW_INPUT_FOCUS);
|
mWindowHasFocus = (flags & SDL_WINDOW_INPUT_FOCUS);
|
||||||
mMouseInWindow = (flags & SDL_WINDOW_MOUSE_FOCUS);
|
mMouseInWindow = (flags & SDL_WINDOW_MOUSE_FOCUS);
|
||||||
|
_setWindowScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
InputWrapper::~InputWrapper()
|
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)
|
void InputWrapper::capture(bool windowEventsOnly)
|
||||||
{
|
{
|
||||||
mViewer->getEventQueue()->frame(0.f);
|
mViewer->getEventQueue()->frame(0.f);
|
||||||
|
@ -231,7 +242,7 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> v
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
int w,h;
|
int w,h;
|
||||||
SDL_GetWindowSize(mSDLWindow, &w, &h);
|
SDL_GL_GetDrawableSize(mSDLWindow, &w, &h);
|
||||||
int x,y;
|
int x,y;
|
||||||
SDL_GetWindowPosition(mSDLWindow, &x,&y);
|
SDL_GetWindowPosition(mSDLWindow, &x,&y);
|
||||||
mViewer->getCamera()->getGraphicsContext()->resized(x,y,w,h);
|
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)
|
if (mWindowListener)
|
||||||
mWindowListener->windowResized(w, h);
|
mWindowListener->windowResized(w, h);
|
||||||
|
|
||||||
|
_setWindowScale();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
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 InputWrapper::_packageMouseMotion(const SDL_Event &evt)
|
||||||
{
|
{
|
||||||
MouseMotionEvent pack_evt = {};
|
MouseMotionEvent pack_evt = {};
|
||||||
pack_evt.x = mMouseX;
|
pack_evt.x = mMouseX * mScaleX;
|
||||||
pack_evt.y = mMouseY;
|
pack_evt.y = mMouseY * mScaleY;
|
||||||
pack_evt.z = mMouseZ;
|
pack_evt.z = mMouseZ;
|
||||||
|
|
||||||
if(evt.type == SDL_MOUSEMOTION)
|
if(evt.type == SDL_MOUSEMOTION)
|
||||||
{
|
{
|
||||||
pack_evt.x = mMouseX = evt.motion.x;
|
pack_evt.x = mMouseX = evt.motion.x * mScaleX;
|
||||||
pack_evt.y = mMouseY = evt.motion.y;
|
pack_evt.y = mMouseY = evt.motion.y * mScaleY;
|
||||||
pack_evt.xrel = evt.motion.xrel;
|
pack_evt.xrel = evt.motion.xrel * mScaleX;
|
||||||
pack_evt.yrel = evt.motion.yrel;
|
pack_evt.yrel = evt.motion.yrel * mScaleY;
|
||||||
pack_evt.type = SDL_MOUSEMOTION;
|
pack_evt.type = SDL_MOUSEMOTION;
|
||||||
if (mFirstMouseMove)
|
if (mFirstMouseMove)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace SDLUtil
|
||||||
bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
|
bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
|
||||||
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
|
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
|
||||||
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
|
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
|
||||||
|
void _setWindowScale();
|
||||||
|
|
||||||
SDL_Window* mSDLWindow;
|
SDL_Window* mSDLWindow;
|
||||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||||
|
@ -79,6 +80,9 @@ namespace SDLUtil
|
||||||
|
|
||||||
bool mWindowHasFocus;
|
bool mWindowHasFocus;
|
||||||
bool mMouseInWindow;
|
bool mMouseInWindow;
|
||||||
|
|
||||||
|
Uint16 mScaleX;
|
||||||
|
Uint16 mScaleY;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,18 +76,23 @@ namespace SDLUtil
|
||||||
if (SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED)
|
if (SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED)
|
||||||
SDL_RestoreWindow(mWindow);
|
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)
|
if (windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen)
|
||||||
{
|
{
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
SDL_GetWindowDisplayMode(mWindow, &mode);
|
SDL_GetWindowDisplayMode(mWindow, &mode);
|
||||||
mode.w = width;
|
mode.w = width / (dw / w);
|
||||||
mode.h = height;
|
mode.h = height / (dh / h);
|
||||||
SDL_SetWindowDisplayMode(mWindow, &mode);
|
SDL_SetWindowDisplayMode(mWindow, &mode);
|
||||||
SDL_SetWindowFullscreen(mWindow, windowMode == Settings::WindowMode::Fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP);
|
SDL_SetWindowFullscreen(mWindow, windowMode == Settings::WindowMode::Fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SDL_SetWindowSize(mWindow, width, height);
|
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
|
||||||
SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE);
|
SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE);
|
||||||
|
|
||||||
centerWindow();
|
centerWindow();
|
||||||
|
|
Loading…
Reference in a new issue