Skip to content

Commit

Permalink
Add highDpi window attribute to allow full-res on mac retina displays…
Browse files Browse the repository at this point in the history
…. For #704
  • Loading branch information
Hugh Sanderson committed Jan 4, 2022
1 parent 04b36ec commit 969fa53
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 12 deletions.
9 changes: 9 additions & 0 deletions project/include/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ enum Cursor { curNone, curPointer, curHand,
extern const char *sTextCursorData[];
extern const char *sHandCursorData[];

#if defined(HX_MACOS)
extern void enableRetinaScale(bool enable);
extern double getRetinaScale();
#else
inline void enableRetinaScale(bool enable) { }
inline double getRetinaScale() { return 1.0; }
#endif

extern bool gMouseShowCursor;

class DisplayObject : public Object
Expand Down Expand Up @@ -573,6 +581,7 @@ enum WindowFlags
wfScaleMask = 0x0000f000,
wfHardwareMetal = 0x00010000,
wfAlwaysOnTop = 0x00020000,
wfHighDpi = 0x00040000,
};

enum WindowScaleMode
Expand Down
26 changes: 24 additions & 2 deletions project/src/mac/System.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ void GetVolumeInfo( std::vector<VolumeInfo> &outInfo )
}
#endif

static bool includeRetinaScale = false;
void enableRetinaScale(bool enable)
{
includeRetinaScale = enable;
}

double getRetinaScale()
{
@autoreleasepool {
NSScreen *screen = [NSScreen mainScreen];

double retinaScale = 1.0;
if (includeRetinaScale && [screen respondsToSelector:@selector(backingScaleFactor)])
retinaScale = [NSScreen mainScreen].backingScaleFactor;

return retinaScale;
}
}

double CapabilitiesGetScreenDPI()
{
Expand All @@ -70,16 +88,20 @@ void GetVolumeInfo( std::vector<VolumeInfo> &outInfo )
#endif

NSScreen *screen = [NSScreen mainScreen];
double retinaScale = 1.0;
if (includeRetinaScale && [screen respondsToSelector:@selector(backingScaleFactor)])
retinaScale = [NSScreen mainScreen].backingScaleFactor;

NSDictionary *description = [screen deviceDescription];
NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
CGSize displayPhysicalSize = CGDisplayScreenSize(
[[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
double result = ((displayPixelSize.width / displayPhysicalSize.width) + (displayPixelSize.height / displayPhysicalSize.height)) * 0.5 * 25.4;

#ifndef OBJC_ARC
[pool drain];
#endif
return result;
return result * retinaScale;
}

double CapabilitiesGetPixelAspectRatio() {
Expand Down
63 changes: 53 additions & 10 deletions project/src/sdl2/SDL2Stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,16 @@ class HardwareRenderSurface : public HardwareSurface
{
int width = 0;
int height = 0;
SDL_GetWindowSize(window, &width, &height);
//SDL_GetWindowSize(window, &width, &height);
SDL_GL_GetDrawableSize(window, &width, &height);
return width;
}
int Height() const
{
int width = 0;
int height = 0;
SDL_GetWindowSize(window, &width, &height);
//SDL_GetWindowSize(window, &width, &height);
SDL_GL_GetDrawableSize(window, &width, &height);
return height;
}
RenderTarget BeginRender(const Rect &inRect,bool inForHitTest)
Expand All @@ -147,7 +149,8 @@ class HardwareRenderSurface : public HardwareSurface
lastWindow = window;
int width = 0;
int height = 0;
SDL_GetWindowSize(window, &width, &height);
SDL_GL_GetDrawableSize(window, &width, &height);
//SDL_GetWindowSize(window, &width, &height);
mHardware->SetWindowSize(width,height);
SDL_GL_MakeCurrent(window, context);
}
Expand Down Expand Up @@ -531,7 +534,8 @@ class SDLStage : public Stage
if (!mIsFullscreen)
{
SDL_GetWindowPosition(mSDLWindow, &sgWindowRect.x, &sgWindowRect.y);
SDL_GetWindowSize(mSDLWindow, &sgWindowRect.w, &sgWindowRect.h);
//SDL_GetWindowSize(mSDLWindow, &sgWindowRect.w, &sgWindowRect.h);
SDL_GL_GetDrawableSize(mSDLWindow, &sgWindowRect.w, &sgWindowRect.h);
}

mIsFullscreen = inFullscreen;
Expand Down Expand Up @@ -942,6 +946,7 @@ class SDLFrame : public Frame
SDL_Window *mWindow;
bool mIsHardware;
uint32 mWindowFlags;
double retinaScale;

double mAccX;
double mAccY;
Expand All @@ -958,6 +963,8 @@ class SDLFrame : public Frame
windowID = SDL_GetWindowID(inWindow);
mStage = new SDLStage(inWindow, inRenderer, mWindowFlags, inIsHardware, inWidth, inHeight);
mStage->IncRef();

retinaScale = getRetinaScale();
}


Expand Down Expand Up @@ -988,6 +995,15 @@ class SDLFrame : public Frame
{
mStage->Resize(inWidth, inHeight);
}

void scaleMouseDpi(Event &ioEvent)
{
if (retinaScale!=1.0)
{
ioEvent.x = (int)(ioEvent.x*retinaScale + 0.5);
ioEvent.y = (int)(ioEvent.y*retinaScale + 0.5);
}
}


// --- Frame Interface ----------------------------------------------------
Expand Down Expand Up @@ -1660,7 +1676,8 @@ void ProcessEvent(SDL_Event &inEvent)
if (frame)
{
Event resize(etResize, inEvent.window.data1, inEvent.window.data2);
frame->Resize(inEvent.window.data1, inEvent.window.data2);
frame->scaleMouseDpi(resize);
frame->Resize(resize.x, resize.y);
frame->ProcessEvent(resize);
Event redraw(etRedraw);
frame->ProcessEvent(redraw);
Expand Down Expand Up @@ -1689,7 +1706,8 @@ void ProcessEvent(SDL_Event &inEvent)

int width = 0;
int height = 0;
SDL_GetWindowSize(frame->mWindow, &width, &height);
//SDL_GetWindowSize(frame->mWindow, &width, &height);
SDL_GL_GetDrawableSize(frame->mWindow, &width, &height);

Event resize(etResize, width, height);
frame->Resize(width,height);
Expand Down Expand Up @@ -1754,6 +1772,7 @@ void ProcessEvent(SDL_Event &inEvent)
int y=0;
SDL_GetMouseState(&x,&y);
Event event(etDropEnd, x, y);
frame->scaleMouseDpi(event);
AddModStates(event.flags);
frame->ProcessEvent(event);
break;
Expand Down Expand Up @@ -1781,10 +1800,14 @@ void ProcessEvent(SDL_Event &inEvent)
//pass the delta in as well through as deltaX
if(SDL_GetRelativeMouseMode()) {
SDL_GetRelativeMouseState( &deltaX, &deltaY );
deltaX = (int)(deltaX * frame->retinaScale);
deltaY = (int)(deltaY * frame->retinaScale);
}

//int inValue=0, int inID=0, int inFlags=0, float inScaleX=1,float inScaleY=1, int inDeltaX=0,int inDeltaY=0
Event mouse(etMouseMove, inEvent.motion.x, inEvent.motion.y, 0, 0, 0, 1.0f, 1.0f, deltaX, deltaY);
frame->scaleMouseDpi(mouse);

#if defined(WEBOS) || defined(BLACKBERRY)
mouse.value = inEvent.motion.which;
mouse.flags |= efLeftDown;
Expand All @@ -1798,6 +1821,7 @@ void ProcessEvent(SDL_Event &inEvent)
{
SDLFrame *frame = getEventFrame(inEvent.button.windowID);
Event mouse(etMouseDown, inEvent.button.x, inEvent.button.y, inEvent.button.button - 1);
frame->scaleMouseDpi(mouse);
#if defined(WEBOS) || defined(BLACKBERRY)
mouse.value = inEvent.motion.which;
mouse.flags |= efLeftDown;
Expand All @@ -1811,6 +1835,7 @@ void ProcessEvent(SDL_Event &inEvent)
{
SDLFrame *frame = getEventFrame(inEvent.button.windowID);
Event mouse(etMouseUp, inEvent.button.x, inEvent.button.y, inEvent.button.button - 1);
frame->scaleMouseDpi(mouse);
#if defined(WEBOS) || defined(BLACKBERRY)
mouse.value = inEvent.motion.which;
#else
Expand Down Expand Up @@ -1838,6 +1863,7 @@ void ProcessEvent(SDL_Event &inEvent)
mouse.deltaY = inEvent.wheel.y;
//add flags for modifier keys
AddModStates(mouse.flags);
frame->scaleMouseDpi(mouse);
//and done.
frame->ProcessEvent(mouse);
break;
Expand All @@ -1848,7 +1874,8 @@ void ProcessEvent(SDL_Event &inEvent)
SDLFrame *frame = getEventFrame(inEvent.tfinger.windowID);
int width = 0;
int height = 0;
SDL_GetWindowSize(frame->mWindow, &width, &height);
//SDL_GetWindowSize(frame->mWindow, &width, &height);
SDL_GL_GetDrawableSize(frame->mWindow, &width, &height);

// button?
Event mouse(etMouseDown, inEvent.tfinger.x*width, inEvent.tfinger.y*height, 0);
Expand All @@ -1862,7 +1889,8 @@ void ProcessEvent(SDL_Event &inEvent)
SDLFrame *frame = getEventFrame(inEvent.tfinger.windowID);
int width = 0;
int height = 0;
SDL_GetWindowSize(frame->mWindow, &width, &height);
//SDL_GetWindowSize(frame->mWindow, &width, &height);
SDL_GL_GetDrawableSize(frame->mWindow, &width, &height);

// button?
Event mouse(etMouseUp, inEvent.tfinger.x*width, inEvent.tfinger.y*height, 0);
Expand All @@ -1876,7 +1904,8 @@ void ProcessEvent(SDL_Event &inEvent)
SDLFrame *frame = getEventFrame(inEvent.tfinger.windowID);
int width = 0;
int height = 0;
SDL_GetWindowSize(frame->mWindow, &width, &height);
//SDL_GetWindowSize(frame->mWindow, &width, &height);
SDL_GL_GetDrawableSize(frame->mWindow, &width, &height);

// button?
Event mouse(etMouseMove, inEvent.tfinger.x*width, inEvent.tfinger.y*height, 0);
Expand Down Expand Up @@ -2116,6 +2145,7 @@ void CreateMainFrame(FrameCreationCallback inOnFrame, int inWidth, int inHeight,
bool resizable = (inFlags & wfResizable) != 0;
bool borderless = (inFlags & wfBorderless) != 0;
bool vsync = (inFlags & wfVSync) != 0;
bool tryHighDpi = (inFlags & wfHighDpi) != 0;
//WindowScaleMode scaleMode = (WindowScaleMode)( (inFlags & wfScaleMask)/wfScaleBase );

#ifdef HX_LINUX
Expand Down Expand Up @@ -2180,6 +2210,11 @@ void CreateMainFrame(FrameCreationCallback inOnFrame, int inWidth, int inHeight,
if (resizable) requestWindowFlags |= SDL_WINDOW_RESIZABLE;
if (borderless) requestWindowFlags |= SDL_WINDOW_BORDERLESS;
if (fullscreen) requestWindowFlags |= FullscreenMode; //SDL_WINDOW_FULLSCREEN_DESKTOP;
if (tryHighDpi)
{
requestWindowFlags |= SDL_WINDOW_ALLOW_HIGHDPI;
enableRetinaScale(true);
}

if (inFlags & wfAlwaysOnTop)
requestWindowFlags |= SDL_WINDOW_ALWAYS_ON_TOP;
Expand Down Expand Up @@ -2223,7 +2258,11 @@ void CreateMainFrame(FrameCreationCallback inOnFrame, int inWidth, int inHeight,
}
}

// Get DPI without retina, "sdl window coordinates"
enableRetinaScale(false);
double dpiScale = CapabilitiesGetScreenDPI()/96.0;
enableRetinaScale(tryHighDpi);

int targetW = dpiScale<1.5 ? inWidth : dpiScale*inWidth;
if (targetW>sgDesktopWidth)
targetW = sgDesktopWidth;
Expand Down Expand Up @@ -2372,6 +2411,7 @@ void CreateMainFrame(FrameCreationCallback inOnFrame, int inWidth, int inHeight,
}

int width, height;
/*
if (windowFlags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP) )
{
//SDL_DisplayMode mode;
Expand All @@ -2382,8 +2422,10 @@ void CreateMainFrame(FrameCreationCallback inOnFrame, int inWidth, int inHeight,
height = sgDesktopHeight;
}
else
*/
{
SDL_GetWindowSize(window, &width, &height);
SDL_GL_GetDrawableSize(window, &width, &height);
//SDL_GetWindowSize(window, &width, &height);
}


Expand All @@ -2394,6 +2436,7 @@ void CreateMainFrame(FrameCreationCallback inOnFrame, int inWidth, int inHeight,
else if (sgMainRenderer==renderer)
renderer = 0;


SDLFrame *frame = new SDLFrame(window, renderer, windowFlags, hardware, width, height);

if (isMain)
Expand Down
1 change: 1 addition & 0 deletions src/nme/app/Application.hx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class Application
public inline static var SCALE_BASE = 0x1000;
public inline static var HARDWARE_METAL =0x10000;
public inline static var ALWAYS_ON_TOP =0x20000;
public inline static var HIGH_DPI =0x40000;

public static var nmeFrameHandle:Dynamic = null;
public static var nmeWindow:Window = null;
Expand Down
1 change: 1 addition & 0 deletions templates/haxe/ApplicationMain.hx
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ class ApplicationMain
(::WIN_ANTIALIASING:: == 4 ? nme.app.Application.HW_AA_HIRES : 0) |
(::WIN_ANTIALIASING:: == 2 ? nme.app.Application.HW_AA : 0)|
(::WIN_SINGLE_INSTANCE:: ? nme.app.Application.SINGLE_INSTANCE : 0) |
(::WIN_HIGH_DPI:: ? nme.app.Application.HIGH_DPI : 0) |
(::WIN_SCALE_FLAGS:: * nme.app.Application.SCALE_BASE)
;

Expand Down
2 changes: 2 additions & 0 deletions tools/nme/src/project/Window.hx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Window
public var alphaBuffer:Bool;
public var ui:String;
public var singleInstance:Bool;
public var highDpi:Bool;
public var scaleMode:ScaleMode;

public function new()
Expand All @@ -43,6 +44,7 @@ class Window
depthBuffer = false;
stencilBuffer = false;
alphaBuffer = false;
highDpi = false;
ui = "";
singleInstance = true;
scaleMode = ScaleNative;
Expand Down

0 comments on commit 969fa53

Please sign in to comment.