From dc62b82900ffb30cf4f144056044053d74c53b86 Mon Sep 17 00:00:00 2001 From: Hz_Zhang <47402297+HaozheZhang6@users.noreply.github.com> Date: Sat, 11 Jul 2026 19:30:12 -0700 Subject: [PATCH 1/4] Widen dock separators to make them easier to grab (#277) --- cq_editor/main_window.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cq_editor/main_window.py b/cq_editor/main_window.py index bece4094..ab725b75 100644 --- a/cq_editor/main_window.py +++ b/cq_editor/main_window.py @@ -100,6 +100,11 @@ def __init__(self, parent=None, filename=None): self.viewer = OCCViewer(self) self.setCentralWidget(self.viewer.canvas) + # Widen the dock separators so they are easy to grab. The default handle + # is only a couple of pixels wide, which is very hard to hit on macOS / + # high-DPI displays (#277). + self.setStyleSheet("QMainWindow::separator { width: 6px; height: 6px; }") + self.prepare_panes() self.registerComponent("viewer", self.viewer) self.prepare_toolbar() From 608e5a7f0c3791e2e3a01a233e9f4d091f3773e2 Mon Sep 17 00:00:00 2001 From: Haozhe Zhang Date: Wed, 15 Jul 2026 10:48:18 -0700 Subject: [PATCH 2/4] Reword the dock separator comment --- cq_editor/main_window.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cq_editor/main_window.py b/cq_editor/main_window.py index ab725b75..1aa5beca 100644 --- a/cq_editor/main_window.py +++ b/cq_editor/main_window.py @@ -100,9 +100,7 @@ def __init__(self, parent=None, filename=None): self.viewer = OCCViewer(self) self.setCentralWidget(self.viewer.canvas) - # Widen the dock separators so they are easy to grab. The default handle - # is only a couple of pixels wide, which is very hard to hit on macOS / - # high-DPI displays (#277). + # Make sure the dock separators are wide enough to grab on high-DPI displays self.setStyleSheet("QMainWindow::separator { width: 6px; height: 6px; }") self.prepare_panes() From 0474165f2b603201a01ba2cca9b15f375e77b350 Mon Sep 17 00:00:00 2001 From: Hz_Zhang <47402297+HaozheZhang6@users.noreply.github.com> Date: Sun, 19 Jul 2026 09:29:24 -0700 Subject: [PATCH 3/4] Widen the separators with a style proxy instead of a stylesheet A stylesheet on the main window moves its whole widget subtree to QStyleSheetStyle, which drops palette based theming (the syntax highlighting regression seen in review). --- cq_editor/main_window.py | 25 +++++++++++++++++++++++-- tests/test_app.py | 28 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/cq_editor/main_window.py b/cq_editor/main_window.py index 1aa5beca..ba52373b 100644 --- a/cq_editor/main_window.py +++ b/cq_editor/main_window.py @@ -12,6 +12,8 @@ QAction, QApplication, QMenu, + QProxyStyle, + QStyle, ) from logbook import Logger import cadquery as cq @@ -63,6 +65,23 @@ def new_stdout_write(text: str): PRINT_REDIRECTOR = _PrintRedirectorSingleton() +class DockSeparatorStyle(QProxyStyle): + """Widens the dock separators so that they are easier to grab (#277). + + A style proxy is used instead of a stylesheet because setting a stylesheet + on the main window moves its whole widget subtree to QStyleSheetStyle, + which discards palette based theming (e.g. editor syntax highlighting). + """ + + def pixelMetric(self, metric, option=None, widget=None): + + extent = super().pixelMetric(metric, option, widget) + if metric == QStyle.PM_DockWidgetSeparatorExtent: + return max(extent, 6) + + return extent + + class MainWindow(QMainWindow, MainMixin): name = "CQ-Editor" @@ -100,8 +119,10 @@ def __init__(self, parent=None, filename=None): self.viewer = OCCViewer(self) self.setCentralWidget(self.viewer.canvas) - # Make sure the dock separators are wide enough to grab on high-DPI displays - self.setStyleSheet("QMainWindow::separator { width: 6px; height: 6px; }") + # Make sure the dock separators are wide enough to grab on high-DPI displays. + # setStyle does not take ownership, so keep a reference on self. + self._separator_style = DockSeparatorStyle() + self.setStyle(self._separator_style) self.prepare_panes() self.registerComponent("viewer", self.viewer) diff --git a/tests/test_app.py b/tests/test_app.py index 76deda64..3a25db17 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -12,10 +12,11 @@ import cadquery as cq from PyQt5.QtCore import Qt, QSettings, QPoint, QEvent, QSize -from PyQt5.QtWidgets import QFileDialog, QMessageBox +from PyQt5.QtWidgets import QApplication, QFileDialog, QMessageBox, QStyle, QStyleFactory from PyQt5.QtGui import QMouseEvent from cq_editor.__main__ import MainWindow +from cq_editor.main_window import DockSeparatorStyle from cq_editor.widgets.editor import Editor from cq_editor.cq_utils import export, get_occ_color @@ -1708,6 +1709,31 @@ def test_launch_syntax_error(tmp_path): assert win.isVisible() +def test_dock_separator_width(qtbot): + + win = MainWindow() + qtbot.addWidget(win) + + # separators are widened through a style proxy, not a stylesheet: a + # stylesheet on the main window would break palette based theming (#595) + assert win.styleSheet() == "" + assert win.style().pixelMetric(QStyle.PM_DockWidgetSeparatorExtent, None, win) >= 6 + + # child widgets keep the application style + editor = win.components["editor"] + assert editor.style().objectName() == QApplication.instance().style().objectName() + + +def test_dock_separator_style_widens_small_extents(qtbot): + + base = QStyleFactory.create("Windows") + assert base.pixelMetric(QStyle.PM_DockWidgetSeparatorExtent) < 6 + + style = DockSeparatorStyle(base) + + assert style.pixelMetric(QStyle.PM_DockWidgetSeparatorExtent) == 6 + + code_import_module_makebox = """ from module_makebox import * z = 1 From 296b6472be9cb4fc0a81f215d80a26bd97fb8b73 Mon Sep 17 00:00:00 2001 From: Hz_Zhang <47402297+HaozheZhang6@users.noreply.github.com> Date: Fri, 31 Jul 2026 22:31:11 -0700 Subject: [PATCH 4/4] Reuse the main_clean fixture in the separator test --- tests/test_app.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/test_app.py b/tests/test_app.py index 3a25db17..224c7fee 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -12,7 +12,13 @@ import cadquery as cq from PyQt5.QtCore import Qt, QSettings, QPoint, QEvent, QSize -from PyQt5.QtWidgets import QApplication, QFileDialog, QMessageBox, QStyle, QStyleFactory +from PyQt5.QtWidgets import ( + QApplication, + QFileDialog, + QMessageBox, + QStyle, + QStyleFactory, +) from PyQt5.QtGui import QMouseEvent from cq_editor.__main__ import MainWindow @@ -1709,10 +1715,9 @@ def test_launch_syntax_error(tmp_path): assert win.isVisible() -def test_dock_separator_width(qtbot): +def test_dock_separator_width(main_clean): - win = MainWindow() - qtbot.addWidget(win) + qtbot, win = main_clean # separators are widened through a style proxy, not a stylesheet: a # stylesheet on the main window would break palette based theming (#595)