[Top][All Lists]


RE: NSTextField -becomeFirstResponder / NSTextView -copySelection

From: David Ayers
Subject: RE: NSTextField -becomeFirstResponder / NSTextView -copySelection
Date: Tue, 21 May 2002 17:11:15 +0200

Hello Nicola

> The current gnustep implementation (which might not be the perfect one or
> may not be the same as other implementation) has two different operations
> -
>  * You make a textfield the first responder.  That means future keyboard
> events for that window will be sent to the textfield.  Done by calling
> [aWindow makeFirstResponder: aTextField].

This is actually not the case. More precisly, aTextField doesn't accept
keyboard events (as input) after [aWindow makeFirstResponder: aTextField]
since it hasn't set up it's field Editor and propagted makeFirstReponder to
the field editor which should be done during -becomeFirstResponder.

You can test this by giving the Find Menu option in ProjectCenter a short
cut and using it, instead of the mouse (actually just using the Menu could
also show you what I mean). ProjectCenter makes the "Search string"
textField firstResponder by sending the window -makeFirstResponder but it
doesn't allow input (because the field editor isn't set up an it is not

[Side note: there is a feature in NSWindows sendEvent: which makes this test
rather hard:
If, while pressing a menu short cut, which opens a panel, the mouse pointer
doesn't happen to be over that part of the screen where the panel opens, an
NSAppKitDefined/GSAppKitWindowFocusIn event returns the key view to the
in which the Cursor happens to be. (The original window for example, instead
of the new panel which was opened with makeKeyAndOrderFront: during the menu
short cut processing.) I commented the code in -sendEvent: for
GSAppKitWindowFocusIn to do my tests.]

I fixed my NSTextField -becomeFirstResponder in my version by
calling -selectText:. This is the behavior of OPENSTEP 4.2 and what I think
should happen. Alternativly I could imagine instead of selecting the entire
contents, one could insert the insertion point at the beginning or at the
end of the text. My preference would definitly be selecting the entire text.

>  * You select all the text in a textfield.  Done by calling [aTextField
> selectText: whatever].

This works fine, but realise that -copySelection method (or rather sending
the PBS-Proxy [_pbs pastboardWithName:]) starts an new RunLoop while the
process waits for a return value. This must happen, so that in case this
invokation takes some time, the app doesn't halt it's responsiveness. In
this RunLoop the window gets displayed before -copySelection returns. Then
the rest of the sendEvent: gets excuted until it finishes and display gets
invoked again as soon as the orginal RunLoop has control again. (this causes
the section to be diplayed immediatly, before sendEvent: has the chance to
send mouseDown:, in this case this is just a minor "curiousity" but starting
new RunLoops (through DO or modal windows) is actually a delicate matter,
which I'll try to elaborate on in another mail.)

> When you click with the mouse in a textfield, the textfield is made first
> responder, but the text in the textfield is not selected.

I had to do some minor modifations in mouseDown: to reflect the fact, the
TextField had already propageted FirstResponder to its field editor.

> When you TAB (/shift-TAB) from one textfield to another one, the new
> textfield is made first responder AND concurrently the text in the
> textfield is selected.

I think I left this part alone.

Ok, and here are my modifications. I can't send you the actual code but I'll
be as specific as I can:

I merely removed the explicit [textObject display]. First I thought it
should be replaced through a setNeedsDisplay:YES but the previous setFrame:
should already take care of that.

If the text field accepts first responder, it selects it's entire contents
(unless this selection already guarentees, that the view is marked for
needing display, this could also be insured here) and returns YES. Otherwise
it returns NO.

This method should test whether the text field is enabled and editable.
(Currently it tests whether it's selectable, but I'm not sure whether this
might cause other problems, so I adapted my implementation.) If so, it
insures that the window ends the editing of the current field editor (for
this object). If the field editor assiciated with this text field is setup,
it sends it the selectAll: message. If not, it obtains the field editor for
this object from the window. Then the textfield caches the length of its
contents before seting up its attributes (see comments in orignal code).
Then it calls its cells selectWithFrame:... selecting the entire length. It
the text field wasn't enabled or editable, it tells its window to select the
following key view.

This method should test whether the text field is enabled and selectable. In
case it is, it checks whether the used field editor happens to be
the -currentEditor (i.e. it is also first responder). If that is the case,
the mouseDown: is forwarded to the field editor. Otherwise, if this text
field can be made first responder its window, it insures that the window
ends the editing of the current field editor (for this object). Then it
retrieves the field editor for this object from the window and setup its
attributes. Now it can call it's cell's -editWithFrame:... with the new
field editor. If the text field wasn't enabled or editable, it forward the
mouseDown: to its next responder, if it has one or falls back to it's
noResponderFor: method with the current selector.

I hope this helps, sorry I can't send code.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]