diff options
| author | Eli Zaretskii | 2013-09-24 19:07:35 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-09-24 19:07:35 +0300 |
| commit | f34729eaec648d9784e68cf407b3ca94b19e3b70 (patch) | |
| tree | 0f5baaa4dc0e5f57fbb5a8282a4e86e8485743ea | |
| parent | df78230943690aa2d95e22f947615c09d2c676e8 (diff) | |
| download | emacs-f34729eaec648d9784e68cf407b3ca94b19e3b70.tar.gz emacs-f34729eaec648d9784e68cf407b3ca94b19e3b70.zip | |
Fix submenus and screen restoration.
| -rw-r--r-- | lisp/menu-bar.el | 4 | ||||
| -rw-r--r-- | src/keyboard.c | 13 | ||||
| -rw-r--r-- | src/term.c | 65 | ||||
| -rw-r--r-- | src/termchar.h | 3 |
4 files changed, 73 insertions, 12 deletions
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 5cc79b9358e..37cbd9f0490 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el | |||
| @@ -2323,7 +2323,9 @@ If FRAME is nil or not given, use the selected frame." | |||
| 2323 | ((eq type 'x) (x-menu-bar-open frame)) | 2323 | ((eq type 'x) (x-menu-bar-open frame)) |
| 2324 | ((eq type 'w32) (w32-menu-bar-open frame)) | 2324 | ((eq type 'w32) (w32-menu-bar-open frame)) |
| 2325 | ((null tty-menu-open-use-tmm) | 2325 | ((null tty-menu-open-use-tmm) |
| 2326 | (popup-menu menu-bar-file-menu (posn-at-x-y 0 0 nil t))) | 2326 | ;; FIXME: This should open the leftmost menu, and let the user |
| 2327 | ;; move to others via C-f or right-arrow. | ||
| 2328 | (popup-menu menu-bar-tools-menu (posn-at-x-y 30 0 nil t))) | ||
| 2327 | (t (with-selected-frame (or frame (selected-frame)) | 2329 | (t (with-selected-frame (or frame (selected-frame)) |
| 2328 | (tmm-menubar)))))) | 2330 | (tmm-menubar)))))) |
| 2329 | 2331 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 4ace767484e..9faa3770cf3 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -3903,7 +3903,18 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 3903 | } | 3903 | } |
| 3904 | } | 3904 | } |
| 3905 | else | 3905 | else |
| 3906 | wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0); | 3906 | { |
| 3907 | bool do_display = true; | ||
| 3908 | struct tty_display_info *tty = CURTTY (); | ||
| 3909 | |||
| 3910 | /* When this TTY is displaying a menu, we must prevent any | ||
| 3911 | redisplay, because we modify the frame's glyph matrix | ||
| 3912 | behind the back of the display engine. */ | ||
| 3913 | if (tty->showing_menu) | ||
| 3914 | do_display = false; | ||
| 3915 | |||
| 3916 | wait_reading_process_output (0, 0, -1, do_display, Qnil, NULL, 0); | ||
| 3917 | } | ||
| 3907 | 3918 | ||
| 3908 | if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr) | 3919 | if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr) |
| 3909 | gobble_input (); | 3920 | gobble_input (); |
diff --git a/src/term.c b/src/term.c index 4da5fd13905..b408a4a0907 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -3075,6 +3075,53 @@ struct tty_menu_state | |||
| 3075 | int x, y; | 3075 | int x, y; |
| 3076 | }; | 3076 | }; |
| 3077 | 3077 | ||
| 3078 | /* Save away the contents of frame F's current frame matrix, and | ||
| 3079 | enable all its rows. Value is a glyph matrix holding the contents | ||
| 3080 | of F's current frame matrix with all its glyph rows enabled. */ | ||
| 3081 | |||
| 3082 | struct glyph_matrix * | ||
| 3083 | save_and_enable_current_matrix (struct frame *f) | ||
| 3084 | { | ||
| 3085 | int i; | ||
| 3086 | struct glyph_matrix *saved = xzalloc (sizeof *saved); | ||
| 3087 | saved->nrows = f->current_matrix->nrows; | ||
| 3088 | saved->rows = xzalloc (saved->nrows * sizeof *saved->rows); | ||
| 3089 | |||
| 3090 | for (i = 0; i < saved->nrows; ++i) | ||
| 3091 | { | ||
| 3092 | struct glyph_row *from = f->current_matrix->rows + i; | ||
| 3093 | struct glyph_row *to = saved->rows + i; | ||
| 3094 | ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); | ||
| 3095 | |||
| 3096 | to->glyphs[TEXT_AREA] = xmalloc (nbytes); | ||
| 3097 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); | ||
| 3098 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; | ||
| 3099 | /* Make sure every row is enabled, or else update_frame will not | ||
| 3100 | redraw them. (Rows that are identical to what is already on | ||
| 3101 | screen will not be redrawn anyway.) */ | ||
| 3102 | to->enabled_p = 1; | ||
| 3103 | to->hash = from->hash; | ||
| 3104 | if (from->used[LEFT_MARGIN_AREA]) | ||
| 3105 | { | ||
| 3106 | nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph); | ||
| 3107 | to->glyphs[LEFT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes); | ||
| 3108 | memcpy (to->glyphs[LEFT_MARGIN_AREA], | ||
| 3109 | from->glyphs[LEFT_MARGIN_AREA], nbytes); | ||
| 3110 | to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA]; | ||
| 3111 | } | ||
| 3112 | if (from->used[RIGHT_MARGIN_AREA]) | ||
| 3113 | { | ||
| 3114 | nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph); | ||
| 3115 | to->glyphs[RIGHT_MARGIN_AREA] = (struct glyph *) xmalloc (nbytes); | ||
| 3116 | memcpy (to->glyphs[RIGHT_MARGIN_AREA], | ||
| 3117 | from->glyphs[RIGHT_MARGIN_AREA], nbytes); | ||
| 3118 | to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA]; | ||
| 3119 | } | ||
| 3120 | } | ||
| 3121 | |||
| 3122 | return saved; | ||
| 3123 | } | ||
| 3124 | |||
| 3078 | /* Restore the contents of frame F's desired frame matrix from SAVED, | 3125 | /* Restore the contents of frame F's desired frame matrix from SAVED, |
| 3079 | and free memory associated with SAVED. */ | 3126 | and free memory associated with SAVED. */ |
| 3080 | 3127 | ||
| @@ -3094,7 +3141,6 @@ restore_desired_matrix (struct frame *f, struct glyph_matrix *saved) | |||
| 3094 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; | 3141 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; |
| 3095 | to->enabled_p = from->enabled_p; | 3142 | to->enabled_p = from->enabled_p; |
| 3096 | to->hash = from->hash; | 3143 | to->hash = from->hash; |
| 3097 | xfree (from->glyphs[TEXT_AREA]); | ||
| 3098 | nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph); | 3144 | nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph); |
| 3099 | if (nbytes) | 3145 | if (nbytes) |
| 3100 | { | 3146 | { |
| @@ -3102,7 +3148,6 @@ restore_desired_matrix (struct frame *f, struct glyph_matrix *saved) | |||
| 3102 | memcpy (to->glyphs[LEFT_MARGIN_AREA], | 3148 | memcpy (to->glyphs[LEFT_MARGIN_AREA], |
| 3103 | from->glyphs[LEFT_MARGIN_AREA], nbytes); | 3149 | from->glyphs[LEFT_MARGIN_AREA], nbytes); |
| 3104 | to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA]; | 3150 | to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA]; |
| 3105 | xfree (from->glyphs[LEFT_MARGIN_AREA]); | ||
| 3106 | } | 3151 | } |
| 3107 | else | 3152 | else |
| 3108 | to->used[LEFT_MARGIN_AREA] = 0; | 3153 | to->used[LEFT_MARGIN_AREA] = 0; |
| @@ -3113,14 +3158,10 @@ restore_desired_matrix (struct frame *f, struct glyph_matrix *saved) | |||
| 3113 | memcpy (to->glyphs[RIGHT_MARGIN_AREA], | 3158 | memcpy (to->glyphs[RIGHT_MARGIN_AREA], |
| 3114 | from->glyphs[RIGHT_MARGIN_AREA], nbytes); | 3159 | from->glyphs[RIGHT_MARGIN_AREA], nbytes); |
| 3115 | to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA]; | 3160 | to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA]; |
| 3116 | xfree (from->glyphs[RIGHT_MARGIN_AREA]); | ||
| 3117 | } | 3161 | } |
| 3118 | else | 3162 | else |
| 3119 | to->used[RIGHT_MARGIN_AREA] = 0; | 3163 | to->used[RIGHT_MARGIN_AREA] = 0; |
| 3120 | } | 3164 | } |
| 3121 | |||
| 3122 | xfree (saved->rows); | ||
| 3123 | xfree (saved); | ||
| 3124 | } | 3165 | } |
| 3125 | 3166 | ||
| 3126 | static void | 3167 | static void |
| @@ -3182,10 +3223,15 @@ read_menu_input (struct frame *sf, int *x, int *y, int min_y, int max_y, | |||
| 3182 | Lisp_Object cmd; | 3223 | Lisp_Object cmd; |
| 3183 | int usable_input = 1; | 3224 | int usable_input = 1; |
| 3184 | int st = 0; | 3225 | int st = 0; |
| 3226 | struct tty_display_info *tty = FRAME_TTY (sf); | ||
| 3185 | 3227 | ||
| 3228 | /* Signal the keyboard reading routines we are displaying a menu | ||
| 3229 | on this terminal. */ | ||
| 3230 | tty->showing_menu = 1; | ||
| 3186 | do { | 3231 | do { |
| 3187 | cmd = read_menu_command (); | 3232 | cmd = read_menu_command (); |
| 3188 | } while NILP (cmd); | 3233 | } while NILP (cmd); |
| 3234 | tty->showing_menu = 0; | ||
| 3189 | 3235 | ||
| 3190 | if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit)) | 3236 | if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit)) |
| 3191 | return -1; | 3237 | return -1; |
| @@ -3333,7 +3379,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3333 | update_frame_with_menu (sf); | 3379 | update_frame_with_menu (sf); |
| 3334 | state[0].menu = menu; | 3380 | state[0].menu = menu; |
| 3335 | mouse_off (); /* FIXME */ | 3381 | mouse_off (); /* FIXME */ |
| 3336 | state[0].screen_behind = save_current_matrix (sf); | 3382 | state[0].screen_behind = save_and_enable_current_matrix (sf); |
| 3337 | 3383 | ||
| 3338 | /* Turn off the cursor. Otherwise it shows through the menu | 3384 | /* Turn off the cursor. Otherwise it shows through the menu |
| 3339 | panes, which is ugly. */ | 3385 | panes, which is ugly. */ |
| @@ -3383,7 +3429,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3383 | } | 3429 | } |
| 3384 | leave = 1; | 3430 | leave = 1; |
| 3385 | } | 3431 | } |
| 3386 | else if (sf->mouse_moved) | 3432 | if (sf->mouse_moved && input_status != -1) |
| 3387 | { | 3433 | { |
| 3388 | sf->mouse_moved = 0; | 3434 | sf->mouse_moved = 0; |
| 3389 | result = TTYM_IA_SELECT; | 3435 | result = TTYM_IA_SELECT; |
| @@ -3425,7 +3471,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3425 | state[statecount].pane = state[i].menu->panenumber[dy]; | 3471 | state[statecount].pane = state[i].menu->panenumber[dy]; |
| 3426 | mouse_off (); /* FIXME */ | 3472 | mouse_off (); /* FIXME */ |
| 3427 | state[statecount].screen_behind | 3473 | state[statecount].screen_behind |
| 3428 | = save_current_matrix (sf); | 3474 | = save_and_enable_current_matrix (sf); |
| 3429 | state[statecount].x | 3475 | state[statecount].x |
| 3430 | = state[i].x + state[i].menu->width + 2; | 3476 | = state[i].x + state[i].menu->width + 2; |
| 3431 | state[statecount].y = y; | 3477 | state[statecount].y = y; |
| @@ -3476,7 +3522,6 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3476 | /* FIXME: Since we set the fram's garbaged flag, do we need this | 3522 | /* FIXME: Since we set the fram's garbaged flag, do we need this |
| 3477 | call to screen_update? */ | 3523 | call to screen_update? */ |
| 3478 | screen_update (sf, state[0].screen_behind); | 3524 | screen_update (sf, state[0].screen_behind); |
| 3479 | state[0].screen_behind = NULL; | ||
| 3480 | #if 0 | 3525 | #if 0 |
| 3481 | /* We have a situation here. ScreenUpdate has just restored the | 3526 | /* We have a situation here. ScreenUpdate has just restored the |
| 3482 | screen contents as it was before we started drawing this menu. | 3527 | screen contents as it was before we started drawing this menu. |
diff --git a/src/termchar.h b/src/termchar.h index 687f7fbd119..9dea46f0b76 100644 --- a/src/termchar.h +++ b/src/termchar.h | |||
| @@ -198,6 +198,9 @@ struct tty_display_info | |||
| 198 | /* Nonzero means use ^S/^Q for flow control. */ | 198 | /* Nonzero means use ^S/^Q for flow control. */ |
| 199 | 199 | ||
| 200 | unsigned flow_control : 1; | 200 | unsigned flow_control : 1; |
| 201 | |||
| 202 | /* Non-zero means we are displaying a TTY menu on this tty. */ | ||
| 203 | unsigned showing_menu : 1; | ||
| 201 | }; | 204 | }; |
| 202 | 205 | ||
| 203 | /* A chain of structures for all tty devices currently in use. */ | 206 | /* A chain of structures for all tty devices currently in use. */ |