diff options
| -rw-r--r-- | src/dispextern.h | 2 | ||||
| -rw-r--r-- | src/term.c | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 71 |
3 files changed, 62 insertions, 17 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index 0e6d934991a..f70b1f8092e 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3266,7 +3266,7 @@ extern int clear_mouse_face (Mouse_HLInfo *); | |||
| 3266 | extern int cursor_in_mouse_face_p (struct window *w); | 3266 | extern int cursor_in_mouse_face_p (struct window *w); |
| 3267 | extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *, | 3267 | extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *, |
| 3268 | int, int, enum draw_glyphs_face); | 3268 | int, int, enum draw_glyphs_face); |
| 3269 | extern void display_tty_menu_item (const char *, int, int, int, int); | 3269 | extern void display_tty_menu_item (const char *, int, int, int, int, int); |
| 3270 | 3270 | ||
| 3271 | /* Flags passed to try_window. */ | 3271 | /* Flags passed to try_window. */ |
| 3272 | #define TRY_WINDOW_CHECK_MARGINS (1 << 0) | 3272 | #define TRY_WINDOW_CHECK_MARGINS (1 << 0) |
diff --git a/src/term.c b/src/term.c index f27bf8d900d..28338a3cc48 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2942,9 +2942,11 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces, | |||
| 2942 | #endif | 2942 | #endif |
| 2943 | for (i = 0; i < menu->count; i++) | 2943 | for (i = 0; i < menu->count; i++) |
| 2944 | { | 2944 | { |
| 2945 | int max_width = width + 2; | 2945 | int max_width = width + 2; /* +2 for padding blanks on each side */ |
| 2946 | 2946 | ||
| 2947 | cursor_to (sf, y + i, x); | 2947 | cursor_to (sf, y + i, x); |
| 2948 | if (menu->submenu[i]) | ||
| 2949 | max_width += 2; /* for displaying " >" after the item */ | ||
| 2948 | enabled | 2950 | enabled |
| 2949 | = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]); | 2951 | = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]); |
| 2950 | mousehere = (y + i == my && x <= mx && mx < x + max_width); | 2952 | mousehere = (y + i == my && x <= mx && mx < x + max_width); |
| @@ -2958,7 +2960,7 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces, | |||
| 2958 | menu_help_paneno = pn - 1; | 2960 | menu_help_paneno = pn - 1; |
| 2959 | menu_help_itemno = i; | 2961 | menu_help_itemno = i; |
| 2960 | } | 2962 | } |
| 2961 | display_tty_menu_item (menu->text[i], face, x, y + i, | 2963 | display_tty_menu_item (menu->text[i], max_width, face, x, y + i, |
| 2962 | menu->submenu[i] != NULL); | 2964 | menu->submenu[i] != NULL); |
| 2963 | } | 2965 | } |
| 2964 | update_frame_with_menu (sf); | 2966 | update_frame_with_menu (sf); |
diff --git a/src/xdisp.c b/src/xdisp.c index 29d8118ff8e..b2e60549fcd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -20576,6 +20576,40 @@ display_menu_bar (struct window *w) | |||
| 20576 | } | 20576 | } |
| 20577 | 20577 | ||
| 20578 | #ifdef HAVE_MENUS | 20578 | #ifdef HAVE_MENUS |
| 20579 | /* Deep copy of a glyph row, including the glyphs. */ | ||
| 20580 | static void | ||
| 20581 | deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) | ||
| 20582 | { | ||
| 20583 | int area, i, sum_used = 0; | ||
| 20584 | struct glyph *pointers[1 + LAST_AREA]; | ||
| 20585 | |||
| 20586 | /* Save glyph pointers of TO. */ | ||
| 20587 | memcpy (pointers, to->glyphs, sizeof to->glyphs); | ||
| 20588 | |||
| 20589 | /* Do a structure assignment. */ | ||
| 20590 | *to = *from; | ||
| 20591 | |||
| 20592 | /* Restore original pointers of TO. */ | ||
| 20593 | memcpy (to->glyphs, pointers, sizeof to->glyphs); | ||
| 20594 | |||
| 20595 | /* Count how many glyphs to copy and update glyph pointers. */ | ||
| 20596 | for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) | ||
| 20597 | { | ||
| 20598 | if (area > LEFT_MARGIN_AREA) | ||
| 20599 | { | ||
| 20600 | eassert (from->glyphs[area] - from->glyphs[area - 1] | ||
| 20601 | == from->used[area - 1]); | ||
| 20602 | to->glyphs[area] = to->glyphs[area - 1] + to->used[area - 1]; | ||
| 20603 | } | ||
| 20604 | sum_used += from->used[area]; | ||
| 20605 | } | ||
| 20606 | |||
| 20607 | /* Copy the glyphs. */ | ||
| 20608 | eassert (sum_used <= to->glyphs[LAST_AREA] - to->glyphs[LEFT_MARGIN_AREA]); | ||
| 20609 | for (i = 0; i < sum_used; i++) | ||
| 20610 | to->glyphs[LEFT_MARGIN_AREA][i] = from->glyphs[LEFT_MARGIN_AREA][i]; | ||
| 20611 | } | ||
| 20612 | |||
| 20579 | /* Display one menu item on a TTY, by overwriting the glyphs in the | 20613 | /* Display one menu item on a TTY, by overwriting the glyphs in the |
| 20580 | desired glyph matrix with glyphs produced from the menu item text. | 20614 | desired glyph matrix with glyphs produced from the menu item text. |
| 20581 | Called from term.c to display TTY drop-down menus one item at a | 20615 | Called from term.c to display TTY drop-down menus one item at a |
| @@ -20598,14 +20632,15 @@ display_menu_bar (struct window *w) | |||
| 20598 | item text. */ | 20632 | item text. */ |
| 20599 | 20633 | ||
| 20600 | void | 20634 | void |
| 20601 | display_tty_menu_item (const char *item_text, int face_id, int x, int y, | 20635 | display_tty_menu_item (const char *item_text, int width, int face_id, |
| 20602 | int submenu) | 20636 | int x, int y, int submenu) |
| 20603 | { | 20637 | { |
| 20604 | struct it it; | 20638 | struct it it; |
| 20605 | struct frame *f = SELECTED_FRAME (); | 20639 | struct frame *f = SELECTED_FRAME (); |
| 20606 | struct window *w = XWINDOW (f->selected_window); | 20640 | struct window *w = XWINDOW (f->selected_window); |
| 20607 | int saved_used, saved_truncated, saved_width, saved_reversed; | 20641 | int saved_used, saved_truncated, saved_width, saved_reversed; |
| 20608 | struct glyph_row *row; | 20642 | struct glyph_row *row; |
| 20643 | size_t item_len = strlen (item_text); | ||
| 20609 | 20644 | ||
| 20610 | eassert (FRAME_TERMCAP_P (f)); | 20645 | eassert (FRAME_TERMCAP_P (f)); |
| 20611 | 20646 | ||
| @@ -20613,20 +20648,27 @@ display_tty_menu_item (const char *item_text, int face_id, int x, int y, | |||
| 20613 | it.first_visible_x = 0; | 20648 | it.first_visible_x = 0; |
| 20614 | it.last_visible_x = FRAME_COLS (f); | 20649 | it.last_visible_x = FRAME_COLS (f); |
| 20615 | row = it.glyph_row; | 20650 | row = it.glyph_row; |
| 20616 | /* Copy the row contents from the current matrix. */ | 20651 | /* Start with the row contents from the current matrix. */ |
| 20617 | *row = f->current_matrix->rows[y]; | 20652 | deep_copy_glyph_row (row, f->current_matrix->rows + y); |
| 20618 | saved_width = row->full_width_p; | 20653 | saved_width = row->full_width_p; |
| 20619 | row->full_width_p = 1; | 20654 | row->full_width_p = 1; |
| 20620 | saved_reversed = row->reversed_p; | 20655 | saved_reversed = row->reversed_p; |
| 20621 | row->reversed_p = 0; | 20656 | row->reversed_p = 0; |
| 20657 | row->enabled_p = 1; | ||
| 20622 | 20658 | ||
| 20623 | /* Arrange for the menu item glyphs to start at X and have the | 20659 | /* We can only write over TEXT_AREA, as display_string cannot do |
| 20660 | display margins. */ | ||
| 20661 | x += row->used[LEFT_MARGIN_AREA]; | ||
| 20662 | |||
| 20663 | /* Arrange for the menu item glyphs to start at (X,Y) and have the | ||
| 20624 | desired face. */ | 20664 | desired face. */ |
| 20625 | it.current_x = it.hpos = x; | 20665 | it.current_x = it.hpos = x; |
| 20666 | it.current_y = it.vpos = y; | ||
| 20626 | saved_used = row->used[TEXT_AREA]; | 20667 | saved_used = row->used[TEXT_AREA]; |
| 20627 | saved_truncated = row->truncated_on_right_p; | 20668 | saved_truncated = row->truncated_on_right_p; |
| 20628 | row->used[TEXT_AREA] = x - row->used[LEFT_MARGIN_AREA]; | 20669 | row->used[TEXT_AREA] = x - row->used[LEFT_MARGIN_AREA]; |
| 20629 | it.face_id = face_id; | 20670 | it.face_id = face_id; |
| 20671 | it.line_wrap = TRUNCATE; | ||
| 20630 | 20672 | ||
| 20631 | /* FIXME: This should be controlled by a user option. See the | 20673 | /* FIXME: This should be controlled by a user option. See the |
| 20632 | comments in redisplay_tool_bar and display_mode_line about this. | 20674 | comments in redisplay_tool_bar and display_mode_line about this. |
| @@ -20636,20 +20678,21 @@ display_tty_menu_item (const char *item_text, int face_id, int x, int y, | |||
| 20636 | it.paragraph_embedding = L2R; | 20678 | it.paragraph_embedding = L2R; |
| 20637 | 20679 | ||
| 20638 | /* Pad with a space on the left. */ | 20680 | /* Pad with a space on the left. */ |
| 20639 | display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, 0, -1); | 20681 | display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1); |
| 20682 | width--; | ||
| 20683 | /* Display the menu item, pad with spaces to WIDTH. */ | ||
| 20640 | if (submenu) | 20684 | if (submenu) |
| 20641 | { | 20685 | { |
| 20642 | /* Indicate with ">" that there's a submenu. */ | ||
| 20643 | display_string (item_text, Qnil, Qnil, 0, 0, &it, | 20686 | display_string (item_text, Qnil, Qnil, 0, 0, &it, |
| 20644 | strlen (item_text), 0, FRAME_COLS (f) - 2, -1); | 20687 | item_len, 0, FRAME_COLS (f) - 1, -1); |
| 20645 | display_string (">", Qnil, Qnil, 0, 0, &it, 1, 0, 0, -1); | 20688 | width -= item_len; |
| 20689 | /* Indicate with " >" that there's a submenu. */ | ||
| 20690 | display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0, | ||
| 20691 | FRAME_COLS (f) - 1, -1); | ||
| 20646 | } | 20692 | } |
| 20647 | else | 20693 | else |
| 20648 | { | 20694 | display_string (item_text, Qnil, Qnil, 0, 0, &it, |
| 20649 | /* Display the menu item, pad with one space. */ | 20695 | width, 0, FRAME_COLS (f) - 1, -1); |
| 20650 | display_string (item_text, Qnil, Qnil, 0, 0, &it, | ||
| 20651 | strlen (item_text) + 1, 0, 0, -1); | ||
| 20652 | } | ||
| 20653 | 20696 | ||
| 20654 | row->used[TEXT_AREA] = saved_used; | 20697 | row->used[TEXT_AREA] = saved_used; |
| 20655 | row->truncated_on_right_p = saved_truncated; | 20698 | row->truncated_on_right_p = saved_truncated; |