Skip to content

Commit b6efc8a

Browse files
authored
Fix non-native macOS cursor (#14101)
1 parent 0b56ea2 commit b6efc8a

2 files changed

Lines changed: 14 additions & 40 deletions

File tree

mne/viz/backends/_qt.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@
131131
os.environ.setdefault("QT_MAC_WANTS_LAYER", "1")
132132

133133

134+
def _qcursor(name):
135+
# map to a native name on macOS (instead of using Qt pixmap)
136+
if sys.platform == "darwin" and name in ("WaitCursor", "BusyCursor"):
137+
name = "ForbiddenCursor"
138+
return QCursor(getattr(Qt, name))
139+
140+
134141
# fix for qscroll needing two layouts, one parent, one child
135142
def _get_layout(layout):
136143
if hasattr(layout, "_parent_layout"):
@@ -885,7 +892,7 @@ def func(button):
885892
button_id = widget.standardButton(button)
886893
for button_name in _QtDialog.supported_button_names:
887894
if button_id == getattr(QMessageBox, button_name):
888-
widget.setCursor(QCursor(Qt.WaitCursor))
895+
widget.setCursor(_qcursor("WaitCursor"))
889896
try:
890897
callback(button_name)
891898
finally:
@@ -1610,7 +1617,7 @@ def _window_set_cursor(self, cursor):
16101617
self._window.setCursor(cursor)
16111618

16121619
def _window_new_cursor(self, name):
1613-
return QCursor(getattr(Qt, name))
1620+
return _qcursor(name)
16141621

16151622
@contextmanager
16161623
def _window_ensure_minimum_sizes(self):

tools/github_actions_test.sh

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,16 @@
33
set -eo pipefail
44

55
if [[ "${CI_OS_NAME}" == "ubuntu"* ]]; then
6-
CONDITIONS=("not (ultraslowtest or pgtest)")
6+
CONDITION="not (ultraslowtest or pgtest)"
77
elif [[ "${CI_OS_NAME}" == "macos"* ]]; then
88
# detect arch and run slowtest on arm64 only (pgtest is already ultraslow on macOS)
99
if [[ "$(uname -m)" == "arm64" ]]; then
10-
# Split the PyVista/VTK ("pvtest") tests into their own xdist invocation.
11-
# Run all together, a worker that accumulates heavy state (loky pools,
12-
# leftover ipykernel/jupyter_client asyncio loops, tqdm monitors) creates
13-
# the scheduling jitter that trips an xdist loadscope dispatch deadlock at
14-
# end-of-run: workers idle in TestQueue.get, controller loops forever in
15-
# dsession.loop_once without dispatching the remaining scopes or SHUTDOWN
16-
# (see pytest-xdist#1313). Two shorter, lighter invocations avoid it while
17-
# keeping parallelism; pvtest alone under xdist does not hang.
18-
CONDITIONS=("not (ultraslowtest or pgtest or pvtest)" "pvtest and not ultraslowtest")
10+
CONDITION="not (ultraslowtest or pgtest)"
1911
else
20-
CONDITIONS=("not (slowtest or pgtest)")
12+
CONDITION="not (slowtest or pgtest)"
2113
fi
2214
elif [[ "${CI_OS_NAME}" == "windows"* ]]; then
23-
CONDITIONS=("not (slowtest or pgtest)")
15+
CONDITION="not (slowtest or pgtest)"
2416
else
2517
echo "✕ ERROR: Unrecognized CI_OS_NAME=${CI_OS_NAME}"
2618
exit 1
@@ -53,29 +45,4 @@ if [[ ! -z "$CONDA_ENV" ]] && [[ "${CI_OS_NAME}" != "windows"* ]] && [[ "${MNE_C
5345
fi
5446

5547
# $COV_ARGS is set in github_actions_env_vars.sh (coverage only on Python >= 3.14)
56-
# Run each marker expression as its own pytest invocation (usually just one; on
57-
# macOS arm64 the pvtest tests are split out, see above). Later runs append
58-
# coverage, each gets its own junit file, and we run them all before exiting
59-
# with the first nonzero code so one failing split does not mask the other.
60-
set +e # capture each pytest's exit code manually rather than aborting on it
61-
CODE=0
62-
COV_APPEND=""
63-
i=0
64-
for CONDITION in "${CONDITIONS[@]}"; do
65-
if [ "${#CONDITIONS[@]}" -gt 1 ]; then
66-
THIS_JUNIT="${JUNIT_PATH%.xml}-${i}.xml"
67-
else
68-
THIS_JUNIT="$JUNIT_PATH"
69-
fi
70-
set -x
71-
pytest -m "${CONDITION}" -n "$PYTEST_XDIST_N" --dist loadscope --timeout=120 --timeout-method=thread -o faulthandler_timeout=110 ${COV_ARGS} ${COV_APPEND} --color=yes --continue-on-collection-errors --junit-xml="$THIS_JUNIT" -vv ${USE_DIRS}
72-
THIS_CODE=$?
73-
set +x
74-
echo "Exited with code $THIS_CODE for: ${CONDITION}"
75-
if [ "$THIS_CODE" -ne 0 ] && [ "$CODE" -eq 0 ]; then
76-
CODE=$THIS_CODE
77-
fi
78-
COV_APPEND="--cov-append"
79-
i=$((i + 1))
80-
done
81-
exit $CODE
48+
pytest -m "${CONDITION}" -n "$PYTEST_XDIST_N" --dist loadscope --timeout=120 --timeout-method=thread -o faulthandler_timeout=110 ${COV_ARGS} --color=yes --continue-on-collection-errors --junit-xml="$JUNIT_PATH" -vv ${USE_DIRS}

0 commit comments

Comments
 (0)