Как получить глобальные экранные координаты выделенного в данный момент текста через API специальных возможностей.
Мне нужна помощь, чтобы узнать, как приложение "Словарь" показывает следующее всплывающее диалоговое окно для выделенного текста при нажатии CMD+CTRL+D в любом приложении. Я хочу реализовать такую же функциональность для моего приложения с какао, где мое приложение будет работать в фоновом режиме и отображать предложения по нажатию горячей клавиши для выбранного текста.
Я уже реализовал захват с помощью горячих клавиш, мне просто нужен код, чтобы получить область прямоугольника выделенного текста на экране, чтобы я мог показывать диалог, как приложение словаря.
Спасибо
2 ответа
Вы можете использовать специальные API для этого. Убедитесь, что установлен флажок "Включить доступ для вспомогательных устройств" (в "Системных настройках" / "Универсальный доступ").
Следующий фрагмент кода определит границы (в экранных координатах) выделенного текста в большинстве приложений. К сожалению, это не работает в Mail и Safari, потому что они используют приватные атрибуты доступности. Вероятно, можно заставить его работать там, но это требует больше работы и, возможно, частных вызовов API.
AXUIElementRef systemWideElement = AXUIElementCreateSystemWide();
AXUIElementRef focussedElement = NULL;
AXError error = AXUIElementCopyAttributeValue(systemWideElement, kAXFocusedUIElementAttribute, (CFTypeRef *)&focussedElement);
if (error != kAXErrorSuccess) {
NSLog(@"Could not get focussed element");
} else {
AXValueRef selectedRangeValue = NULL;
AXError getSelectedRangeError = AXUIElementCopyAttributeValue(focussedElement, kAXSelectedTextRangeAttribute, (CFTypeRef *)&selectedRangeValue);
if (getSelectedRangeError == kAXErrorSuccess) {
CFRange selectedRange;
AXValueGetValue(selectedRangeValue, kAXValueCFRangeType, &selectedRange);
AXValueRef selectionBoundsValue = NULL;
AXError getSelectionBoundsError = AXUIElementCopyParameterizedAttributeValue(focussedElement, kAXBoundsForRangeParameterizedAttribute, selectedRangeValue, (CFTypeRef *)&selectionBoundsValue);
CFRelease(selectedRangeValue);
if (getSelectionBoundsError == kAXErrorSuccess) {
CGRect selectionBounds;
AXValueGetValue(selectionBoundsValue, kAXValueCGRectType, &selectionBounds);
NSLog(@"Selection bounds: %@", NSStringFromRect(NSRectFromCGRect(selectionBounds)));
} else {
NSLog(@"Could not get bounds for selected range");
}
if (selectionBoundsValue != NULL) CFRelease(selectionBoundsValue);
} else {
NSLog(@"Could not get selected range");
}
}
if (focussedElement != NULL) CFRelease(focussedElement);
CFRelease(systemWideElement);
Здесь вы идете для ответа @omz в Swift
let systemWideElement = AXUIElementCreateSystemWide()
var focusedElement : AnyObject?
let error = AXUIElementCopyAttributeValue(systemWideElement, kAXFocusedUIElementAttribute as CFString, &focusedElement)
if (error != .success){
print("Couldn't get the focused element. Probably a webkit application")
} else {
var selectedRangeValue : AnyObject?
let selectedRangeError = AXUIElementCopyAttributeValue(focusedElement as! AXUIElement, kAXSelectedTextRangeAttribute as CFString, &selectedRangeValue)
if (selectedRangeError == .success){
var selectedRange : CFRange?
AXValueGetValue(selectedRangeValue as! AXValue, AXValueType(rawValue: kAXValueCFRangeType)!, &selectedRange)
var selectRect = CGRect()
var selectBounds : AnyObject?
let selectedBoundsError = AXUIElementCopyParameterizedAttributeValue(focusedElement as! AXUIElement, kAXBoundsForRangeParameterizedAttribute as CFString, selectedRangeValue!, &selectBounds)
if (selectedBoundsError == .success){
AXValueGetValue(selectBounds as! AXValue, .cgRect, &selectRect)
//do whatever you want with your selectRect
print(selectRect)
}
}
}
То, что вы ищете, это Сервис. С сервисами ваше приложение даже не должно запускаться или захватывать глобальные горячие клавиши.
Например, функциональность описанного вами словарного приложения на самом деле является службой, которую можно увидеть в меню " Службы".
Руководство по внедрению услуг Apple, вероятно, является лучшей информацией об услугах.