Not being able to edit NSTextField on NSPopover even though Editable behavior is set
Asked Answered
B

8

20

I have an application, which open popover with NSTextField. The text field is not editable. Behavior for text field is set to Editable. I still can paste and copy text to this field but i can't edit it.

Anyone knows, what can be wrong?

Brookner answered 27/8, 2011 at 11:36 Comment(1)
possible duplicate of NSTextField not active in NSPopOverImmortal
K
41

Not sure if you still need the answer, but there may be some others still looking. I found a solution on apple developer forums. Quoting the original author:

The main problem is the way keyboard events works. Although the NSTextField (and all its superviews) receives keyboard events, it doesn't make any action. That happens because the view where the popover is atached, is in a window which can't become a key window. You can't access that window in any way, at least I couldn't. So the solution is override the method canBecomeKeyWindow for every NSWindow in our application using a category.

NSWindow+canBecomeKeyWindow.h
@interface NSWindow (canBecomeKeyWindow)

@end

NSWindow+canBecomeKeyWindow.m
@implementation NSWindow (canBecomeKeyWindow)

//This is to fix a bug with 10.7 where an NSPopover with a text field cannot be edited if its parent window won't become key
//The pragma statements disable the corresponding warning for overriding an already-implemented method
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (BOOL)canBecomeKeyWindow
{
    return YES;
}
#pragma clang diagnostic pop

@end

That makes the popover fully resposive. If you need another window which must respond NO to canBecomeKeyWindow, you can always make a subclass.

Kazbek answered 17/10, 2011 at 13:17 Comment(3)
Could you elaborate on exactly how to do this?Nurseryman
When you add files to a project you can choose to add an "Objective-C category". That's what he did naming it "canBecomeKeyWindow". Copy paste what he posted onto your code and it should work.Makings
Thank you so much!! I would +1 a thousand times if I could! :)Heptahedron
J
8

I struggled with this for a while as well, until I realized it was a bug.

However, instead of relying on an isActive state of a NSStatusItem view, I find it much more reliable to use the isShown property of the NSPopover you have implemented.

In my code, I have a NSPopover in a NSViewController:

  - (BOOL)canBecomeKeyWindow
    {
        if([self class]==NSClassFromString(@"NSStatusBarWindow"))
        {
            NSPopover *mainPopover = [[((AppDelegate*)[NSApp delegate]) mainViewController] mainPopover];
            if(![mainPopover isShown])
                return NO;
        }

        return YES;
    }
Jokjakarta answered 20/6, 2012 at 14:39 Comment(0)
S
2

Balazs Toth's answer works, but if you're attaching the popover to NSStatusItem.view the status item becomes unresponsive - requiring two clicks to focus.

Sundog answered 6/11, 2011 at 22:23 Comment(3)
the_snitch: on which view should you override this selector? overriding it on the NSStatusItem.view (which is a custom view i've written) does not work. the selector never gets fired.Basidiomycete
I'm having this same issue and can't figure out how to solve it.Friesian
github.com/aschuch/AXStatusItemPopup/pull/7/… make this changes and it will work.Recension
T
1

What i found when working with this solution is that when NSStatusItem becomes unresponsive, you can easily override this behavior like this

- (BOOL)canBecomeKeyWindow {
    if([self class]==NSClassFromString(@"NSStatusBarWindow")) {
        CBStatusBarView* view = [((CBAppDelegate*)[NSApp delegate]) statusItemView];
        if(![view isActive]) return NO;
    }
    return YES;
}

You will check for the class of the window, if it matches the NSStatusBarWindow we can then check somehow if the NSStatusItem is active. If it is, that means we have to return YES, because this way the NSPopover from NSStatusItem will have all keyboard events.

What I'm using for checking if the NSStatusItem was clicked (or is active) is that in my own custom view i have a bool value which changes when user clicks on the NSStatusItem, system automatically checks for "canBecomeKeyWindow" and when it does it will return NO and after user clicks on it (while it is returning the NO) it will change the bool value and return YES when system asks again (when NSPopover is being clicked for NSTextField editing).

Sidenotes:

  • CBStatusBarView is my custom view for NSStatusItem
  • CBAppDelegate is my App Delegate class
Typo answered 20/12, 2011 at 10:54 Comment(1)
Had the same problem but works now with this workaroundRebeccarebecka
L
1

If anyone is still looking for an answer to this, I am working in Swift.

At the time where you wish the field to allow text entry, I have used myTextField.becomeFirstReponder()

To opt out; just use myTextField.resignFirstResponder()

Leatherjacket answered 17/1, 2018 at 10:33 Comment(0)
A
0

Definitely a bug. That bug report is exactly what I was trying to do. Even down to creating the status item and overriding mousdown.

I can confirm that Balazs Toth's answer works. I just wonder if it might get in the way down the road.

Arose answered 1/11, 2011 at 19:43 Comment(0)
S
0

If someone gets it and the solution above didn't do the trick for him. The problem in my app was in the info tab in the targets my application was set to

Application is background only = true

and shulde of been

 Application is agent = true

Spent an entire day on this thing.

enter image description here

Shear answered 4/8, 2018 at 19:24 Comment(0)
B
-1

Bug. http://openradar.appspot.com/9722231

Brookner answered 28/8, 2011 at 6:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.