Skip to content

Commit 5eaed9a

Browse files
committed
Clean up Joystick parent-child on red-X dismissal
JoystickConfigurationController previously did its parent-child teardown in -cancel:, leaving the red-X dismissal path (and the Preferences-close cascade) without a removeChildWindow:. The stale relationship was reconciled on the next showWindow: by the parent check, so the bug was invisible in practice — but the asymmetry diverged from the close-path matrix in spec 004 which mandates a single teardown hook for every closable-with-pause-or-parent panel. Add an NSWindowWillCloseNotification observer in showWindow:; route the unpin through handleWillClose: so every dismissal path (Apply, Cancel, red X, Preferences close cascade) does the same teardown. Joystick is the only utility window whose showWindow: can run a second time without an intervening close: re-clicking Configure for the other joystick reuses the same instance, switching contents via sender's tag. The spec explicitly disallows a singleton early-return guard here. To keep observer registration idempotent across that switch, remove any prior registration before adding.
1 parent 7d2224b commit 5eaed9a

1 file changed

Lines changed: 29 additions & 1 deletion

File tree

fusepb/controllers/JoystickConfigurationController.m

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,24 @@ - (IBAction)apply:(id)sender;
154154

155155
- (IBAction)cancel:(id)sender
156156
{
157-
[[self window] unpinFromParent];
157+
/* All dismissal paths (Apply, Cancel, red X, Preferences close
158+
cascade) funnel through handleWillClose: via the
159+
NSWindowWillCloseNotification observer registered in showWindow:,
160+
so this just closes the window and lets the observer do the
161+
parent-child teardown. */
158162
[[self window] close];
159163
}
160164

165+
- (void)handleWillClose:(NSNotification *)note
166+
{
167+
[[NSNotificationCenter defaultCenter]
168+
removeObserver:self
169+
name:@"NSWindowWillCloseNotification"
170+
object:[self window]];
171+
172+
[[self window] unpinFromParent];
173+
}
174+
161175
- (void)showWindow:(id)sender
162176
{
163177
size_t i;
@@ -176,6 +190,20 @@ - (void)showWindow:(id)sender
176190
enforces z-order for two windows at the same level. */
177191
[[self window] pinAsChildOf:parent];
178192

193+
/* Register the close observer here. Joystick is reused across Joy1
194+
and Joy2 invocations on the same open window (the spec disallows a
195+
singleton early-return guard for that reason), so showWindow: may
196+
run a second time without an intervening close — remove any prior
197+
registration before adding to keep this idempotent. */
198+
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
199+
[nc removeObserver:self
200+
name:@"NSWindowWillCloseNotification"
201+
object:[self window]];
202+
[nc addObserver:self
203+
selector:@selector(handleWillClose:)
204+
name:@"NSWindowWillCloseNotification"
205+
object:[self window]];
206+
179207
[joyXAxis removeAllItems];
180208
[joyYAxis removeAllItems];
181209

0 commit comments

Comments
 (0)