On 19 Jul 2008, at 19:16, Adrian Robert wrote:
It's been a longstanding TODO to normalize the cursor handling under NS. Both for storing the shape, as mentioned, and also the blink handling. Most of the code that's in there dates from before emacs itself had these features, and since it has been mostly working it's been less pain to keep it working than to rip it out and start afresh with the emacs stuff. Time for that to change, and I'd definitely welcome help or a patch for all or part of it.
The code below takes care of- frame background rather than the right glyph in the white-out phases during blinking - `cursor-type' variable as in core Emacs, rather than NS specific solution
- with it, support for things like (box . 2) - box/hollow cursors too narrowThe code clearly needs further revision (see FIXME), but I don't know what to do. If you do, please look into it, otherwise I suggest we take this as iterative improvement and get back to it after more important things have been dealt with. The whole redisplay stuff appears complicated and not very well documented.
Apart from this: the way the blinking cursor is implemented is half- hearted at beast (or rather, a hack). With this, the cursor blinks even if it is being moved around, which is really not good. I wonder why no-one has complained about this yet...
I don't understand why internal-show-cursor and the w->cursor_off_p (that it sets) do not work in the NS port - they are checked by redisplay_internal. Is there any commentary regarding stuff like that? I mean, the original authors of this code went to lengths to replace the blink-cursor-mode with something off their own (which is a lot less configurable).
*** nsterm.m 21 Jul 2008 20:32:30 -0400 1.11 --- nsterm.m 21 Jul 2008 22:57:54 -0400 *************** *** 2274,2279 **** --- 2274,2285 ---- int on_p, int active_p)/* --------------------------------------------------------------------------
External call (RIF): draw cursor + (modeled after x_draw_window_cursor and erase_phys_cursor. + FIXME: erase_phys_cursor is called from display_and_set_cursor, + called from update_window_cursor/x_update_window_end/... + Why do we have to duplicate this code? + Also, why doesn't cursor_off_p (internal_show_cursor) work? + This prevents the original blink-cursor-mode from working.-------------------------------------------------------------------------- */
{ NSRect r, s; *************** *** 2282,2295 **** struct glyph *phys_cursor_glyph; int overspill; unsigned char drawGlyph = 0, cursorType, oldCursorType; NSTRACE (dumpcursor); ! if (!on_p) return; w->phys_cursor_type = cursor_type; ! w->phys_cursor_on_p = 1; if (cursor_type == NO_CURSOR) { --- 2288,2310 ---- struct glyph *phys_cursor_glyph; int overspill; unsigned char drawGlyph = 0, cursorType, oldCursorType; + int new_cursor_type; + int new_cursor_width; + int active_cursor; + enum draw_glyphs_face hl; + struct glyph_matrix *active_glyphs = w->current_matrix; + Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + int hpos = w->phys_cursor.hpos; + int vpos = w->phys_cursor.vpos; + struct glyph_row *cursor_row; NSTRACE (dumpcursor); ! if (!on_p) // check this? && !w->phys_cursor_on_p) return; w->phys_cursor_type = cursor_type; ! w->phys_cursor_on_p = on_p; if (cursor_type == NO_CURSOR) { *************** *** 2322,2333 **** --- 2337,2350 ---- if (overspill > 0) r.size.width -= overspill; +/* PENDING: 23: use emacs stored f->cursor_type instead of ns- specific */
oldCursorType = FRAME_CURSOR (f); cursorType = FRAME_CURSOR (f) = FRAME_NEW_CURSOR (f); f->output_data.ns->current_cursor_color = f->output_data.ns->desired_cursor_color; +/* PENDING: only needed in rare cases with last-resort font in HELLO..
should we do this more efficiently? */ ns_clip_to_row (w, glyph_row, -1, NULL); *************** *** 2346,2396 **** if (cursorType == no_highlight || cursor_type == NO_CURSOR) { /* clearing for blink: erase the cursor itself */ [FRAME_BACKGROUND_COLOR (f) set]; - cursorType = oldCursorType; /* just clear what we had before */ } else [FRAME_CURSOR_COLOR (f) set]; ! if (!active_p) ! {! /* inactive window: ignore what we just set and use a hollow box */
! cursorType = hollow_box; ! [FRAME_CURSOR_COLOR (f) set]; ! } ! switch (cursorType) ! { ! case no_highlight: ! break; ! case filled_box: ! NSRectFill (r); ! drawGlyph = 1; ! break; ! case hollow_box: ! NSRectFill (r); ! [FRAME_BACKGROUND_COLOR (f) set]; ! NSRectFill (NSInsetRect (r, 1, 1)); ! [FRAME_CURSOR_COLOR (f) set]; ! drawGlyph = 1; ! break; ! case underscore: ! s = r; ! s.origin.y += lrint (0.75 * s.size.height); ! s.size.height = lrint (s.size.height * 0.25); ! NSRectFill (s); ! break; ! case bar: ! s = r; ! s.size.width = 1; ! NSRectFill (s); ! break; } ns_unfocus (f); /* if needed, draw the character under the cursor */ if (drawGlyph) ! draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); } --- 2363,2479 ---- if (cursorType == no_highlight || cursor_type == NO_CURSOR) { /* clearing for blink: erase the cursor itself */ ++ /* No cursor displayed or row invalidated => nothing to do on the
+ screen. */ + if (w->phys_cursor_type == NO_CURSOR) + return; ++ /* VPOS >= active_glyphs->nrows means that window has been resized.
+ Don't bother to erase the cursor. */ + if (vpos >= active_glyphs->nrows) + return; ++ /* If row containing cursor is marked invalid, there is nothing we
+ can do. */ + cursor_row = MATRIX_ROW (active_glyphs, vpos); + if (!cursor_row->enabled_p) + return; ++ /* If line spacing is > 0, old cursor may only be partially visible in
+ window after split-window. So adjust visible height. */ + cursor_row->visible_height = min (cursor_row->visible_height, + window_text_bottom_y (w) - cursor_row->y); ++ /* If row is completely invisible, don't attempt to delete a cursor which
+ isn't there. This can happen if cursor is at top of a window, and + we switch to a buffer with a header line in that window. */ + if (cursor_row->visible_height <= 0) + return; ++ /* If cursor is in the fringe, erase by drawing actual bitmap there. */
+ if (cursor_row->cursor_in_fringe_p) + { + cursor_row->cursor_in_fringe_p = 0; + draw_fringe_bitmap (w, cursor_row, 0); + return; + } + + /* This can happen when the new row is shorter than the old one. + In this case, either draw_glyphs or clear_end_of_line + should have cleared the cursor. Note that we wouldn't be + able to erase the cursor in this case because we don't have a + cursor glyph at hand. */ + if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]) + return; + + /* If the cursor is in the mouse face area, redisplay that when + we clear the cursor. */ + if (! NILP (dpyinfo->mouse_face_window) + && w == XWINDOW (dpyinfo->mouse_face_window) + && (vpos > dpyinfo->mouse_face_beg_row + || (vpos == dpyinfo->mouse_face_beg_row + && hpos >= dpyinfo->mouse_face_beg_col)) + && (vpos < dpyinfo->mouse_face_end_row + || (vpos == dpyinfo->mouse_face_end_row + && hpos < dpyinfo->mouse_face_end_col)) + /* Don't redraw the cursor's spot in mouse face if it is at the + end of a line (on a newline). The cursor appears there, but + mouse highlighting does not. */ + && cursor_row->used[TEXT_AREA] > hpos) + hl = DRAW_MOUSE_FACE; + else + hl = DRAW_NORMAL_TEXT; + drawGlyph = 1; // just draw the Glyph [FRAME_BACKGROUND_COLOR (f) set]; } else + { + cursorType = cursor_type; + hl = DRAW_CURSOR; [FRAME_CURSOR_COLOR (f) set]; + ! if (!active_p) ! { ! /* inactive window: ignore what we just set and use a hollow box */ ! cursorType = hollow_box; ! [FRAME_CURSOR_COLOR (f) set]; ! } ! switch (cursorType) ! { ! case NO_CURSOR: // no_highlight: ! break; ! case FILLED_BOX_CURSOR: //filled_box: ! NSRectFill (r); ! drawGlyph = 1; ! break; ! case HOLLOW_BOX_CURSOR: //hollow_box: ! NSRectFill (r); ! [FRAME_BACKGROUND_COLOR (f) set]; ! NSRectFill (NSInsetRect (r, 1, 1)); ! [FRAME_CURSOR_COLOR (f) set]; ! drawGlyph = 1; ! break; ! case HBAR_CURSOR: // underscore: ! s = r; ! s.origin.y += lrint (0.75 * s.size.height); ! s.size.height = cursor_width; //lrint (s.size.height * 0.25); ! NSRectFill (s); ! break; ! case BAR_CURSOR: //bar: ! s = r; ! s.size.width = cursor_width; ! NSRectFill (s); ! break; ! } } ns_unfocus (f); /* if needed, draw the character under the cursor */ if (drawGlyph) ! draw_phys_cursor_glyph (w, glyph_row, hl); } *** xdisp.c 19 Jul 2008 10:43:47 -0400 1.1236 --- xdisp.c 21 Jul 2008 22:47:35 -0400 *************** *** 2099,2105 **** rectangle as wide as the glyph, but use a canonical character width instead. */ wd = glyph->pixel_width - 1; ! #ifdef HAVE_NTGUI wd++; /* Why? */ #endif --- 2099,2105 ---- rectangle as wide as the glyph, but use a canonical character width instead. */ wd = glyph->pixel_width - 1; ! #if defined(HAVE_NTGUI) || defined(HAVE_NS) wd++; /* Why? */ #endif
smime.p7s
Description: S/MIME cryptographic signature
------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________ Emacs-app-dev- mailing list Emacs-app-dev-@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/emacs-app-dev-