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.
This commit is contained in:
parent
449ab399f4
commit
e2f79c8d27
3 changed files with 66 additions and 46 deletions
|
@ -1,5 +1,23 @@
|
|||
2011-01-21 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
int rows, cols;
|
||||
int scrollbarsNeedingUpdate;
|
||||
EmacsToolbar *toolbar;
|
||||
NSRect ns_userRect;
|
||||
}
|
||||
|
||||
/* AppKit-side interface */
|
||||
|
@ -565,6 +566,12 @@ struct ns_output
|
|||
|
||||
/* This is the Emacs structure for the NS display this frame is on. */
|
||||
struct ns_display_info *display_info;
|
||||
|
||||
/* Non-zero if we want to constrain the frame to the screen. */
|
||||
int dont_constrain;
|
||||
|
||||
/* Non-zero if we are zooming (maximizing) the frame. */
|
||||
int zooming;
|
||||
};
|
||||
|
||||
/* this dummy decl needed to support TTYs */
|
||||
|
|
87
src/nsterm.m
87
src/nsterm.m
|
@ -1053,8 +1053,10 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
External: Position the window
|
||||
-------------------------------------------------------------------------- */
|
||||
{
|
||||
NSScreen *screen;
|
||||
NSView *view = FRAME_NS_VIEW (f);
|
||||
NSArray *screens = [NSScreen screens];
|
||||
NSScreen *fscreen = [screens objectAtIndex: 0];
|
||||
NSScreen *screen = [[view window] screen];
|
||||
|
||||
NSTRACE (x_set_offset);
|
||||
|
||||
|
@ -1063,7 +1065,7 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
f->left_pos = xoff;
|
||||
f->top_pos = yoff;
|
||||
|
||||
if (view != nil && (screen = [[view window] screen]))
|
||||
if (view != nil && screen && fscreen)
|
||||
{
|
||||
f->left_pos = f->size_hint_flags & XNegative
|
||||
? [screen visibleFrame].size.width + f->left_pos - FRAME_PIXEL_WIDTH (f)
|
||||
|
@ -1082,7 +1084,7 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
#endif
|
||||
[[view window] setFrameTopLeftPoint:
|
||||
NSMakePoint (SCREENMAXBOUND (f->left_pos),
|
||||
SCREENMAXBOUND ([screen frame].size.height
|
||||
SCREENMAXBOUND ([fscreen frame].size.height
|
||||
- NS_TOP_POS (f)))];
|
||||
f->size_hint_flags &= ~(XNegative|YNegative);
|
||||
}
|
||||
|
@ -1096,13 +1098,12 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
/* --------------------------------------------------------------------------
|
||||
Adjust window pixel size based on given character grid size
|
||||
Impl is a bit more complex than other terms, need to do some
|
||||
internal clipping and also pay attention to screen constraints.
|
||||
internal clipping.
|
||||
-------------------------------------------------------------------------- */
|
||||
{
|
||||
EmacsView *view = FRAME_NS_VIEW (f);
|
||||
EmacsToolbar *toolbar = [view toolbar];
|
||||
NSWindow *window = [view window];
|
||||
NSScreen *screen = [window screen];
|
||||
NSRect wr = [window frame];
|
||||
int tb = FRAME_EXTERNAL_TOOL_BAR (f);
|
||||
int pixelwidth, pixelheight;
|
||||
|
@ -1153,31 +1154,13 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
wr.size.height = pixelheight + FRAME_NS_TITLEBAR_HEIGHT (f)
|
||||
+ FRAME_TOOLBAR_HEIGHT (f);
|
||||
|
||||
/* constrain to screen if we can */
|
||||
if (screen)
|
||||
{
|
||||
NSSize sz = [screen visibleFrame].size;
|
||||
NSSize ez = { wr.size.width - sz.width, wr.size.height - sz.height };
|
||||
if (ez.width > 0)
|
||||
{
|
||||
int cr = ez.width / FRAME_COLUMN_WIDTH (f) + 1;
|
||||
cols -= cr;
|
||||
oldCols = cols;
|
||||
wr.size.width -= cr * FRAME_COLUMN_WIDTH (f);
|
||||
pixelwidth -= cr * FRAME_COLUMN_WIDTH (f);
|
||||
}
|
||||
if (ez.height > 0)
|
||||
{
|
||||
int rr = ez.height / FRAME_LINE_HEIGHT (f) + 1;
|
||||
rows -= rr;
|
||||
oldRows = rows;
|
||||
wr.size.height -= rr * FRAME_LINE_HEIGHT (f);
|
||||
pixelheight -= rr * FRAME_LINE_HEIGHT (f);
|
||||
}
|
||||
wr.origin.x = f->left_pos;
|
||||
wr.origin.y = [screen frame].size.height - NS_TOP_POS (f)
|
||||
- wr.size.height;
|
||||
}
|
||||
/* Do not try to constrain to this screen. We may have multiple
|
||||
screens, and want Emacs to span those. Constraining to screen
|
||||
prevents that, and that is not nice to the user. */
|
||||
if (f->output_data.ns->zooming)
|
||||
f->output_data.ns->zooming = 0;
|
||||
else
|
||||
wr.origin.y += FRAME_PIXEL_HEIGHT (f) - pixelheight;
|
||||
|
||||
[view setRows: rows andColumns: cols];
|
||||
[window setFrame: wr display: YES];
|
||||
|
@ -4987,7 +4970,6 @@ - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
|
|||
#endif
|
||||
if (cols < MINWIDTH)
|
||||
cols = MINWIDTH;
|
||||
frameSize.width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (emacsframe, cols);
|
||||
|
||||
rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, frameSize.height
|
||||
#ifdef NS_IMPL_GNUSTEP
|
||||
|
@ -4999,9 +4981,6 @@ - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize
|
|||
#endif
|
||||
if (rows < MINHEIGHT)
|
||||
rows = MINHEIGHT;
|
||||
frameSize.height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (emacsframe, rows)
|
||||
+ FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
|
||||
+ FRAME_TOOLBAR_HEIGHT (emacsframe);
|
||||
#ifdef NS_IMPL_COCOA
|
||||
{
|
||||
/* this sets window title to have size in it; the wm does this under GS */
|
||||
|
@ -5069,7 +5048,7 @@ - (void)windowDidResize: (NSNotification *)notification
|
|||
a "windowDidResize" which calls x_set_window_size). */
|
||||
#ifndef NS_IMPL_GNUSTEP
|
||||
if (cols > 0 && rows > 0)
|
||||
x_set_window_size (emacsframe, 0, cols, rows);
|
||||
x_set_window_size (emacsframe, 0, cols, rows);
|
||||
#endif
|
||||
|
||||
ns_send_appdefined (-1);
|
||||
|
@ -5084,6 +5063,7 @@ - (void)windowDidBecomeKey: (NSNotification *)notification
|
|||
|
||||
NSTRACE (windowDidBecomeKey);
|
||||
|
||||
emacsframe->output_data.ns->dont_constrain = 1;
|
||||
if (emacsframe != old_focus)
|
||||
dpyinfo->x_focus_frame = emacsframe;
|
||||
|
||||
|
@ -5162,6 +5142,7 @@ - (BOOL)isOpaque
|
|||
|
||||
/*fprintf (stderr,"init with %d, %d\n",f->text_cols, f->text_lines); */
|
||||
|
||||
ns_userRect = NSMakeRect (0, 0, 0, 0);
|
||||
r = NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
|
||||
FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines));
|
||||
[self initWithFrame: r];
|
||||
|
@ -5248,7 +5229,8 @@ - (void)windowDidMove: sender
|
|||
{
|
||||
NSWindow *win = [self window];
|
||||
NSRect r = [win frame];
|
||||
NSScreen *screen = [win screen];
|
||||
NSArray *screens = [NSScreen screens];
|
||||
NSScreen *screen = [screens objectAtIndex: 0];
|
||||
|
||||
NSTRACE (windowDidMove);
|
||||
|
||||
|
@ -5268,10 +5250,7 @@ - (void)windowDidMove: sender
|
|||
location so set_window_size moves the frame. */
|
||||
- (BOOL)windowShouldZoom: (NSWindow *)sender toFrame: (NSRect)newFrame
|
||||
{
|
||||
NSTRACE (windowShouldZoom);
|
||||
emacsframe->left_pos = (int)newFrame.origin.x;
|
||||
emacsframe->top_pos = [[sender screen] frame].size.height
|
||||
- (newFrame.origin.y+newFrame.size.height);
|
||||
emacsframe->output_data.ns->zooming = 1;
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
@ -5283,7 +5262,6 @@ - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
|
|||
defaultFrame:(NSRect)defaultFrame
|
||||
{
|
||||
NSRect result = [sender frame];
|
||||
static NSRect ns_userRect = { 0, 0, 0, 0 };
|
||||
|
||||
NSTRACE (windowWillUseStandardFrame);
|
||||
|
||||
|
@ -5301,7 +5279,11 @@ - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
|
|||
> FRAME_COLUMN_WIDTH (emacsframe))
|
||||
result = defaultFrame; /* second click */
|
||||
else
|
||||
result = ns_userRect.size.height ? ns_userRect : result; /* restore */
|
||||
{
|
||||
/* restore */
|
||||
result = ns_userRect.size.height ? ns_userRect : result;
|
||||
ns_userRect = NSMakeRect (0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
[self windowWillResize: sender toSize: result.size];
|
||||
|
@ -5686,9 +5668,25 @@ - (void) setRows: (int) r andColumns: (int) c
|
|||
|
||||
@implementation EmacsWindow
|
||||
|
||||
/* If we have multiple monitors, one above the other, we don't want to
|
||||
restrict the height to just one monitor. So we override this. */
|
||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
|
||||
{
|
||||
/* When making the frame visible for the first time, we want to
|
||||
constrain. Other times not. */
|
||||
struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
|
||||
if (f->output_data.ns->dont_constrain)
|
||||
return frameRect;
|
||||
|
||||
return [super constrainFrameRect:frameRect toScreen:screen];
|
||||
}
|
||||
|
||||
|
||||
/* called only on resize clicks by special case in EmacsApp-sendEvent */
|
||||
- (void)mouseDown: (NSEvent *)theEvent
|
||||
{
|
||||
struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
|
||||
f->output_data.ns->dont_constrain = 1;
|
||||
if (ns_in_resize)
|
||||
{
|
||||
NSSize size = [[theEvent window] frame].size;
|
||||
|
@ -5731,12 +5729,9 @@ - (void)mouseDragged: (NSEvent *)theEvent
|
|||
return;
|
||||
|
||||
vettedSize = [[self delegate] windowWillResize: self toSize: size];
|
||||
if (vettedSize.width != size.width || vettedSize.height != size.height)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: NSWindowDidResizeNotification
|
||||
object: self];
|
||||
}
|
||||
}
|
||||
else
|
||||
[super mouseDragged: theEvent];
|
||||
|
|
Loading…
Add table
Reference in a new issue