My NSTextView find panel buttons are dimmed and I don't know why.
The Cocoa NSTextView docs refer to dimmed find panel buttons if the text view is made not selectable. But that isn't the case. My text view is both editable and selectable.
I have been implementing my applications menu and toolbar validation code so I suspect that have misrouted something in the responder chain.
The find panel sends - (void)performFindPanelAction:(id)sender up the responder chain. The finder panel is displayed, which indicates that the first responder was an NSTextView instance. But once the find panel is displayed the panel buttons are disabled. This makes me think that the first responder is getting modified when the find panel is displayed. So how could this happen?
Looking at my window controller I see the following, and a dim light comes on.
/*
window did resign key
*/
- (void)windowDidResignKey:(NSNotification *)notification
{
#pragma unused(notification)
[[self window] endEditing];
}
When my window closes I want my editing to be complete and my bound models to be updated. This generally occurs when the control resigns its first responder status. An NSWindow category implements -(void)endEditing to force the current first responder to resign its status and thus update its model.
/*
end all editing in window
*/
-(void)endEditing
{
// gracefully end all editing in a window named aWindow
if ([self makeFirstResponder:self])
{
// All editing is now ended and delegate messages sent etc.
}
else
{
// For some reason the text object being edited will not resign
// first responder status so force an end to editing anyway
[self endEditingFor:nil];
}
}
From this its clear that when the window resigns its key status, which it will do when the find panel is displayed, the first responder for the window will end up as the window itself. Hence, when the find panel queries the main window first responder to see if it can perform - (void)performFindPanelAction:(id)sender the answer will be a resounding NO.
The solution is simply to restore the window's first responder once the edit has been committed.
/*
end all editing in window
*/
-(void)endEditing
{
id firstResponder = [self firstResponder];
// gracefully end all editing in a window named aWindow
if ([self makeFirstResponder:self])
{
// All editing is now ended and delegate messages sent etc.
}
else
{
// For some reason the text object being edited will not resign
// first responder status so force an end to editing anyway
[self endEditingFor:nil];
}
// restore the first responder once editing completed.
// this is required in situations where this message is sent from
// - (void)windowDidResignKey:(NSNotification *)notification.
// a panel, such as the find panel, may be being displayed.
// it will require the window's firstResponder to be maintained.
[self makeFirstResponder:firstResponder];
}
Post new comment