comparison src/nsterm.m @ 112396:e79e716435f4

Make Nextstep port handle multiple screens for resize and move. * nsterm.h (ns_output): Add dont_constrain and zooming. (EmacsView): Add ns_userRect. * nsterm.m (keyDown): If ns_right_alternate_modifier is Qleft, check if ns_alternate_modifier is none. * nsterm.m (x_set_offset, windowDidMove): When calculating y, use first screen, not the window screen. (x_set_window_size): Remove constraints. Calculate origin.y only if zooming is 0 and without referring to a screen. (windowWillResize): Don't modify frameSize. (windowDidBecomeKey, mouseDown): Set dont_constrain to 1. (initFrameFromEmacs): Initialize ns_userRect. (windowShouldZoom): Set zooming to one. Remove all other code. (windowWillUseStandardFrame): Move static ns_userRect to EmacsView. Zero it after restore. (constrainFrameRect): New method for EmacsWindow. (mouseDragged): Always post NSWindowDidResizeNotification after call to windowWillResize.
author Jan D. <jan.h.d@swipnet.se>
date Fri, 21 Jan 2011 15:19:44 +0100
parents f1de024f822c
children 4b27e6d58d2c
comparison
equal deleted inserted replaced
112395:f1de024f822c 112396:e79e716435f4
1051 x_set_offset (struct frame *f, int xoff, int yoff, int change_grav) 1051 x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
1052 /* -------------------------------------------------------------------------- 1052 /* --------------------------------------------------------------------------
1053 External: Position the window 1053 External: Position the window
1054 -------------------------------------------------------------------------- */ 1054 -------------------------------------------------------------------------- */
1055 { 1055 {
1056 NSScreen *screen;
1057 NSView *view = FRAME_NS_VIEW (f); 1056 NSView *view = FRAME_NS_VIEW (f);
1057 NSArray *screens = [NSScreen screens];
1058 NSScreen *fscreen = [screens objectAtIndex: 0];
1059 NSScreen *screen = [[view window] screen];
1058 1060
1059 NSTRACE (x_set_offset); 1061 NSTRACE (x_set_offset);
1060 1062
1061 BLOCK_INPUT; 1063 BLOCK_INPUT;
1062 1064
1063 f->left_pos = xoff; 1065 f->left_pos = xoff;
1064 f->top_pos = yoff; 1066 f->top_pos = yoff;
1065 1067
1066 if (view != nil && (screen = [[view window] screen])) 1068 if (view != nil && screen && fscreen)
1067 { 1069 {
1068 f->left_pos = f->size_hint_flags & XNegative 1070 f->left_pos = f->size_hint_flags & XNegative
1069 ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f) 1071 ? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f)
1070 : f->left_pos; 1072 : f->left_pos;
1071 /* We use visibleFrame here to take menu bar into account. 1073 /* We use visibleFrame here to take menu bar into account.
1080 if (f->left_pos < 100) 1082 if (f->left_pos < 100)
1081 f->left_pos = 100; /* don't overlap menu */ 1083 f->left_pos = 100; /* don't overlap menu */
1082 #endif 1084 #endif
1083 [[view window] setFrameTopLeftPoint: 1085 [[view window] setFrameTopLeftPoint:
1084 NSMakePoint (SCREENMAXBOUND (f->left_pos), 1086 NSMakePoint (SCREENMAXBOUND (f->left_pos),
1085 SCREENMAXBOUND ([screen frame].size.height 1087 SCREENMAXBOUND ([fscreen frame].size.height
1086 - NS_TOP_POS (f)))]; 1088 - NS_TOP_POS (f)))];
1087 f->size_hint_flags &= ~(XNegative|YNegative); 1089 f->size_hint_flags &= ~(XNegative|YNegative);
1088 } 1090 }
1089 1091
1090 UNBLOCK_INPUT; 1092 UNBLOCK_INPUT;
1094 void 1096 void
1095 x_set_window_size (struct frame *f, int change_grav, int cols, int rows) 1097 x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
1096 /* -------------------------------------------------------------------------- 1098 /* --------------------------------------------------------------------------
1097 Adjust window pixel size based on given character grid size 1099 Adjust window pixel size based on given character grid size
1098 Impl is a bit more complex than other terms, need to do some 1100 Impl is a bit more complex than other terms, need to do some
1099 internal clipping and also pay attention to screen constraints. 1101 internal clipping.
1100 -------------------------------------------------------------------------- */ 1102 -------------------------------------------------------------------------- */
1101 { 1103 {
1102 EmacsView *view = FRAME_NS_VIEW (f); 1104 EmacsView *view = FRAME_NS_VIEW (f);
1103 EmacsToolbar *toolbar = [view toolbar]; 1105 EmacsToolbar *toolbar = [view toolbar];
1104 NSWindow *window = [view window]; 1106 NSWindow *window = [view window];
1105 NSScreen *screen = [window screen];
1106 NSRect wr = [window frame]; 1107 NSRect wr = [window frame];
1107 int tb = FRAME_EXTERNAL_TOOL_BAR (f); 1108 int tb = FRAME_EXTERNAL_TOOL_BAR (f);
1108 int pixelwidth, pixelheight; 1109 int pixelwidth, pixelheight;
1109 static int oldRows, oldCols, oldFontWidth, oldFontHeight; 1110 static int oldRows, oldCols, oldFontWidth, oldFontHeight;
1110 static int oldTB; 1111 static int oldTB;
1151 1152
1152 wr.size.width = pixelwidth + f->border_width; 1153 wr.size.width = pixelwidth + f->border_width;
1153 wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f) 1154 wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f)
1154 + FRAME_TOOLBAR_HEIGHT (f); 1155 + FRAME_TOOLBAR_HEIGHT (f);
1155 1156
1156 /* constrain to screen if we can */ 1157 /* Do not try to constrain to this screen. We may have multiple
1157 if (screen) 1158 screens, and want Emacs to span those. Constraining to screen
1158 { 1159 prevents that, and that is not nice to the user. */
1159 NSSize sz = [screen visibleFrame].size; 1160 if (f->output_data.ns->zooming)
1160 NSSize ez = { wr.size.width - sz.width, wr.size.height - sz.height }; 1161 f->output_data.ns->zooming = 0;
1161 if (ez.width > 0) 1162 else
1162 { 1163 wr.origin.y += FRAME_PIXEL_HEIGHT (f) - pixelheight;
1163 int cr = ez.width / FRAME_COLUMN_WIDTH (f) + 1;
1164 cols -= cr;
1165 oldCols = cols;
1166 wr.size.width -= cr * FRAME_COLUMN_WIDTH (f);
1167 pixelwidth -= cr * FRAME_COLUMN_WIDTH (f);
1168 }
1169 if (ez.height > 0)
1170 {
1171 int rr = ez.height / FRAME_LINE_HEIGHT (f) + 1;
1172 rows -= rr;
1173 oldRows = rows;
1174 wr.size.height -= rr * FRAME_LINE_HEIGHT (f);
1175 pixelheight -= rr * FRAME_LINE_HEIGHT (f);
1176 }
1177 wr.origin.x = f->left_pos;
1178 wr.origin.y = [screen frame].size.height - NS_TOP_POS (f)
1179 - wr.size.height;
1180 }
1181 1164
1182 [view setRows: rows andColumns: cols]; 1165 [view setRows: rows andColumns: cols];
1183 [window setFrame: wr display: YES]; 1166 [window setFrame: wr display: YES];
1184 1167
1185 /*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */ 1168 /*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */
4985 #else 4968 #else
4986 frameSize.width); 4969 frameSize.width);
4987 #endif 4970 #endif
4988 if (cols < MINWIDTH) 4971 if (cols < MINWIDTH)
4989 cols = MINWIDTH; 4972 cols = MINWIDTH;
4990 frameSize.width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (emacsframe, cols);
4991 4973
4992 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, frameSize.height 4974 rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, frameSize.height
4993 #ifdef NS_IMPL_GNUSTEP 4975 #ifdef NS_IMPL_GNUSTEP
4994 - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) + 3 4976 - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) + 3
4995 - FRAME_TOOLBAR_HEIGHT (emacsframe)); 4977 - FRAME_TOOLBAR_HEIGHT (emacsframe));
4997 - FRAME_NS_TITLEBAR_HEIGHT (emacsframe) 4979 - FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
4998 - FRAME_TOOLBAR_HEIGHT (emacsframe)); 4980 - FRAME_TOOLBAR_HEIGHT (emacsframe));
4999 #endif 4981 #endif
5000 if (rows < MINHEIGHT) 4982 if (rows < MINHEIGHT)
5001 rows = MINHEIGHT; 4983 rows = MINHEIGHT;
5002 frameSize.height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (emacsframe, rows)
5003 + FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
5004 + FRAME_TOOLBAR_HEIGHT (emacsframe);
5005 #ifdef NS_IMPL_COCOA 4984 #ifdef NS_IMPL_COCOA
5006 { 4985 {
5007 /* this sets window title to have size in it; the wm does this under GS */ 4986 /* this sets window title to have size in it; the wm does this under GS */
5008 NSRect r = [[self window] frame]; 4987 NSRect r = [[self window] frame];
5009 if (r.size.height == frameSize.height && r.size.width == frameSize.width) 4988 if (r.size.height == frameSize.height && r.size.width == frameSize.width)
5067 /* Avoid loop under GNUstep due to call at beginning of this function. 5046 /* Avoid loop under GNUstep due to call at beginning of this function.
5068 (x_set_window_size causes a resize which causes 5047 (x_set_window_size causes a resize which causes
5069 a "windowDidResize" which calls x_set_window_size). */ 5048 a "windowDidResize" which calls x_set_window_size). */
5070 #ifndef NS_IMPL_GNUSTEP 5049 #ifndef NS_IMPL_GNUSTEP
5071 if (cols > 0 && rows > 0) 5050 if (cols > 0 && rows > 0)
5072 x_set_window_size (emacsframe, 0, cols, rows); 5051 x_set_window_size (emacsframe, 0, cols, rows);
5073 #endif 5052 #endif
5074 5053
5075 ns_send_appdefined (-1); 5054 ns_send_appdefined (-1);
5076 } 5055 }
5077 5056
5082 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); 5061 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
5083 struct frame *old_focus = dpyinfo->x_focus_frame; 5062 struct frame *old_focus = dpyinfo->x_focus_frame;
5084 5063
5085 NSTRACE (windowDidBecomeKey); 5064 NSTRACE (windowDidBecomeKey);
5086 5065
5066 emacsframe->output_data.ns->dont_constrain = 1;
5087 if (emacsframe != old_focus) 5067 if (emacsframe != old_focus)
5088 dpyinfo->x_focus_frame = emacsframe; 5068 dpyinfo->x_focus_frame = emacsframe;
5089 5069
5090 ns_frame_rehighlight (emacsframe); 5070 ns_frame_rehighlight (emacsframe);
5091 5071
5160 processingCompose = NO; 5140 processingCompose = NO;
5161 scrollbarsNeedingUpdate = 0; 5141 scrollbarsNeedingUpdate = 0;
5162 5142
5163 /*fprintf (stderr,"init with %d, %d\n",f->text_cols, f->text_lines); */ 5143 /*fprintf (stderr,"init with %d, %d\n",f->text_cols, f->text_lines); */
5164 5144
5145 ns_userRect = NSMakeRect (0, 0, 0, 0);
5165 r = NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols), 5146 r = NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
5166 FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines)); 5147 FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines));
5167 [self initWithFrame: r]; 5148 [self initWithFrame: r];
5168 [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; 5149 [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
5169 5150
5246 5227
5247 - (void)windowDidMove: sender 5228 - (void)windowDidMove: sender
5248 { 5229 {
5249 NSWindow *win = [self window]; 5230 NSWindow *win = [self window];
5250 NSRect r = [win frame]; 5231 NSRect r = [win frame];
5251 NSScreen *screen = [win screen]; 5232 NSArray *screens = [NSScreen screens];
5233 NSScreen *screen = [screens objectAtIndex: 0];
5252 5234
5253 NSTRACE (windowDidMove); 5235 NSTRACE (windowDidMove);
5254 5236
5255 if (!emacsframe->output_data.ns) 5237 if (!emacsframe->output_data.ns)
5256 return; 5238 return;
5266 /* Called AFTER method below, but before our windowWillResize call there leads 5248 /* Called AFTER method below, but before our windowWillResize call there leads
5267 to windowDidResize -> x_set_window_size. Update emacs' notion of frame 5249 to windowDidResize -> x_set_window_size. Update emacs' notion of frame
5268 location so set_window_size moves the frame. */ 5250 location so set_window_size moves the frame. */
5269 - (BOOL)windowShouldZoom: (NSWindow *)sender toFrame: (NSRect)newFrame 5251 - (BOOL)windowShouldZoom: (NSWindow *)sender toFrame: (NSRect)newFrame
5270 { 5252 {
5271 NSTRACE (windowShouldZoom); 5253 emacsframe->output_data.ns->zooming = 1;
5272 emacsframe->left_pos = (int)newFrame.origin.x;
5273 emacsframe->top_pos = [[sender screen] frame].size.height
5274 - (newFrame.origin.y+newFrame.size.height);
5275 return YES; 5254 return YES;
5276 } 5255 }
5277 5256
5278 5257
5279 /* Override to do something slightly nonstandard, but nice. First click on 5258 /* Override to do something slightly nonstandard, but nice. First click on
5281 returns to original. */ 5260 returns to original. */
5282 - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender 5261 - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
5283 defaultFrame:(NSRect)defaultFrame 5262 defaultFrame:(NSRect)defaultFrame
5284 { 5263 {
5285 NSRect result = [sender frame]; 5264 NSRect result = [sender frame];
5286 static NSRect ns_userRect = { 0, 0, 0, 0 };
5287 5265
5288 NSTRACE (windowWillUseStandardFrame); 5266 NSTRACE (windowWillUseStandardFrame);
5289 5267
5290 if (abs (defaultFrame.size.height - result.size.height) 5268 if (abs (defaultFrame.size.height - result.size.height)
5291 > FRAME_LINE_HEIGHT (emacsframe)) 5269 > FRAME_LINE_HEIGHT (emacsframe))
5299 { 5277 {
5300 if (abs (defaultFrame.size.width - result.size.width) 5278 if (abs (defaultFrame.size.width - result.size.width)
5301 > FRAME_COLUMN_WIDTH (emacsframe)) 5279 > FRAME_COLUMN_WIDTH (emacsframe))
5302 result = defaultFrame; /* second click */ 5280 result = defaultFrame; /* second click */
5303 else 5281 else
5304 result = ns_userRect.size.height ? ns_userRect : result; /* restore */ 5282 {
5283 /* restore */
5284 result = ns_userRect.size.height ? ns_userRect : result;
5285 ns_userRect = NSMakeRect (0, 0, 0, 0);
5286 }
5305 } 5287 }
5306 5288
5307 [self windowWillResize: sender toSize: result.size]; 5289 [self windowWillResize: sender toSize: result.size];
5308 return result; 5290 return result;
5309 } 5291 }
5684 5666
5685 ========================================================================== */ 5667 ========================================================================== */
5686 5668
5687 @implementation EmacsWindow 5669 @implementation EmacsWindow
5688 5670
5671 /* If we have multiple monitors, one above the other, we don't want to
5672 restrict the height to just one monitor. So we override this. */
5673 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
5674 {
5675 /* When making the frame visible for the first time, we want to
5676 constrain. Other times not. */
5677 struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
5678 if (f->output_data.ns->dont_constrain)
5679 return frameRect;
5680
5681 return [super constrainFrameRect:frameRect toScreen:screen];
5682 }
5683
5684
5689 /* called only on resize clicks by special case in EmacsApp-sendEvent */ 5685 /* called only on resize clicks by special case in EmacsApp-sendEvent */
5690 - (void)mouseDown: (NSEvent *)theEvent 5686 - (void)mouseDown: (NSEvent *)theEvent
5691 { 5687 {
5688 struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
5689 f->output_data.ns->dont_constrain = 1;
5692 if (ns_in_resize) 5690 if (ns_in_resize)
5693 { 5691 {
5694 NSSize size = [[theEvent window] frame].size; 5692 NSSize size = [[theEvent window] frame].size;
5695 grabOffset = [theEvent locationInWindow]; 5693 grabOffset = [theEvent locationInWindow];
5696 grabOffset.x = size.width - grabOffset.x; 5694 grabOffset.x = size.width - grabOffset.x;
5729 5727
5730 if (size.width == origSize.width && size.height == origSize.height) 5728 if (size.width == origSize.width && size.height == origSize.height)
5731 return; 5729 return;
5732 5730
5733 vettedSize = [[self delegate] windowWillResize: self toSize: size]; 5731 vettedSize = [[self delegate] windowWillResize: self toSize: size];
5734 if (vettedSize.width != size.width || vettedSize.height != size.height) 5732 [[NSNotificationCenter defaultCenter]
5735 {
5736 [[NSNotificationCenter defaultCenter]
5737 postNotificationName: NSWindowDidResizeNotification 5733 postNotificationName: NSWindowDidResizeNotification
5738 object: self]; 5734 object: self];
5739 }
5740 } 5735 }
5741 else 5736 else
5742 [super mouseDragged: theEvent]; 5737 [super mouseDragged: theEvent];
5743 } 5738 }
5744 5739