Я возился с вашим кодом, и @Ted верен NSWindow.order(_:relativeTo)
- это именно то, что вам нужно.
Почему NSWindow.level не будет работать:
Использование NSWindow.level
не будет работать для вас, потому что все обычные окна (как на скриншоте) имеют уровень окна 0
или .normal
. Если вы просто отрегулируете уровень окна, скажем, например, «1», ваш вид подсветки будет отображаться над всеми другими окнами. Напротив, если вы установите его на «-1», ваше выделение будет отображаться ниже всех обычных окон и над рабочим столом.
Проблемы, которые будут введены с помощью NSWindow.order (_ :lativeTo)
Нет хорошего решения без предостережений, верно? Чтобы использовать этот метод, вам нужно установить уровень окна на 0
, чтобы он мог быть наслоен среди других окон. Однако это приведет к тому, что ваше окно выделения будет выбрано в вашем методе WindowList.window(at: mouseLocation)
. И когда он выбран, ваш оператор if удаляет его, потому что считает, что это главное окно. Это вызовет мерцание. (исправление для этого включено в TLDR ниже)
Кроме того, если вы попытаетесь выделить окно, в котором не имеет уровень 0
, у вас возникнут проблемы. Чтобы исправить такие проблемы, вам нужно найти уровень окна того окна, которое вы выделяете, и установить ваше окно выделения на этот уровень. (мой код не содержит исправления для этой проблемы)
В дополнение к вышеупомянутым проблемам вам необходимо учитывать, что происходит, когда пользователь наводит курсор на фоновое окно и щелкает по нему, не перемещая мышь. Что произойдет, если фоновое окно станет передним. без перемещения окна выделения. Возможным решением этой проблемы является обновление окна выделения при событиях щелчка.
Наконец, я заметил, что вы создаете новое окно HighlightWindowController
+ каждый раз, когда пользователь перемещает свою мышь. В системе может быть немного легче, если вы просто измените кадр уже существующего HighlightWindowController
при движении мыши (вместо того, чтобы создать его). Чтобы скрыть это, вы можете вызвать функцию NSWindowController.close()
или даже установить фрейм в {0,0,0,0} (не уверен насчет второй идеи).
TLDR; Покажите нам код
Вот что я сделал.
1. Измените структуру окна, включив в нее номер окна:
struct Window {
let frame: CGRect
let applicationName: String
let windowNumber: Int
init(frame: CGRect, applicationName: String, refNumber: Int) {
self.frame = frame.flippedScreenBounds
self.applicationName = applicationName
self.windowNumber = refNumber
}
var isCapture: Bool {
return applicationName.caseInsensitiveCompare("Capture") == .orderedSame
}
}
2. В вашей функции листинга окна, например, static func all() -> [Window]
, укажите номер окна:
refNumber: $0["kCGWindowNumber"] as! Int
3. В вашей функции подсветки окна, после highlightWindowController?.showWindow(nil)
, расположите окно относительно окна, которое вы выделяете!
highlightWindowController!.window!.order(.above, relativeTo: window.windowNumber)
4. В контроллере подсветки обязательно установите уровень окна в нормальное состояние:
window.level = .normal
5. Теперь окно будет мерцать, чтобы предотвратить это, обновите оператор if вашего оператора представления:
if let window = WindowList.window(at: mouseLocation) {
if !window.isCapture {
highlight(window: window)
}
} else {
removeHighlight()
}
Желаю удачи и веселья!
Edit:
Я забыл упомянуть, моя swift версия 4.2 (еще не обновлена), поэтому синтаксис может немного отличаться.