[Bug] `nullmoth-wsreset.sh` never restarts WindowServer at the real login window: `/dev/console` is `_windowserver`, not `root` (guard + test blind spot)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
Research direction
Read app/Resources/nullmoth-setup.sh around lines 1319–1325 and tools/test_wsreset_login.py; the issue identifies both the guard and the missing test case. Run the login-window tests with the stat stub returning _windowserver, then check the auto-login and logged-in-user cases. Done means the login-window owner triggers one restart while those two cases still skip.
Written by the indexing model from the issue text.
Description
[Bug] nullmoth-wsreset.sh never restarts WindowServer at the real login window: /dev/console is _windowserver, not root (guard + test blind spot)
What happens
The 1.4 flicker stopgap (/Library/NullMoth/nullmoth-wsreset.sh) is meant to restart the first
WindowServer of a boot, so the user logs into a clean compositor. On macOS 15.8.1 it mostly does
nothing, because the "is somebody already logged in?" guard compares /dev/console's owner against
root — and at the login window that owner is _windowserver. The guard therefore fires when nobody
is logged in, and the stopgap exits without restarting anything.
Evidence — real machine, driver 1.13.0, macOS 15.8.1 (24H32)
/Library/NullMoth/wsreset.log, same machine, same day:
303: 12:48:10 restarted WindowServer once; before/after captured above <- console was root: worked
353: 12:56:32 skipped the restart: _windowserver is already logged in <- nobody logged in: race lost
363: 13:07:27 skipped the restart: hq is already logged in <- correct skip (a user really was in)
380: 13:14:34 restarted WindowServer once; before/after captured above <- worked
430: 13:17:58 skipped the restart: _windowserver is already logged in <- race lost
480: 13:32:34 skipped the restart: _windowserver is already logged in <- race lost
Two restarts, three false skips, one legitimate skip — a coin flip, not a stopgap.
Code (main, app/Resources/nullmoth-setup.sh, ~1319-1325)
CONSOLE=$(stat -f%Su /dev/console 2>/dev/null)
...
if [ -n "$CONSOLE" ] && [ "$CONSOLE" != root ]; then
echo "$(date) skipped the restart: $CONSOLE is already logged in" >> "$LOG" 2>&1; exit 0
fi
Why the test suite does not catch it
tools/test_wsreset_login.py runs the real script body with a stat stub, for exactly three cases:
def test_at_the_login_window_it_restarts_once(self): run("root") -> restarts
def test_auto_login_is_never_interrupted(self): run("root", autologin="jake") -> skips
def test_a_logged_in_user_is_never_logged_out(self): run("jake") -> skips
There is no case for the value the real login window actually reports (_windowserver), so the suite
stays green while the stopgap is ineffective on the machines that need it.
Suggested fix
Accept _windowserver as "nobody is logged in":
if [ -n "$CONSOLE" ] && [ "$CONSOLE" != root ] && [ "$CONSOLE" != _windowserver ]; then
and add the missing case:
def test_login_window_owned_by_windowserver_still_restarts(self):
rc, log = run("_windowserver")
self.assertIn("restarted WindowServer once", log)
Verified here with the one-line change only: bash -n passes, the auto-login and logged-in-user paths
are untouched, and the stopgap keeps its once-per-boot marker.
Why it matters
Until the hand-off strobe itself is fixed (see #101, #122, #16, #26), this stopgap is the only
mitigation there is. When the guard loses the race, the user's whole session keeps flickering or stays
black-with-a-cursor, and the only way out is a manual sudo kill -9 $(pgrep -x WindowServer) — which
is also worth knowing: on 15.8.1 killall WindowServer (SIGTERM) does not replace the compositor
(same pid, same start time, only the graphical session ends); kill -9 does.
Also seen on the same machine (short, in case it helps the hand-off work)
- During a strobe the flip path looks healthy but AGDC does not:
iop_fail=0 iop_flip_refused=0 iop_flip_stale=0 iop_flip_miss=6whileagdc_cmds=145 agdc_refused=117 agdc_last_refused=1809
(frozen). Everyagdc_*counter was0at tracker start earlier the same day (fbmap: never scanned), so the path degrades after the take-over.nvrm-barshere is
bar1@0x14:0xfa00000000+0x200000000(8 GB — the large-BAR side of the family in #127), and
nvrm-flip = "on". - A
-nvoffboot makes the stopgap's capture blocks come out empty, yet it still logs "restarted
WindowServer once; before/after captured above". - (The tracker itself not starting is #108 — seen here too, not re-reported.)
Environment
macOS 15.8.1 (24H32), Darwin 24.6.0 x86_64, SMBIOS MacPro7,1, Ryzen 9 9955HX, NVIDIA RTX 5060 Laptop
8 GB (0x2d59) plus an AMD iGPU, internal eDP panel 2560x1600 @165 Hz (BOE NE160QDM-NYM), driver
1.13.0 / app 1.13.0, boot-args:
nvfb=1 nvaccel=1 nvfbheads=4 -nvkmsnosmooth -v debug=0x100 keepsyms=1 -vi2c-force-polling amfi_get_out_of_my_way=0x1 amfi=0x80 ipc_control_port_options=0 npci=0x2000
Note: the reporter is still on 1.13.0 and will update to 1.14.1, but the guard above is unchanged on
main, so the update does not fix this one.
- Dominant language
- Rust
- Stars
- 2.5k
- Forks
- 233
- PR merge metrics
- No merged PRs in 30d
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from nullmoth/nvidia-macos-driver
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
nullmoth/nvidia-macos-driver#126 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
nullmoth/nvidia-macos-driver#108 · 6 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
nullmoth/nvidia-macos-driver#28 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
nullmoth/nvidia-macos-driver#170 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
nullmoth/nvidia-macos-driver#169 ·
Maintainers usually reply within 1 day
All issues in nullmoth/nvidia-macos-driver
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
RustCrypto/SSH#596 ·
-
proxy: SQL-over-HTTP turns empty arrays into [""] or [false], or HTTP 500 for int and float arraysOpen
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
neondatabase/neon#12965 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
goauthentik/authentik#26867 ·
Maintainers usually reply within 1 day
-
Table and code-block right borders are clipped when the TOC panel is resized wider than the defaultOpen
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
api bug macos maintainer-needed p2 triaged
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Maintainers usually reply within 1 day