Mercurial > emacs
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 |