From 888bd602ca566a97d6e5a17cd8e2b702fc909fd2 Mon Sep 17 00:00:00 2001 From: Xiao Date: Fri, 10 Apr 2026 17:00:21 +0200 Subject: [PATCH 1/4] Fix unit visibility change not propagating to other views `get_visible_unit_ids()` returned a direct reference to the internal `_visible_unit_ids` list. Callers that snapshot the list before and after `set_unit_visibility()` to detect changes were comparing the same mutated object, so the comparison always found no difference and never triggered `notify_unit_visibility_changed()`. Return a copy instead so before/after comparisons work correctly. Co-Authored-By: Claude Opus 4.6 (1M context) --- spikeinterface_gui/controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spikeinterface_gui/controller.py b/spikeinterface_gui/controller.py index 3ddea2d..e150888 100644 --- a/spikeinterface_gui/controller.py +++ b/spikeinterface_gui/controller.py @@ -600,7 +600,7 @@ def set_visible_unit_ids(self, visible_unit_ids): def get_visible_unit_ids(self): """Get list of visible unit_ids""" - return self._visible_unit_ids + return list(self._visible_unit_ids) def get_visible_unit_indices(self): """Get list of indices of visible units""" From 02c60c7748f511469469c17d85d557142360ce87 Mon Sep 17 00:00:00 2001 From: Xiao Date: Tue, 14 Apr 2026 16:39:55 +0200 Subject: [PATCH 2/4] Equalize dock zone sizes on startup Dock widgets created by splitDockWidget() have uneven default sizes. Add a showEvent hook that calls resizeDocks() with equal weights after the window is visible, so all zones start proportionally sized. Co-Authored-By: Claude Opus 4.6 --- spikeinterface_gui/backend_qt.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/spikeinterface_gui/backend_qt.py b/spikeinterface_gui/backend_qt.py index d106a38..7db8797 100644 --- a/spikeinterface_gui/backend_qt.py +++ b/spikeinterface_gui/backend_qt.py @@ -255,6 +255,19 @@ def create_main_layout(self): # make visible the first of each zone self.docks[view_name0].raise_() + def showEvent(self, event): + super().showEvent(event) + if not hasattr(self, '_splitters_equalized'): + self._splitters_equalized = True + QT.QTimer.singleShot(100, self._equalize_splitters) + + def _equalize_splitters(self): + all_docks = [dock for dock in self.docks.values() if dock.isVisible()] + if all_docks: + size_weight = 1 + self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Horizontal) + self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Vertical) + def make_half_layout(self, widgets_zone, left_or_right): """ Function contains the logic for the greedy layout. Given the 2x2 box of zones From f0673f9866952523a3fdacb9dcc39465ac3534bd Mon Sep 17 00:00:00 2001 From: Xiao Date: Tue, 14 Apr 2026 16:51:14 +0200 Subject: [PATCH 3/4] Use processEvents instead of timer for dock equalization Replace QTimer.singleShot(100ms) hack with QApplication.processEvents() to flush pending layout events synchronously before calling resizeDocks. Deterministic and avoids arbitrary delay. Co-Authored-By: Claude Opus 4.6 --- spikeinterface_gui/backend_qt.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/spikeinterface_gui/backend_qt.py b/spikeinterface_gui/backend_qt.py index 7db8797..1d4aaaa 100644 --- a/spikeinterface_gui/backend_qt.py +++ b/spikeinterface_gui/backend_qt.py @@ -259,14 +259,12 @@ def showEvent(self, event): super().showEvent(event) if not hasattr(self, '_splitters_equalized'): self._splitters_equalized = True - QT.QTimer.singleShot(100, self._equalize_splitters) - - def _equalize_splitters(self): - all_docks = [dock for dock in self.docks.values() if dock.isVisible()] - if all_docks: - size_weight = 1 - self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Horizontal) - self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Vertical) + QT.QApplication.processEvents() + all_docks = [dock for dock in self.docks.values() if dock.isVisible()] + if all_docks: + size_weight = 1 + self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Horizontal) + self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Vertical) def make_half_layout(self, widgets_zone, left_or_right): """ From d04957e0b02875fd7ea00ee892ed04f57690605f Mon Sep 17 00:00:00 2001 From: xiao-1011 Date: Wed, 15 Apr 2026 19:51:11 +0200 Subject: [PATCH 4/4] Fix dock equalization not working on macOS Replace synchronous processEvents() + resizeDocks() with a deferred QTimer.singleShot(0) call. On macOS, the Cocoa window system performs a layout pass after Qt's showEvent, overwriting sizes set synchronously. The deferred call ensures resizeDocks runs after the native layout completes. Co-Authored-By: Claude Opus 4.6 (1M context) --- spikeinterface_gui/backend_qt.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/spikeinterface_gui/backend_qt.py b/spikeinterface_gui/backend_qt.py index 1d4aaaa..9adda83 100644 --- a/spikeinterface_gui/backend_qt.py +++ b/spikeinterface_gui/backend_qt.py @@ -259,12 +259,18 @@ def showEvent(self, event): super().showEvent(event) if not hasattr(self, '_splitters_equalized'): self._splitters_equalized = True - QT.QApplication.processEvents() - all_docks = [dock for dock in self.docks.values() if dock.isVisible()] - if all_docks: - size_weight = 1 - self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Horizontal) - self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Vertical) + # On macOS, the native Cocoa window system performs a layout pass after + # Qt's showEvent, overwriting any sizes set synchronously. A deferred + # call via QTimer.singleShot ensures resizeDocks runs after both Qt and + # the macOS window server have finished laying out the docks. + QT.QTimer.singleShot(0, self._equalize_dock_sizes) + + def _equalize_dock_sizes(self): + all_docks = [dock for dock in self.docks.values() if dock.isVisible()] + if all_docks: + size_weight = 1 + self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Horizontal) + self.resizeDocks(all_docks, [size_weight] * len(all_docks), QT.Qt.Vertical) def make_half_layout(self, widgets_zone, left_or_right): """