From 806f2bc13798acc0a625e1becd004a5794017c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Wed, 27 Jun 2018 04:50:49 +0200 Subject: [PATCH] anaconda: save keyboard layout to udev Xorg loads keyboard layout for new devices (or existing one re-detected) only from its config, ignoring runtime changes done in the meantime (setxkbmap etc). Since installation process calls udevadm trigger somewhere, all input devices are re-discovered and reverted to default keyboard layout (us). Avoid this by configuring current keyboard layout also as udev rules, which are loaded by Xorg while discovering device. Fixes QubesOS/qubes-issues#3352 --- anaconda/pyanaconda/ui/gui/xkl_wrapper.py | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/anaconda/pyanaconda/ui/gui/xkl_wrapper.py b/anaconda/pyanaconda/ui/gui/xkl_wrapper.py index a2f14ce..7317831 100644 --- a/anaconda/pyanaconda/ui/gui/xkl_wrapper.py +++ b/anaconda/pyanaconda/ui/gui/xkl_wrapper.py @@ -307,6 +307,8 @@ class XklWrapper(object): raise XklWrapperError("Failed to add layout '%s (%s)'" % (layout, variant)) + self.save_layouts_to_udev(self._rec.layouts, self._rec.variants) + @gtk_action_wait def remove_layout(self, layout): """ @@ -341,6 +343,8 @@ class XklWrapper(object): raise XklWrapperError("Failed to remove layout '%s (%s)'" % (layout, variant)) + self.save_layouts_to_udev(new_layouts, new_variants) + @gtk_action_wait def replace_layouts(self, layouts_list): """ @@ -368,6 +372,8 @@ class XklWrapper(object): msg = "Failed to replace layouts with: %s" % ",".join(layouts_list) raise XklWrapperError(msg) + self.save_layouts_to_udev(new_layouts, new_variants) + @gtk_action_wait def set_switching_options(self, options): """ @@ -391,3 +397,26 @@ class XklWrapper(object): msg = "Failed to set switching options to: %s" % ",".join(options) raise XklWrapperError(msg) + def save_layouts_to_udev(self, layouts, variants): + """ + Sets layouts to udev, so it will also apply to newly connected + keyboards (or existing after udevadm trigger). Otherwise Xorg setup + them based on xorg.conf with a fallback to hardcoded values. + + :param layouts: list of layouts + :param variants: list of layout variants, matching *layouts* + """ + + udev_rules_dir = '/run/udev/rules.d' + udev_rules_path = udev_rules_dir + '/90-keyboard-layout.rules' + try: + iutil.mkdirChain(udev_rules_dir) + except FileExistsError: + pass + with open(udev_rules_path, 'w') as rules: + rules.write('ENV{{ID_INPUT_KEYBOARD}}=="1", ' + 'ENV{{xkblayout}}="{layouts}", ' + 'ENV{{xkbvariant}}="{variants}"\n'.format( + layouts=','.join(layouts), variants=','.join(variants))) + + iutil.startProgram(['udevadm', 'control', '-R']).communicate()