The role ran no window manager on the theory that Firefox is the only X client and --kiosk makes it full-screen by itself. It doesn't: --kiosk *asks* to be full-screen over EWMH, and with no WM running nobody answers. Firefox kept its default window size in the top-left corner - on musicdolphin's 1920x1080 monitor, a 1280x972 window with black bands down the right edge and along the bottom, which looks exactly like an overscan problem and isn't one. Openbox answers the request and does nothing else. pi_kiosk_mode=debug then turns the attached screen into something workable: Firefox as an ordinary window that is not relaunched when you close it, a visible pointer, Openbox as the session leader with a root menu offering a terminal, and xterm, x11-utils and mesa-utils installed. musicdolphin is set to debug for now. The templates notify the getty handler, so a mode switch restarts the session on its own - Xorg lives in that unit's cgroup. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
128 lines
4.4 KiB
YAML
128 lines
4.4 KiB
YAML
---
|
|
- name: Packages
|
|
ansible.builtin.apt:
|
|
name:
|
|
- xserver-xorg
|
|
- xinit
|
|
- x11-xserver-utils
|
|
# Without a window manager, Firefox's request to go full-screen (which is all
|
|
# --kiosk does) has nobody to answer it, and it settles for its default window
|
|
# size in the corner of the screen. Openbox answers it, and nothing else.
|
|
- openbox
|
|
- firefox-esr
|
|
- unclutter
|
|
cache_valid_time: 7200
|
|
|
|
- name: Debugging tools for the attached screen
|
|
# Only pulled in for pi_kiosk_mode=debug; apt does not take them away again when the
|
|
# host goes back to kiosk mode, which is fine - they are inert and small.
|
|
ansible.builtin.apt:
|
|
name:
|
|
- xterm # a terminal that is ours, whatever x-terminal-emulator points at
|
|
- x11-utils # xwininfo, xprop: is the window actually the size of the screen?
|
|
- mesa-utils # glxinfo, glxgears: is anything accelerated, or is this llvmpipe?
|
|
cache_valid_time: 7200
|
|
when: pi_kiosk_mode == 'debug'
|
|
|
|
- name: Create kiosk user
|
|
ansible.builtin.user:
|
|
name: "{{ pi_kiosk_user }}"
|
|
groups: [video, input, tty]
|
|
shell: /bin/bash
|
|
create_home: true
|
|
|
|
- name: Own the directories X and Firefox write into
|
|
# Xorg runs as root here (Debian's wrapper, allowed_users=console) with HOME set to
|
|
# the kiosk user's, so it creates ~/.cache itself - root-owned and 0700 - the first
|
|
# time it writes a mesa shader cache. Firefox then cannot create ~/.cache/mozilla and
|
|
# gives up with "Your Firefox profile cannot be loaded. It may be missing or
|
|
# inaccessible". Creating these up front, owned by the user, means root only ever
|
|
# adds subdirectories to a directory the user already owns.
|
|
ansible.builtin.file:
|
|
path: "/home/{{ pi_kiosk_user }}/{{ item }}"
|
|
state: directory
|
|
owner: "{{ pi_kiosk_user }}"
|
|
group: "{{ pi_kiosk_user }}"
|
|
mode: "0700"
|
|
loop:
|
|
- .cache
|
|
- .mozilla
|
|
|
|
- name: Autologin the kiosk user on tty1
|
|
ansible.builtin.file:
|
|
path: /etc/systemd/system/getty@tty1.service.d
|
|
state: directory
|
|
mode: "0755"
|
|
|
|
- name: Install getty autologin override
|
|
ansible.builtin.template:
|
|
src: autologin.conf.j2
|
|
dest: /etc/systemd/system/getty@tty1.service.d/autologin.conf
|
|
mode: "0644"
|
|
notify: Reload systemd and restart getty
|
|
|
|
- name: Enable the autologin getty on tty1
|
|
# Enabling it is the part that survives a reboot. These images do not enable
|
|
# getty@tty1 themselves - getty.target pulls in getty-static.service and nothing
|
|
# else - so without this the drop-in above is installed, the handler starts the unit
|
|
# once, and the kiosk then silently stops coming up after the next reboot.
|
|
ansible.builtin.systemd:
|
|
name: "getty@tty1"
|
|
enabled: true
|
|
state: started
|
|
daemon_reload: true
|
|
|
|
- name: Install .bash_profile (starts X on tty1 login)
|
|
ansible.builtin.template:
|
|
src: bash_profile.j2
|
|
dest: "/home/{{ pi_kiosk_user }}/.bash_profile"
|
|
owner: "{{ pi_kiosk_user }}"
|
|
group: "{{ pi_kiosk_user }}"
|
|
mode: "0644"
|
|
notify: Reload systemd and restart getty
|
|
|
|
- name: Install .xinitrc (starts Openbox, then Firefox)
|
|
ansible.builtin.template:
|
|
src: xinitrc.j2
|
|
dest: "/home/{{ pi_kiosk_user }}/.xinitrc"
|
|
owner: "{{ pi_kiosk_user }}"
|
|
group: "{{ pi_kiosk_user }}"
|
|
mode: "0755"
|
|
notify: Reload systemd and restart getty
|
|
|
|
- name: Ensure firefox-esr policy directory exists
|
|
ansible.builtin.file:
|
|
path: /etc/firefox-esr
|
|
state: directory
|
|
mode: "0755"
|
|
# apt normally creates this; a backstop in case the package layout doesn't
|
|
|
|
- name: Install Firefox enterprise policy (suppress session-restore/update prompts)
|
|
ansible.builtin.copy:
|
|
src: policies.json
|
|
dest: /etc/firefox-esr/policies.json
|
|
mode: "0644"
|
|
|
|
- name: Ensure the Openbox config directories exist
|
|
# Both levels explicitly, and owned by the user: a file: task creates missing parents
|
|
# as root, and a root-owned ~/.config is the same trap that broke the Firefox profile
|
|
# above.
|
|
ansible.builtin.file:
|
|
path: "/home/{{ pi_kiosk_user }}/{{ item }}"
|
|
state: directory
|
|
owner: "{{ pi_kiosk_user }}"
|
|
group: "{{ pi_kiosk_user }}"
|
|
mode: "0755"
|
|
loop:
|
|
- .config
|
|
- .config/openbox
|
|
|
|
- name: Install the Openbox root menu
|
|
ansible.builtin.template:
|
|
src: openbox-menu.xml.j2
|
|
dest: "/home/{{ pi_kiosk_user }}/.config/openbox/menu.xml"
|
|
owner: "{{ pi_kiosk_user }}"
|
|
group: "{{ pi_kiosk_user }}"
|
|
mode: "0644"
|
|
notify: Reload systemd and restart getty
|