From 75c27828600e43bfe55f092510ae34693fb1e8c2 Mon Sep 17 00:00:00 2001 From: Talon Date: Thu, 18 Jun 2026 17:35:14 +0200 Subject: [PATCH] fix(macos): fix split view layout so panels are visible and VoiceOver-reachable The main window's NSSplitView panels (channel list, user list, chat, activity log) were collapsing to zero size because: 1. The scroll views inside the split views were missing translatesAutoresizingMaskIntoConstraints = false, so Auto Layout couldn't manage their sizes. 2. The inner split views were also missing it. 3. The voice panel had no height constraint, so it expanded to fill all available space (539px of the 600px window), starving the outer split view down to 1px tall. 4. The split views had no initial divider positions, so panels collapsed to zero even when the split view had space. Add translatesAutoresizingMaskIntoConstraints = false to all four scroll views and both inner split views, give the voice panel a 96px height constraint, and set initial divider positions after the window is on screen. The panels now get reasonable space, are visible on screen, and are reachable by VoiceOver. --- .../Windows/MainWindowController.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/clients/apple/macOS/VoiceCatMac/Windows/MainWindowController.swift b/clients/apple/macOS/VoiceCatMac/Windows/MainWindowController.swift index f8f524d..de5446a 100644 --- a/clients/apple/macOS/VoiceCatMac/Windows/MainWindowController.swift +++ b/clients/apple/macOS/VoiceCatMac/Windows/MainWindowController.swift @@ -125,6 +125,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { let innerSplit = NSSplitView() innerSplit.isVertical = false innerSplit.dividerStyle = .thin + innerSplit.translatesAutoresizingMaskIntoConstraints = false let channelPanel = buildChannelPanel() let userPanel = buildUserPanel() @@ -137,6 +138,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { let rightSplit = NSSplitView() rightSplit.isVertical = false rightSplit.dividerStyle = .thin + rightSplit.translatesAutoresizingMaskIntoConstraints = false let chatPanel = buildChatPanel() let activityPanel = buildActivityPanel() rightSplit.addArrangedSubview(chatPanel) @@ -178,6 +180,17 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { composeBar.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), composeBar.heightAnchor.constraint(equalToConstant: 36), ]) + + // Set initial divider positions so panels get reasonable space instead of + // collapsing to zero. These are applied after the window is on screen. + DispatchQueue.main.async { [weak self, weak outerSplit, weak innerSplit, weak rightSplit] in + // outerSplit is vertical (left|right): divide at 40% from left + outerSplit?.setPosition(360, ofDividerAt: 0) + // innerSplit is horizontal (channels on top, users below): divide at 60% from top + innerSplit?.setPosition(260, ofDividerAt: 0) + // rightSplit is horizontal (chat on top, activity below): divide at 70% from top + rightSplit?.setPosition(280, ofDividerAt: 0) + } } private func buildChannelPanel() -> NSView { @@ -195,6 +208,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { sv.documentView = channelOutlineView sv.hasVerticalScroller = true sv.borderType = .noBorder + sv.translatesAutoresizingMaskIntoConstraints = false let menu = NSMenu() menu.delegate = self @@ -221,6 +235,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { sv.documentView = userTableView sv.hasVerticalScroller = true sv.borderType = .noBorder + sv.translatesAutoresizingMaskIntoConstraints = false return sv } @@ -233,6 +248,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { sv.documentView = chatTextView sv.hasVerticalScroller = true sv.borderType = .noBorder + sv.translatesAutoresizingMaskIntoConstraints = false return sv } @@ -248,6 +264,7 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { sv.documentView = activityTableView sv.hasVerticalScroller = true sv.borderType = .noBorder + sv.translatesAutoresizingMaskIntoConstraints = false return sv } @@ -365,6 +382,8 @@ final class MainWindowController: NSWindowController, NSWindowDelegate { levelMeter.widthAnchor.constraint(equalToConstant: 100), devicePicker.widthAnchor.constraint(greaterThanOrEqualToConstant: 160), + + panel.heightAnchor.constraint(equalToConstant: 96), ]) return panel }