mirror of
https://github.com/love2d/love.git
synced 2026-08-16 16:20:42 +02:00
Added opt-in support for high-dpi mode in OS X when on a retina display (resolves issue #761).
Added a ‘highdpi’ boolean flag to t.window/love.window.setMode (defaults to false.) When the window is actually in high-dpi mode on a supported display, the graphics width and height and the mouse position are in pixels, rather than ‘window coordinates’. Added love.window.getPixelScale. Returns the scale factor of the window from user-space points to pixels (e.g. it will be 1 normally, and 2 on a retina display in OS X with high-dpi mode enabled.)
This commit is contained in:
@@ -63,21 +63,21 @@ Window::~Window()
|
||||
Window::_currentMode::_currentMode()
|
||||
: width(800)
|
||||
, height(600)
|
||||
, attribs()
|
||||
, settings()
|
||||
, icon(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool Window::setWindow(int width, int height, WindowAttributes *attribs)
|
||||
bool Window::setWindow(int width, int height, WindowSettings *settings)
|
||||
{
|
||||
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
|
||||
if (gfx)
|
||||
if (gfx != nullptr)
|
||||
gfx->unSetMode();
|
||||
|
||||
WindowAttributes f;
|
||||
WindowSettings f;
|
||||
|
||||
if (attribs)
|
||||
f = *attribs;
|
||||
if (settings)
|
||||
f = *settings;
|
||||
|
||||
f.minwidth = std::max(f.minwidth, 1);
|
||||
f.minheight = std::max(f.minheight, 1);
|
||||
@@ -116,15 +116,28 @@ bool Window::setWindow(int width, int height, WindowAttributes *attribs)
|
||||
if (f.borderless)
|
||||
sdlflags |= SDL_WINDOW_BORDERLESS;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
if (f.highdpi)
|
||||
sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
#endif
|
||||
|
||||
// Destroy and recreate the window if the dimensions or flags have changed.
|
||||
if (window)
|
||||
{
|
||||
int curdisplay = SDL_GetWindowDisplayIndex(window);
|
||||
Uint32 wflags = SDL_GetWindowFlags(window);
|
||||
wflags &= (SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS);
|
||||
|
||||
Uint32 testflags = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP
|
||||
| SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
testflags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
#endif
|
||||
|
||||
wflags &= testflags;
|
||||
|
||||
if (sdlflags != wflags || width != curMode.width || height != curMode.height
|
||||
|| f.display != curdisplay || f.fsaa != curMode.attribs.fsaa)
|
||||
|| f.display != curdisplay || f.fsaa != curMode.settings.fsaa)
|
||||
{
|
||||
SDL_DestroyWindow(window);
|
||||
window = 0;
|
||||
@@ -182,10 +195,19 @@ bool Window::setWindow(int width, int height, WindowAttributes *attribs)
|
||||
|
||||
created = true;
|
||||
|
||||
updateAttributes(f);
|
||||
updateSettings(f);
|
||||
|
||||
if (gfx)
|
||||
gfx->setMode(curMode.width, curMode.height);
|
||||
if (gfx != nullptr)
|
||||
{
|
||||
int width = curMode.width;
|
||||
int height = curMode.height;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
SDL_GL_GetDrawableSize(window, &width, &height);
|
||||
#endif
|
||||
|
||||
gfx->setMode(width, height);
|
||||
}
|
||||
|
||||
// Make sure the mouse keeps its previous grab setting.
|
||||
setMouseGrab(mouseGrabbed);
|
||||
@@ -250,8 +272,8 @@ bool Window::setContext(int fsaa, bool vsync)
|
||||
fsaa = (buffers > 0) ? samples : 0;
|
||||
}
|
||||
|
||||
curMode.attribs.fsaa = fsaa;
|
||||
curMode.attribs.vsync = SDL_GL_GetSwapInterval() != 0;
|
||||
curMode.settings.fsaa = fsaa;
|
||||
curMode.settings.vsync = SDL_GL_GetSwapInterval() != 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -271,7 +293,7 @@ void Window::setWindowGLAttributes(int fsaa) const
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
|
||||
}
|
||||
|
||||
void Window::updateAttributes(const WindowAttributes &newattribs)
|
||||
void Window::updateSettings(const WindowSettings &newsettings)
|
||||
{
|
||||
Uint32 wflags = SDL_GetWindowFlags(window);
|
||||
|
||||
@@ -280,54 +302,60 @@ void Window::updateAttributes(const WindowAttributes &newattribs)
|
||||
|
||||
if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
curMode.attribs.fullscreen = true;
|
||||
curMode.attribs.fstype = FULLSCREEN_TYPE_DESKTOP;
|
||||
curMode.settings.fullscreen = true;
|
||||
curMode.settings.fstype = FULLSCREEN_TYPE_DESKTOP;
|
||||
}
|
||||
else if ((wflags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)
|
||||
{
|
||||
curMode.attribs.fullscreen = true;
|
||||
curMode.attribs.fstype = FULLSCREEN_TYPE_NORMAL;
|
||||
curMode.settings.fullscreen = true;
|
||||
curMode.settings.fstype = FULLSCREEN_TYPE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
curMode.attribs.fullscreen = false;
|
||||
curMode.attribs.fstype = newattribs.fstype;
|
||||
curMode.settings.fullscreen = false;
|
||||
curMode.settings.fstype = newsettings.fstype;
|
||||
}
|
||||
|
||||
// The min width/height is set to 0 internally in SDL when in fullscreen.
|
||||
if (curMode.attribs.fullscreen)
|
||||
if (curMode.settings.fullscreen)
|
||||
{
|
||||
curMode.attribs.minwidth = newattribs.minwidth;
|
||||
curMode.attribs.minheight = newattribs.minheight;
|
||||
curMode.settings.minwidth = newsettings.minwidth;
|
||||
curMode.settings.minheight = newsettings.minheight;
|
||||
}
|
||||
else
|
||||
SDL_GetWindowMinimumSize(window, &curMode.attribs.minwidth, &curMode.attribs.minheight);
|
||||
SDL_GetWindowMinimumSize(window, &curMode.settings.minwidth, &curMode.settings.minheight);
|
||||
|
||||
curMode.attribs.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
|
||||
curMode.attribs.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
|
||||
curMode.attribs.centered = newattribs.centered;
|
||||
curMode.attribs.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
curMode.settings.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
|
||||
curMode.settings.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
|
||||
curMode.settings.centered = newsettings.centered;
|
||||
curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
curMode.settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
|
||||
#else
|
||||
curMode.settings.highdpi = false;
|
||||
#endif
|
||||
|
||||
// Only minimize on focus loss if the window is in exclusive-fullscreen
|
||||
// mode (mimics behaviour of SDL 2.0.2+).
|
||||
// In OS X we always disable this to prevent dock minimization weirdness.
|
||||
#ifndef LOVE_MACOSX
|
||||
if (curMode.attribs.fullscreen && curMode.attribs.fstype == FULLSCREEN_TYPE_NORMAL)
|
||||
if (curMode.settings.fullscreen && curMode.settings.fstype == FULLSCREEN_TYPE_NORMAL)
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "1");
|
||||
else
|
||||
#endif
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
}
|
||||
|
||||
void Window::getWindow(int &width, int &height, WindowAttributes &attribs)
|
||||
void Window::getWindow(int &width, int &height, WindowSettings &settings)
|
||||
{
|
||||
// Window position may be different from creation - update display index.
|
||||
if (window)
|
||||
curMode.attribs.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
|
||||
|
||||
width = curMode.width;
|
||||
height = curMode.height;
|
||||
attribs = curMode.attribs;
|
||||
settings = curMode.settings;
|
||||
}
|
||||
|
||||
bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
@@ -335,9 +363,9 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
WindowAttributes newattribs = curMode.attribs;
|
||||
newattribs.fullscreen = fullscreen;
|
||||
newattribs.fstype = fstype;
|
||||
WindowSettings newsettings = curMode.settings;
|
||||
newsettings.fullscreen = fullscreen;
|
||||
newsettings.fstype = fstype;
|
||||
|
||||
Uint32 sdlflags = 0;
|
||||
|
||||
@@ -361,12 +389,21 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
if (SDL_SetWindowFullscreen(window, sdlflags) == 0)
|
||||
{
|
||||
SDL_GL_MakeCurrent(window, context);
|
||||
updateAttributes(newattribs);
|
||||
updateSettings(newsettings);
|
||||
|
||||
// Update the viewport size now instead of waiting for event polling.
|
||||
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
|
||||
if (gfx)
|
||||
gfx->setViewportSize(curMode.width, curMode.height);
|
||||
if (gfx != nullptr)
|
||||
{
|
||||
int width = curMode.width;
|
||||
int height = curMode.height;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
SDL_GL_GetDrawableSize(window, &width, &height);
|
||||
#endif
|
||||
|
||||
gfx->setViewportSize(width, height);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -376,7 +413,7 @@ bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
|
||||
|
||||
bool Window::setFullscreen(bool fullscreen)
|
||||
{
|
||||
return setFullscreen(fullscreen, curMode.attribs.fstype);
|
||||
return setFullscreen(fullscreen, curMode.settings.fstype);
|
||||
}
|
||||
|
||||
int Window::getDisplayCount() const
|
||||
@@ -559,6 +596,26 @@ bool Window::isMouseGrabbed() const
|
||||
return mouseGrabbed;
|
||||
}
|
||||
|
||||
double Window::getPixelScale() const
|
||||
{
|
||||
double scale = 1.0;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,1)
|
||||
if (window)
|
||||
{
|
||||
int wheight;
|
||||
SDL_GetWindowSize(window, nullptr, &wheight);
|
||||
|
||||
int dheight = wheight;
|
||||
SDL_GL_GetDrawableSize(window, nullptr, &dheight);
|
||||
|
||||
scale = (double) dheight / wheight;
|
||||
}
|
||||
#endif
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
const void *Window::getHandle() const
|
||||
{
|
||||
return window;
|
||||
|
||||
@@ -41,8 +41,8 @@ public:
|
||||
Window();
|
||||
~Window();
|
||||
|
||||
bool setWindow(int width = 800, int height = 600, WindowAttributes *attribs = 0);
|
||||
void getWindow(int &width, int &height, WindowAttributes &attribs);
|
||||
bool setWindow(int width = 800, int height = 600, WindowSettings *settings = nullptr);
|
||||
void getWindow(int &width, int &height, WindowSettings &settings);
|
||||
|
||||
bool setFullscreen(bool fullscreen, FullscreenType fstype);
|
||||
bool setFullscreen(bool fullscreen);
|
||||
@@ -79,6 +79,8 @@ public:
|
||||
void setMouseGrab(bool grab);
|
||||
bool isMouseGrabbed() const;
|
||||
|
||||
double getPixelScale() const;
|
||||
|
||||
const void *getHandle() const;
|
||||
|
||||
static love::window::Window *createSingleton();
|
||||
@@ -91,8 +93,8 @@ private:
|
||||
bool setContext(int fsaa, bool vsync);
|
||||
void setWindowGLAttributes(int fsaa) const;
|
||||
|
||||
// Update the saved window attribs based on the window's actual state.
|
||||
void updateAttributes(const WindowAttributes &newattribs);
|
||||
// Update the saved window settings based on the window's actual state.
|
||||
void updateSettings(const WindowSettings &newsettings);
|
||||
|
||||
std::string windowTitle;
|
||||
|
||||
@@ -102,7 +104,7 @@ private:
|
||||
|
||||
int width;
|
||||
int height;
|
||||
WindowAttributes attribs;
|
||||
WindowSettings settings;
|
||||
love::image::ImageData *icon;
|
||||
|
||||
} curMode;
|
||||
|
||||
Reference in New Issue
Block a user