Fix child frame restacking on NS (bug#41422)

* src/nsfns.m (Fns_frame_restack): Use new restackWindow method.
* src/nsterm.m ([EmacsWindow orderFront:]):
([EmacsWindow makeKeyAndOrderFront:]):
(nswindow_orderedIndex_sort):
([EmacsWindow orderBack:]):
([EmacsWindow restackWindow:above:]): Override superclass methods to
handle child windows the way we want.
This commit is contained in:
Alan Third 2021-01-03 16:15:18 +00:00
parent 825b4ec338
commit ad2567fb1e
3 changed files with 114 additions and 7 deletions

View file

@ -1485,14 +1485,14 @@ Frames are listed from topmost (first) to bottommost (last). */)
if (FRAME_NS_VIEW (f1) && FRAME_NS_VIEW (f2))
{
NSWindow *window = [FRAME_NS_VIEW (f1) window];
NSInteger window2 = [[FRAME_NS_VIEW (f2) window] windowNumber];
NSWindowOrderingMode flag = NILP (above) ? NSWindowBelow : NSWindowAbove;
EmacsWindow *window = (EmacsWindow *)[FRAME_NS_VIEW (f1) window];
NSWindow *window2 = [FRAME_NS_VIEW (f2) window];
BOOL flag = !NILP (above);
[window orderWindow: flag
relativeTo: window2];
return Qt;
if ([window restackWindow:window2 above:!NILP (above)])
return Qt;
else
return Qnil;
}
else
{

View file

@ -498,6 +498,7 @@ typedef id instancetype;
NSPoint grabOffset;
}
- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above;
- (void)setAppearance;
@end

View file

@ -8693,6 +8693,112 @@ - (int) fullscreenState
@implementation EmacsWindow
/* It seems the only way to reorder child frames is by removing them
from the parent and then reattaching them in the correct order. */
- (void)orderFront:(id)sender
{
NSTRACE ("[EmacsWindow orderFront:]");
NSWindow *parent = [self parentWindow];
if (parent)
{
[parent removeChildWindow:self];
[parent addChildWindow:self ordered:NSWindowAbove];
}
else
[super orderFront:sender];
}
- (void)makeKeyAndOrderFront:(id)sender
{
NSTRACE ("[EmacsWindow makeKeyAndOrderFront:]");
if ([self parentWindow])
{
[self orderFront:sender];
[self makeKeyWindow];
}
else
[super makeKeyAndOrderFront:sender];
}
/* The array returned by [NSWindow parentWindow] may already be
sorted, but the documentation doesn't tell us whether or not it is,
so to be safe we'll sort it. */
NSInteger nswindow_orderedIndex_sort (id w1, id w2, void *c)
{
NSInteger i1 = [w1 orderedIndex];
NSInteger i2 = [w2 orderedIndex];
if (i1 > i2)
return NSOrderedAscending;
if (i1 < i2)
return NSOrderedDescending;
return NSOrderedSame;
}
- (void)orderBack:(id)sender
{
NSTRACE ("[EmacsWindow orderBack:]");
NSWindow *parent = [self parentWindow];
if (parent)
{
NSArray *children = [[parent childWindows]
sortedArrayUsingFunction:nswindow_orderedIndex_sort
context:nil];
[parent removeChildWindow:self];
[parent addChildWindow:self ordered:NSWindowAbove];
for (NSWindow *win in children)
{
if (win != self)
{
[parent removeChildWindow:win];
[parent addChildWindow:win ordered:NSWindowAbove];
}
}
}
else
[super orderBack:sender];
}
- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above
{
NSTRACE ("[EmacsWindow restackWindow:above:]");
/* If parent windows don't match we can't restack these frames
without changing the parents. */
if ([self parentWindow] != [win parentWindow])
return NO;
else if (![self parentWindow])
[self orderWindow:(above ? NSWindowAbove : NSWindowBelow)
relativeTo:[win windowNumber]];
else
{
NSInteger index;
NSWindow *parent = [self parentWindow];
NSMutableArray *children = [[[parent childWindows]
sortedArrayUsingFunction:nswindow_orderedIndex_sort
context:nil]
mutableCopy];
[children removeObject:self];
index = [children indexOfObject:win];
[children insertObject:self atIndex:(above ? index+1 : index)];
for (NSWindow *w in children)
{
[parent removeChildWindow:w];
[parent addChildWindow:w ordered:NSWindowAbove];
}
}
return YES;
}
#ifdef NS_IMPL_COCOA
- (id)accessibilityAttributeValue:(NSString *)attribute
{