82877

How to disable all NSCursor updates in my application?

Question:

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.

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.

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.

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.

Answer1:

You can use a user stylesheet in the WebView to set the default curser for html elements.

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;

Answer2:

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

Subclass NSView and override the resetCursorRects method, in which send addCursorRect:cursor: with its bounds as the cursor rect and the required cursor (described <a href="https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CursorMgmt/Tasks/ChangingCursors.html" rel="nofollow">here</a>). Then make an instance of this custom NSView <em>with the same frame</em> 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.

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) ...

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)

Some additional things to note:

<ul><li>Using an NSTrackingArea instead of the cursor rect doesn't seem to work well. For me it didn't.</li> <li>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.</li> <li>Finally the overlay view <em>should be</em> 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.</li> </ul>

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

Hope this helps someone!

Recommend

  • JTextPane - Make Caret Normal Size?
  • How can I ensure Realm schema is identical across Android and iOS?
  • Botframework - resize bot chat in width [duplicate]
  • Git subtree post hook
  • Jquery ajax request not able to return data to other function
  • How to import Navit into Eclipse and use it in own android project
  • HABTM associations in Rails : collecting and counting the categories of a model's children
  • data.table replicate rows after join?
  • Attemping to change attributes of $(this) inside success function
  • How to add regEx in angular filter
  • insert a picture into database(sqlite) with java code. what should i do?
  • How to synchronize two scrollview in Android?
  • Using android opencv apps without downloading opencv sdk manager
  • Google OAuth: can't get refresh token with authorization code
  • Add reference to ASP.NET 5 Class Library from Framework 4.5 Class Library Project
  • IE11 throwing “SCRIPT1014: invalid character” where all other browsers work
  • nonblocking BIO_do_connect blocked when there is no internet connected
  • Adjust width of select element according to selected option's width
  • ViewController With Transparent Background Entering Current ViewController With Push Transition
  • Content-Length header not returned from Pylons response
  • Play WS (2.2.1): post/put large request
  • Jquery UI tool tip close icon
  • Get data from AJAX - How to
  • How to access EntityManager inside Entity class in EJB3
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • jQuery show() function is not executed in Safari if submit handler returns true
  • Spray.io: When (not) to use non-blocking route handling?
  • Bug in WPF DataGrid
  • Modifying destination and filename of gulp-svg-sprite
  • javascript inside java/jsp code
  • WinForms: two way TextBox problem
  • Perl system calls when running as another user using sudo
  • vba code to select only visible cells in specific column except heading
  • GridView Sorting works once only
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • How to disable jQuery.jplayer autoplay?
  • Proper way to use connect-multiparty with express.js?
  • Load html files in TinyMce
  • JaxB to read class hierarchy