On 1/25/07, Christophe Rhodes csr21@cantab.net wrote:
The implementation of click-to-focus is kludgy. It's fine for drei-gadgets, and for text-gadgets generally; it's not so hot for general streams. I've taken the line that interactor-panes should be focusable with a click; somewhat to my surprise, you can't just write a method on handle-event to get this, but have to work with frame-input-context-button-press-handler. A potential gotcha is that I have not implented click-to-focus for application-panes; this may cause surprises, but it seemed to me the only way not to break the address book demo ;-)
The degree to which read-gesture separates the programmer from the interaction implemented by the stream via various button handling methods, functions bound in special variables, etc., has always made me nervous. It's somehow relieving to see it causing someone difficulty.
Maybe we want a slot or method defined on those panes implementing click-to-focus behavior which determines whether they are currently focussable. An interactor-pane would default to t, application-pane nil. If nil, clicks would pass through and be handled as they are currently, without reassigning focus. This should preserve the behavior of the address book.
I'm slightly concerned that because frame-input-context-button-press-handler is a function from the spec, users might expect that defining their own method for it would not to break input focus handling. Maybe focus handling should be pushed down into stream-read-gesture, but I'm not sure how/where.
One new spec compliance is that initially keyboard focus really does go to *query-io*. This might cause some surprising behaviour. Somewhat to my surprise, gsharp seems to work -- maybe because its toplevel loop is different -- but ESAs with default-frame-top-level deliver keyboard events to the minibuffer by default, which isn't ideal. On the other hand, the focus behaviour of text gadgets is, to me, much nicer -- and there's no more focus stealing going on.
Hmm, that's tricky. Playing around yesterday, I'd added an :initial-input-focus initarg for the frame, but that only works in gadget-y applications where there is no query-io (otherwise run-frame-top-level uses that instead). Maybe we can just change how the specified behavior is achieved, so that (keyboard-input-focus frame) is nil by default, and focus is initially assigned to (or (keyboard-input-focus frame) (frame-query-io frame)) ?