如何禁用我的应用程序中的所有NSCursor更新? [英] How to disable all NSCursor updates in my application?

查看:110
本文介绍了如何禁用我的应用程序中的所有NSCursor更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的macOS应用程序中,我有一个自定义WebView.当用户将鼠标光标移到WebView网页中的不同元素(如文本,链接等)(我认为是实现为子视图)时,光标会根据元素的类型自动更新.

In my macOS application, I have a custom WebView. When the user moves the mouse cursor over different elements in the WebView's webpage like text, links, etc. (which are implemented as subviews, I think), the cursor updates automatically, based on the type of the element.

我的要求是,我想为WebView设置一个自定义光标(即使可能的话,也要为我的整个应用程序设置),并且不要让它发生任何改变,至少直到我在代码的其他部分中以编程方式更改它为止.我试图在AppDelegate的applicationDidFinishLaunching:方法中设置NSCursor,但它会立即重置.

My requirement is that I want to set a custom cursor for the WebView (even for my entire application if possible), and not let it change whatsoever, at least till I programmatically change it in some other part of the code. I tried to set the NSCursor in the AppDelegate's applicationDidFinishLaunching: method, but it gets instantly reset.

我尝试了许多解决方案,例如设置NSTrackingArea,将disableCursorRects发送到我的NSApplicationNSWindow甚至监视游标更新事件,都没有成功.

I have tried many solutions like setting an NSTrackingArea, sending disableCursorRects to both my NSApplication and NSWindow, and even monitoring cursor update events, without much success.

那么有什么方法可以禁用我的应用程序中的所有NSCursor更新?我会将其设置为applicationDidFinishLaunching:中的自定义光标,并希望它在应用程序运行时保持不变,或者在代码中进行更改.

So is there a way to disable all NSCursor updates within my application? I would set it to my custom cursor in applicationDidFinishLaunching: and want it to remain the same as long as the application runs, or I change it in code.

推荐答案

找到了对我有用的解决方案!这是我的操作方式:

Found a solution that worked for me! Here's how I did it:

子类NSView并覆盖resetCursorRects方法,在该方法中,以其边界作为光标rect和所需的光标发送addCursorRect:cursor:(描述

Subclass NSView and override the resetCursorRects method, in which send addCursorRect:cursor: with its bounds as the cursor rect and the required cursor (described here). Then make an instance of this custom NSView with the same frame as the WebView, and add it to the later as a subview. This will act as a transparent overlay over the WebView. It affects only the cursor and does not interfere with mouse clicks or keypresses.

这是PyObjC中的代码(该概念也应适用于Objective C):

Here's the code in PyObjC (the concept should apply in Objective C as well):

# 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:消息来将其暂时隐藏:

If I ever want to reset the cursor back to auto, I can just remove this overlay view, or even better, set it temporarily hidden by sending it the setHidden: message:

self.overlay.setHidden_(Foundation.YES)

其他一些注意事项:

  • 使用NSTrackingArea代替光标rect似乎效果不佳.对我来说不是.
  • 我已经在自定义WebView上尝试了上述方法,但是没有用. WebView的默认跟踪区域/光标矩形始终会干扰.像上面的代码一样,在子视图的顶部添加子视图会阻止此行为.
  • 最后,叠加视图应该是 WebView的子视图.如果两个视图都是同一个超级视图的同级视图,则Cocoa不保证哪个视图将位于另一个视图之上.
  • Using an NSTrackingArea instead of the cursor rect doesn't seem to work well. For me it didn't.
  • I had tried the above method on the custom WebView itself, but it didn't work. The WebView's default tracking areas/cursor rects always interfere. Adding a subview on top of it blocks this behaviour, as the above code does.
  • Finally the overlay view should be a subview of the WebView. If both are sibling views of the same superview, Cocoa doesn't guarantee which one will be on top of the other.

如果有人有更好的解决方案,或者可以改进此解决方案,请随时发布.

If someone has a better solution, or can improve this one, feel free to post it.

希望这对某人有帮助!

这篇关于如何禁用我的应用程序中的所有NSCursor更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆