[PATCH 3/3] Enable setting up multiple layouts on the installed system

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We need to write a config file to the /etc/X11/xorg.conf.d/ defining
the layouts selected in the installation.
---
 pyanaconda/install.py    |    1 +
 pyanaconda/keyboard.py   |  122 +++++++++++++++++++++++++++++++++++++---------
 pyanaconda/kickstart.py  |    7 +++
 pyanaconda/livecd.py     |    2 -
 pyanaconda/yuminstall.py |    2 -
 5 files changed, 106 insertions(+), 28 deletions(-)

diff --git a/pyanaconda/install.py b/pyanaconda/install.py
index 86ae076..a323ca3 100644
--- a/pyanaconda/install.py
+++ b/pyanaconda/install.py
@@ -79,6 +79,7 @@ def doInstall(storage, payload, ksdata, instClass):
     # Now run the execute methods of ksdata that require an installed system
     # to be present first.
     ksdata.services.execute(storage, ksdata, instClass)
+    ksdata.keyboard.execute()
 
     runPostScripts(ksdata.scripts)
 
diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py
index 3ede35b..d756962 100755
--- a/pyanaconda/keyboard.py
+++ b/pyanaconda/keyboard.py
@@ -30,8 +30,102 @@ for listing and various modifications of keyboard layouts settings.
 
 """
 
+import os
 from gi.repository import Xkl, Gdk, GdkX11
 
+class KeyboardConfigError(Exception):
+    """Exception class for keyboard configuration related problems"""
+
+    pass
+
+def _parse_layout_variant(layout):
+    """
+    Parse layout and variant from the string that may look like 'layout' or
+    'layout (variant)'.
+
+    @return: the (layout, variant) pair, where variant can be ""
+    @rtype: tuple
+
+    """
+
+    variant = ""
+
+    lbracket_idx = layout.find("(")
+    rbracket_idx = layout.rfind(")")
+    if lbracket_idx != -1:
+        variant = layout[(lbracket_idx + 1) : rbracket_idx]
+        layout = layout[:lbracket_idx].strip()
+
+    return (layout, variant)
+
+def get_layouts_xorg_conf(keyboard):
+    """
+    Get the xorg.conf content setting up layouts in the ksdata.
+
+    @param keyboard: ksdata.keyboard object
+    @rtype: str
+
+    """
+
+    layouts = list()
+    variants = list()
+
+    for layout_variant in keyboard.layouts_list:
+        (layout, variant) = _parse_layout_variant(layout_variant)
+        layouts.append(layout)
+        variants.append(variant)
+
+    #section header
+    ret = 'Section "InputClass"\n'\
+          '\tIdentifier\t"kickstart"\n'\
+          '\tMatchIsKeyboard\t"on"\n'
+
+    #layouts
+    ret += '\tOption\t"XkbLayout"\t'
+    ret += '"' + ','.join(layouts) + '"\n'
+
+    #variants
+    ret += '\tOption\t"XkbVariant"\t'
+    ret += '"' + ','.join(variants) + '"\n'
+
+    #switching
+    #TODO: add option for switching combination
+    #for now, let's default to Alt+Shift
+    ret += '\tOption\t"XkbOptions"\t'
+    ret += '"grp:alt_shift_toggle"\n'
+
+    #section footer
+    ret += 'EndSection'
+
+    return ret
+
+def write_layouts_config(keyboard, root):
+    """
+    Function that writes a file with layouts configuration to
+    $root/etc/X11/xorg.conf.d/01-anaconda-layouts.conf
+
+    @param keyboard: ksdata.keyboard object
+    @param root: path to the root of the installed system
+
+    """
+
+    conf_dir = os.path.join(root, "/etc/X11/xorg.conf.d")
+    conf_file = "01-anaconda-keyboard.conf"
+
+    try:
+        if not os.path.isdir(conf_dir):
+            os.makedirs(conf_dir)
+
+    except OSError as oserr:
+        raise KeyboardConfigError("Cannot create directory xorg.conf.d")
+
+    try:
+        with open(os.path.join(conf_dir, conf_file), "w") as f:
+            f.write(get_layouts_xorg_conf(keyboard))
+
+    except IOError as ioerr:
+        raise KeyboardConfigError("Cannot write keyboard configuration file")
+
 def item_str(s):
     """Convert a zero-terminated byte array to a proper str"""
 
@@ -52,7 +146,7 @@ class _Layout(object):
     def description(self):
         return self.desc
 
-class XklWrapperError(Exception):
+class XklWrapperError(KeyboardConfigError):
     """Exception class for reporting libxklavier-related problems"""
 
     pass
@@ -160,26 +254,6 @@ class XklWrapper(object):
         #first layout (should exist for every language)
         return language_layouts[0].name
 
-    def _parse_layout_variant(self, layout):
-        """
-        Parse layout and variant from the string that may look like 'layout' or
-        'layout (variant)'.
-
-        @return: the (layout, variant) pair, where variant can be ""
-        @rtype: tuple
-
-        """
-
-        variant = ""
-
-        lbracket_idx = layout.find("(")
-        rbracket_idx = layout.rfind(")")
-        if lbracket_idx != -1:
-            variant = layout[(lbracket_idx + 1) : rbracket_idx]
-            layout = layout[:lbracket_idx].strip()
-
-        return (layout, variant)
-
     def add_layout(self, layout):
         """
         Method that tries to add a given layout to the current X configuration.
@@ -195,7 +269,7 @@ class XklWrapper(object):
         """
 
         #we can get 'layout' or 'layout (variant)'
-        (layout, variant) = self._parse_layout_variant(layout)
+        (layout, variant) = _parse_layout_variant(layout)
 
         #do not add the same layout-variant combinanion multiple times
         if (layout, variant) in zip(self._rec.layouts, self._rec.variants):
@@ -221,7 +295,7 @@ class XklWrapper(object):
         """
 
         #we can get 'layout' or 'layout (variant)'
-        (layout, variant) = self._parse_layout_variant(layout)
+        (layout, variant) = _parse_layout_variant(layout)
 
         layouts_variants = zip(self._rec.layouts, self._rec.variants)
 
@@ -253,7 +327,7 @@ class XklWrapper(object):
         new_variants = list()
 
         for layout_variant in layouts_list:
-            (layout, variant) = self._parse_layout_variant(layout_variant)
+            (layout, variant) = _parse_layout_variant(layout_variant)
             new_layouts.append(layout)
             new_layouts.append(variant)
 
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 3a6a20c..bbdcbc3 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -46,6 +46,7 @@ import upgrade
 import pykickstart.commands as commands
 from storage.devices import *
 from scdate.core import zonetab
+from pyanaconda import keyboard
 
 from pykickstart.base import KickstartCommand
 from pykickstart.constants import *
@@ -1085,6 +1086,11 @@ class ZFCP(commands.zfcp.F14_ZFCP):
 
         return fcp
 
+class Keyboard(commands.keyboard.F18_Keyboard):
+    def execute(self):
+        if self.layouts_list:
+            keyboard.write_layouts_config(self, ROOT_PATH)
+
 ###
 ### HANDLERS
 ###
@@ -1100,6 +1106,7 @@ commandMap = {
         "ignoredisk": IgnoreDisk,
         "iscsi": Iscsi,
         "iscsiname": IscsiName,
+        "keyboard": Keyboard,
         "logging": Logging,
         "multipath": MultiPath,
         "services": Services,
diff --git a/pyanaconda/livecd.py b/pyanaconda/livecd.py
index f72d5d2..0c03d38 100644
--- a/pyanaconda/livecd.py
+++ b/pyanaconda/livecd.py
@@ -316,8 +316,6 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
         if os.path.exists("/etc/modprobe.conf"):
             shutil.copyfile("/etc/modprobe.conf", 
                             ROOT_PATH + "/etc/modprobe.conf")
-        # set the same keyboard the user selected in the keyboard dialog:
-        anaconda.keyboard.write(ROOT_PATH)
 
         # rebuild the initrd(s)
         vers = self.kernelVersionList()
diff --git a/pyanaconda/yuminstall.py b/pyanaconda/yuminstall.py
index d895e27..7536788 100644
--- a/pyanaconda/yuminstall.py
+++ b/pyanaconda/yuminstall.py
@@ -1618,8 +1618,6 @@ reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anacon
             anaconda.network.write()
             anaconda.network.copyConfigToPath()
             anaconda.storage.write()
-            if not anaconda.isHeadless:
-                anaconda.keyboard.write(ROOT_PATH)
         else:
             # ensure that /etc/mtab is a symlink to /proc/self/mounts
             anaconda.storage.makeMtab()
-- 
1.7.4.4

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux