Christiaan Hofman | 20 Dec 2011 14:14
Picon

Calling commitEditing text field loses focus

I have a text field whose value is bound through an NSObjectController. Before performing certain actions
I call -commitEditing on that object controller to make sure I have the current value from the text field.
What I notice is that if there are any uncommitted changes to the text, the text field loses focus due to this
call. This is certainly not what I want, I just want to commit the edit. I also don't recall this to happen in
the past, but I am not sure for how long this has been going on. Also, the focus is not lost when the text had not
changed since the last commit. To me this sounds like a bug. Can anyone confirm this is a bug, or tell me why
this would make sense? Or tell me whether there is some kind of setting to change this behavior?

thanks,
Christiaan
Kyle Sluder | 20 Dec 2011 21:50
Picon

Re: Calling commitEditing text field loses focus

On Tue, Dec 20, 2011 at 5:14 AM, Christiaan Hofman
<cmhofman@...> wrote:
> I have a text field whose value is bound through an NSObjectController. Before performing certain
actions I call -commitEditing on that object controller to make sure I have the current value from the text
field. What I notice is that if there are any uncommitted changes to the text, the text field loses focus due
to this call. This is certainly not what I want, I just want to commit the edit. I also don't recall this to
happen in the past, but I am not sure for how long this has been going on. Also, the focus is not lost when the
text had not changed since the last commit. To me this sounds like a bug. Can anyone confirm this is a bug, or
tell me why this would make sense? Or tell me whether there is some kind of setting to change this behavior?

Try using -commitEditingAndReturnError: (new in 10.7) instead?

--Kyle Sluder
Christiaan Hofman | 20 Dec 2011 22:41
Picon

Re: Calling commitEditing text field loses focus


On Dec 20, 2011, at 21:50, Kyle Sluder wrote:

> On Tue, Dec 20, 2011 at 5:14 AM, Christiaan Hofman
<cmhofman@...> wrote:
>> I have a text field whose value is bound through an NSObjectController. Before performing certain
actions I call -commitEditing on that object controller to make sure I have the current value from the text
field. What I notice is that if there are any uncommitted changes to the text, the text field loses focus due
to this call. This is certainly not what I want, I just want to commit the edit. I also don't recall this to
happen in the past, but I am not sure for how long this has been going on. Also, the focus is not lost when the
text had not changed since the last commit. To me this sounds like a bug. Can anyone confirm this is a bug, or
tell me why this would make sense? Or tell me whether there is some kind of setting to change this behavior?
> 
> Try using -commitEditingAndReturnError: (new in 10.7) instead?
> 
> --Kyle Sluder

Not relevant, I support 10.5. Moreover, why would or should returning an error change this behavior?

Christiaan
Kyle Sluder | 21 Dec 2011 00:49
Picon

Re: Calling commitEditing text field loses focus

On Tue, Dec 20, 2011 at 1:41 PM, Christiaan Hofman
<cmhofman@...> wrote:
>
> On Dec 20, 2011, at 21:50, Kyle Sluder wrote:
>
>> Try using -commitEditingAndReturnError: (new in 10.7) instead?
>>
>> --Kyle Sluder
>
> Not relevant, I support 10.5. Moreover, why would or should returning an error change this behavior?

It's not "returning an error" that would change the behavior. That
method was added to support autosaving in Lion, which you probably
wouldn't want to disturb the responder chain at random times even if
it was successful. Now that that method exists, it could be possible
that the behavior of NSTextField's -commitEditing was changed to give
up first responder. That's why I suggested you try it.

--Kyle Sluder
Christiaan Hofman | 21 Dec 2011 01:09
Picon

Re: Calling commitEditing text field loses focus


On Dec 21, 2011, at 0:49, Kyle Sluder wrote:

> On Tue, Dec 20, 2011 at 1:41 PM, Christiaan Hofman
<cmhofman@...> wrote:
>> 
>> On Dec 20, 2011, at 21:50, Kyle Sluder wrote:
>> 
>>> Try using -commitEditingAndReturnError: (new in 10.7) instead?
>>> 
>>> --Kyle Sluder
>> 
>> Not relevant, I support 10.5. Moreover, why would or should returning an error change this behavior?
> 
> It's not "returning an error" that would change the behavior. That
> method was added to support autosaving in Lion, which you probably
> wouldn't want to disturb the responder chain at random times even if
> it was successful. Now that that method exists, it could be possible
> that the behavior of NSTextField's -commitEditing was changed to give
> up first responder. That's why I suggested you try it.
> 
> --Kyle Sluder

The fact that you may want this for autosaving does not mean you may not want this for other commits. So this
would be no explanation. Moreover, it now also behaves this way in 10.6.8 where the new method is not
available. I see no reason why generically committing should stop an edit.

Christiaan
Kyle Sluder | 21 Dec 2011 01:33
Picon

Re: Calling commitEditing text field loses focus

On Tue, Dec 20, 2011 at 4:09 PM, Christiaan Hofman
<cmhofman@...> wrote:
> The fact that you may want this for autosaving does not mean you may not want this for other commits. So this
would be no explanation.

I offered a possible explanation for what might have happened, made
under the assumption that you correctly identified this as a recent
change in behavior. The validity of the explanation and the
desirability of its implications are separate issues. Please don't
jump down my throat simply because you don't like the consequences
posed by a theory I posited in good faith.

> Moreover, it now also behaves this way in 10.6.8 where the new method is not available. I see no reason why
generically committing should stop an edit.

_This_ would be the reason that my explanation is invalid.

I agree that I would not expect -commitEditing to lose focus. I
_would_ expect it to select all the text in the text field, as if the
user had pressed the Return key.

--Kyle Sluder
Jim Correia | 21 Dec 2011 02:45
Picon
Favicon

Re: Calling commitEditing text field loses focus


On Dec 20, 2011, at 5:14 AM, Christiaan Hofman wrote:

> I have a text field whose value is bound through an NSObjectController. Before performing certain
actions I call -commitEditing on that object controller to make sure I have the current value from the text
field. What I notice is that if there are any uncommitted changes to the text, the text field loses focus due
to this call. This is certainly not what I want, I just want to commit the edit. I also don't recall this to
happen in the past, but I am not sure for how long this has been going on. Also, the focus is not lost when the
text had not changed since the last commit. To me this sounds like a bug. Can anyone confirm this is a bug, or
tell me why this would make sense? Or tell me whether there is some kind of setting to change this behavior?

This how it has worked since NSController was introduced.

It is less than ideal for a number of reasons. (You need to commit editing before saving, but that really
shouldn’t change keyboard focus, nor should it change the user’s selection in many situations.)

If you want to solve this problem specifically, you can manually push the value through to the bound object
when the field is editing. (Make sure you also take care of the value transformer case. Yes, this feels a
little bit like you’ve given up most of the advantages of having bindings.)

A more general solution would be to write something like adding

	- (void)commitEditingAndRestoreFirstResponderMumbleMumble;

to NSController. It’s a bit tedious to get this implementation right, since you have to handle
NSTextView, plus field editors for the various types of things which might use them, scrolling selection
ranges back into view, etc. This will take longer, but then you’ll have the problem solved centrally, 
once and for all. 

—Jim
(Continue reading)

Christiaan Hofman | 21 Dec 2011 12:15
Picon

Re: Calling commitEditing text field loses focus


On Dec 21, 2011, at 2:45, Jim Correia wrote:

> 
> On Dec 20, 2011, at 5:14 AM, Christiaan Hofman wrote:
> 
>> I have a text field whose value is bound through an NSObjectController. Before performing certain
actions I call -commitEditing on that object controller to make sure I have the current value from the text
field. What I notice is that if there are any uncommitted changes to the text, the text field loses focus due
to this call. This is certainly not what I want, I just want to commit the edit. I also don't recall this to
happen in the past, but I am not sure for how long this has been going on. Also, the focus is not lost when the
text had not changed since the last commit. To me this sounds like a bug. Can anyone confirm this is a bug, or
tell me why this would make sense? Or tell me whether there is some kind of setting to change this behavior?
> 
> This how it has worked since NSController was introduced.
> 

I am pretty sure that long ago when I tested these things out it did remain first responder. I distinctly
remember being frustrated that it's so hard to manually (i.e. without bindings) commit without losing
first responder the way bindings can do.

> It is less than ideal for a number of reasons. (You need to commit editing before saving, but that really
shouldn’t change keyboard focus, nor should it change the user’s selection in many situations.)
> 

Sorry, can't think of any. If it can push through an edit on every key stroke without losing focus, why can't
it do that at a point when I ask it to?

> If you want to solve this problem specifically, you can manually push the value through to the bound object
when the field is editing. (Make sure you also take care of the value transformer case. Yes, this feels a
(Continue reading)

Jim Correia | 21 Dec 2011 17:08
Picon
Favicon

Re: Calling commitEditing text field loses focus


On Dec 21, 2011, at 3:15 AM, Christiaan Hofman wrote:

>> This is how it has worked since NSController was introduced.
> 
> I am pretty sure that long ago when I tested these things out it did remain first responder. I distinctly
remember being frustrated that it's so hard to manually (i.e. without bindings) commit without losing
first responder the way bindings can do.

I’ve been using bindings since 10.4, and this is always how -commitEditing has worked. (I wouldn’t
have gone through the trouble to write -commitEditingAndRestoreFirstResponderMumbleMumble otherwise.)

>> It is less than ideal for a number of reasons. (You need to commit editing before saving, but that really
shouldn’t change keyboard focus, nor should it change the user’s selection in many situations.)
>> 
> 
> Sorry, can't think of any. If it can push through an edit on every key stroke without losing focus, why can't
it do that at a point when I ask it to?

Depending on the user interface element, it may also be appropriate to end editing on save, and select the
entire context of the field, for example. (This isn’t giving up first responder, but it isn’t
preserving the insertion point either.)

>> If you want to solve this problem specifically, you can manually push the value through to the bound
object when the field is editing. (Make sure you also take care of the value transformer case. Yes, this
feels a little bit like you’ve given up most of the advantages of having bindings.)
> 
> Not just a little. That basically makes bindings meaningless, it comes to manual updating the old way with
an extra registration layer added.

(Continue reading)

Christiaan Hofman | 21 Dec 2011 17:28
Picon

Re: Calling commitEditing text field loses focus


On Dec 21, 2011, at 17:08, Jim Correia wrote:

> 
> On Dec 21, 2011, at 3:15 AM, Christiaan Hofman wrote:
> 
>>> This is how it has worked since NSController was introduced.
>> 
>> I am pretty sure that long ago when I tested these things out it did remain first responder. I distinctly
remember being frustrated that it's so hard to manually (i.e. without bindings) commit without losing
first responder the way bindings can do.
> 
> I’ve been using bindings since 10.4, and this is always how -commitEditing has worked. (I wouldn’t
have gone through the trouble to write -commitEditingAndRestoreFirstResponderMumbleMumble otherwise.)
> 
>>> It is less than ideal for a number of reasons. (You need to commit editing before saving, but that really
shouldn’t change keyboard focus, nor should it change the user’s selection in many situations.)
>>> 
>> 
>> Sorry, can't think of any. If it can push through an edit on every key stroke without losing focus, why
can't it do that at a point when I ask it to?
> 
> Depending on the user interface element, it may also be appropriate to end editing on save, and select the
entire context of the field, for example. (This isn’t giving up first responder, but it isn’t
preserving the insertion point either.)
> 
>>> If you want to solve this problem specifically, you can manually push the value through to the bound
object when the field is editing. (Make sure you also take care of the value transformer case. Yes, this
feels a little bit like you’ve given up most of the advantages of having bindings.)
>> 
(Continue reading)

Jim Correia | 21 Dec 2011 17:32
Picon
Favicon

Re: Calling commitEditing text field loses focus

On Dec 21, 2011, at 8:28 AM, Christiaan Hofman wrote:

> This makes no sense to me. An NSController does not even have *any* properties, let alone a window. It's not
an interface element. And NSObjectController only knows (publicly) about things it binds to (its
content or selection), but what is needed is the objects that bind *to* it. There's no API for that. So I
really fail to see how you could have done this without using SPI.

You’ve got two options here:

You know where you use the controller, so you can associate one or more windows with your controller. (It
doesn’t have any built-in properties to track this association—you’ll have to add this.)

Or, you can just snapshot the first responder and state for every window, commit editing, and restore it in
those windows where it has changed.

For my purposes, the latter performed perfectly acceptably (having hundreds of windows open isn’t a
typical use case), so that was the solution that I wrote.

Jim
Christiaan Hofman | 21 Dec 2011 17:50
Picon

Re: Calling commitEditing text field loses focus


On Dec 21, 2011, at 17:32, Jim Correia wrote:

> On Dec 21, 2011, at 8:28 AM, Christiaan Hofman wrote:
> 
>> This makes no sense to me. An NSController does not even have *any* properties, let alone a window. It's
not an interface element. And NSObjectController only knows (publicly) about things it binds to (its
content or selection), but what is needed is the objects that bind *to* it. There's no API for that. So I
really fail to see how you could have done this without using SPI.
> 
> You’ve got two options here:
> 
> You know where you use the controller, so you can associate one or more windows with your controller. (It
doesn’t have any built-in properties to track this association—you’ll have to add this.)
> 
> Or, you can just snapshot the first responder and state for every window, commit editing, and restore it in
those windows where it has changed.
> 
> For my purposes, the latter performed perfectly acceptably (having hundreds of windows open isn’t a
typical use case), so that was the solution that I wrote.
> 
> Jim

Sounds like overkill to me. I guess as one has to write and call a custom method for this anyway that one can
just as well pass the relevant window as an argument to that method
-(BOOL)commitEditingAndRestoreFirstResponderForWindow:(NSWindow *)aWindow.

Christiaan
Jim Correia | 21 Dec 2011 17:52
Picon
Favicon

Re: Calling commitEditing text field loses focus

On Dec 21, 2011, at 8:50 AM, Christiaan Hofman wrote:

> Sounds like overkill to me. I guess as one has to write and call a custom method for this anyway that one can
just as well pass the relevant window as an argument to that method
-(BOOL)commitEditingAndRestoreFirstResponderForWindow:(NSWindow *)aWindow.

In the simple case, that should work fine.

In the more complex case, you may have multiple document windows and multiple inspector windows to consider.

If the simple case covers your needs, there’s no reason to worry about the complex case, for now.

Jim

Gmane