Version: at least since 19.12
X environment: x11 5, motif 1.2 (SCO xds 5.2.5h, SCO BaseX 5.1.1b),
mwm
`x_output_string' in `redisplay-x.c' may consider frame with input
focus not to have one. So it does not draw cursor of that frame.
This depends on whether right value of `DEVICE_FRAME_WITH_FOCUS_REAL
(d)' for that frame is set. Setting that field occurs in
`emacs_handle_focus_change_preliminary' in `event-stream.c'.
When window manager iconifies one xemacs frame and passes input focus
to another, xemacs can get (or not get - race condition) `XEvent'
sequence where the last one is `FocusOut' for the frame losing focus.
I can not cause my X environment to reproduce such a sequence
reliably. The simplest way to simulate it is using debugger to print
`FocusOut' events in `emacs_Xt_event_handler' and then call
`emacs_Xt_event_handler' with an appropriate (for a frame that has
just lost focus) event from value history.
An event sequence like that causes
`emacs_handle_focus_change_preliminary' to act as if no xemacs frame
with focus remains. Comment in code doing this says:
> We ignore the frame reported in the event. If it's different
> from where we think the focus was, oh well -- we messed up.
> Nonetheless, we pretend we were right, for sensible behavior.
And this ignoring does not work for me, the messing up really occurs.
Without this comment I would just change this, but now that it is
there, I need to know, what is the `sensible behavior' it achieves and
why can not it be done otherwise. In particular, what harm will the
patch below cause?
Perhaps some environments are bogus and ignoring the frame reported in
the event should be done for them only, but not for ones like mine.
Then there should be a device field showing what kind of behavior is
desired on that device (with default value for a `typical' environment
of xemacs build).
Since the msg both contains a patch that worked for me and requests
for discussion, I cross-post it.
The patch is to r-21-5-3.
* event-stream.c (emacs_handle_focus_change_preliminary): consider
focus lost on device only if frame losing focus is one currently
having it.
--- event-stream.c Mon Sep 10 20:42:56 2001
+++ event-stream.c Mon Sep 10 20:42:59 2001
@@ -1805,14 +1805,20 @@
}
else
{
- /* We ignore the frame reported in the event. If it's different
- from where we think the focus was, oh well -- we messed up.
- Nonetheless, we pretend we were right, for sensible behavior. */
- frame = DEVICE_FRAME_WITH_FOCUS_REAL (d);
- if (!NILP (frame))
+ Lisp_Object old_frm = DEVICE_FRAME_WITH_FOCUS_REAL (d);
+
+ if (!NILP (old_frm))
{
- DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil;
+ if (EQ (frame, old_frm))
+ DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil;
+ /* Perhaps `focus out' for `frame' came only now, and two
+ frames including `frame' were remaining with focus cursor
+ displayed. `DEVICE_FRAME_WITH_FOCUS_REAL' changed not in
+ above statement, but somewhere before, and did not cause
+ `frame' redisplay. (Is this ever possible? Or missing
+ `focus out' was assumed on `focus in'?) The following
+ (perhaps redundantly) fixes this. */
if (FRAME_LIVE_P (XFRAME (frame)))
redisplay_redraw_cursor (XFRAME (frame), 1);
}