emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Emacs Mac port


From: YAMAMOTO Mitsuharu
Subject: Re: Emacs Mac port
Date: Mon, 15 Apr 2013 11:17:20 +0900
User-agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (Shijō) APEL/10.6 Emacs/22.3 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI)

>>>>> On Sun, 14 Apr 2013 14:49:56 +0300, Eli Zaretskii <address@hidden> said:

> Sorry, I don't understand: why would an expose event trigger erasing
> of a cursor in the minibuffer window?

> Could you possibly describe in detail the sequence of events that
> leads to this problem, and perhaps also give a reproducible recipe?
> And how is this related to the size of the buffer and isearch?

> Better make all that a bug report.

The actual scenario is rather complicated and mostly specific to the
newest version of the Mac port, and difficult to reproduce on the
other platforms (or earlier versions of the Mac port), because it is
difficult to predict when expose events happen.  I'll explain the
scenario at the end of this mail, but you can just skip it.  The point
is, the cursor shape depends on the *current value* of
`cursor-in-echo-area' and it may be different between the last
redisplay and the subsequent expose_frame.

Simply recording the value of `cursor-in-echo-area' seems to work and
need only a small change.  Recording the calculated cursor shape would
be more efficient, but would require nontrivial changes.

=== modified file 'src/dispextern.h'
*** src/dispextern.h    2013-03-28 14:04:49 +0000
--- src/dispextern.h    2013-04-15 01:48:51 +0000
***************
*** 665,670 ****
--- 665,674 ----
       line.  */
    unsigned header_line_p : 1;
  
+   /* Value of cursor_in_echo_area as of last window update.  Set in
+      set_window_cursor_after_update.  */
+   unsigned cursor_in_echo_area_p : 1;
+ 
  #ifdef GLYPH_DEBUG
    /* A string identifying the method used to display the matrix.  */
    char method[512];

=== modified file 'src/dispnew.c'
*** src/dispnew.c       2013-04-02 01:54:56 +0000
--- src/dispnew.c       2013-04-15 01:48:51 +0000
***************
*** 3860,3865 ****
--- 3860,3866 ----
    /* Not intended for frame matrix updates.  */
    eassert (FRAME_WINDOW_P (f));
  
+   w->current_matrix->cursor_in_echo_area_p = cursor_in_echo_area;
    if (cursor_in_echo_area
        && !NILP (echo_area_buffer[0])
        /* If we are showing a message instead of the mini-buffer,

=== modified file 'src/xdisp.c'
*** src/xdisp.c 2013-04-02 01:54:56 +0000
--- src/xdisp.c 2013-04-15 01:48:51 +0000
***************
*** 25481,25487 ****
    *active_cursor = 1;
  
    /* Echo area */
!   if (cursor_in_echo_area
        && FRAME_HAS_MINIBUF_P (f)
        && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
      {
--- 25481,25487 ----
    *active_cursor = 1;
  
    /* Echo area */
!   if (w->current_matrix && w->current_matrix->cursor_in_echo_area_p
        && FRAME_HAS_MINIBUF_P (f)
        && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
      {


The actual scenario on the latest version of the Mac port: (you can
skip it)

First of all, on OS X 10.7 and later, the bottom corners of an
ordinary window are rounded if every drawing happens in response to an
"expose" (in X11 terminology) event.  This does not apply to Emacs,
and the previous versions of the Mac port (and also the current NS
port) show square frame bottom corner(s) if internal-border-width is
0.

The newest version of the Mac port implements rounded bottom corners
by invalidating the bottom area (containing echo area partly) when
drawing operations outside "expose" events might have drawn into one
of the bottom corners.  This invalidation triggers an "expose" event
at the next event.

1. A Lisp program (e.g. isearch) shows a message with temporarily
   setting `cursor-in-echo-area' by let-binding.

2. Emacs performs redisplay.  At this moment, the cursor is drawn in
   the echo area because `cursor-in-echo-area' is set.

3. At the end of update, the invalidation explained above happens.
   The height of the invalidated area is 4 (~ the radius of the
   rounded corner) and it partially overlaps with the echo area.

4. At the next event loop, expose_frame is called, and the echo area
   is redrawn with setting the clipping area to the invalidated area.
   But at this moment, `cursor-in-echo-area' is already cleared.  So
   the cursor is not drawn and the lower half of the cursor is cleared
   and upper half remains displayed because of clipping.

5. The Lisp program shows the same message again, but
   `cursor-in-echo-area' is nil this time.

6. Redisplay happens again.  The display engine considers the cursor
   has already been cleared (at the last expose) and do not clear or
   draw the cursor.  As a result, the upper half of the cursor remains
   displayed and lower half looks cleared.

                                     YAMAMOTO Mitsuharu
                                address@hidden



reply via email to

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