aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorJuri Linkov2019-10-01 23:15:03 +0300
committerJuri Linkov2019-10-01 23:15:03 +0300
commit2698d3dba2e9858b026ed127d4de3f86810a5ef3 (patch)
tree8e9b8f194cfcad8af83a4174a0105bbc691f06d6 /src/keyboard.c
parent25f45d710e91a7c1049f056ff27bc3e6968f5624 (diff)
parent3f981a0a89bca47a207fb362485f07e7322bb145 (diff)
downloademacs-2698d3dba2e9858b026ed127d4de3f86810a5ef3.tar.gz
emacs-2698d3dba2e9858b026ed127d4de3f86810a5ef3.zip
Merge branch 'feature/tabs'
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c436
1 files changed, 425 insertions, 11 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index a16d13cc7b8..40aaf496384 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2385,7 +2385,8 @@ read_char (int commandflag, Lisp_Object map,
2385 if (used_mouse_menu 2385 if (used_mouse_menu
2386 /* Also check was_disabled so last-nonmenu-event won't return 2386 /* Also check was_disabled so last-nonmenu-event won't return
2387 a bad value when submenus are involved. (Bug#447) */ 2387 a bad value when submenus are involved. (Bug#447) */
2388 && (EQ (c, Qtool_bar) || EQ (c, Qmenu_bar) || was_disabled)) 2388 && (EQ (c, Qtool_bar) || EQ (c, Qtab_bar) || EQ (c, Qmenu_bar)
2389 || was_disabled))
2389 *used_mouse_menu = true; 2390 *used_mouse_menu = true;
2390 2391
2391 goto reread_for_input_method; 2392 goto reread_for_input_method;
@@ -2666,6 +2667,7 @@ read_char (int commandflag, Lisp_Object map,
2666 && !NILP (prev_event) 2667 && !NILP (prev_event)
2667 && EVENT_HAS_PARAMETERS (prev_event) 2668 && EVENT_HAS_PARAMETERS (prev_event)
2668 && !EQ (XCAR (prev_event), Qmenu_bar) 2669 && !EQ (XCAR (prev_event), Qmenu_bar)
2670 && !EQ (XCAR (prev_event), Qtab_bar)
2669 && !EQ (XCAR (prev_event), Qtool_bar) 2671 && !EQ (XCAR (prev_event), Qtool_bar)
2670 /* Don't bring up a menu if we already have another event. */ 2672 /* Don't bring up a menu if we already have another event. */
2671 && !CONSP (Vunread_command_events)) 2673 && !CONSP (Vunread_command_events))
@@ -2930,7 +2932,7 @@ read_char (int commandflag, Lisp_Object map,
2930 posn = POSN_POSN (xevent_start (c)); 2932 posn = POSN_POSN (xevent_start (c));
2931 /* Handle menu-bar events: 2933 /* Handle menu-bar events:
2932 insert the dummy prefix event `menu-bar'. */ 2934 insert the dummy prefix event `menu-bar'. */
2933 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) 2935 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
2934 { 2936 {
2935 /* Change menu-bar to (menu-bar) as the event "position". */ 2937 /* Change menu-bar to (menu-bar) as the event "position". */
2936 POSN_SET_POSN (xevent_start (c), list1 (posn)); 2938 POSN_SET_POSN (xevent_start (c), list1 (posn));
@@ -3974,6 +3976,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3974 if (used_mouse_menu 3976 if (used_mouse_menu
3975 && !EQ (event->ie.frame_or_window, event->ie.arg) 3977 && !EQ (event->ie.frame_or_window, event->ie.arg)
3976 && (event->kind == MENU_BAR_EVENT 3978 && (event->kind == MENU_BAR_EVENT
3979 || event->kind == TAB_BAR_EVENT
3977 || event->kind == TOOL_BAR_EVENT)) 3980 || event->kind == TOOL_BAR_EVENT))
3978 *used_mouse_menu = true; 3981 *used_mouse_menu = true;
3979#endif 3982#endif
@@ -5012,7 +5015,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5012 int xret = 0, yret = 0; 5015 int xret = 0, yret = 0;
5013 /* The window or frame under frame pixel coordinates (x,y) */ 5016 /* The window or frame under frame pixel coordinates (x,y) */
5014 Lisp_Object window_or_frame = f 5017 Lisp_Object window_or_frame = f
5015 ? window_from_coordinates (f, XFIXNUM (x), XFIXNUM (y), &part, 0) 5018 ? window_from_coordinates (f, XFIXNUM (x), XFIXNUM (y), &part, 0, 0)
5016 : Qnil; 5019 : Qnil;
5017 5020
5018 if (WINDOWP (window_or_frame)) 5021 if (WINDOWP (window_or_frame))
@@ -5036,17 +5039,21 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5036 if (part == ON_TEXT) 5039 if (part == ON_TEXT)
5037 { 5040 {
5038 xret = XFIXNUM (x) - window_box_left (w, TEXT_AREA); 5041 xret = XFIXNUM (x) - window_box_left (w, TEXT_AREA);
5039 yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); 5042 yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5040 } 5043 }
5041 /* For mode line and header line clicks, return X, Y relative to 5044 /* For mode line and header line clicks, return X, Y relative to
5042 the left window edge. Use mode_line_string to look for a 5045 the left window edge. Use mode_line_string to look for a
5043 string on the click position. */ 5046 string on the click position. */
5044 else if (part == ON_MODE_LINE || part == ON_HEADER_LINE) 5047 else if (part == ON_MODE_LINE || part == ON_TAB_LINE
5048 || part == ON_HEADER_LINE)
5045 { 5049 {
5046 Lisp_Object string; 5050 Lisp_Object string;
5047 ptrdiff_t charpos; 5051 ptrdiff_t charpos;
5048 5052
5049 posn = (part == ON_MODE_LINE) ? Qmode_line : Qheader_line; 5053 posn = (part == ON_MODE_LINE ? Qmode_line
5054 : (part == ON_TAB_LINE ? Qtab_line
5055 : Qheader_line));
5056
5050 /* Note that mode_line_string takes COL, ROW as pixels and 5057 /* Note that mode_line_string takes COL, ROW as pixels and
5051 converts them to characters. */ 5058 converts them to characters. */
5052 col = wx; 5059 col = wx;
@@ -5075,7 +5082,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5075 if (STRINGP (string)) 5082 if (STRINGP (string))
5076 string_info = Fcons (string, make_fixnum (charpos)); 5083 string_info = Fcons (string, make_fixnum (charpos));
5077 xret = wx; 5084 xret = wx;
5078 yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); 5085 yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5079 } 5086 }
5080 else if (part == ON_LEFT_FRINGE) 5087 else if (part == ON_LEFT_FRINGE)
5081 { 5088 {
@@ -5085,7 +5092,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5085 dx = wx 5092 dx = wx
5086 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5093 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5087 ? 0 : window_box_width (w, LEFT_MARGIN_AREA)); 5094 ? 0 : window_box_width (w, LEFT_MARGIN_AREA));
5088 dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); 5095 dy = yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5089 } 5096 }
5090 else if (part == ON_RIGHT_FRINGE) 5097 else if (part == ON_RIGHT_FRINGE)
5091 { 5098 {
@@ -5098,7 +5105,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5098 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5105 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5099 ? window_box_width (w, RIGHT_MARGIN_AREA) 5106 ? window_box_width (w, RIGHT_MARGIN_AREA)
5100 : 0); 5107 : 0);
5101 dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); 5108 dy = yret = wy - WINDOW_TAB_LINE_HEIGHT (w) - WINDOW_HEADER_LINE_HEIGHT (w);
5102 } 5109 }
5103 else if (part == ON_VERTICAL_BORDER) 5110 else if (part == ON_VERTICAL_BORDER)
5104 { 5111 {
@@ -5953,6 +5960,16 @@ make_lispy_event (struct input_event *event)
5953 /* Make an event (select-window (WINDOW)). */ 5960 /* Make an event (select-window (WINDOW)). */
5954 return list2 (Qselect_window, list1 (event->frame_or_window)); 5961 return list2 (Qselect_window, list1 (event->frame_or_window));
5955 5962
5963 case TAB_BAR_EVENT:
5964 if (EQ (event->arg, event->frame_or_window))
5965 /* This is the prefix key. We translate this to
5966 `(tab_bar)' because the code in keyboard.c for tab bar
5967 events, which we use, relies on this. */
5968 return list1 (Qtab_bar);
5969 else if (SYMBOLP (event->arg))
5970 return apply_modifiers (event->modifiers, event->arg);
5971 return event->arg;
5972
5956 case TOOL_BAR_EVENT: 5973 case TOOL_BAR_EVENT:
5957 if (EQ (event->arg, event->frame_or_window)) 5974 if (EQ (event->arg, event->frame_or_window))
5958 /* This is the prefix key. We translate this to 5975 /* This is the prefix key. We translate this to
@@ -6730,6 +6747,7 @@ lucid_event_type_list_p (Lisp_Object object)
6730 if (EQ (XCAR (object), Qhelp_echo) 6747 if (EQ (XCAR (object), Qhelp_echo)
6731 || EQ (XCAR (object), Qvertical_line) 6748 || EQ (XCAR (object), Qvertical_line)
6732 || EQ (XCAR (object), Qmode_line) 6749 || EQ (XCAR (object), Qmode_line)
6750 || EQ (XCAR (object), Qtab_line)
6733 || EQ (XCAR (object), Qheader_line)) 6751 || EQ (XCAR (object), Qheader_line))
6734 return 0; 6752 return 0;
6735 6753
@@ -7891,6 +7909,389 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7891 7909
7892 7910
7893/*********************************************************************** 7911/***********************************************************************
7912 Tab-bars
7913 ***********************************************************************/
7914
7915/* A vector holding tab bar items while they are parsed in function
7916 tab_bar_items. Each item occupies TAB_BAR_ITEM_NSCLOTS elements
7917 in the vector. */
7918
7919static Lisp_Object tab_bar_items_vector;
7920
7921/* A vector holding the result of parse_tab_bar_item. Layout is like
7922 the one for a single item in tab_bar_items_vector. */
7923
7924static Lisp_Object tab_bar_item_properties;
7925
7926/* Next free index in tab_bar_items_vector. */
7927
7928static int ntab_bar_items;
7929
7930/* Function prototypes. */
7931
7932static void init_tab_bar_items (Lisp_Object);
7933static void process_tab_bar_item (Lisp_Object, Lisp_Object, Lisp_Object,
7934 void *);
7935static bool parse_tab_bar_item (Lisp_Object, Lisp_Object);
7936static void append_tab_bar_item (void);
7937
7938
7939/* Return a vector of tab bar items for keymaps currently in effect.
7940 Reuse vector REUSE if non-nil. Return in *NITEMS the number of
7941 tab bar items found. */
7942
7943Lisp_Object
7944tab_bar_items (Lisp_Object reuse, int *nitems)
7945{
7946 Lisp_Object *maps;
7947 Lisp_Object mapsbuf[3];
7948 ptrdiff_t nmaps, i;
7949 Lisp_Object oquit;
7950 Lisp_Object *tmaps;
7951 USE_SAFE_ALLOCA;
7952
7953 *nitems = 0;
7954
7955 /* In order to build the menus, we need to call the keymap
7956 accessors. They all call maybe_quit. But this function is called
7957 during redisplay, during which a quit is fatal. So inhibit
7958 quitting while building the menus. We do this instead of
7959 specbind because (1) errors will clear it anyway and (2) this
7960 avoids risk of specpdl overflow. */
7961 oquit = Vinhibit_quit;
7962 Vinhibit_quit = Qt;
7963
7964 /* Initialize tab_bar_items_vector and protect it from GC. */
7965 init_tab_bar_items (reuse);
7966
7967 /* Build list of keymaps in maps. Set nmaps to the number of maps
7968 to process. */
7969
7970 /* Should overriding-terminal-local-map and overriding-local-map apply? */
7971 if (!NILP (Voverriding_local_map_menu_flag)
7972 && !NILP (Voverriding_local_map))
7973 {
7974 /* Yes, use them (if non-nil) as well as the global map. */
7975 maps = mapsbuf;
7976 nmaps = 0;
7977 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
7978 maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
7979 if (!NILP (Voverriding_local_map))
7980 maps[nmaps++] = Voverriding_local_map;
7981 }
7982 else
7983 {
7984 /* No, so use major and minor mode keymaps and keymap property.
7985 Note that tab-bar bindings in the local-map and keymap
7986 properties may not work reliably, as they are only
7987 recognized when the tab-bar (or mode-line) is updated,
7988 which does not normally happen after every command. */
7989 ptrdiff_t nminor = current_minor_maps (NULL, &tmaps);
7990 SAFE_NALLOCA (maps, 1, nminor + 4);
7991 nmaps = 0;
7992 Lisp_Object tem = KVAR (current_kboard, Voverriding_terminal_local_map);
7993 if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
7994 maps[nmaps++] = tem;
7995 if (tem = get_local_map (PT, current_buffer, Qkeymap), !NILP (tem))
7996 maps[nmaps++] = tem;
7997 if (nminor != 0)
7998 {
7999 memcpy (maps + nmaps, tmaps, nminor * sizeof (maps[0]));
8000 nmaps += nminor;
8001 }
8002 maps[nmaps++] = get_local_map (PT, current_buffer, Qlocal_map);
8003 }
8004
8005 /* Add global keymap at the end. */
8006 maps[nmaps++] = current_global_map;
8007
8008 /* Process maps in reverse order and look up in each map the prefix
8009 key `tab-bar'. */
8010 for (i = nmaps - 1; i >= 0; --i)
8011 if (!NILP (maps[i]))
8012 {
8013 Lisp_Object keymap;
8014
8015 keymap = get_keymap (access_keymap (maps[i], Qtab_bar, 1, 0, 1), 0, 1);
8016 if (CONSP (keymap))
8017 map_keymap (keymap, process_tab_bar_item, Qnil, NULL, 1);
8018 }
8019
8020 Vinhibit_quit = oquit;
8021 *nitems = ntab_bar_items / TAB_BAR_ITEM_NSLOTS;
8022 SAFE_FREE ();
8023 return tab_bar_items_vector;
8024}
8025
8026
8027/* Process the definition of KEY which is DEF. */
8028
8029static void
8030process_tab_bar_item (Lisp_Object key, Lisp_Object def, Lisp_Object data, void *args)
8031{
8032 int i;
8033
8034 if (EQ (def, Qundefined))
8035 {
8036 /* If a map has an explicit `undefined' as definition,
8037 discard any previously made item. */
8038 for (i = 0; i < ntab_bar_items; i += TAB_BAR_ITEM_NSLOTS)
8039 {
8040 Lisp_Object *v = XVECTOR (tab_bar_items_vector)->contents + i;
8041
8042 if (EQ (key, v[TAB_BAR_ITEM_KEY]))
8043 {
8044 if (ntab_bar_items > i + TAB_BAR_ITEM_NSLOTS)
8045 memmove (v, v + TAB_BAR_ITEM_NSLOTS,
8046 ((ntab_bar_items - i - TAB_BAR_ITEM_NSLOTS)
8047 * word_size));
8048 ntab_bar_items -= TAB_BAR_ITEM_NSLOTS;
8049 break;
8050 }
8051 }
8052 }
8053 else if (parse_tab_bar_item (key, def))
8054 /* Append a new tab bar item to tab_bar_items_vector. Accept
8055 more than one definition for the same key. */
8056 append_tab_bar_item ();
8057}
8058
8059/* Access slot with index IDX of vector tab_bar_item_properties. */
8060#define PROP(IDX) AREF (tab_bar_item_properties, (IDX))
8061static void
8062set_prop_tab_bar (ptrdiff_t idx, Lisp_Object val)
8063{
8064 ASET (tab_bar_item_properties, idx, val);
8065}
8066
8067
8068/* Parse a tab bar item specification ITEM for key KEY and return the
8069 result in tab_bar_item_properties. Value is false if ITEM is
8070 invalid.
8071
8072 ITEM is a list `(menu-item CAPTION BINDING PROPS...)'.
8073
8074 CAPTION is the caption of the item, If it's not a string, it is
8075 evaluated to get a string.
8076
8077 BINDING is the tab bar item's binding. Tab-bar items with keymaps
8078 as binding are currently ignored.
8079
8080 The following properties are recognized:
8081
8082 - `:enable FORM'.
8083
8084 FORM is evaluated and specifies whether the tab bar item is
8085 enabled or disabled.
8086
8087 - `:visible FORM'
8088
8089 FORM is evaluated and specifies whether the tab bar item is visible.
8090
8091 - `:filter FUNCTION'
8092
8093 FUNCTION is invoked with one parameter `(quote BINDING)'. Its
8094 result is stored as the new binding.
8095
8096 - `:button (TYPE SELECTED)'
8097
8098 TYPE must be one of `:radio' or `:toggle'. SELECTED is evaluated
8099 and specifies whether the button is selected (pressed) or not.
8100
8101 - `:image IMAGES'
8102
8103 IMAGES is either a single image specification or a vector of four
8104 image specifications. See enum tab_bar_item_images.
8105
8106 - `:help HELP-STRING'.
8107
8108 Gives a help string to display for the tab bar item.
8109
8110 - `:label LABEL-STRING'.
8111
8112 A text label to show with the tab bar button if labels are enabled. */
8113
8114static bool
8115parse_tab_bar_item (Lisp_Object key, Lisp_Object item)
8116{
8117 Lisp_Object filter = Qnil;
8118 Lisp_Object caption;
8119 int i;
8120
8121 /* Definition looks like `(menu-item CAPTION BINDING PROPS...)'.
8122 Rule out items that aren't lists, don't start with
8123 `menu-item' or whose rest following `tab-bar-item' is not a
8124 list. */
8125 if (!CONSP (item))
8126 return 0;
8127
8128 /* As an exception, allow old-style menu separators. */
8129 if (STRINGP (XCAR (item)))
8130 item = list1 (XCAR (item));
8131 else if (!EQ (XCAR (item), Qmenu_item)
8132 || (item = XCDR (item), !CONSP (item)))
8133 return 0;
8134
8135 /* Create tab_bar_item_properties vector if necessary. Reset it to
8136 defaults. */
8137 if (VECTORP (tab_bar_item_properties))
8138 {
8139 for (i = 0; i < TAB_BAR_ITEM_NSLOTS; ++i)
8140 set_prop_tab_bar (i, Qnil);
8141 }
8142 else
8143 tab_bar_item_properties = make_nil_vector (TAB_BAR_ITEM_NSLOTS);
8144
8145 /* Set defaults. */
8146 set_prop_tab_bar (TAB_BAR_ITEM_KEY, key);
8147 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, Qt);
8148
8149 /* Get the caption of the item. If the caption is not a string,
8150 evaluate it to get a string. If we don't get a string, skip this
8151 item. */
8152 caption = XCAR (item);
8153 if (!STRINGP (caption))
8154 {
8155 caption = menu_item_eval_property (caption);
8156 if (!STRINGP (caption))
8157 return 0;
8158 }
8159 set_prop_tab_bar (TAB_BAR_ITEM_CAPTION, caption);
8160
8161 /* If the rest following the caption is not a list, the menu item is
8162 either a separator, or invalid. */
8163 item = XCDR (item);
8164 if (!CONSP (item))
8165 {
8166 if (menu_separator_name_p (SSDATA (caption)))
8167 {
8168 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, Qnil);
8169 set_prop_tab_bar (TAB_BAR_ITEM_SELECTED_P, Qnil);
8170 set_prop_tab_bar (TAB_BAR_ITEM_CAPTION, Qnil);
8171 return 1;
8172 }
8173 return 0;
8174 }
8175
8176 /* Store the binding. */
8177 set_prop_tab_bar (TAB_BAR_ITEM_BINDING, XCAR (item));
8178 item = XCDR (item);
8179
8180 /* Ignore cached key binding, if any. */
8181 if (CONSP (item) && CONSP (XCAR (item)))
8182 item = XCDR (item);
8183
8184 /* Process the rest of the properties. */
8185 for (; CONSP (item) && CONSP (XCDR (item)); item = XCDR (XCDR (item)))
8186 {
8187 Lisp_Object ikey, value;
8188
8189 ikey = XCAR (item);
8190 value = XCAR (XCDR (item));
8191
8192 if (EQ (ikey, QCenable))
8193 {
8194 /* `:enable FORM'. */
8195 if (!NILP (Venable_disabled_menus_and_buttons))
8196 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, Qt);
8197 else
8198 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P, value);
8199 }
8200 else if (EQ (ikey, QCvisible))
8201 {
8202 /* `:visible FORM'. If got a visible property and that
8203 evaluates to nil then ignore this item. */
8204 if (NILP (menu_item_eval_property (value)))
8205 return 0;
8206 }
8207 else if (EQ (ikey, QChelp))
8208 /* `:help HELP-STRING'. */
8209 set_prop_tab_bar (TAB_BAR_ITEM_HELP, value);
8210 else if (EQ (ikey, QCfilter))
8211 /* ':filter FORM'. */
8212 filter = value;
8213 else if (EQ (ikey, QCbutton) && CONSP (value))
8214 {
8215 /* `:button (TYPE . SELECTED)'. */
8216 Lisp_Object type, selected;
8217
8218 type = XCAR (value);
8219 selected = XCDR (value);
8220 if (EQ (type, QCtoggle) || EQ (type, QCradio))
8221 {
8222 set_prop_tab_bar (TAB_BAR_ITEM_SELECTED_P, selected);
8223 }
8224 }
8225 }
8226
8227 /* If got a filter apply it on binding. */
8228 if (!NILP (filter))
8229 set_prop_tab_bar (TAB_BAR_ITEM_BINDING,
8230 (menu_item_eval_property
8231 (list2 (filter,
8232 list2 (Qquote,
8233 PROP (TAB_BAR_ITEM_BINDING))))));
8234
8235 /* See if the binding is a keymap. Give up if it is. */
8236 if (CONSP (get_keymap (PROP (TAB_BAR_ITEM_BINDING), 0, 1)))
8237 return 0;
8238
8239 /* Enable or disable selection of item. */
8240 if (!EQ (PROP (TAB_BAR_ITEM_ENABLED_P), Qt))
8241 set_prop_tab_bar (TAB_BAR_ITEM_ENABLED_P,
8242 menu_item_eval_property (PROP (TAB_BAR_ITEM_ENABLED_P)));
8243
8244 /* Handle radio buttons or toggle boxes. */
8245 if (!NILP (PROP (TAB_BAR_ITEM_SELECTED_P)))
8246 set_prop_tab_bar (TAB_BAR_ITEM_SELECTED_P,
8247 menu_item_eval_property (PROP (TAB_BAR_ITEM_SELECTED_P)));
8248
8249 return 1;
8250
8251#undef PROP
8252}
8253
8254
8255/* Initialize tab_bar_items_vector. REUSE, if non-nil, is a vector
8256 that can be reused. */
8257
8258static void
8259init_tab_bar_items (Lisp_Object reuse)
8260{
8261 if (VECTORP (reuse))
8262 tab_bar_items_vector = reuse;
8263 else
8264 tab_bar_items_vector = make_nil_vector (64);
8265 ntab_bar_items = 0;
8266}
8267
8268
8269/* Append parsed tab bar item properties from
8270 tab_bar_item_properties */
8271
8272static void
8273append_tab_bar_item (void)
8274{
8275 ptrdiff_t incr
8276 = (ntab_bar_items
8277 - (ASIZE (tab_bar_items_vector) - TAB_BAR_ITEM_NSLOTS));
8278
8279 /* Enlarge tab_bar_items_vector if necessary. */
8280 if (incr > 0)
8281 tab_bar_items_vector = larger_vector (tab_bar_items_vector, incr, -1);
8282
8283 /* Append entries from tab_bar_item_properties to the end of
8284 tab_bar_items_vector. */
8285 vcopy (tab_bar_items_vector, ntab_bar_items,
8286 XVECTOR (tab_bar_item_properties)->contents, TAB_BAR_ITEM_NSLOTS);
8287 ntab_bar_items += TAB_BAR_ITEM_NSLOTS;
8288}
8289
8290
8291
8292
8293
8294/***********************************************************************
7894 Tool-bars 8295 Tool-bars
7895 ***********************************************************************/ 8296 ***********************************************************************/
7896 8297
@@ -8402,6 +8803,7 @@ read_char_x_menu_prompt (Lisp_Object map,
8402 use a real menu for mouse selection. */ 8803 use a real menu for mouse selection. */
8403 if (EVENT_HAS_PARAMETERS (prev_event) 8804 if (EVENT_HAS_PARAMETERS (prev_event)
8404 && !EQ (XCAR (prev_event), Qmenu_bar) 8805 && !EQ (XCAR (prev_event), Qmenu_bar)
8806 && !EQ (XCAR (prev_event), Qtab_bar)
8405 && !EQ (XCAR (prev_event), Qtool_bar)) 8807 && !EQ (XCAR (prev_event), Qtool_bar))
8406 { 8808 {
8407 /* Display the menu and get the selection. */ 8809 /* Display the menu and get the selection. */
@@ -9377,7 +9779,7 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt,
9377 posn = POSN_POSN (xevent_start (key)); 9779 posn = POSN_POSN (xevent_start (key));
9378 /* Handle menu-bar events: 9780 /* Handle menu-bar events:
9379 insert the dummy prefix event `menu-bar'. */ 9781 insert the dummy prefix event `menu-bar'. */
9380 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) 9782 if (EQ (posn, Qmenu_bar) || EQ (posn, Qtab_bar) || EQ (posn, Qtool_bar))
9381 { 9783 {
9382 if (READ_KEY_ELTS - t <= 1) 9784 if (READ_KEY_ELTS - t <= 1)
9383 error ("Key sequence too long"); 9785 error ("Key sequence too long");
@@ -10237,7 +10639,8 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10237 get_tty_size (fileno (CURTTY ()->input), &width, &height); 10639 get_tty_size (fileno (CURTTY ()->input), &width, &height);
10238 if (width != old_width || height != old_height) 10640 if (width != old_width || height != old_height)
10239 change_frame_size (SELECTED_FRAME (), width, 10641 change_frame_size (SELECTED_FRAME (), width,
10240 height - FRAME_MENU_BAR_LINES (SELECTED_FRAME ()), 10642 height - FRAME_MENU_BAR_LINES (SELECTED_FRAME ())
10643 - FRAME_TAB_BAR_LINES (SELECTED_FRAME ()),
10241 0, 0, 0, 0); 10644 0, 0, 0, 0);
10242 10645
10243 run_hook (intern ("suspend-resume-hook")); 10646 run_hook (intern ("suspend-resume-hook"));
@@ -11057,6 +11460,11 @@ syms_of_keyboard (void)
11057 staticpro (&item_properties); 11460 staticpro (&item_properties);
11058 item_properties = Qnil; 11461 item_properties = Qnil;
11059 11462
11463 staticpro (&tab_bar_item_properties);
11464 tab_bar_item_properties = Qnil;
11465 staticpro (&tab_bar_items_vector);
11466 tab_bar_items_vector = Qnil;
11467
11060 staticpro (&tool_bar_item_properties); 11468 staticpro (&tool_bar_item_properties);
11061 tool_bar_item_properties = Qnil; 11469 tool_bar_item_properties = Qnil;
11062 staticpro (&tool_bar_items_vector); 11470 staticpro (&tool_bar_items_vector);
@@ -11610,6 +12018,12 @@ See also `pre-command-hook'. */);
11610The elements of the list are event types that may have menu bar bindings. */); 12018The elements of the list are event types that may have menu bar bindings. */);
11611 Vmenu_bar_final_items = Qnil; 12019 Vmenu_bar_final_items = Qnil;
11612 12020
12021 DEFVAR_LISP ("tab-bar-separator-image-expression", Vtab_bar_separator_image_expression,
12022 doc: /* Expression evaluating to the image spec for a tab-bar separator.
12023This is used internally by graphical displays that do not render
12024tab-bar separators natively. Otherwise it is unused (e.g. on GTK). */);
12025 Vtab_bar_separator_image_expression = Qnil;
12026
11613 DEFVAR_LISP ("tool-bar-separator-image-expression", Vtool_bar_separator_image_expression, 12027 DEFVAR_LISP ("tool-bar-separator-image-expression", Vtool_bar_separator_image_expression,
11614 doc: /* Expression evaluating to the image spec for a tool-bar separator. 12028 doc: /* Expression evaluating to the image spec for a tool-bar separator.
11615This is used internally by graphical displays that do not render 12029This is used internally by graphical displays that do not render