diff options
| author | Juri Linkov | 2019-09-02 00:32:10 +0300 |
|---|---|---|
| committer | Juri Linkov | 2019-09-02 00:32:10 +0300 |
| commit | 5bf45ec48b781a1165e882e7216892bf201d15f4 (patch) | |
| tree | 2be92e4c40bb078796fa485ff92da43944a79e3e /src | |
| parent | 51ac64d9aa6aec969c38a3774310479d1cbb4dc9 (diff) | |
| download | emacs-5bf45ec48b781a1165e882e7216892bf201d15f4.tar.gz emacs-5bf45ec48b781a1165e882e7216892bf201d15f4.zip | |
Try to add more tab-bar support on macos
Diffstat (limited to 'src')
| -rw-r--r-- | src/nsfns.m | 86 | ||||
| -rw-r--r-- | src/nsmenu.m | 316 | ||||
| -rw-r--r-- | src/nsterm.h | 65 | ||||
| -rw-r--r-- | src/nsterm.m | 147 |
4 files changed, 601 insertions, 13 deletions
diff --git a/src/nsfns.m b/src/nsfns.m index 2470c05c4b5..890da99082b 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -610,6 +610,75 @@ ns_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | |||
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | 612 | ||
| 613 | /* tabbar support */ | ||
| 614 | static void | ||
| 615 | ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | ||
| 616 | { | ||
| 617 | /* Currently, when the tab bar changes state, the frame is resized. | ||
| 618 | |||
| 619 | TODO: It would be better if this didn't occur when 1) the frame | ||
| 620 | is full height or maximized or 2) when specified by | ||
| 621 | `frame-inhibit-implied-resize'. */ | ||
| 622 | int nlines; | ||
| 623 | |||
| 624 | NSTRACE ("ns_set_tab_bar_lines"); | ||
| 625 | |||
| 626 | if (FRAME_MINIBUF_ONLY_P (f)) | ||
| 627 | return; | ||
| 628 | |||
| 629 | if (RANGED_FIXNUMP (0, value, INT_MAX)) | ||
| 630 | nlines = XFIXNAT (value); | ||
| 631 | else | ||
| 632 | nlines = 0; | ||
| 633 | |||
| 634 | if (nlines) | ||
| 635 | { | ||
| 636 | FRAME_EXTERNAL_TAB_BAR (f) = 1; | ||
| 637 | update_frame_tab_bar (f); | ||
| 638 | } | ||
| 639 | else | ||
| 640 | { | ||
| 641 | if (FRAME_EXTERNAL_TAB_BAR (f)) | ||
| 642 | { | ||
| 643 | free_frame_tab_bar (f); | ||
| 644 | FRAME_EXTERNAL_TAB_BAR (f) = 0; | ||
| 645 | |||
| 646 | { | ||
| 647 | EmacsView *view = FRAME_NS_VIEW (f); | ||
| 648 | int fs_state = [view fullscreenState]; | ||
| 649 | |||
| 650 | if (fs_state == FULLSCREEN_MAXIMIZED) | ||
| 651 | { | ||
| 652 | [view setFSValue:FULLSCREEN_WIDTH]; | ||
| 653 | } | ||
| 654 | else if (fs_state == FULLSCREEN_HEIGHT) | ||
| 655 | { | ||
| 656 | [view setFSValue:FULLSCREEN_NONE]; | ||
| 657 | } | ||
| 658 | } | ||
| 659 | } | ||
| 660 | } | ||
| 661 | |||
| 662 | { | ||
| 663 | int inhibit | ||
| 664 | = ((f->after_make_frame | ||
| 665 | && !f->tab_bar_resized | ||
| 666 | && (EQ (frame_inhibit_implied_resize, Qt) | ||
| 667 | || (CONSP (frame_inhibit_implied_resize) | ||
| 668 | && !NILP (Fmemq (Qtab_bar_lines, | ||
| 669 | frame_inhibit_implied_resize)))) | ||
| 670 | && NILP (get_frame_param (f, Qfullscreen))) | ||
| 671 | ? 0 | ||
| 672 | : 2); | ||
| 673 | |||
| 674 | NSTRACE_MSG ("inhibit:%d", inhibit); | ||
| 675 | |||
| 676 | frame_size_history_add (f, Qupdate_frame_tab_bar, 0, 0, Qnil); | ||
| 677 | adjust_frame_size (f, -1, -1, inhibit, 0, Qtab_bar_lines); | ||
| 678 | } | ||
| 679 | } | ||
| 680 | |||
| 681 | |||
| 613 | /* toolbar support */ | 682 | /* toolbar support */ |
| 614 | static void | 683 | static void |
| 615 | ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) | 684 | ns_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) |
| @@ -923,6 +992,7 @@ frame_parm_handler ns_frame_parm_handlers[] = | |||
| 923 | gui_set_vertical_scroll_bars, /* generic OK */ | 992 | gui_set_vertical_scroll_bars, /* generic OK */ |
| 924 | gui_set_horizontal_scroll_bars, /* generic OK */ | 993 | gui_set_horizontal_scroll_bars, /* generic OK */ |
| 925 | gui_set_visibility, /* generic OK */ | 994 | gui_set_visibility, /* generic OK */ |
| 995 | ns_set_tab_bar_lines, | ||
| 926 | ns_set_tool_bar_lines, | 996 | ns_set_tool_bar_lines, |
| 927 | 0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */ | 997 | 0, /* x_set_scroll_bar_foreground, will ignore (not possible on NS) */ |
| 928 | 0, /* x_set_scroll_bar_background, will ignore (not possible on NS) */ | 998 | 0, /* x_set_scroll_bar_background, will ignore (not possible on NS) */ |
| @@ -1286,6 +1356,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 1286 | NILP (Vmenu_bar_mode) | 1356 | NILP (Vmenu_bar_mode) |
| 1287 | ? make_fixnum (0) : make_fixnum (1), | 1357 | ? make_fixnum (0) : make_fixnum (1), |
| 1288 | NULL, NULL, RES_TYPE_NUMBER); | 1358 | NULL, NULL, RES_TYPE_NUMBER); |
| 1359 | gui_default_parameter (f, parms, Qtab_bar_lines, | ||
| 1360 | NILP (Vtab_bar_mode) | ||
| 1361 | ? make_fixnum (0) : make_fixnum (1), | ||
| 1362 | NULL, NULL, RES_TYPE_NUMBER); | ||
| 1289 | gui_default_parameter (f, parms, Qtool_bar_lines, | 1363 | gui_default_parameter (f, parms, Qtool_bar_lines, |
| 1290 | NILP (Vtool_bar_mode) | 1364 | NILP (Vtool_bar_mode) |
| 1291 | ? make_fixnum (0) : make_fixnum (1), | 1365 | ? make_fixnum (0) : make_fixnum (1), |
| @@ -2790,6 +2864,10 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 2790 | int native_right = f->left_pos + outer_width - border; | 2864 | int native_right = f->left_pos + outer_width - border; |
| 2791 | int native_bottom = f->top_pos + outer_height - border; | 2865 | int native_bottom = f->top_pos + outer_height - border; |
| 2792 | int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f); | 2866 | int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f); |
| 2867 | int tab_bar_height = FRAME_TABBAR_HEIGHT (f); | ||
| 2868 | int tab_bar_width = (tab_bar_height | ||
| 2869 | ? outer_width - 2 * internal_border_width | ||
| 2870 | : 0); | ||
| 2793 | int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f); | 2871 | int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f); |
| 2794 | int tool_bar_width = (tool_bar_height | 2872 | int tool_bar_width = (tool_bar_height |
| 2795 | ? outer_width - 2 * internal_border_width | 2873 | ? outer_width - 2 * internal_border_width |
| @@ -2805,7 +2883,7 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 2805 | native_right, native_bottom); | 2883 | native_right, native_bottom); |
| 2806 | else if (EQ (attribute, Qinner_edges)) | 2884 | else if (EQ (attribute, Qinner_edges)) |
| 2807 | return list4i (native_left + internal_border_width, | 2885 | return list4i (native_left + internal_border_width, |
| 2808 | native_top + tool_bar_height + internal_border_width, | 2886 | native_top + tab_bar_height + tool_bar_height + internal_border_width, |
| 2809 | native_right - internal_border_width, | 2887 | native_right - internal_border_width, |
| 2810 | native_bottom - internal_border_width); | 2888 | native_bottom - internal_border_width); |
| 2811 | else | 2889 | else |
| @@ -2824,6 +2902,9 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute) | |||
| 2824 | Fcons (make_fixnum (0), make_fixnum (title_height))), | 2902 | Fcons (make_fixnum (0), make_fixnum (title_height))), |
| 2825 | Fcons (Qmenu_bar_external, Qnil), | 2903 | Fcons (Qmenu_bar_external, Qnil), |
| 2826 | Fcons (Qmenu_bar_size, Fcons (make_fixnum (0), make_fixnum (0))), | 2904 | Fcons (Qmenu_bar_size, Fcons (make_fixnum (0), make_fixnum (0))), |
| 2905 | Fcons (Qtab_bar_size, | ||
| 2906 | Fcons (make_fixnum (tab_bar_width), | ||
| 2907 | make_fixnum (tab_bar_height))), | ||
| 2827 | Fcons (Qtool_bar_external, | 2908 | Fcons (Qtool_bar_external, |
| 2828 | FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil), | 2909 | FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil), |
| 2829 | Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)), | 2910 | Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)), |
| @@ -2861,6 +2942,9 @@ and width values are in pixels. | |||
| 2861 | `menu-bar-size' is a cons of the width and height of the menu bar of | 2942 | `menu-bar-size' is a cons of the width and height of the menu bar of |
| 2862 | FRAME. | 2943 | FRAME. |
| 2863 | 2944 | ||
| 2945 | `tab-bar-size' is a cons of the width and height of the tab bar of | ||
| 2946 | FRAME. | ||
| 2947 | |||
| 2864 | `tool-bar-external', if non-nil, means the tool bar is external (never | 2948 | `tool-bar-external', if non-nil, means the tool bar is external (never |
| 2865 | included in the inner edges of FRAME). | 2949 | included in the inner edges of FRAME). |
| 2866 | 2950 | ||
diff --git a/src/nsmenu.m b/src/nsmenu.m index 817f8cff184..223561b9730 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -993,6 +993,322 @@ ns_menu_show (struct frame *f, int x, int y, int menuflags, | |||
| 993 | 993 | ||
| 994 | /* ========================================================================== | 994 | /* ========================================================================== |
| 995 | 995 | ||
| 996 | Tabbar: externally-called functions | ||
| 997 | |||
| 998 | ========================================================================== */ | ||
| 999 | |||
| 1000 | void | ||
| 1001 | free_frame_tab_bar (struct frame *f) | ||
| 1002 | /* -------------------------------------------------------------------------- | ||
| 1003 | Under NS we just hide the tabbar until it might be needed again. | ||
| 1004 | -------------------------------------------------------------------------- */ | ||
| 1005 | { | ||
| 1006 | EmacsView *view = FRAME_NS_VIEW (f); | ||
| 1007 | |||
| 1008 | NSTRACE ("free_frame_tab_bar"); | ||
| 1009 | |||
| 1010 | block_input (); | ||
| 1011 | view->wait_for_tab_bar = NO; | ||
| 1012 | |||
| 1013 | /* Note: This triggers an animation, which calls windowDidResize | ||
| 1014 | repeatedly. */ | ||
| 1015 | f->output_data.ns->in_animation = 1; | ||
| 1016 | [[view tabbar] setVisible: NO]; | ||
| 1017 | f->output_data.ns->in_animation = 0; | ||
| 1018 | |||
| 1019 | unblock_input (); | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | void | ||
| 1023 | update_frame_tab_bar (struct frame *f) | ||
| 1024 | /* -------------------------------------------------------------------------- | ||
| 1025 | Update tabbar contents. | ||
| 1026 | -------------------------------------------------------------------------- */ | ||
| 1027 | { | ||
| 1028 | int i, k = 0; | ||
| 1029 | EmacsView *view = FRAME_NS_VIEW (f); | ||
| 1030 | EmacsTabbar *tabbar = [view tabbar]; | ||
| 1031 | int oldh; | ||
| 1032 | |||
| 1033 | NSTRACE ("update_frame_tab_bar"); | ||
| 1034 | |||
| 1035 | if (view == nil || tabbar == nil) return; | ||
| 1036 | block_input (); | ||
| 1037 | |||
| 1038 | oldh = FRAME_TABBAR_HEIGHT (f); | ||
| 1039 | |||
| 1040 | #ifdef NS_IMPL_COCOA | ||
| 1041 | [tabbar clearActive]; | ||
| 1042 | #else | ||
| 1043 | [tabbar clearAll]; | ||
| 1044 | #endif | ||
| 1045 | |||
| 1046 | /* Update EmacsTabbar as in GtkUtils, build items list. */ | ||
| 1047 | for (i = 0; i < f->n_tab_bar_items; ++i) | ||
| 1048 | { | ||
| 1049 | #define TABPROP(IDX) AREF (f->tab_bar_items, \ | ||
| 1050 | i * TAB_BAR_ITEM_NSLOTS + (IDX)) | ||
| 1051 | |||
| 1052 | BOOL enabled_p = !NILP (TABPROP (TAB_BAR_ITEM_ENABLED_P)); | ||
| 1053 | int idx; | ||
| 1054 | ptrdiff_t img_id; | ||
| 1055 | struct image *img; | ||
| 1056 | Lisp_Object image; | ||
| 1057 | Lisp_Object helpObj; | ||
| 1058 | const char *helpText; | ||
| 1059 | |||
| 1060 | /* Check if this is a separator. */ | ||
| 1061 | if (EQ (TABPROP (TAB_BAR_ITEM_TYPE), Qt)) | ||
| 1062 | { | ||
| 1063 | /* Skip separators. Newer macOS don't show them, and on | ||
| 1064 | GNUstep they are wide as a button, thus overflowing the | ||
| 1065 | tabbar most of the time. */ | ||
| 1066 | continue; | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | /* If image is a vector, choose the image according to the | ||
| 1070 | button state. */ | ||
| 1071 | image = TABPROP (TAB_BAR_ITEM_IMAGES); | ||
| 1072 | if (VECTORP (image)) | ||
| 1073 | { | ||
| 1074 | /* NS tabbar auto-computes disabled and selected images. */ | ||
| 1075 | idx = TAB_BAR_IMAGE_ENABLED_SELECTED; | ||
| 1076 | eassert (ASIZE (image) >= idx); | ||
| 1077 | image = AREF (image, idx); | ||
| 1078 | } | ||
| 1079 | else | ||
| 1080 | { | ||
| 1081 | idx = -1; | ||
| 1082 | } | ||
| 1083 | helpObj = TABPROP (TAB_BAR_ITEM_HELP); | ||
| 1084 | if (NILP (helpObj)) | ||
| 1085 | helpObj = TABPROP (TAB_BAR_ITEM_CAPTION); | ||
| 1086 | helpText = NILP (helpObj) ? "" : SSDATA (helpObj); | ||
| 1087 | |||
| 1088 | /* Ignore invalid image specifications. */ | ||
| 1089 | if (!valid_image_p (image)) | ||
| 1090 | { | ||
| 1091 | /* Don't log anything, GNUS makes invalid images all the time. */ | ||
| 1092 | continue; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | img_id = lookup_image (f, image); | ||
| 1096 | img = IMAGE_FROM_ID (f, img_id); | ||
| 1097 | prepare_image_for_display (f, img); | ||
| 1098 | |||
| 1099 | if (img->load_failed_p || img->pixmap == nil) | ||
| 1100 | { | ||
| 1101 | NSLog (@"Could not prepare tabbar image for display."); | ||
| 1102 | continue; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | [tabbar addDisplayItemWithImage: img->pixmap | ||
| 1106 | idx: k++ | ||
| 1107 | tag: i | ||
| 1108 | helpText: helpText | ||
| 1109 | enabled: enabled_p]; | ||
| 1110 | #undef TABPROP | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | if (![tabbar isVisible]) | ||
| 1114 | { | ||
| 1115 | f->output_data.ns->in_animation = 1; | ||
| 1116 | [tabbar setVisible: YES]; | ||
| 1117 | f->output_data.ns->in_animation = 0; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | #ifdef NS_IMPL_COCOA | ||
| 1121 | if ([tabbar changed]) | ||
| 1122 | { | ||
| 1123 | /* Inform app that tabbar has changed. */ | ||
| 1124 | NSDictionary *dict = [tabbar configurationDictionary]; | ||
| 1125 | NSMutableDictionary *newDict = [dict mutableCopy]; | ||
| 1126 | NSEnumerator *keys = [[dict allKeys] objectEnumerator]; | ||
| 1127 | id key; | ||
| 1128 | while ((key = [keys nextObject]) != nil) | ||
| 1129 | { | ||
| 1130 | NSObject *val = [dict objectForKey: key]; | ||
| 1131 | if ([val isKindOfClass: [NSArray class]]) | ||
| 1132 | { | ||
| 1133 | [newDict setObject: | ||
| 1134 | [tabbar tabbarDefaultItemIdentifiers: tabbar] | ||
| 1135 | forKey: key]; | ||
| 1136 | break; | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | [tabbar setConfigurationFromDictionary: newDict]; | ||
| 1140 | [newDict release]; | ||
| 1141 | } | ||
| 1142 | #endif | ||
| 1143 | |||
| 1144 | if (oldh != FRAME_TABBAR_HEIGHT (f)) | ||
| 1145 | [view updateFrameSize:YES]; | ||
| 1146 | if (view->wait_for_tab_bar && FRAME_TABBAR_HEIGHT (f) > 0) | ||
| 1147 | { | ||
| 1148 | view->wait_for_tab_bar = NO; | ||
| 1149 | [view setNeedsDisplay: YES]; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | unblock_input (); | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | |||
| 1156 | /* ========================================================================== | ||
| 1157 | |||
| 1158 | Tabbar: class implementation | ||
| 1159 | |||
| 1160 | ========================================================================== */ | ||
| 1161 | |||
| 1162 | @implementation EmacsTabbar | ||
| 1163 | |||
| 1164 | - (instancetype)initForView: (EmacsView *)view withIdentifier: (NSString *)identifier | ||
| 1165 | { | ||
| 1166 | NSTRACE ("[EmacsTabbar initForView: withIdentifier:]"); | ||
| 1167 | |||
| 1168 | self = [super initWithIdentifier: identifier]; | ||
| 1169 | emacsView = view; | ||
| 1170 | [self setDisplayMode: NSTabbarDisplayModeIconOnly]; | ||
| 1171 | [self setSizeMode: NSTabbarSizeModeSmall]; | ||
| 1172 | [self setDelegate: self]; | ||
| 1173 | identifierToItem = [[NSMutableDictionary alloc] initWithCapacity: 10]; | ||
| 1174 | activeIdentifiers = [[NSMutableArray alloc] initWithCapacity: 8]; | ||
| 1175 | prevIdentifiers = nil; | ||
| 1176 | prevEnablement = enablement = 0L; | ||
| 1177 | return self; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | - (void)dealloc | ||
| 1181 | { | ||
| 1182 | NSTRACE ("[EmacsTabbar dealloc]"); | ||
| 1183 | |||
| 1184 | [prevIdentifiers release]; | ||
| 1185 | [activeIdentifiers release]; | ||
| 1186 | [identifierToItem release]; | ||
| 1187 | [super dealloc]; | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | - (void) clearActive | ||
| 1191 | { | ||
| 1192 | NSTRACE ("[EmacsTabbar clearActive]"); | ||
| 1193 | |||
| 1194 | [prevIdentifiers release]; | ||
| 1195 | prevIdentifiers = [activeIdentifiers copy]; | ||
| 1196 | [activeIdentifiers removeAllObjects]; | ||
| 1197 | prevEnablement = enablement; | ||
| 1198 | enablement = 0L; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | - (void) clearAll | ||
| 1202 | { | ||
| 1203 | NSTRACE ("[EmacsTabbar clearAll]"); | ||
| 1204 | |||
| 1205 | [self clearActive]; | ||
| 1206 | while ([[self items] count] > 0) | ||
| 1207 | [self removeItemAtIndex: 0]; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | - (BOOL) changed | ||
| 1211 | { | ||
| 1212 | NSTRACE ("[EmacsTabbar changed]"); | ||
| 1213 | |||
| 1214 | return [activeIdentifiers isEqualToArray: prevIdentifiers] && | ||
| 1215 | enablement == prevEnablement ? NO : YES; | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | - (void) addDisplayItemWithImage: (EmacsImage *)img | ||
| 1219 | idx: (int)idx | ||
| 1220 | tag: (int)tag | ||
| 1221 | helpText: (const char *)help | ||
| 1222 | enabled: (BOOL)enabled | ||
| 1223 | { | ||
| 1224 | NSTRACE ("[EmacsTabbar addDisplayItemWithImage: ...]"); | ||
| 1225 | |||
| 1226 | /* 1) come up w/identifier */ | ||
| 1227 | NSString *identifier | ||
| 1228 | = [NSString stringWithFormat: @"%lu", (unsigned long)[img hash]]; | ||
| 1229 | [activeIdentifiers addObject: identifier]; | ||
| 1230 | |||
| 1231 | /* 2) create / reuse item */ | ||
| 1232 | NSTabbarItem *item = [identifierToItem objectForKey: identifier]; | ||
| 1233 | if (item == nil) | ||
| 1234 | { | ||
| 1235 | item = [[[NSTabbarItem alloc] initWithItemIdentifier: identifier] | ||
| 1236 | autorelease]; | ||
| 1237 | [item setImage: img]; | ||
| 1238 | [item setTabTip: [NSString stringWithUTF8String: help]]; | ||
| 1239 | [item setTarget: emacsView]; | ||
| 1240 | [item setAction: @selector (tabbarClicked:)]; | ||
| 1241 | [identifierToItem setObject: item forKey: identifier]; | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | #ifdef NS_IMPL_GNUSTEP | ||
| 1245 | [self insertItemWithItemIdentifier: identifier atIndex: idx]; | ||
| 1246 | #endif | ||
| 1247 | |||
| 1248 | [item setTag: tag]; | ||
| 1249 | [item setEnabled: enabled]; | ||
| 1250 | |||
| 1251 | /* 3) update state */ | ||
| 1252 | enablement = (enablement << 1) | (enabled == YES); | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | /* This overrides super's implementation, which automatically sets | ||
| 1256 | all items to enabled state (for some reason). */ | ||
| 1257 | - (void)validateVisibleItems | ||
| 1258 | { | ||
| 1259 | NSTRACE ("[EmacsTabbar validateVisibleItems]"); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | |||
| 1263 | /* delegate methods */ | ||
| 1264 | |||
| 1265 | - (NSTabbarItem *)tabbar: (NSTabbar *)tabbar | ||
| 1266 | itemForItemIdentifier: (NSString *)itemIdentifier | ||
| 1267 | willBeInsertedIntoTabbar: (BOOL)flag | ||
| 1268 | { | ||
| 1269 | NSTRACE ("[EmacsTabbar tabbar: ...]"); | ||
| 1270 | |||
| 1271 | /* Look up NSTabbarItem by identifier and return... */ | ||
| 1272 | return [identifierToItem objectForKey: itemIdentifier]; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | - (NSArray *)tabbarDefaultItemIdentifiers: (NSTabbar *)tabbar | ||
| 1276 | { | ||
| 1277 | NSTRACE ("[EmacsTabbar tabbarDefaultItemIdentifiers:]"); | ||
| 1278 | |||
| 1279 | /* Return entire set. */ | ||
| 1280 | return activeIdentifiers; | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | /* for configuration palette (not yet supported) */ | ||
| 1284 | - (NSArray *)tabbarAllowedItemIdentifiers: (NSTabbar *)tabbar | ||
| 1285 | { | ||
| 1286 | NSTRACE ("[EmacsTabbar tabbarAllowedItemIdentifiers:]"); | ||
| 1287 | |||
| 1288 | /* return entire set... */ | ||
| 1289 | return activeIdentifiers; | ||
| 1290 | //return [identifierToItem allKeys]; | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | - (void)setVisible:(BOOL)shown | ||
| 1294 | { | ||
| 1295 | NSTRACE ("[EmacsTabbar setVisible:%d]", shown); | ||
| 1296 | |||
| 1297 | [super setVisible:shown]; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | |||
| 1301 | /* optional and unneeded */ | ||
| 1302 | /* - tabbarWillAddItem: (NSNotification *)notification { } */ | ||
| 1303 | /* - tabbarDidRemoveItem: (NSNotification *)notification { } */ | ||
| 1304 | /* - (NSArray *)tabbarSelectableItemIdentifiers: (NSTabbar *)tabbar */ | ||
| 1305 | |||
| 1306 | @end /* EmacsTabbar */ | ||
| 1307 | |||
| 1308 | |||
| 1309 | |||
| 1310 | /* ========================================================================== | ||
| 1311 | |||
| 996 | Toolbar: externally-called functions | 1312 | Toolbar: externally-called functions |
| 997 | 1313 | ||
| 998 | ========================================================================== */ | 1314 | ========================================================================== */ |
diff --git a/src/nsterm.h b/src/nsterm.h index 9773eb3e662..ea0e5a44818 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -397,6 +397,7 @@ typedef id instancetype; | |||
| 397 | 397 | ||
| 398 | ========================================================================== */ | 398 | ========================================================================== */ |
| 399 | 399 | ||
| 400 | @class EmacsTabbar; | ||
| 400 | @class EmacsToolbar; | 401 | @class EmacsToolbar; |
| 401 | 402 | ||
| 402 | #ifdef NS_IMPL_COCOA | 403 | #ifdef NS_IMPL_COCOA |
| @@ -421,14 +422,18 @@ typedef id instancetype; | |||
| 421 | struct frame *emacsframe; | 422 | struct frame *emacsframe; |
| 422 | int rows, cols; | 423 | int rows, cols; |
| 423 | int scrollbarsNeedingUpdate; | 424 | int scrollbarsNeedingUpdate; |
| 425 | EmacsTabbar *tabbar; | ||
| 424 | EmacsToolbar *toolbar; | 426 | EmacsToolbar *toolbar; |
| 425 | NSRect ns_userRect; | 427 | NSRect ns_userRect; |
| 428 | BOOL wait_for_tab_bar; | ||
| 426 | BOOL wait_for_tool_bar; | 429 | BOOL wait_for_tool_bar; |
| 427 | } | 430 | } |
| 428 | 431 | ||
| 429 | /* AppKit-side interface */ | 432 | /* AppKit-side interface */ |
| 430 | - (instancetype)menuDown: (id)sender; | 433 | - (instancetype)menuDown: (id)sender; |
| 434 | - (instancetype)tabbarClicked: (id)item; | ||
| 431 | - (instancetype)toolbarClicked: (id)item; | 435 | - (instancetype)toolbarClicked: (id)item; |
| 436 | - (instancetype)toggleTabbar: (id)sender; | ||
| 432 | - (instancetype)toggleToolbar: (id)sender; | 437 | - (instancetype)toggleToolbar: (id)sender; |
| 433 | - (void)keyDown: (NSEvent *)theEvent; | 438 | - (void)keyDown: (NSEvent *)theEvent; |
| 434 | - (void)mouseDown: (NSEvent *)theEvent; | 439 | - (void)mouseDown: (NSEvent *)theEvent; |
| @@ -437,9 +442,11 @@ typedef id instancetype; | |||
| 437 | 442 | ||
| 438 | /* Emacs-side interface */ | 443 | /* Emacs-side interface */ |
| 439 | - (instancetype) initFrameFromEmacs: (struct frame *) f; | 444 | - (instancetype) initFrameFromEmacs: (struct frame *) f; |
| 445 | - (void) createTabbar: (struct frame *)f; | ||
| 440 | - (void) createToolbar: (struct frame *)f; | 446 | - (void) createToolbar: (struct frame *)f; |
| 441 | - (void) setRows: (int) r andColumns: (int) c; | 447 | - (void) setRows: (int) r andColumns: (int) c; |
| 442 | - (void) setWindowClosing: (BOOL)closing; | 448 | - (void) setWindowClosing: (BOOL)closing; |
| 449 | - (EmacsTabbar *) tabbar; | ||
| 443 | - (EmacsToolbar *) toolbar; | 450 | - (EmacsToolbar *) toolbar; |
| 444 | - (void) deleteWorkingText; | 451 | - (void) deleteWorkingText; |
| 445 | - (void) updateFrameSize: (BOOL) delay; | 452 | - (void) updateFrameSize: (BOOL) delay; |
| @@ -512,6 +519,45 @@ typedef id instancetype; | |||
| 512 | 519 | ||
| 513 | /* ========================================================================== | 520 | /* ========================================================================== |
| 514 | 521 | ||
| 522 | Tabbar | ||
| 523 | |||
| 524 | ========================================================================== */ | ||
| 525 | |||
| 526 | @class EmacsImage; | ||
| 527 | |||
| 528 | #ifdef NS_IMPL_COCOA | ||
| 529 | @interface EmacsTabbar : NSTabbar <NSTabbarDelegate> | ||
| 530 | #else | ||
| 531 | @interface EmacsTabbar : NSTabbar | ||
| 532 | #endif | ||
| 533 | { | ||
| 534 | EmacsView *emacsView; | ||
| 535 | NSMutableDictionary *identifierToItem; | ||
| 536 | NSMutableArray *activeIdentifiers; | ||
| 537 | NSArray *prevIdentifiers; | ||
| 538 | unsigned long enablement, prevEnablement; | ||
| 539 | } | ||
| 540 | - (instancetype) initForView: (EmacsView *)view withIdentifier: (NSString *)identifier; | ||
| 541 | - (void) clearActive; | ||
| 542 | - (void) clearAll; | ||
| 543 | - (BOOL) changed; | ||
| 544 | - (void) addDisplayItemWithImage: (EmacsImage *)img | ||
| 545 | idx: (int)idx | ||
| 546 | tag: (int)tag | ||
| 547 | helpText: (const char *)help | ||
| 548 | enabled: (BOOL)enabled; | ||
| 549 | |||
| 550 | /* delegate methods */ | ||
| 551 | - (NSTabbarItem *)tabbar: (NSTabbar *)tabbar | ||
| 552 | itemForItemIdentifier: (NSString *)itemIdentifier | ||
| 553 | willBeInsertedIntoTabbar: (BOOL)flag; | ||
| 554 | - (NSArray *)tabbarDefaultItemIdentifiers: (NSTabbar *)tabbar; | ||
| 555 | - (NSArray *)tabbarAllowedItemIdentifiers: (NSTabbar *)tabbar; | ||
| 556 | @end | ||
| 557 | |||
| 558 | |||
| 559 | /* ========================================================================== | ||
| 560 | |||
| 515 | Toolbar | 561 | Toolbar |
| 516 | 562 | ||
| 517 | ========================================================================== */ | 563 | ========================================================================== */ |
| @@ -753,6 +799,7 @@ extern EmacsMenu *svcsMenu; | |||
| 753 | #define KEY_NS_NEW_FRAME ((1<<28)|(0<<16)|12) | 799 | #define KEY_NS_NEW_FRAME ((1<<28)|(0<<16)|12) |
| 754 | #define KEY_NS_TOGGLE_TOOLBAR ((1<<28)|(0<<16)|13) | 800 | #define KEY_NS_TOGGLE_TOOLBAR ((1<<28)|(0<<16)|13) |
| 755 | #define KEY_NS_SHOW_PREFS ((1<<28)|(0<<16)|14) | 801 | #define KEY_NS_SHOW_PREFS ((1<<28)|(0<<16)|14) |
| 802 | #define KEY_NS_TOGGLE_TABBAR ((1<<28)|(0<<16)|15) | ||
| 756 | 803 | ||
| 757 | /* Could use list to store these, but rest of emacs has a big infrastructure | 804 | /* Could use list to store these, but rest of emacs has a big infrastructure |
| 758 | for managing a table of bitmap "records". */ | 805 | for managing a table of bitmap "records". */ |
| @@ -923,6 +970,7 @@ struct ns_output | |||
| 923 | NSColor *cursor_color; | 970 | NSColor *cursor_color; |
| 924 | NSColor *foreground_color; | 971 | NSColor *foreground_color; |
| 925 | NSColor *background_color; | 972 | NSColor *background_color; |
| 973 | EmacsTabbar *tabbar; | ||
| 926 | EmacsToolbar *toolbar; | 974 | EmacsToolbar *toolbar; |
| 927 | #else | 975 | #else |
| 928 | void *view; | 976 | void *view; |
| @@ -930,6 +978,7 @@ struct ns_output | |||
| 930 | void *cursor_color; | 978 | void *cursor_color; |
| 931 | void *foreground_color; | 979 | void *foreground_color; |
| 932 | void *background_color; | 980 | void *background_color; |
| 981 | void *tabbar; | ||
| 933 | void *toolbar; | 982 | void *toolbar; |
| 934 | #endif | 983 | #endif |
| 935 | 984 | ||
| @@ -974,6 +1023,9 @@ struct ns_output | |||
| 974 | /* The height of the titlebar decoration (included in NSWindow's frame). */ | 1023 | /* The height of the titlebar decoration (included in NSWindow's frame). */ |
| 975 | int titlebar_height; | 1024 | int titlebar_height; |
| 976 | 1025 | ||
| 1026 | /* The height of the tabbar if displayed, else 0. */ | ||
| 1027 | int tabbar_height; | ||
| 1028 | |||
| 977 | /* The height of the toolbar if displayed, else 0. */ | 1029 | /* The height of the toolbar if displayed, else 0. */ |
| 978 | int toolbar_height; | 1030 | int toolbar_height; |
| 979 | 1031 | ||
| @@ -1029,6 +1081,16 @@ struct x_output | |||
| 1029 | [[FRAME_NS_VIEW (f) window] frame] \ | 1081 | [[FRAME_NS_VIEW (f) window] frame] \ |
| 1030 | styleMask:[[FRAME_NS_VIEW (f) window] styleMask]]))) | 1082 | styleMask:[[FRAME_NS_VIEW (f) window] styleMask]]))) |
| 1031 | 1083 | ||
| 1084 | /* Compute pixel height of the tabbar. */ | ||
| 1085 | #define FRAME_TABBAR_HEIGHT(f) \ | ||
| 1086 | (([[FRAME_NS_VIEW (f) window] tabbar] == nil \ | ||
| 1087 | || ! [[FRAME_NS_VIEW (f) window] tabbar].isVisible) ? \ | ||
| 1088 | 0 \ | ||
| 1089 | : (int)(NSHeight([NSWindow contentRectForFrameRect: \ | ||
| 1090 | [[FRAME_NS_VIEW (f) window] frame] \ | ||
| 1091 | styleMask:[[FRAME_NS_VIEW (f) window] styleMask]]) \ | ||
| 1092 | - NSHeight([[[FRAME_NS_VIEW (f) window] contentView] frame]))) | ||
| 1093 | |||
| 1032 | /* Compute pixel height of the toolbar. */ | 1094 | /* Compute pixel height of the toolbar. */ |
| 1033 | #define FRAME_TOOLBAR_HEIGHT(f) \ | 1095 | #define FRAME_TOOLBAR_HEIGHT(f) \ |
| 1034 | (([[FRAME_NS_VIEW (f) window] toolbar] == nil \ | 1096 | (([[FRAME_NS_VIEW (f) window] toolbar] == nil \ |
| @@ -1169,6 +1231,8 @@ extern const char *ns_get_defaults_value (const char *key); | |||
| 1169 | extern void ns_init_locale (void); | 1231 | extern void ns_init_locale (void); |
| 1170 | 1232 | ||
| 1171 | /* in nsmenu */ | 1233 | /* in nsmenu */ |
| 1234 | extern void update_frame_tab_bar (struct frame *f); | ||
| 1235 | extern void free_frame_tab_bar (struct frame *f); | ||
| 1172 | extern void update_frame_tool_bar (struct frame *f); | 1236 | extern void update_frame_tool_bar (struct frame *f); |
| 1173 | extern void free_frame_tool_bar (struct frame *f); | 1237 | extern void free_frame_tool_bar (struct frame *f); |
| 1174 | extern Lisp_Object find_and_return_menu_selection (struct frame *f, | 1238 | extern Lisp_Object find_and_return_menu_selection (struct frame *f, |
| @@ -1276,6 +1340,7 @@ extern char gnustep_base_version[]; /* version tracking */ | |||
| 1276 | #define NSWindowCollectionBehaviorFullScreenPrimary (1 << 7) | 1340 | #define NSWindowCollectionBehaviorFullScreenPrimary (1 << 7) |
| 1277 | #define NSApplicationPresentationFullScreen (1 << 10) | 1341 | #define NSApplicationPresentationFullScreen (1 << 10) |
| 1278 | #define NSApplicationPresentationAutoHideToolbar (1 << 11) | 1342 | #define NSApplicationPresentationAutoHideToolbar (1 << 11) |
| 1343 | #define NSApplicationPresentationAutoHideTabbar (1 << 12) | ||
| 1279 | #define NSAppKitVersionNumber10_7 1138 | 1344 | #define NSAppKitVersionNumber10_7 1138 |
| 1280 | #endif /* !defined (MAC_OS_X_VERSION_10_7) */ | 1345 | #endif /* !defined (MAC_OS_X_VERSION_10_7) */ |
| 1281 | 1346 | ||
diff --git a/src/nsterm.m b/src/nsterm.m index c8094d0ee37..321cdc462ec 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -1088,11 +1088,15 @@ ns_update_begin (struct frame *f) | |||
| 1088 | 1088 | ||
| 1089 | if ([view isFullscreen] && [view fsIsNative]) | 1089 | if ([view isFullscreen] && [view fsIsNative]) |
| 1090 | { | 1090 | { |
| 1091 | // Fix reappearing tool bar in fullscreen for Mac OS X 10.7 | 1091 | // Fix reappearing tool bar or tab bar in fullscreen for Mac OS X 10.7 |
| 1092 | BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (f) ? YES : NO; | 1092 | BOOL tarbar_visible = FRAME_EXTERNAL_TAB_BAR (f) ? YES : NO; |
| 1093 | NSTabbar *tabbar = [FRAME_NS_VIEW (f) tabbar]; | ||
| 1094 | if (! tarbar_visible != ! [tabbar isVisible]) | ||
| 1095 | [tabbar setVisible: tarbar_visible]; | ||
| 1096 | BOOL toolbar_visible = FRAME_EXTERNAL_TOOL_BAR (f) ? YES : NO; | ||
| 1093 | NSToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar]; | 1097 | NSToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar]; |
| 1094 | if (! tbar_visible != ! [toolbar isVisible]) | 1098 | if (! toolbar_visible != ! [toolbar isVisible]) |
| 1095 | [toolbar setVisible: tbar_visible]; | 1099 | [toolbar setVisible: toolbar_visible]; |
| 1096 | } | 1100 | } |
| 1097 | #endif | 1101 | #endif |
| 1098 | } | 1102 | } |
| @@ -1683,7 +1687,7 @@ ns_set_offset (struct frame *f, int xoff, int yoff, int change_grav) | |||
| 1683 | f->top_pos = f->size_hint_flags & YNegative | 1687 | f->top_pos = f->size_hint_flags & YNegative |
| 1684 | ? ([screen visibleFrame].size.height + f->top_pos | 1688 | ? ([screen visibleFrame].size.height + f->top_pos |
| 1685 | - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f) | 1689 | - FRAME_PIXEL_HEIGHT (f) - FRAME_NS_TITLEBAR_HEIGHT (f) |
| 1686 | - FRAME_TOOLBAR_HEIGHT (f)) | 1690 | - FRAME_TABBAR_HEIGHT (f) - FRAME_TOOLBAR_HEIGHT (f)) |
| 1687 | : f->top_pos; | 1691 | : f->top_pos; |
| 1688 | #ifdef NS_IMPL_GNUSTEP | 1692 | #ifdef NS_IMPL_GNUSTEP |
| 1689 | if (f->left_pos < 100) | 1693 | if (f->left_pos < 100) |
| @@ -1701,7 +1705,7 @@ ns_set_offset (struct frame *f, int xoff, int yoff, int change_grav) | |||
| 1701 | f->left_pos = FRAME_PIXEL_WIDTH (parent) - FRAME_PIXEL_WIDTH (f) + f->left_pos; | 1705 | f->left_pos = FRAME_PIXEL_WIDTH (parent) - FRAME_PIXEL_WIDTH (f) + f->left_pos; |
| 1702 | 1706 | ||
| 1703 | if (f->top_pos < 0) | 1707 | if (f->top_pos < 0) |
| 1704 | f->top_pos = FRAME_PIXEL_HEIGHT (parent) + FRAME_TOOLBAR_HEIGHT (parent) | 1708 | f->top_pos = FRAME_PIXEL_HEIGHT (parent) + FRAME_TABBAR_HEIGHT (parent) + FRAME_TOOLBAR_HEIGHT (parent) |
| 1705 | - FRAME_PIXEL_HEIGHT (f) + f->top_pos; | 1709 | - FRAME_PIXEL_HEIGHT (f) + f->top_pos; |
| 1706 | } | 1710 | } |
| 1707 | 1711 | ||
| @@ -1764,6 +1768,7 @@ ns_set_window_size (struct frame *f, | |||
| 1764 | wr.size.height = pixelheight; | 1768 | wr.size.height = pixelheight; |
| 1765 | if (! [view isFullscreen]) | 1769 | if (! [view isFullscreen]) |
| 1766 | wr.size.height += FRAME_NS_TITLEBAR_HEIGHT (f) | 1770 | wr.size.height += FRAME_NS_TITLEBAR_HEIGHT (f) |
| 1771 | + FRAME_TABBAR_HEIGHT (f) | ||
| 1767 | + FRAME_TOOLBAR_HEIGHT (f); | 1772 | + FRAME_TOOLBAR_HEIGHT (f); |
| 1768 | 1773 | ||
| 1769 | /* Do not try to constrain to this screen. We may have multiple | 1774 | /* Do not try to constrain to this screen. We may have multiple |
| @@ -1780,7 +1785,7 @@ ns_set_window_size (struct frame *f, | |||
| 1780 | Fcons (make_fixnum (wr.size.width), make_fixnum (wr.size.height)), | 1785 | Fcons (make_fixnum (wr.size.width), make_fixnum (wr.size.height)), |
| 1781 | make_fixnum (f->border_width), | 1786 | make_fixnum (f->border_width), |
| 1782 | make_fixnum (FRAME_NS_TITLEBAR_HEIGHT (f)), | 1787 | make_fixnum (FRAME_NS_TITLEBAR_HEIGHT (f)), |
| 1783 | make_fixnum (FRAME_TOOLBAR_HEIGHT (f)))); | 1788 | make_fixnum (FRAME_TABBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)))); |
| 1784 | 1789 | ||
| 1785 | [window setFrame: wr display: YES]; | 1790 | [window setFrame: wr display: YES]; |
| 1786 | 1791 | ||
| @@ -1817,10 +1822,12 @@ ns_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu | |||
| 1817 | [window setStyleMask: ((window.styleMask | FRAME_DECORATED_FLAGS) | 1822 | [window setStyleMask: ((window.styleMask | FRAME_DECORATED_FLAGS) |
| 1818 | ^ FRAME_UNDECORATED_FLAGS)]; | 1823 | ^ FRAME_UNDECORATED_FLAGS)]; |
| 1819 | 1824 | ||
| 1825 | [view createTabbar: f]; | ||
| 1820 | [view createToolbar: f]; | 1826 | [view createToolbar: f]; |
| 1821 | } | 1827 | } |
| 1822 | else | 1828 | else |
| 1823 | { | 1829 | { |
| 1830 | [window setTabbar: nil]; | ||
| 1824 | [window setToolbar: nil]; | 1831 | [window setToolbar: nil]; |
| 1825 | /* Do I need to release the toolbar here? */ | 1832 | /* Do I need to release the toolbar here? */ |
| 1826 | 1833 | ||
| @@ -2405,7 +2412,7 @@ frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) | |||
| 2405 | CGPoint mouse_pos = | 2412 | CGPoint mouse_pos = |
| 2406 | CGPointMake(f->left_pos + pix_x, | 2413 | CGPointMake(f->left_pos + pix_x, |
| 2407 | f->top_pos + pix_y + | 2414 | f->top_pos + pix_y + |
| 2408 | FRAME_NS_TITLEBAR_HEIGHT(f) + FRAME_TOOLBAR_HEIGHT(f)); | 2415 | FRAME_NS_TITLEBAR_HEIGHT(f) + FRAME_TABBAR_HEIGHT(f) + FRAME_TOOLBAR_HEIGHT(f)); |
| 2409 | CGWarpMouseCursorPosition (mouse_pos); | 2416 | CGWarpMouseCursorPosition (mouse_pos); |
| 2410 | #endif | 2417 | #endif |
| 2411 | } | 2418 | } |
| @@ -6100,6 +6107,7 @@ not_in_argv (NSString *arg) | |||
| 6100 | - (void)dealloc | 6107 | - (void)dealloc |
| 6101 | { | 6108 | { |
| 6102 | NSTRACE ("[EmacsView dealloc]"); | 6109 | NSTRACE ("[EmacsView dealloc]"); |
| 6110 | [tabbar release]; | ||
| 6103 | [toolbar release]; | 6111 | [toolbar release]; |
| 6104 | if (fs_state == FULLSCREEN_BOTH) | 6112 | if (fs_state == FULLSCREEN_BOTH) |
| 6105 | [nonfs_window release]; | 6113 | [nonfs_window release]; |
| @@ -6951,19 +6959,40 @@ not_in_argv (NSString *arg) | |||
| 6951 | 6959 | ||
| 6952 | if (! [self isFullscreen]) | 6960 | if (! [self isFullscreen]) |
| 6953 | { | 6961 | { |
| 6962 | int tabbar_height; | ||
| 6954 | int toolbar_height; | 6963 | int toolbar_height; |
| 6955 | #ifdef NS_IMPL_GNUSTEP | 6964 | #ifdef NS_IMPL_GNUSTEP |
| 6956 | // GNUstep does not always update the tool bar height. Force it. | 6965 | // GNUstep does not always update the tool bar height. Force it. |
| 6957 | if (toolbar && [toolbar isVisible]) | 6966 | if (toolbar && [toolbar isVisible]) |
| 6958 | update_frame_tool_bar (emacsframe); | 6967 | update_frame_tool_bar (emacsframe); |
| 6968 | if (tabbar && [tabbar isVisible]) | ||
| 6969 | update_frame_tab_bar (emacsframe); | ||
| 6959 | #endif | 6970 | #endif |
| 6960 | 6971 | ||
| 6972 | tabbar_height = FRAME_TABBAR_HEIGHT (emacsframe); | ||
| 6973 | if (tabbar_height < 0) | ||
| 6974 | tabbar_height = 35; | ||
| 6975 | |||
| 6961 | toolbar_height = FRAME_TOOLBAR_HEIGHT (emacsframe); | 6976 | toolbar_height = FRAME_TOOLBAR_HEIGHT (emacsframe); |
| 6962 | if (toolbar_height < 0) | 6977 | if (toolbar_height < 0) |
| 6963 | toolbar_height = 35; | 6978 | toolbar_height = 35; |
| 6964 | 6979 | ||
| 6965 | extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) | 6980 | extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) |
| 6966 | + toolbar_height; | 6981 | + tabbar_height + toolbar_height; |
| 6982 | } | ||
| 6983 | |||
| 6984 | if (wait_for_tab_bar) | ||
| 6985 | { | ||
| 6986 | /* The tabbar height is always 0 in fullscreen and undecorated | ||
| 6987 | frames, so don't wait for it to become available. */ | ||
| 6988 | if (FRAME_TABBAR_HEIGHT (emacsframe) == 0 | ||
| 6989 | && FRAME_UNDECORATED (emacsframe) == false | ||
| 6990 | && ! [self isFullscreen]) | ||
| 6991 | { | ||
| 6992 | NSTRACE_MSG ("Waiting for tabbar"); | ||
| 6993 | return; | ||
| 6994 | } | ||
| 6995 | wait_for_tab_bar = NO; | ||
| 6967 | } | 6996 | } |
| 6968 | 6997 | ||
| 6969 | if (wait_for_tool_bar) | 6998 | if (wait_for_tool_bar) |
| @@ -6984,6 +7013,7 @@ not_in_argv (NSString *arg) | |||
| 6984 | newh = (int)wr.size.height - extra; | 7013 | newh = (int)wr.size.height - extra; |
| 6985 | 7014 | ||
| 6986 | NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); | 7015 | NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); |
| 7016 | NSTRACE_MSG ("FRAME_TABBAR_HEIGHT: %d", FRAME_TABBAR_HEIGHT (emacsframe)); | ||
| 6987 | NSTRACE_MSG ("FRAME_TOOLBAR_HEIGHT: %d", FRAME_TOOLBAR_HEIGHT (emacsframe)); | 7017 | NSTRACE_MSG ("FRAME_TOOLBAR_HEIGHT: %d", FRAME_TOOLBAR_HEIGHT (emacsframe)); |
| 6988 | NSTRACE_MSG ("FRAME_NS_TITLEBAR_HEIGHT: %d", FRAME_NS_TITLEBAR_HEIGHT (emacsframe)); | 7018 | NSTRACE_MSG ("FRAME_NS_TITLEBAR_HEIGHT: %d", FRAME_NS_TITLEBAR_HEIGHT (emacsframe)); |
| 6989 | 7019 | ||
| @@ -7058,6 +7088,7 @@ not_in_argv (NSString *arg) | |||
| 7058 | if (! [self isFullscreen]) | 7088 | if (! [self isFullscreen]) |
| 7059 | { | 7089 | { |
| 7060 | extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) | 7090 | extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) |
| 7091 | + FRAME_TABBAR_HEIGHT (emacsframe) | ||
| 7061 | + FRAME_TOOLBAR_HEIGHT (emacsframe); | 7092 | + FRAME_TOOLBAR_HEIGHT (emacsframe); |
| 7062 | } | 7093 | } |
| 7063 | 7094 | ||
| @@ -7284,6 +7315,34 @@ not_in_argv (NSString *arg) | |||
| 7284 | } | 7315 | } |
| 7285 | 7316 | ||
| 7286 | 7317 | ||
| 7318 | - (void)createTabbar: (struct frame *)f | ||
| 7319 | { | ||
| 7320 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); | ||
| 7321 | NSWindow *window = [view window]; | ||
| 7322 | |||
| 7323 | tabbar = [[EmacsTabbar alloc] initForView: self withIdentifier: | ||
| 7324 | [NSString stringWithFormat: @"Emacs Frame %d", | ||
| 7325 | ns_window_num]]; | ||
| 7326 | [tabbar setVisible: NO]; | ||
| 7327 | [window setTabbar: tabbar]; | ||
| 7328 | |||
| 7329 | /* Don't set frame garbaged until tab bar is up to date? | ||
| 7330 | This avoids an extra clear and redraw (flicker) at frame creation. */ | ||
| 7331 | if (FRAME_EXTERNAL_TAB_BAR (f)) wait_for_tab_bar = YES; | ||
| 7332 | else wait_for_tab_bar = NO; | ||
| 7333 | |||
| 7334 | |||
| 7335 | #ifdef NS_IMPL_COCOA | ||
| 7336 | { | ||
| 7337 | NSButton *toggleButton; | ||
| 7338 | toggleButton = [window standardWindowButton: NSWindowTabbarButton]; | ||
| 7339 | [toggleButton setTarget: self]; | ||
| 7340 | [toggleButton setAction: @selector (toggleTabbar: )]; | ||
| 7341 | } | ||
| 7342 | #endif | ||
| 7343 | } | ||
| 7344 | |||
| 7345 | |||
| 7287 | - (void)createToolbar: (struct frame *)f | 7346 | - (void)createToolbar: (struct frame *)f |
| 7288 | { | 7347 | { |
| 7289 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); | 7348 | EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); |
| @@ -7390,6 +7449,10 @@ not_in_argv (NSString *arg) | |||
| 7390 | NILP (tem) ? "Emacs" : SSDATA (tem)]; | 7449 | NILP (tem) ? "Emacs" : SSDATA (tem)]; |
| 7391 | [win setTitle: name]; | 7450 | [win setTitle: name]; |
| 7392 | 7451 | ||
| 7452 | /* tabbar support */ | ||
| 7453 | if (! FRAME_UNDECORATED (f)) | ||
| 7454 | [self createTabbar: f]; | ||
| 7455 | |||
| 7393 | /* toolbar support */ | 7456 | /* toolbar support */ |
| 7394 | if (! FRAME_UNDECORATED (f)) | 7457 | if (! FRAME_UNDECORATED (f)) |
| 7395 | [self createToolbar: f]; | 7458 | [self createToolbar: f]; |
| @@ -7693,7 +7756,7 @@ not_in_argv (NSString *arg) | |||
| 7693 | willUseFullScreenPresentationOptions: | 7756 | willUseFullScreenPresentationOptions: |
| 7694 | (NSApplicationPresentationOptions)proposedOptions | 7757 | (NSApplicationPresentationOptions)proposedOptions |
| 7695 | { | 7758 | { |
| 7696 | return proposedOptions|NSApplicationPresentationAutoHideToolbar; | 7759 | return proposedOptions|NSApplicationPresentationAutoHideTabbar|NSApplicationPresentationAutoHideToolbar; |
| 7697 | } | 7760 | } |
| 7698 | #endif | 7761 | #endif |
| 7699 | 7762 | ||
| @@ -7725,7 +7788,8 @@ not_in_argv (NSString *arg) | |||
| 7725 | } | 7788 | } |
| 7726 | else | 7789 | else |
| 7727 | { | 7790 | { |
| 7728 | BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (emacsframe) ? YES : NO; | 7791 | BOOL tarbar_visible = FRAME_EXTERNAL_TAB_BAR (emacsframe) ? YES : NO; |
| 7792 | BOOL toolbar_visible = FRAME_EXTERNAL_TOOL_BAR (emacsframe) ? YES : NO; | ||
| 7729 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 \ | 7793 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 \ |
| 7730 | && MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 | 7794 | && MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 |
| 7731 | unsigned val = (unsigned)[NSApp presentationOptions]; | 7795 | unsigned val = (unsigned)[NSApp presentationOptions]; |
| @@ -7738,12 +7802,14 @@ not_in_argv (NSString *arg) | |||
| 7738 | = NSApplicationPresentationAutoHideDock | 7802 | = NSApplicationPresentationAutoHideDock |
| 7739 | | NSApplicationPresentationAutoHideMenuBar | 7803 | | NSApplicationPresentationAutoHideMenuBar |
| 7740 | | NSApplicationPresentationFullScreen | 7804 | | NSApplicationPresentationFullScreen |
| 7805 | | NSApplicationPresentationAutoHideTabbar | ||
| 7741 | | NSApplicationPresentationAutoHideToolbar; | 7806 | | NSApplicationPresentationAutoHideToolbar; |
| 7742 | 7807 | ||
| 7743 | [NSApp setPresentationOptions: options]; | 7808 | [NSApp setPresentationOptions: options]; |
| 7744 | } | 7809 | } |
| 7745 | #endif | 7810 | #endif |
| 7746 | [toolbar setVisible:tbar_visible]; | 7811 | [tabbar setVisible:tarbar_visible]; |
| 7812 | [toolbar setVisible:toolbar_visible]; | ||
| 7747 | } | 7813 | } |
| 7748 | } | 7814 | } |
| 7749 | 7815 | ||
| @@ -7784,6 +7850,16 @@ not_in_argv (NSString *arg) | |||
| 7784 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 | 7850 | #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 |
| 7785 | [self updateCollectionBehavior]; | 7851 | [self updateCollectionBehavior]; |
| 7786 | #endif | 7852 | #endif |
| 7853 | if (FRAME_EXTERNAL_TAB_BAR (emacsframe)) | ||
| 7854 | { | ||
| 7855 | [tabbar setVisible:YES]; | ||
| 7856 | update_frame_tab_bar (emacsframe); | ||
| 7857 | [self updateFrameSize:YES]; | ||
| 7858 | [[self window] display]; | ||
| 7859 | } | ||
| 7860 | else | ||
| 7861 | [tabbar setVisible:NO]; | ||
| 7862 | |||
| 7787 | if (FRAME_EXTERNAL_TOOL_BAR (emacsframe)) | 7863 | if (FRAME_EXTERNAL_TOOL_BAR (emacsframe)) |
| 7788 | { | 7864 | { |
| 7789 | [toolbar setVisible:YES]; | 7865 | [toolbar setVisible:YES]; |
| @@ -8097,6 +8173,53 @@ not_in_argv (NSString *arg) | |||
| 8097 | } | 8173 | } |
| 8098 | 8174 | ||
| 8099 | 8175 | ||
| 8176 | - (EmacsTabbar *)tabbar | ||
| 8177 | { | ||
| 8178 | return tabbar; | ||
| 8179 | } | ||
| 8180 | |||
| 8181 | |||
| 8182 | /* This gets called on tabbar button click. */ | ||
| 8183 | - (instancetype)tabbarClicked: (id)item | ||
| 8184 | { | ||
| 8185 | NSEvent *theEvent; | ||
| 8186 | int idx = [item tag] * TAB_BAR_ITEM_NSLOTS; | ||
| 8187 | |||
| 8188 | NSTRACE ("[EmacsView tabbarClicked:]"); | ||
| 8189 | |||
| 8190 | if (!emacs_event) | ||
| 8191 | return self; | ||
| 8192 | |||
| 8193 | /* Send first event (for some reason two needed). */ | ||
| 8194 | theEvent = [[self window] currentEvent]; | ||
| 8195 | emacs_event->kind = TAB_BAR_EVENT; | ||
| 8196 | XSETFRAME (emacs_event->arg, emacsframe); | ||
| 8197 | EV_TRAILER (theEvent); | ||
| 8198 | |||
| 8199 | emacs_event->kind = TAB_BAR_EVENT; | ||
| 8200 | /* XSETINT (emacs_event->code, 0); */ | ||
| 8201 | emacs_event->arg = AREF (emacsframe->tab_bar_items, | ||
| 8202 | idx + TAB_BAR_ITEM_KEY); | ||
| 8203 | emacs_event->modifiers = EV_MODIFIERS (theEvent); | ||
| 8204 | EV_TRAILER (theEvent); | ||
| 8205 | return self; | ||
| 8206 | } | ||
| 8207 | |||
| 8208 | |||
| 8209 | - (instancetype)toggleTabbar: (id)sender | ||
| 8210 | { | ||
| 8211 | NSTRACE ("[EmacsView toggleTabbar:]"); | ||
| 8212 | |||
| 8213 | if (!emacs_event) | ||
| 8214 | return self; | ||
| 8215 | |||
| 8216 | emacs_event->kind = NS_NONKEY_EVENT; | ||
| 8217 | emacs_event->code = KEY_NS_TOGGLE_TABBAR; | ||
| 8218 | EV_TRAILER ((id)nil); | ||
| 8219 | return self; | ||
| 8220 | } | ||
| 8221 | |||
| 8222 | |||
| 8100 | - (EmacsToolbar *)toolbar | 8223 | - (EmacsToolbar *)toolbar |
| 8101 | { | 8224 | { |
| 8102 | return toolbar; | 8225 | return toolbar; |