Я являюсь автором Hearthstone tracker, и мне нужно переместить несколько NSWindow
над окном Каменного камня.NSWindow positioning
Я получаю раму из Hearthstone, используя CGWindowListCopyWindowInfo
. Затем я должен переместить свои окна в некоторых положениях относительно Сердца.
Красные стрелки над картами противников, зеленая стрелка над кнопкой поворота, а синие стрелки расположены слева и справа от окна.
Моя текущая настройка экрана является следующее:
, который дает мне следующие кадры
// screen 1 : {x 0 y 0 w 1.440 h 900}
// screen 2 : {x 1.440 y -180 w 1.920 h 1.080}
Чтобы поместить противника трекер (левый кадр) в нужное положение, которое это самый простой случай, я использую {x 0 y somepadding w 185 h hearthstoneHeight - somepadding}
и получаю правильную рамку с этим
func relativeFrame(frame: NSRect) -> NSRect {
var relative = frame
relative.origin.x = NSMinX(hearthstoneFrame) + NSMinX(frame)
relative.origin.y = NSMinY(hearthstoneFrame) + NSMinY(frame)
return relative
}
Право трекер находится с помощью {x hearthstoneWidth - trackerWidth, ...}
Для других наложений, я использовал мой текущий (Хартстон) разрешение поместить их и их вычислить их, используя простую математику
x = x/1404.0 * NSWidth(hearthstoneFrame)
y = y/840.0 * NSHeight(hearthstoneFrame)
Это работает очень хорошо. Кроме того, если я использую свой второй экран. В этом случае рамки кажутся правильными, но положение окна не очень хорошо.
Вот скриншот окна отладки с {x 0 y 0 w hearthstoneWidth h hearthsoneHeight }
. Если я сравню рамки Сердца и моего наложения, они будут идентичны.
Полная функция следующая (я нахожусь в «статическом классе», я только показываю код переоценки). Наверное, мне не хватает чего-то в расчетах, но я не могу найти что.
class frameRelative {
static var hearthstoneFrame = NSZeroRect
static func findHearthstoneFrame() {
let options = CGWindowListOption(arrayLiteral: .ExcludeDesktopElements)
let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
if let info = (windowListInfo as NSArray? as? [[String: AnyObject]])?
.filter({
!$0.filter({ $0.0 == "kCGWindowName" && $0.1 as? String == "Hearthstone" }).isEmpty
})
.first {
var rect = NSRect()
let bounds = info["kCGWindowBounds"] as! CFDictionary
CGRectMakeWithDictionaryRepresentation(bounds, &rect)
rect.size.height -= titleBarHeight // remove the 22px from the title
hearthstoneFrame = rect
}
}
static func frameRelative(frame: NSRect, _ isRelative: Bool = false) -> NSRect {
var relative = frame
var pointX = NSMinX(relative)
var pointY = NSMinY(relative)
if isRelative {
pointX = pointX/1404.0 * NSWidth(hearthstoneFrame)
pointY = pointY/840.0 * NSHeight(hearthstoneFrame)
}
let x: CGFloat = NSMinX(hearthstoneFrame) + pointX
let y = NSMinY(hearthstoneFrame) + pointY
relative.origin = NSMakePoint(x, y)
return relative
}
}
// somewhere here
let frame = NSMakeRect(0, 0, hearthstoneWidth, hearthstoneHeight)
let relativeFrame = SizeHelper.frameRelative(frame)
myWindow.setFrame(relativeFrame, display: true)
Любая помощь будет признателен :)