From ea4c167527ea4fed4ce26a1d1708053a84cd0d98 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Sun, 20 Nov 2022 00:32:22 +0100 Subject: [PATCH] First commit --- README.md | 54 +++++++++++++++++++++++++++++++++++++++++ files/kanshi.service | 11 +++++++++ tasks/main.yml | 38 +++++++++++++++++++++++++++++ templates/config.j2 | 57 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 README.md create mode 100644 files/kanshi.service create mode 100644 tasks/main.yml create mode 100644 templates/config.j2 diff --git a/README.md b/README.md new file mode 100644 index 0000000..cf854e0 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +Kanshi Ansible role +------------------- + +This role install and configure [Kanshi](https://git.sr.ht/~emersion/kanshi}) +service. + + +## Variables + +This role needs two variables for creating Kanshi configuration file +`sway_output` provided by [ansible-sway](https://git.epha.se/ephase/ansible-sway) +role and `kanshi_profiles`. + +`sway_outputs` is not mandatory butuseful to provide id ans options for outputs. + +Here is an example of `kanshi_profile` + +```yaml +kanshi_profiles: + - profile: 'laptop' + screens: + - id: 'eDP-1' + - profile: 'home' + screens: + - id: 'eDP-1' + enable: false + - id: 'iiyama_27_4k' + position: '1080,0' + - id: 'iiyama_23_fhd' + position: '0,0' + mode: '1920x1024' + transform: 90 + options: + - id: 'eDP-1' + option: 'bg' + value: '~/images/bg.jpg' + commands: + - swaymsg workspace 1, move workspace to +eDP1+ +``` + + * `profile`: name of the profile + * `screens`: list of outputs + * `id`: id of the screen, could be the real name, ouput name like *HDMI-1* + (both given by `swaymsg -t output`) or id referenced in `sway_outputs` + * `position`: absolute position of the screen + * `mode`: resolution of the screen + * `scale`: scale factor for the screen + * `transform`: rotation (90, 180 or 270 degres) for the screen + * `options`: list of options: + * `id`: see above in *screens* section + * `options`: option name + * `value`: value + * `commands`: list of command to execute when switching to profile + diff --git a/files/kanshi.service b/files/kanshi.service new file mode 100644 index 0000000..8054271 --- /dev/null +++ b/files/kanshi.service @@ -0,0 +1,11 @@ +[Unit] +Description=Dynamic output configuration for Wayland compositors +Documentation=https://sr.ht/~emersion/kanshi +BindsTo=sway-session.target + +[Service] +Type=simple +ExecStart=/usr/bin/kanshi + +[Install] +WantedBy=sway-session.target diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..c64a97c --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,38 @@ +--- +- name: Install Kanshi package + ansible.builtin.package: + name: kanshi + state: present + become: true + +- name: Create Sway config dirs + ansible.builtin.file: + path: '{{ ansible_user_dir ~ "/.config/sway/conf.d" }}' + state: directory + mode: 0750 + owner: '{{ ansible_user_uid }}' + group: '{{ ansible_user_gid }}' + +- name: Render templates for Kanshi config file + ansible.builtin.template: + src: config.j2 + dest: '{{ ansible_user_dir}}/.config/kanshi/config' + owner: '{{ ansible_user_uid }}' + group: '{{ ansible_user_gid }}' + lstrip_blocks: yes + trim_blocks: yes + mode: 0640 + #any_errors_fatal: true + +- name: copy systemd service file {{ item }} + ansible.builtin.copy: + src: 'kanshi.service' + dest: '{{ ansible_user_dir }}/.config/systemd/user/' + mode: 0640 + +- name: activate service + ansible.builtin.systemd: + name: 'kanshi.service' + scope: user + state: started + enabled: yes diff --git a/templates/config.j2 b/templates/config.j2 new file mode 100644 index 0000000..de87f2d --- /dev/null +++ b/templates/config.j2 @@ -0,0 +1,57 @@ +# {{ ansible_managed }} +{% if kanshi_profiles is defined %} +{% for p in kanshi_profiles %} +profile {{ p.profile | default('') }} { + {# Process screens #} + {% for s in p.screens %} + {% set current = (sway_outputs | selectattr('id','==', s.id))[0] %} + {{- ' output "' ~ current['name'] | default(s.id) ~ '"' -}} + {% if s.status is defined and s.status == 'disable' %} + {{- ' disable' -}} + {% else %} + {% if s.status is defined and s.status == 'enable' %} + {{- ' enable' -}} + {% endif %} + {% if s.position is defined %} + {{- ' position ' ~ s.position -}} + {% endif %} + {% if s.transform is defined %} + {# + use sway config transform here is not a good idea because + rotation will be applied two times + #} + {{- ' transform ' ~ s.transform -}} + {% endif %} + {% if s.scale is defined %} + {{- ' scale ' ~ s.scale -}} + {% elif current['options']['scale'] is defined %} + {{- ' scale ' ~ current['options']['scale'] -}} + {% endif %} + {% endif %} + + {% endfor -%} + + {# process options#} + {% if p.options is defined %} + {% for o in p.options %} + {% set current = (sway_outputs | selectattr('id','==', o.id))[0] %} + {{- ' output "' ~ current['name'] | default(s.id) ~ '" ' -}} + {{ o.option }} {{ o.value }} + {% endfor -%} + {% endif -%} + + {# Process command#} + {% if p.commands is defined %} + {% for c in p.commands %} + {% set cmd = namespace(cmd = c) %} + {% if sway_outputs is defined %} + {% for o in sway_outputs %} + {% set cmd.cmd = ( cmd.cmd | replace('+'+o.id+'+', '"'+o.name+'"')) %} + {% endfor %} + {% endif %} + {{- ' exec ' ~ cmd.cmd }} + {% endfor -%} + {% endif -%} +} +{% endfor %} +{% endif %}