aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2013-09-24 19:07:35 +0300
committerEli Zaretskii2013-09-24 19:07:35 +0300
commitf34729eaec648d9784e68cf407b3ca94b19e3b70 (patch)
tree0f5baaa4dc0e5f57fbb5a8282a4e86e8485743ea
parentdf78230943690aa2d95e22f947615c09d2c676e8 (diff)
downloademacs-f34729eaec648d9784e68cf407b3ca94b19e3b70.tar.gz
emacs-f34729eaec648d9784e68cf407b3ca94b19e3b70.zip
Fix submenus and screen restoration.
-rw-r--r--lisp/menu-bar.el4
-rw-r--r--src/keyboard.c13
-rw-r--r--src/term.c65
-rw-r--r--src/termchar.h3
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
3082struct glyph_matrix *
3083save_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
3126static void 3167static 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. */