Skip to content

Commit 0364c3a

Browse files
authored
Fix up PR #388789 (#389213)
2 parents 1e73a63 + c8d0a94 commit 0364c3a

File tree

5 files changed

+192
-96
lines changed

5 files changed

+192
-96
lines changed

nixos/doc/manual/configuration/x-windows.chapter.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ using lightdm for a user `alice`:
117117
## Running X without a display manager {#sec-x11-startx}
118118

119119
It is possible to avoid a display manager entirely and starting the X server
120-
manually from a virtual terminal. Add to your configuration
120+
manually from a virtual terminal. Add to your configuration:
121121
```nix
122122
{
123123
services.xserver.displayManager.startx = {
@@ -130,7 +130,9 @@ then you can start the X server with the `startx` command.
130130

131131
The second option will generate a base `xinitrc` script that will run your
132132
window manager and set up the systemd user session.
133-
You can extend the script using the [extraCommands](#opt-services.xserver.displayManager.startx.extraCommands) for example:
133+
You can extend the script using the
134+
[extraCommands](#opt-services.xserver.displayManager.startx.extraCommands)
135+
option, for example:
134136
```nix
135137
{
136138
services.xserver.displayManager.startx = {
@@ -146,7 +148,7 @@ You can extend the script using the [extraCommands](#opt-services.xserver.displa
146148
or, alternatively, you can write your own from scratch in `~/.xinitrc`.
147149

148150
In this case, remember you're responsible for starting the window manager, for
149-
example
151+
example:
150152
```shell
151153
sxhkd &
152154
bspwm &

nixos/doc/manual/release-notes/rl-2505.section.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@
548548

549549
- `services.avahi.ipv6` now defaults to true.
550550

551+
- In the `services.xserver.displayManager.startx` module, two new options [generateScript](#opt-services.xserver.displayManager.startx.generateScript) and [extraCommands](#opt-services.xserver.displayManager.startx.extraCommands) have been added to to declaratively configure the .xinitrc script.
552+
551553
- All services that require a root certificate bundle now use the value of a new read-only option, `security.pki.caBundle`.
552554

553555
- hddfancontrol has been updated to major release 2. See the [migration guide](https://github.com/desbma/hddfancontrol/tree/master?tab=readme-ov-file#migrating-from-v1x), as there are breaking changes.

nixos/modules/services/x11/display-managers/startx.nix

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ in
8282
'';
8383

8484
# Add a sane system-wide xinitrc script
85-
environment.etc."X11/xinit/xinitrc".source = lib.mkIf cfg.generateScript (
86-
pkgs.writeShellScript "xinitrc" ''
85+
environment.etc."X11/xinit/xinitrc" = lib.mkIf cfg.generateScript {
86+
source = pkgs.writeShellScript "xinitrc" ''
8787
${cfg.extraCommands}
8888
8989
# start user services
@@ -97,8 +97,8 @@ in
9797
# stop services and all subprocesses
9898
systemctl --user stop nixos-fake-graphical-session.target
9999
kill 0
100-
''
101-
);
100+
'';
101+
};
102102

103103
environment.systemPackages = with pkgs; [ xorg.xinit ];
104104

nixos/tests/all-tests.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ in {
11531153
systemd-userdbd = handleTest ./systemd-userdbd.nix {};
11541154
systemd-homed = handleTest ./systemd-homed.nix {};
11551155
systemtap = handleTest ./systemtap.nix {};
1156-
startx = runTest ./startx.nix;
1156+
startx = import ./startx.nix { inherit pkgs runTest; };
11571157
taler = handleTest ./taler {};
11581158
tandoor-recipes = handleTest ./tandoor-recipes.nix {};
11591159
tandoor-recipes-script-name = handleTest ./tandoor-recipes-script-name.nix {};

nixos/tests/startx.nix

Lines changed: 180 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,200 @@
1-
{ lib, ... }:
1+
{ pkgs, runTest }:
22

33
{
4-
name = "startx";
5-
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
64

7-
nodes.machine =
8-
{ pkgs, ... }:
9-
{
10-
services.getty.autologinUser = "root";
5+
declarative = runTest {
6+
name = "startx";
7+
meta.maintainers = with pkgs.lib.maintainers; [ rnhmjoj ];
118

12-
environment.systemPackages = with pkgs; [
13-
xdotool
14-
catclock
15-
];
9+
nodes.machine =
10+
{ pkgs, ... }:
11+
{
12+
services.getty.autologinUser = "root";
1613

17-
programs.bash.promptInit = "PS1='# '";
14+
environment.systemPackages = with pkgs; [
15+
xdotool
16+
catclock
17+
];
1818

19-
# startx+bspwm setup
20-
services.xserver = {
21-
enable = true;
22-
windowManager.bspwm = {
19+
programs.bash.promptInit = "PS1='# '";
20+
21+
# startx+bspwm setup
22+
services.xserver = {
2323
enable = true;
24-
configFile = pkgs.writeShellScript "bspwrc" ''
25-
bspc config border_width 2
26-
bspc config window_gap 12
27-
bspc rule -a xclock state=floating sticky=on
28-
'';
29-
sxhkd.configFile = pkgs.writeText "sxhkdrc" ''
30-
# open a terminal
31-
super + Return
32-
urxvtc
33-
# quit bspwm
34-
super + alt + Escape
35-
bspc quit
36-
'';
24+
windowManager.bspwm = {
25+
enable = true;
26+
configFile = pkgs.writeShellScript "bspwrc" ''
27+
bspc config border_width 2
28+
bspc config window_gap 12
29+
bspc rule -a xclock state=floating sticky=on
30+
'';
31+
sxhkd.configFile = pkgs.writeText "sxhkdrc" ''
32+
# open a terminal
33+
super + Return
34+
urxvtc
35+
# quit bspwm
36+
super + alt + Escape
37+
bspc quit
38+
'';
39+
};
40+
displayManager.startx = {
41+
enable = true;
42+
generateScript = true;
43+
extraCommands = ''
44+
xrdb -load ~/.Xresources
45+
xsetroot -solid '#343d46'
46+
xsetroot -cursor_name trek
47+
xclock &
48+
'';
49+
};
3750
};
38-
displayManager.startx = {
51+
52+
# enable some user services
53+
security.polkit.enable = true;
54+
services.urxvtd.enable = true;
55+
programs.xss-lock.enable = true;
56+
};
57+
58+
testScript = ''
59+
import textwrap
60+
61+
sysu = "env XDG_RUNTIME_DIR=/run/user/0 systemctl --user";
62+
prompt = "# "
63+
64+
with subtest("Wait for the autologin"):
65+
machine.wait_until_tty_matches("1", prompt)
66+
67+
with subtest("Setup dotfiles"):
68+
machine.execute(textwrap.dedent("""
69+
cat <<EOF > ~/.Xresources
70+
urxvt*foreground: #9b9081
71+
urxvt*background: #181b20
72+
urxvt*scrollBar: false
73+
urxvt*title: myterm
74+
urxvt*geometry: 80x240+0+0
75+
xclock*geometry: 164x164+24+440
76+
EOF
77+
"""))
78+
79+
with subtest("Can start the X server"):
80+
machine.send_chars("startx\n")
81+
machine.wait_for_x()
82+
machine.wait_for_window("xclock")
83+
84+
with subtest("Graphical services are running"):
85+
machine.succeed(f"{sysu} is-active graphical-session.target")
86+
machine.succeed(f"{sysu} is-active urxvtd")
87+
machine.succeed(f"{sysu} is-active xss-lock")
88+
89+
with subtest("Can interact with the WM"):
90+
machine.wait_until_succeeds("pgrep sxhkd")
91+
machine.wait_until_succeeds("pgrep bspwm")
92+
# spawn some terminals
93+
machine.send_key("meta_l-ret", delay=0.5)
94+
machine.send_key("meta_l-ret", delay=0.5)
95+
machine.send_key("meta_l-ret", delay=0.5)
96+
# Note: this tests that resources have beeen loaded
97+
machine.wait_for_window("myterm")
98+
machine.screenshot("screenshot.png")
99+
100+
with subtest("Can stop the X server"):
101+
# kill the WM
102+
machine.send_key("meta_l-alt-esc")
103+
machine.wait_until_tty_matches("1", prompt)
104+
105+
with subtest("Graphical session has stopped"):
106+
machine.fail(f"{sysu} is-active graphical-session.target")
107+
machine.fail(f"{sysu} is-active urxvtd")
108+
machine.fail(f"{sysu} is-active xss-lock")
109+
'';
110+
};
111+
112+
imperative = runTest {
113+
name = "startx-imperative";
114+
meta.maintainers = with pkgs.lib.maintainers; [ rnhmjoj ];
115+
116+
nodes.machine =
117+
{ pkgs, ... }:
118+
{
119+
services.getty.autologinUser = "root";
120+
programs.bash.promptInit = "PS1='# '";
121+
122+
# startx+twm setup
123+
services.xserver = {
39124
enable = true;
40-
generateScript = true;
41-
extraCommands = ''
42-
xrdb -load ~/.Xresources
43-
xsetroot -solid '#343d46'
44-
xsetroot -cursor_name trek
45-
xclock &
46-
'';
125+
windowManager.twm.enable = true;
126+
displayManager.startx.enable = true;
127+
displayManager.startx.generateScript = false;
47128
};
48-
};
49129

50-
# enable some user services
51-
security.polkit.enable = true;
52-
services.urxvtd.enable = true;
53-
programs.xss-lock.enable = true;
54-
};
130+
# enable some user services
131+
security.polkit.enable = true;
132+
services.urxvtd.enable = true;
133+
programs.xss-lock.enable = true;
134+
};
55135

56-
testScript = ''
57-
import textwrap
136+
testScript = ''
137+
import textwrap
58138
59-
sysu = "env XDG_RUNTIME_DIR=/run/user/0 systemctl --user";
60-
prompt = "# "
139+
sysu = "env XDG_RUNTIME_DIR=/run/user/0 systemctl --user";
140+
prompt = "# "
61141
62-
with subtest("Wait for the autologin"):
63-
machine.wait_until_tty_matches("1", prompt)
142+
with subtest("Wait for the autologin"):
143+
machine.wait_until_tty_matches("1", prompt)
64144
65-
with subtest("Setup dotfiles"):
66-
machine.execute(textwrap.dedent("""
67-
cat <<EOF > ~/.Xresources
145+
with subtest("Setup dotfiles"):
146+
machine.execute(textwrap.dedent("""
147+
cat <<EOF > ~/.Xresources
68148
urxvt*foreground: #9b9081
69149
urxvt*background: #181b20
70150
urxvt*scrollBar: false
71151
urxvt*title: myterm
72-
urxvt*geometry: 80x240+0+0
73-
xclock*geometry: 164x164+24+440
74-
EOF
75-
"""))
76-
77-
with subtest("Can start the X server"):
78-
machine.send_chars("startx\n")
79-
machine.wait_for_x()
80-
machine.wait_for_window("xclock")
81-
82-
with subtest("Graphical services are running"):
83-
machine.succeed(f"{sysu} is-active graphical-session.target")
84-
machine.succeed(f"{sysu} is-active urxvtd")
85-
machine.succeed(f"{sysu} is-active xss-lock")
86-
87-
with subtest("Can interact with the WM"):
88-
machine.wait_until_succeeds("pgrep sxhkd")
89-
machine.wait_until_succeeds("pgrep bspwm")
90-
# spawn some terminals
91-
machine.send_key("meta_l-ret", delay=0.5)
92-
machine.send_key("meta_l-ret", delay=0.5)
93-
machine.send_key("meta_l-ret", delay=0.5)
94-
# Note: this tests that resources have beeen loaded
95-
machine.wait_for_window("myterm")
96-
machine.screenshot("screenshot.png")
97-
98-
with subtest("Can stop the X server"):
99-
# kill the WM
100-
machine.send_key("meta_l-alt-esc")
101-
machine.wait_until_tty_matches("1", prompt)
102-
103-
with subtest("Graphical session has stopped"):
104-
machine.fail(f"{sysu} is-active graphical-session.target")
105-
machine.fail(f"{sysu} is-active urxvtd")
106-
machine.fail(f"{sysu} is-active xss-lock")
107-
'';
152+
urxvt*geometry: 20x20+40+40
153+
EOF
154+
cat <<EOF > ~/.twmrc
155+
"Return" = meta : all : f.exec "urxvtc"
156+
"Escape" = meta : all : f.quit
157+
EOF
158+
cat <<EOF > ~/.xinitrc
159+
xrdb -load ~/.Xresources
160+
xsetroot -solid '#343d46'
161+
xsetroot -cursor_name trek
162+
# start user services
163+
systemctl --user import-environment DISPLAY XDG_SESSION_ID
164+
systemctl --user start nixos-fake-graphical-session.target
165+
# run the window manager
166+
twm
167+
# stop services and all subprocesses
168+
systemctl --user stop nixos-fake-graphical-session.target
169+
EOF
170+
"""))
171+
172+
with subtest("Can start the X server"):
173+
machine.send_chars("startx\n")
174+
machine.wait_for_x()
175+
176+
with subtest("Graphical services are running"):
177+
machine.succeed(f"{sysu} is-active graphical-session.target")
178+
machine.succeed(f"{sysu} is-active urxvtd")
179+
machine.succeed(f"{sysu} is-active xss-lock")
180+
181+
with subtest("Can interact with the WM"):
182+
machine.wait_until_succeeds("pgrep twm")
183+
# spawn a terminal
184+
machine.send_key("alt-ret")
185+
machine.wait_for_window("myterm")
186+
machine.screenshot("screenshot.png")
187+
188+
with subtest("Can stop the X server"):
189+
# kill the WM
190+
machine.send_key("alt-esc")
191+
machine.wait_until_tty_matches("1", prompt)
192+
193+
with subtest("Graphical session has stopped"):
194+
machine.fail(f"{sysu} is-active graphical-session.target")
195+
machine.fail(f"{sysu} is-active urxvtd")
196+
machine.fail(f"{sysu} is-active xss-lock")
197+
'';
198+
};
199+
108200
}

0 commit comments

Comments
 (0)