Search code examples
cocoanstextviewfirst-responder

NSTextView overlay causes oddities with first responder status


I have an NSTextView in an NSScrollView, and I am programmatically inserting an NSView subclass as a subview of the NSTextView. This NSView acts as an overlay, superimposing graphical information about the text beneath it.

I thought it was working quite well until I noticed that the text view does not respond to right clicks. Other operations (editing, selection) seem to work just fine.

Also, if the first responder is changed to a sibling of the scroll view (an outline view, for example) the text view does not regain first responder status from clicking on it. The selection will change in response to clicking, but the selection highlight is gray instead of blue (indicating that the text view is not the first responder).

If I offset the frame of the overlay subview, the text view behaves 100% normally in the area not overlapped by the overlay, but the overlapped area behaves incorrectly, as outlined above.

Steps To Replicate This Behavior on Mac OS X 10.6.4:

  1. Create a plain old non-document-based Cocoa app.
  2. Add an `NSTextView' IBOutlet to the app delegate .h.
  3. Add an NSTextView to the window in MainMenu.xib. Connect the textView outlet.
  4. Type in a bit of code:

In applicationDidFinishLaunching:

NSView *overlay = [[NSView alloc] initWithFrame:textView.bounds];
[textView addSubview:overlay];
[overlay release];

Run the app, observe that right click in the text area does not work as it should, yet you can still otherwise interact with the text view.

Next, add an NSOutlineView to the window in the xib. Observe that once focus leaves the text area (if you click on the outline view) with the overlay in place, you cannot set the focus back to the text view (it will not become first responder again).


Is there some way I can enable the NSTextView to receive all of its events, even though my NSView overlay does not accept first responder or mouse events? I suspect this might be related to the field editor – perhaps it is ignoring events it thinks are destined to the overlay view?


Solution

  • You probably need to make your overlay an instance of a custom view class that forwards all events and accessibility messages to the text view. You may also need to convert any view-relative coordinates to the text view's coordinate system.