NSScreen - reports wrong dimensions [SWIFT]

Has anyone ever used NSScreen… I am trying to get the dimensions and it is giving me wrong results on my main screen.

I have 3 monitors… 2 19" 1280x1024 and the main 27" iMac at 5120x2880 (retina)

When I query either of the 19" monitors NScreen returns 1280x1024 which is of course the correct value (note these are NOT Retina monitors)

On the iMac it says the screen is 2048x1152 (tiny!) and this is not off by a factor of “scale” [which is 2.0] … it is off by a factor of exactly 2.50

print(\(NSScreen.main!.frame)

“main” is the screen where the current active window is

every article I can find says I am doing this exactly correctly

Screen #0 = (2048.0, 1152.0) scale=2.0
Screen #1 = (1280.0, 1024.0) scale=1.0
Screen #2 = (1280.0, 1024.0) scale=1.0

Ok… I figured out what the issue was. In Settings I had the Screen set to “Scaled”

which is fine, if I can find a way to determine what the “Scaled” value is (and it is not the same as the Retina backingScaleFactor

I’m getting there… it is so stupid that somethings have Y=0 at the top, and other views flip it… makes it a royal pain to normalize things

1 Like

FINALLY!

private func sFlipY(_ y:CGFloat) -> CGFloat { return ((NSScreen.main?.frame.size.height)!-y) }  // NSScreen has y=0 at bottom
	
private func flipRect(_ rr:NSRect) -> NSRect {
		var r = rr
		r.origin.y = sFlipY(r.origin.y)
		return r
	}

public final var top : CGFloat {
		get { return sFlipY(self.frame.origin.y) }
		set { // updated 28Oct2020
			zWindowTop = newValue
			var f      = self.frame;
			f.origin.y =  newValue+f.size.height+titlebarHeight+0
			f=flipRect(f)
			self.setFrame(f, display: true)
		}
	}

public final var height : CGFloat {
		get { return self.frame.size.height }
		set { // updated 28Oct2020
			if newValue<=self.maxSize.height && newValue>=self.minSize.height {
				var f=self.frame
				f.size.height = newValue+titlebarHeight
				self.setFrame(f, display: true)
				top=zWindowTop
				updateMouseArea()
			}
		}
	}

private var titlebarHeight: CGFloat { get {
		let contentHeight = contentRect(forFrameRect: frame).height
		return frame.height - contentHeight
	}
	}

if you change the HEIGHT, you need to reset the TOP

1 Like