Как отключить все обновления NSCursor в моем приложении?
В моем приложении MacOS у меня есть собственный WebView. Когда пользователь наводит курсор мыши на различные элементы веб-страницы WebView, такие как текст, ссылки и т. Д. (Которые, я думаю, реализованы в виде подпредставлений), курсор обновляется автоматически в зависимости от типа элемента.
Мое требование состоит в том, что я хочу установить пользовательский курсор для WebView (даже для всего моего приложения, если это возможно), и не позволять ему что-либо менять, по крайней мере, пока я программно не изменим его в какой-то другой части кода. Я пытался установить NSCursor в AppDelegate в applicationDidFinishLaunching:
метод, но он мгновенно сбрасывается.
Я пробовал много решений, таких как установка NSTrackingArea
, отправка disableCursorRects
обоим моим NSApplication
а также NSWindow
и даже мониторинг событий обновления курсора, без особого успеха.
Так есть ли способ отключить все обновления NSCursor в моем приложении? Я бы установил его на свой пользовательский курсор в applicationDidFinishLaunching:
и хочу, чтобы он оставался таким же, пока приложение работает, или я изменяю его в коде.
2 ответа
Нашел решение, которое сработало для меня! Вот как я это сделал:
Подкласс NSView
и переопределить resetCursorRects
метод, в котором отправить addCursorRect:cursor:
с его границами в качестве курсора прямоугольника и требуемого курсора (описано здесь). Затем сделайте экземпляр этого обычая NSView
с той же рамкой, что и WebView
и добавить его к последующему в качестве подпредставления. Это будет действовать как прозрачное наложение поверх WebView
, Он влияет только на курсор и не мешает щелчкам мыши или нажатиям клавиш.
Вот код в PyObjC (концепция должна применяться и в Objective C):
# Overlay View (NSView subclass)
class OverLayView(AppKit.NSView):
def resetCursorRects(self):
self.addCursorRect_cursor_(self.bounds(), my_custom_cursor)
# In my main class
...
self.overlay = OverLayView.alloc().initWithFrame_(self.webview.bounds())
self.webview.addSubview_(self.overlay)
...
Если я когда-нибудь захочу вернуть курсор на автоматический режим, я могу просто удалить это представление наложения или, что еще лучше, временно скрыть его, отправив setHidden:
сообщение:
self.overlay.setHidden_(Foundation.YES)
Некоторые дополнительные вещи, чтобы отметить:
- Используя
NSTrackingArea
вместо курсора прямоугольник, кажется, не работает хорошо. Для меня это не так. - Я попробовал вышеупомянутый метод на заказ
WebView
сам, но это не сработало.WebView
области отслеживания по умолчанию / участки курсора всегда мешают. Добавление подпредставления поверх него блокирует это поведение, как и приведенный выше код. - Наконец, представление наложения должно быть подвидом
WebView
, Если оба имеют одинаковые взгляды на одно и то же суперпредставление, Какао не гарантирует, какой из них будет поверх другого.
Если у кого-то есть лучшее решение, или вы можете улучшить его, не стесняйтесь опубликовать его.
Надеюсь, это поможет кому-то!
Вы можете использовать пользовательскую таблицу стилей в WebView для установки курсора по умолчанию для элементов HTML.
WebPreferences *preferences = [[[WebPreferences alloc] initWithIdentifier:@"TestIdentifier"] autorelease];
NSURL *stylesheetURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"yosemite-stylesheet" withExtension:@"css" subdirectory:@"Welcome"];
preferences.userStyleSheetEnabled = YES;
preferences.userStyleSheetLocation = stylesheetURL;
self.webView.preferences = preferences;