diff --git a/ChangeLog b/ChangeLog index ec355eaf8..093827c63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-06-27 Marcian Lytwyn + + * Source/NSWindow.m - Fix [NSWindow screen] method according + to documented behavior (return screen that window show up + the most or nil). Fix [NSWindow setFrameFromString] to account for + possible nil screen on input frame and throw window on main screen + in this case. This is to fix an issue with windows not properly + showing up when moved to another monitor during multi-monitor + usage and then the extra monitor(s) are removed. + * Source/NSScreen.m - Added -description method for more information. + 2012-06-27 Marcian Lytwyn *** NSOpenSavePanelDelegate *** diff --git a/Source/NSScreen.m b/Source/NSScreen.m index 075f5e560..7270100b7 100644 --- a/Source/NSScreen.m +++ b/Source/NSScreen.m @@ -119,6 +119,7 @@ static NSMutableArray *screenArray = nil; [screenArray addObject: screen]; RELEASE(screen); } + NSLog(@"NSScreen:screens: %@", screenArray); return [NSArray arrayWithArray: screenArray]; } @@ -258,6 +259,15 @@ static NSMutableArray *screenArray = nil; return _frame; } +- (NSString*)description +{ + NSMutableString *description = [NSMutableString stringWithString:[super description]]; + [description appendFormat:@"number: %ld\n",(long)_screenNumber]; + [description appendFormat:@"frame: %@\n",NSStringFromRect(_frame)]; + return([[description copy] autorelease]); +} + + /** *

* This method generates a dictionary containing information diff --git a/Source/NSWindow.m b/Source/NSWindow.m index 2881799af..a4d818057 100644 --- a/Source/NSWindow.m +++ b/Source/NSWindow.m @@ -164,6 +164,7 @@ static GSWindowAnimationDelegate *animationDelegate; - (void) _lossOfKeyOrMainWindow; - (NSView *) _windowView; +- (NSScreen *) _screenForFrame:(NSRect)frame; @end @implementation NSWindow (GNUstepPrivate) @@ -378,12 +379,40 @@ has blocked and waited for events. { return _wv; } - + +/* Support method to properly implement the 'screen' method for NSWindow. + According to documentation the 'screen' method should return the screen + that the window "show up the most or nil". This method supports the 'screen' + method and internal requests for the correct 'screen' based on the + supplied frame request. +*/ +- (NSScreen *) _screenForFrame:(NSRect)frame +{ + NSInteger largest = 0; + NSArray *screens = [NSScreen screens]; + NSInteger index = 0; + NSScreen *theScreen = nil; + for (index = 0; index < [screens count]; ++index) + { + NSScreen *screen = [screens objectAtIndex:index]; + NSRect sframe = [screen frame]; + NSRect iframe = NSIntersectionRect(frame, sframe); + NSInteger isize = NSWidth(iframe) * NSHeight(iframe); + if (isize > largest) + { + largest = isize; + theScreen = screen; + } + } + NSDebugLLog(@"NSWindow", @"%s: frame: %@ screen: %@ size: %ld\n", __PRETTY_FUNCTION__, + NSStringFromRect(frame), theScreen, (long)largest); + + return theScreen; +} + @end - - @interface NSMiniWindow : NSWindow @end @@ -1073,9 +1102,9 @@ many times. if (style == NSWindows95InterfaceStyle) { if([self canBecomeMainWindow]) - { - [self setMenu: [NSApp mainMenu]]; - } + { + [self setMenu: [NSApp mainMenu]]; + } } NSDebugLLog(@"NSWindow", @"NSWindow end of init\n"); @@ -2553,6 +2582,7 @@ many times. /** Returns the screen the window is on. */ - (NSScreen *) screen { + ASSIGN(_screen, [self _screenForFrame:_frame]); return _screen; } @@ -4638,11 +4668,13 @@ current key view.
/* * Check that the window will come up on screen */ +#if 0 // Not valid since screen frame x/y values can be negative... if (fRect.origin.x + fRect.size.width < 0) { NSLog(@"Bad screen frame - window is off screen"); - return; + return; } +#endif // if toolbar is showing, adjust saved frame to add the toolbar back in if ([_toolbar isVisible]) @@ -4694,8 +4726,19 @@ current key view.
* The screen rectangle gives the area of the screen in which * the window could be placed (ie a rectangle excluding the dock). */ - nRect = [[self screen] visibleFrame]; - + NSScreen *screen = [self _screenForFrame:fRect]; + + // Check whether a portion is showing somewhere... + if (screen == nil) + { + // If the window doesn't show up on any screen then we need + // to move it so it can be seen and assign it to the main + // screen... + screen = [NSScreen mainScreen]; + NSDebugLLog(@"NSWindow", @"%s: re-assigning to main screen\n", __PRETTY_FUNCTION__); + } + nRect = [screen visibleFrame]; + /* * If the new screen drawable area has moved relative to the one in * which the window was saved, adjust the window position accordingly. @@ -4725,9 +4768,9 @@ current key view.
* If height of the window goes above the screen height, then adjust the window down. */ if ((fRect.size.height + fRect.origin.y) > nRect.size.height) - { - fRect.origin.y = nRect.size.height - fRect.size.height; - } + { + fRect.origin.y = nRect.size.height - fRect.size.height; + } } // FIXME: Is this check needed? @@ -4745,6 +4788,9 @@ current key view.
} } + // Make sure we are using the new screen we are applying to... + ASSIGN(_screen, screen); + /* * Set frame. */ @@ -4804,12 +4850,15 @@ current key view.
* the window could be placed (ie a rectangle excluding the dock). */ sRect = [[self screen] visibleFrame]; + NSString *autosaveString = [NSString stringWithFormat: @"%d %d %d %d %d %d % d %d ", + (int)fRect.origin.x, (int)fRect.origin.y, + (int)fRect.size.width, (int)fRect.size.height, + (int)sRect.origin.x, (int)sRect.origin.y, + (int)sRect.size.width, (int)sRect.size.height]; + NSDebugLLog(@"NSWindow", @"%s:autosaveName: %@ frame string: %@", __PRETTY_FUNCTION__, + _autosaveName, autosaveString); - return [NSString stringWithFormat: @"%d %d %d %d %d %d % d %d ", - (int)fRect.origin.x, (int)fRect.origin.y, - (int)fRect.size.width, (int)fRect.size.height, - (int)sRect.origin.x, (int)sRect.origin.y, - (int)sRect.size.width, (int)sRect.size.height]; + return autosaveString; } /*