diff options
| author | Martin Rudalics | 2025-03-17 09:36:59 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2025-03-17 09:36:59 +0100 |
| commit | 7e71b0a2c938623872ec7404d81339c8ff51b012 (patch) | |
| tree | dbdd6a42187ca09405a19d165f183e0279b225e5 /src | |
| parent | d708ebe401a2001e764821b7e43d9e9aaa23ea95 (diff) | |
| download | emacs-7e71b0a2c938623872ec7404d81339c8ff51b012.tar.gz emacs-7e71b0a2c938623872ec7404d81339c8ff51b012.zip | |
Implement surrogate menu bars for tty child frames
* lisp/menu-bar.el (popup-menu): When asked to pop up MENU from
a tty child frame try to use menu of its root frame.
(menu-bar-open): When FRAME is a child frame and
'tty-menu-open-use-tmm' is nil, navigate menu bar of its root
frame.
* src/keymap.c (Fcurrent_active_maps): Accept live window as
POSITION argument and use its buffer as current when processing
the key sequence. Needed for tty child frames so the root
frame's menu bar can be updated according to the selected
window's buffer when navigating the menu bar from keyboard.
* src/xdisp.c (prepare_menu_bars): If the selected window's
frame is a tty child frame without menu bar, that frame's root
frame has a menu bar and 'tty-menu-open-use-tmm' is nil, prepare
to update the menu bar of the root frame as surrogate.
(update_menu_bar): New argument W denoting the window that
should be considered as selected. For a tty child frame using F
as surrogate menu bar frame this specifies the child frame's
selected window and its buffer shall be used for updating the
menu bar of the root frame instead of the buffer of the root
frame's selected window.
(redisplay_window): Instead of setting redisplay_menu_p flag
always call display_menu_bar right away. This facilitates to
call display_menu_bar for a tty child frame with its root
frame as surrogate menu bar frame.
(display_tty_menu_item): If the selected frame is a tty child
frame, overwrite its root frame's glyph matrix (and not that of
the child frame) when displaying a menu item.
(Qtty_menu_open_use_tmm): Define symbol.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keymap.c | 13 | ||||
| -rw-r--r-- | src/xdisp.c | 99 |
2 files changed, 86 insertions, 26 deletions
diff --git a/src/keymap.c b/src/keymap.c index bc731c54ef0..2c250578b00 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1652,7 +1652,8 @@ DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps, | |||
| 1652 | doc: /* Return a list of the currently active keymaps. | 1652 | doc: /* Return a list of the currently active keymaps. |
| 1653 | OLP if non-nil indicates that we should obey `overriding-local-map' and | 1653 | OLP if non-nil indicates that we should obey `overriding-local-map' and |
| 1654 | `overriding-terminal-local-map'. POSITION can specify a click position | 1654 | `overriding-terminal-local-map'. POSITION can specify a click position |
| 1655 | like in the respective argument of `key-binding'. */) | 1655 | like in the respective argument of `key-binding' or a live window which |
| 1656 | means to return the active maps for that window's buffer. */) | ||
| 1656 | (Lisp_Object olp, Lisp_Object position) | 1657 | (Lisp_Object olp, Lisp_Object position) |
| 1657 | { | 1658 | { |
| 1658 | specpdl_ref count = SPECPDL_INDEX (); | 1659 | specpdl_ref count = SPECPDL_INDEX (); |
| @@ -1682,6 +1683,16 @@ like in the respective argument of `key-binding'. */) | |||
| 1682 | set_buffer_internal (XBUFFER (XWINDOW (window)->contents)); | 1683 | set_buffer_internal (XBUFFER (XWINDOW (window)->contents)); |
| 1683 | } | 1684 | } |
| 1684 | } | 1685 | } |
| 1686 | else if (WINDOW_LIVE_P (position)) | ||
| 1687 | { | ||
| 1688 | if (BUFFERP (XWINDOW (position)->contents) | ||
| 1689 | && XBUFFER (XWINDOW (position)->contents) != current_buffer) | ||
| 1690 | { | ||
| 1691 | /* See comment above. */ | ||
| 1692 | record_unwind_current_buffer (); | ||
| 1693 | set_buffer_internal (XBUFFER (XWINDOW (position)->contents)); | ||
| 1694 | } | ||
| 1695 | } | ||
| 1685 | 1696 | ||
| 1686 | if (!NILP (olp) | 1697 | if (!NILP (olp) |
| 1687 | /* The doc said that overriding-terminal-local-map should | 1698 | /* The doc said that overriding-terminal-local-map should |
diff --git a/src/xdisp.c b/src/xdisp.c index d7e0691c44d..c396b213b92 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1147,7 +1147,7 @@ static bool set_cursor_from_row (struct window *, struct glyph_row *, | |||
| 1147 | struct glyph_matrix *, ptrdiff_t, ptrdiff_t, | 1147 | struct glyph_matrix *, ptrdiff_t, ptrdiff_t, |
| 1148 | int, int); | 1148 | int, int); |
| 1149 | static bool cursor_row_fully_visible_p (struct window *, bool, bool, bool); | 1149 | static bool cursor_row_fully_visible_p (struct window *, bool, bool, bool); |
| 1150 | static bool update_menu_bar (struct frame *, bool, bool); | 1150 | static bool update_menu_bar (struct frame *, bool, bool, struct window *); |
| 1151 | static bool try_window_reusing_current_matrix (struct window *); | 1151 | static bool try_window_reusing_current_matrix (struct window *); |
| 1152 | static int try_window_id (struct window *); | 1152 | static int try_window_id (struct window *); |
| 1153 | static void maybe_produce_line_number (struct it *); | 1153 | static void maybe_produce_line_number (struct it *); |
| @@ -14066,13 +14066,32 @@ prepare_menu_bars (void) | |||
| 14066 | /* True means that update_menu_bar has run its hooks | 14066 | /* True means that update_menu_bar has run its hooks |
| 14067 | so any further calls to update_menu_bar shouldn't do so again. */ | 14067 | so any further calls to update_menu_bar shouldn't do so again. */ |
| 14068 | bool menu_bar_hooks_run = false; | 14068 | bool menu_bar_hooks_run = false; |
| 14069 | struct window *sw = XWINDOW (selected_window); | ||
| 14070 | struct frame *sf = WINDOW_XFRAME (sw); | ||
| 14071 | struct frame *rf = NULL; | ||
| 14072 | |||
| 14073 | if (FRAME_PARENT_FRAME (sf) && !FRAME_WINDOW_P (sf) | ||
| 14074 | && FRAME_MENU_BAR_LINES (sf) == 0 | ||
| 14075 | && FRAME_MENU_BAR_LINES (rf = root_frame (sf)) != 0 | ||
| 14076 | && NILP (Fdefault_value (Qtty_menu_open_use_tmm))) | ||
| 14077 | /* If the selected window's frame is a tty child frame without | ||
| 14078 | menu bar, that frame's root frame has a menu bar and | ||
| 14079 | 'tty-menu-open-use-tmm' is nil, update the menu bar of the | ||
| 14080 | root frame from the selected window. */ | ||
| 14081 | sf = rf; | ||
| 14082 | else | ||
| 14083 | { | ||
| 14084 | sf = NULL; | ||
| 14085 | sw = NULL; | ||
| 14086 | } | ||
| 14069 | 14087 | ||
| 14070 | record_unwind_save_match_data (); | 14088 | record_unwind_save_match_data (); |
| 14071 | 14089 | ||
| 14072 | FOR_EACH_FRAME (tail, frame) | 14090 | FOR_EACH_FRAME (tail, frame) |
| 14073 | { | 14091 | { |
| 14074 | struct frame *f = XFRAME (frame); | 14092 | struct frame *f = XFRAME (frame); |
| 14075 | struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); | 14093 | struct window *w |
| 14094 | = sf == f ? sw : XWINDOW (FRAME_SELECTED_WINDOW (f)); | ||
| 14076 | 14095 | ||
| 14077 | /* Ignore tooltip frame. */ | 14096 | /* Ignore tooltip frame. */ |
| 14078 | if (FRAME_TOOLTIP_P (f)) | 14097 | if (FRAME_TOOLTIP_P (f)) |
| @@ -14084,8 +14103,8 @@ prepare_menu_bars (void) | |||
| 14084 | && !XBUFFER (w->contents)->text->redisplay) | 14103 | && !XBUFFER (w->contents)->text->redisplay) |
| 14085 | continue; | 14104 | continue; |
| 14086 | 14105 | ||
| 14087 | if (!FRAME_PARENT_FRAME (f)) | 14106 | menu_bar_hooks_run |
| 14088 | menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run); | 14107 | = update_menu_bar (f, false, menu_bar_hooks_run, w); |
| 14089 | 14108 | ||
| 14090 | update_tab_bar (f, false); | 14109 | update_tab_bar (f, false); |
| 14091 | #ifdef HAVE_WINDOW_SYSTEM | 14110 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -14097,10 +14116,21 @@ prepare_menu_bars (void) | |||
| 14097 | } | 14116 | } |
| 14098 | else | 14117 | else |
| 14099 | { | 14118 | { |
| 14100 | struct frame *sf = SELECTED_FRAME (); | 14119 | struct window *sw = XWINDOW (selected_window); |
| 14120 | struct frame *sf = WINDOW_XFRAME (sw); | ||
| 14121 | struct frame *rf = NULL; | ||
| 14101 | 14122 | ||
| 14102 | if (!FRAME_PARENT_FRAME (sf)) | 14123 | if (FRAME_PARENT_FRAME (sf) && !FRAME_WINDOW_P (sf) |
| 14103 | update_menu_bar (sf, true, false); | 14124 | && FRAME_MENU_BAR_LINES (sf) == 0 |
| 14125 | && FRAME_MENU_BAR_LINES (rf = root_frame (sf)) != 0 | ||
| 14126 | && NILP (Fdefault_value (Qtty_menu_open_use_tmm))) | ||
| 14127 | /* If the selected window's frame is a tty child frame without | ||
| 14128 | menu bar, that frame's root frame has a menu bar and | ||
| 14129 | 'tty-menu-open-use-tmm' is nil, update the menu bar of the | ||
| 14130 | root frame from the selected window. */ | ||
| 14131 | sf = rf; | ||
| 14132 | |||
| 14133 | update_menu_bar (sf, true, false, sw); | ||
| 14104 | 14134 | ||
| 14105 | update_tab_bar (sf, true); | 14135 | update_tab_bar (sf, true); |
| 14106 | #ifdef HAVE_WINDOW_SYSTEM | 14136 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -14119,23 +14149,23 @@ prepare_menu_bars (void) | |||
| 14119 | If HOOKS_RUN, a previous call to update_menu_bar | 14149 | If HOOKS_RUN, a previous call to update_menu_bar |
| 14120 | already ran the menu bar hooks for this redisplay, so there | 14150 | already ran the menu bar hooks for this redisplay, so there |
| 14121 | is no need to run them again. The return value is the | 14151 | is no need to run them again. The return value is the |
| 14122 | updated value of this flag, to pass to the next call. */ | 14152 | updated value of this flag, to pass to the next call. |
| 14153 | |||
| 14154 | W, if set, denotes the window that should be considered as selected. | ||
| 14155 | For a tty child frame using F as surrogate menu bar frame, this | ||
| 14156 | specifes the child frame's selected window and its buffer shall be | ||
| 14157 | used for updating the menu bar of the root frame instead of the | ||
| 14158 | buffer of the root frame's selected window. */ | ||
| 14123 | 14159 | ||
| 14124 | static bool | 14160 | static bool |
| 14125 | update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run) | 14161 | update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run, struct window *w) |
| 14126 | { | 14162 | { |
| 14127 | Lisp_Object window; | ||
| 14128 | struct window *w; | ||
| 14129 | |||
| 14130 | /* If called recursively during a menu update, do nothing. This can | 14163 | /* If called recursively during a menu update, do nothing. This can |
| 14131 | happen when, for instance, an activate-menubar-hook causes a | 14164 | happen when, for instance, an activate-menubar-hook causes a |
| 14132 | redisplay. */ | 14165 | redisplay. */ |
| 14133 | if (inhibit_menubar_update) | 14166 | if (inhibit_menubar_update) |
| 14134 | return hooks_run; | 14167 | return hooks_run; |
| 14135 | 14168 | ||
| 14136 | window = FRAME_SELECTED_WINDOW (f); | ||
| 14137 | w = XWINDOW (window); | ||
| 14138 | |||
| 14139 | if (FRAME_WINDOW_P (f) | 14169 | if (FRAME_WINDOW_P (f) |
| 14140 | ? | 14170 | ? |
| 14141 | #ifdef HAVE_EXT_MENU_BAR | 14171 | #ifdef HAVE_EXT_MENU_BAR |
| @@ -21195,24 +21225,33 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 21195 | 21225 | ||
| 21196 | /* When we reach a frame's selected window, redo the frame's menu | 21226 | /* When we reach a frame's selected window, redo the frame's menu |
| 21197 | bar, tool bar, tab-bar, and the frame's title. */ | 21227 | bar, tool bar, tab-bar, and the frame's title. */ |
| 21198 | if (update_mode_line | 21228 | if (update_mode_line && EQ (FRAME_SELECTED_WINDOW (f), window)) |
| 21199 | && EQ (FRAME_SELECTED_WINDOW (f), window)) | ||
| 21200 | { | 21229 | { |
| 21201 | bool redisplay_menu_p; | ||
| 21202 | |||
| 21203 | if (FRAME_WINDOW_P (f)) | 21230 | if (FRAME_WINDOW_P (f)) |
| 21204 | { | 21231 | { |
| 21205 | #ifdef HAVE_EXT_MENU_BAR | 21232 | #ifdef HAVE_EXT_MENU_BAR |
| 21206 | redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f); | 21233 | if (FRAME_EXTERNAL_MENU_BAR (f)) |
| 21234 | display_menu_bar (w); | ||
| 21207 | #else | 21235 | #else |
| 21208 | redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0; | 21236 | if (FRAME_MENU_BAR_LINES (f) > 0) |
| 21237 | display_menu_bar (w); | ||
| 21209 | #endif | 21238 | #endif |
| 21210 | } | 21239 | } |
| 21211 | else | 21240 | else |
| 21212 | redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0; | 21241 | { |
| 21242 | struct frame *rf = NULL; | ||
| 21213 | 21243 | ||
| 21214 | if (redisplay_menu_p) | 21244 | if (FRAME_PARENT_FRAME (f) |
| 21215 | display_menu_bar (w); | 21245 | && FRAME_MENU_BAR_LINES (f) == 0 |
| 21246 | && FRAME_MENU_BAR_LINES (rf = root_frame (f)) != 0 | ||
| 21247 | && NILP (Fdefault_value (Qtty_menu_open_use_tmm))) | ||
| 21248 | /* If F is a tty child frame without menu bar, that frame's root | ||
| 21249 | frame has a menu bar and 'tty-menu-open-use-tmm' is nil, | ||
| 21250 | display the menu bar of the root frame's selected window. */ | ||
| 21251 | display_menu_bar (XWINDOW (FRAME_SELECTED_WINDOW (rf))); | ||
| 21252 | else if (FRAME_MENU_BAR_LINES (f) > 0) | ||
| 21253 | display_menu_bar (w); | ||
| 21254 | } | ||
| 21216 | 21255 | ||
| 21217 | #ifdef HAVE_WINDOW_SYSTEM | 21256 | #ifdef HAVE_WINDOW_SYSTEM |
| 21218 | if (FRAME_WINDOW_P (f)) | 21257 | if (FRAME_WINDOW_P (f)) |
| @@ -27466,10 +27505,19 @@ display_tty_menu_item (const char *item_text, int width, int face_id, | |||
| 27466 | { | 27505 | { |
| 27467 | struct it it; | 27506 | struct it it; |
| 27468 | struct frame *f = SELECTED_FRAME (); | 27507 | struct frame *f = SELECTED_FRAME (); |
| 27469 | struct window *w = XWINDOW (f->selected_window); | ||
| 27470 | struct glyph_row *row; | 27508 | struct glyph_row *row; |
| 27471 | size_t item_len = strlen (item_text); | 27509 | size_t item_len = strlen (item_text); |
| 27472 | 27510 | ||
| 27511 | struct frame *rf = NULL; | ||
| 27512 | |||
| 27513 | if (FRAME_PARENT_FRAME (f) && !FRAME_WINDOW_P (f) | ||
| 27514 | && FRAME_MENU_BAR_LINES (f) == 0 | ||
| 27515 | && FRAME_MENU_BAR_LINES (rf = root_frame (f)) != 0 | ||
| 27516 | && NILP (Fdefault_value (Qtty_menu_open_use_tmm))) | ||
| 27517 | f = rf; | ||
| 27518 | |||
| 27519 | struct window *w = XWINDOW (f->selected_window); | ||
| 27520 | |||
| 27473 | eassert (FRAME_TERMCAP_P (f)); | 27521 | eassert (FRAME_TERMCAP_P (f)); |
| 27474 | 27522 | ||
| 27475 | /* Don't write beyond the matrix's last row. This can happen for | 27523 | /* Don't write beyond the matrix's last row. This can happen for |
| @@ -38610,6 +38658,7 @@ depending on your patience and the speed of your system. */); | |||
| 38610 | DEFSYM (Qnhdrag, "nhdrag"); | 38658 | DEFSYM (Qnhdrag, "nhdrag"); |
| 38611 | DEFSYM (Qvdrag, "vdrag"); | 38659 | DEFSYM (Qvdrag, "vdrag"); |
| 38612 | DEFSYM (Qhourglass, "hourglass"); | 38660 | DEFSYM (Qhourglass, "hourglass"); |
| 38661 | DEFSYM (Qtty_menu_open_use_tmm, "tty-menu-open-use-tmm"); | ||
| 38613 | } | 38662 | } |
| 38614 | 38663 | ||
| 38615 | 38664 | ||