Как отключить все обновления 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;
Другие вопросы по тегам