diff --git a/subiquity/common/keyboard.py b/subiquity/common/keyboard.py
new file mode 100644
index 00000000..3a934699
--- /dev/null
+++ b/subiquity/common/keyboard.py
@@ -0,0 +1,83 @@
+# Copyright 2020 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import os
+import re
+
+from subiquitycore.utils import arun_command
+
+from subiquity.common.types import KeyboardSetting
+
+
+etc_default_keyboard_template = """\
+# KEYBOARD CONFIGURATION FILE
+
+# Consult the keyboard(5) manual page.
+
+XKBMODEL="pc105"
+XKBLAYOUT="{layout}"
+XKBVARIANT="{variant}"
+XKBOPTIONS="{options}"
+
+BACKSPACE="guess"
+"""
+
+
+def from_config_file(config_file):
+ with open(config_file) as fp:
+ content = fp.read()
+
+ def optval(opt, default):
+ match = re.search(r'(?m)^\s*%s=(.*)$' % (opt,), content)
+ if match:
+ r = match.group(1).strip('"')
+ if r != '':
+ return r
+ return default
+
+ XKBLAYOUT = optval("XKBLAYOUT", "us")
+ XKBVARIANT = optval("XKBVARIANT", "")
+ XKBOPTIONS = optval("XKBOPTIONS", "")
+ toggle = None
+ for option in XKBOPTIONS.split(','):
+ if option.startswith('grp:'):
+ toggle = option[4:]
+ return KeyboardSetting(layout=XKBLAYOUT, variant=XKBVARIANT, toggle=toggle)
+
+
+def render(setting):
+ options = ""
+ if setting.toggle:
+ options = "grp:" + setting.toggle
+ return etc_default_keyboard_template.format(
+ layout=setting.layout,
+ variant=setting.variant,
+ options=options)
+
+
+async def set_keyboard(root, setting, dry_run):
+ path = os.path.join(root, 'etc', 'default', 'keyboard')
+ os.makedirs(os.path.dirname(path), exist_ok=True)
+ with open(path, 'w') as fp:
+ fp.write(render(setting))
+ cmds = [
+ ['setupcon', '--save', '--force', '--keyboard-only'],
+ ['/snap/bin/subiquity.subiquity-loadkeys'],
+ ]
+ if dry_run:
+ scale = os.environ.get('SUBIQUITY_REPLAY_TIMESCALE', "1")
+ cmds = [['sleep', str(1/float(scale))]]
+ for cmd in cmds:
+ await arun_command(cmd)
diff --git a/subiquity/models/tests/test_keyboard.py b/subiquity/common/tests/test_keyboard.py
similarity index 81%
rename from subiquity/models/tests/test_keyboard.py
rename to subiquity/common/tests/test_keyboard.py
index a63b3889..e312ab39 100644
--- a/subiquity/models/tests/test_keyboard.py
+++ b/subiquity/common/tests/test_keyboard.py
@@ -18,10 +18,11 @@ import os
import tempfile
import unittest
-from subiquity.models.keyboard import (
- KeyboardModel,
- KeyboardSetting,
+from subiquity.common.keyboard import (
+ from_config_file,
+ set_keyboard,
)
+from subiquity.common.types import KeyboardSetting
class TestSubiquityModel(unittest.TestCase):
@@ -36,11 +37,10 @@ class TestSubiquityModel(unittest.TestCase):
async def t():
os.environ['SUBIQUITY_REPLAY_TIMESCALE'] = '100'
with tempfile.TemporaryDirectory() as tmpdir:
- model = KeyboardModel(tmpdir)
new_setting = KeyboardSetting('fr', 'azerty')
- await model.set_keyboard(new_setting)
- read_setting = KeyboardSetting.from_config_file(
- model.config_path)
+ await set_keyboard(tmpdir, new_setting, True)
+ read_setting = from_config_file(
+ os.path.join(tmpdir, 'etc', 'default', 'keyboard'))
self.assertEqual(new_setting, read_setting)
loop.run_until_complete(t())
loop.close()
diff --git a/subiquity/common/types.py b/subiquity/common/types.py
index 0d40fe96..1d7462c9 100644
--- a/subiquity/common/types.py
+++ b/subiquity/common/types.py
@@ -19,11 +19,18 @@
import datetime
import enum
-from typing import List
+from typing import List, Optional
import attr
+@attr.s(auto_attribs=True)
+class KeyboardSetting:
+ layout: str
+ variant: str = ''
+ toggle: Optional[str] = None
+
+
@attr.s(auto_attribs=True)
class IdentityData:
realname: str = ''
diff --git a/subiquity/controllers/keyboard.py b/subiquity/controllers/keyboard.py
index eda3bc21..17e6ec6d 100644
--- a/subiquity/controllers/keyboard.py
+++ b/subiquity/controllers/keyboard.py
@@ -17,10 +17,11 @@ import logging
import attr
-from subiquitycore.async_helpers import schedule_task
from subiquitycore.context import with_context
+from subiquity.common.keyboard import set_keyboard
from subiquity.controller import SubiquityTuiController
+from subiquity.keyboard import KeyboardList
from subiquity.models.keyboard import KeyboardSetting
from subiquity.ui.views import KeyboardView
@@ -44,42 +45,57 @@ class KeyboardController(SubiquityTuiController):
('l10n:language-selected', 'language_selected'),
]
+ def __init__(self, app):
+ self.needs_set_keyboard = False
+ super().__init__(app)
+ self.keyboard_list = KeyboardList()
+
def load_autoinstall_data(self, data):
- if data is not None:
- self.model.setting = KeyboardSetting(**data)
+ if data is None:
+ return
+ setting = KeyboardSetting(**data)
+ if self.model.setting != setting:
+ self.needs_set_keyboard = True
+ self.model.setting = setting
@with_context()
async def apply_autoinstall_config(self, context):
- await self.model.set_keyboard(self.model.setting)
+ if self.needs_set_keyboard:
+ await set_keyboard(
+ self.app.root, self.model.setting, self.opts.dry_run)
def language_selected(self, code):
log.debug("language_selected %s", code)
- if not self.model.has_language(code):
+ if not self.keyboard_list.has_language(code):
code = code.split('_')[0]
- if not self.model.has_language(code):
+ if not self.keyboard_list.has_language(code):
code = 'C'
- log.debug("loading launguage %s", code)
- self.model.load_language(code)
+ log.debug("loading language %s", code)
+ self.keyboard_list.load_language(code)
def make_ui(self):
- if self.model.current_lang is None:
- self.model.load_language('C')
- return KeyboardView(self.model, self, self.opts)
+ if self.keyboard_list.current_lang is None:
+ self.keyboard_list.load_language('C')
+ return KeyboardView(self, self.model.setting)
def run_answers(self):
if 'layout' in self.answers:
layout = self.answers['layout']
variant = self.answers.get('variant', '')
- self.done(KeyboardSetting(layout=layout, variant=variant))
+ self.done(KeyboardSetting(layout=layout, variant=variant), True)
- async def apply_settings(self, setting):
- await self.model.set_keyboard(setting)
- log.debug("KeyboardController next_screen")
- self.configured()
- self.app.next_screen()
+ async def set_keyboard(self, setting):
+ await set_keyboard(self.app.root, setting, self.opts.dry_run)
+ self.done(setting, False)
- def done(self, setting):
- schedule_task(self.apply_settings(setting))
+ def done(self, setting, apply):
+ log.debug("KeyboardController.done %s next_screen", setting)
+ if apply:
+ self.app.aio_loop.create_task(self.set_keyboard(setting))
+ else:
+ self.model.setting = setting
+ self.configured()
+ self.app.next_screen()
def cancel(self):
self.app.prev_screen()
diff --git a/subiquity/keyboard.py b/subiquity/keyboard.py
new file mode 100644
index 00000000..12c9ba06
--- /dev/null
+++ b/subiquity/keyboard.py
@@ -0,0 +1,154 @@
+# Copyright 2020 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+from collections import defaultdict
+import os
+
+from subiquity.common.types import KeyboardSetting
+
+
+# Non-latin keyboard layouts that are handled in a uniform way
+standard_non_latin_layouts = set(
+ ('af', 'am', 'ara', 'ben', 'bd', 'bg', 'bt', 'by', 'et', 'ge',
+ 'gh', 'gr', 'guj', 'guru', 'il', 'in', 'iq', 'ir', 'iku', 'kan',
+ 'kh', 'kz', 'la', 'lao', 'lk', 'kg', 'ma', 'mk', 'mm', 'mn', 'mv',
+ 'mal', 'np', 'ori', 'pk', 'ru', 'scc', 'sy', 'syr', 'tel', 'th',
+ 'tj', 'tam', 'tib', 'ua', 'ug', 'uz')
+)
+
+
+def latinizable(setting):
+ """
+ If this setting does not allow the typing of latin characters,
+ return a setting that can be switched to one that can.
+ """
+ if setting.layout == 'rs':
+ if setting.variant.startswith('latin'):
+ return setting
+ else:
+ if setting.variant == 'yz':
+ new_variant = 'latinyz'
+ elif setting.variant == 'alternatequotes':
+ new_variant = 'latinalternatequotes'
+ else:
+ new_variant = 'latin'
+ return KeyboardSetting(layout='rs,rs',
+ variant=(new_variant +
+ ',' + setting.variant))
+ elif setting.layout == 'jp':
+ if setting.variant in ('106', 'common', 'OADG109A',
+ 'nicola_f_bs', ''):
+ return setting
+ else:
+ return KeyboardSetting(layout='jp,jp',
+ variant=',' + setting.variant)
+ elif setting.layout == 'lt':
+ if setting.variant == 'us':
+ return KeyboardSetting(layout='lt,lt', variant='us,')
+ else:
+ return KeyboardSetting(layout='lt,lt',
+ variant=setting.variant + ',us')
+ elif setting.layout == 'me':
+ if setting.variant == 'basic' or setting.variant.startswith('latin'):
+ return setting
+ else:
+ return KeyboardSetting(layout='me,me',
+ variant=setting.variant + ',us')
+ elif setting.layout in standard_non_latin_layouts:
+ return KeyboardSetting(layout='us,' + setting.layout,
+ variant=',' + setting.variant)
+ else:
+ return setting
+
+
+def for_ui(setting):
+ """
+ Attempt to guess a setting the user chose which resulted in the
+ current config. Basically the inverse of latinizable().
+ """
+ if ',' in setting.layout:
+ layout1, layout2 = setting.layout.split(',', 1)
+ else:
+ layout1, layout2 = setting.layout, ''
+ if ',' in setting.variant:
+ variant1, variant2 = setting.variant.split(',', 1)
+ else:
+ variant1, variant2 = setting.variant, ''
+ if setting.layout == 'lt,lt':
+ layout = layout1
+ variant = variant1
+ elif setting.layout in ('rs,rs', 'us,rs', 'jp,jp', 'us,jp'):
+ layout = layout2
+ variant = variant2
+ elif layout1 == 'us' and layout2 in standard_non_latin_layouts:
+ layout = layout2
+ variant = variant2
+ elif ',' in setting.layout:
+ # Something unrecognized
+ layout = 'us'
+ variant = ''
+ else:
+ return setting
+ return KeyboardSetting(layout=layout, variant=variant)
+
+
+class KeyboardList:
+
+ def __init__(self):
+ self._kbnames_file = os.path.join(
+ os.environ.get("SNAP", '.'),
+ 'kbdnames.txt')
+ self._clear()
+
+ def has_language(self, code):
+ self.load_language(code)
+ return bool(self.layouts)
+
+ def load_language(self, code):
+ if code == self.current_lang:
+ return
+
+ self._clear()
+
+ with open(self._kbnames_file, encoding='utf-8') as kbdnames:
+ self._load_file(code, kbdnames)
+ self.current_lang = code
+
+ def _clear(self):
+ self.current_lang = None
+ self.layouts = {}
+ self.variants = defaultdict(dict)
+
+ def _load_file(self, code, kbdnames):
+ for line in kbdnames:
+ line = line.rstrip('\n')
+ got_lang, element, name, value = line.split("*", 3)
+ if got_lang != code:
+ continue
+
+ if element == "layout":
+ self.layouts[name] = value
+ elif element == "variant":
+ variantname, variantdesc = value.split("*", 1)
+ self.variants[name][variantname] = variantdesc
+
+ def lookup(self, code):
+ if ':' in code:
+ layout_code, variant_code = code.split(":", 1)
+ layout = self.layouts.get(layout_code, '?')
+ variant = self.variants.get(layout_code, {}).get(variant_code, '?')
+ return (layout, variant)
+ else:
+ return self.layouts.get(code, '?'), None
diff --git a/subiquity/models/keyboard.py b/subiquity/models/keyboard.py
index 288c2359..8330bc3a 100644
--- a/subiquity/models/keyboard.py
+++ b/subiquity/models/keyboard.py
@@ -1,224 +1,43 @@
+# Copyright 2020 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
-from collections import defaultdict
import logging
import os
-import re
-import attr
-
-from subiquitycore.utils import arun_command
+from subiquity.common.keyboard import from_config_file, render
+from subiquity.common.types import KeyboardSetting
log = logging.getLogger("subiquity.models.keyboard")
-etc_default_keyboard_template = """\
-# KEYBOARD CONFIGURATION FILE
-
-# Consult the keyboard(5) manual page.
-
-XKBMODEL="pc105"
-XKBLAYOUT="{layout}"
-XKBVARIANT="{variant}"
-XKBOPTIONS="{options}"
-
-BACKSPACE="guess"
-"""
-
-
-@attr.s
-class KeyboardSetting:
- layout = attr.ib()
- variant = attr.ib(default='')
- toggle = attr.ib(default=None)
-
- def render(self):
- options = ""
- if self.toggle:
- options = "grp:" + self.toggle
- return etc_default_keyboard_template.format(
- layout=self.layout, variant=self.variant, options=options)
-
- def latinizable(self):
- """
- If this setting does not allow the typing of latin characters,
- return a setting that can be switched to one that can.
- """
- if self.layout == 'rs':
- if self.variant.startswith('latin'):
- return self
- else:
- if self.variant == 'yz':
- new_variant = 'latinyz'
- elif self.variant == 'alternatequotes':
- new_variant = 'latinalternatequotes'
- else:
- new_variant = 'latin'
- return KeyboardSetting(layout='rs,rs',
- variant=(new_variant +
- ',' + self.variant))
- elif self.layout == 'jp':
- if self.variant in ('106', 'common', 'OADG109A',
- 'nicola_f_bs', ''):
- return self
- else:
- return KeyboardSetting(layout='jp,jp',
- variant=',' + self.variant)
- elif self.layout == 'lt':
- if self.variant == 'us':
- return KeyboardSetting(layout='lt,lt', variant='us,')
- else:
- return KeyboardSetting(layout='lt,lt',
- variant=self.variant + ',us')
- elif self.layout == 'me':
- if self.variant == 'basic' or self.variant.startswith('latin'):
- return self
- else:
- return KeyboardSetting(layout='me,me',
- variant=self.variant + ',us')
- elif self.layout in standard_non_latin_layouts:
- return KeyboardSetting(layout='us,' + self.layout,
- variant=',' + self.variant)
- else:
- return self
-
- @classmethod
- def from_config_file(cls, config_file):
- with open(config_file) as fp:
- content = fp.read()
-
- def optval(opt, default):
- match = re.search(r'(?m)^\s*%s=(.*)$' % (opt,), content)
- if match:
- r = match.group(1).strip('"')
- if r != '':
- return r
- return default
- XKBLAYOUT = optval("XKBLAYOUT", "us")
- XKBVARIANT = optval("XKBVARIANT", "")
- XKBOPTIONS = optval("XKBOPTIONS", "")
- toggle = None
- for option in XKBOPTIONS.split(','):
- if option.startswith('grp:'):
- toggle = option[4:]
- return cls(layout=XKBLAYOUT, variant=XKBVARIANT, toggle=toggle)
-
- def for_ui(self):
- """
- Attempt to guess a setting the user chose which resulted in the
- current config. Basically the inverse of latinizable().
- """
- if ',' in self.layout:
- layout1, layout2 = self.layout.split(',', 1)
- else:
- layout1, layout2 = self.layout, ''
- if ',' in self.variant:
- variant1, variant2 = self.variant.split(',', 1)
- else:
- variant1, variant2 = self.variant, ''
- if self.layout == 'lt,lt':
- layout = layout1
- variant = variant1
- elif self.layout in ('rs,rs', 'us,rs', 'jp,jp', 'us,jp'):
- layout = layout2
- variant = variant2
- elif layout1 == 'us' and layout2 in standard_non_latin_layouts:
- layout = layout2
- variant = variant2
- elif ',' in self.layout:
- # Something unrecognized
- layout = 'us'
- variant = ''
- else:
- return self
- return KeyboardSetting(layout=layout, variant=variant)
-
-
-# Non-latin keyboard layouts that are handled in a uniform way
-standard_non_latin_layouts = set(
- ('af', 'am', 'ara', 'ben', 'bd', 'bg', 'bt', 'by', 'et', 'ge',
- 'gh', 'gr', 'guj', 'guru', 'il', 'in', 'iq', 'ir', 'iku', 'kan',
- 'kh', 'kz', 'la', 'lao', 'lk', 'kg', 'ma', 'mk', 'mm', 'mn', 'mv',
- 'mal', 'np', 'ori', 'pk', 'ru', 'scc', 'sy', 'syr', 'tel', 'th',
- 'tj', 'tam', 'tib', 'ua', 'ug', 'uz')
-)
-
class KeyboardModel:
+
def __init__(self, root):
self.root = root
- self._kbnames_file = os.path.join(os.environ.get("SNAP", '.'),
- 'kbdnames.txt')
- self._clear()
- if os.path.exists(self.config_path):
- self.setting = KeyboardSetting.from_config_file(self.config_path)
+ config_path = os.path.join(self.root, 'etc', 'default', 'keyboard')
+ if os.path.exists(config_path):
+ self.setting = from_config_file(config_path)
else:
self.setting = KeyboardSetting(layout='us')
- @property
- def config_path(self):
- return os.path.join(self.root, 'etc', 'default', 'keyboard')
-
- def has_language(self, code):
- self.load_language(code)
- return bool(self.layouts)
-
- def load_language(self, code):
- if code == self.current_lang:
- return
-
- self._clear()
-
- with open(self._kbnames_file, encoding='utf-8') as kbdnames:
- self._load_file(code, kbdnames)
- self.current_lang = code
-
- def _clear(self):
- self.current_lang = None
- self.layouts = {}
- self.variants = defaultdict(dict)
-
- def _load_file(self, code, kbdnames):
- for line in kbdnames:
- line = line.rstrip('\n')
- got_lang, element, name, value = line.split("*", 3)
- if got_lang != code:
- continue
-
- if element == "layout":
- self.layouts[name] = value
- elif element == "variant":
- variantname, variantdesc = value.split("*", 1)
- self.variants[name][variantname] = variantdesc
-
- def lookup(self, code):
- if ':' in code:
- layout_code, variant_code = code.split(":", 1)
- layout = self.layouts.get(layout_code, '?')
- variant = self.variants.get(layout_code, {}).get(variant_code, '?')
- return (layout, variant)
- else:
- return self.layouts.get(code, '?'), None
-
- async def set_keyboard(self, setting):
- path = self.config_path
- os.makedirs(os.path.dirname(path), exist_ok=True)
- with open(path, 'w') as fp:
- fp.write(setting.render())
- if setting != self.setting:
- self.setting = setting
- if self.root == '/':
- await arun_command([
- 'setupcon', '--save', '--force', '--keyboard-only'])
- await arun_command(['/snap/bin/subiquity.subiquity-loadkeys'])
- else:
- scale = os.environ.get('SUBIQUITY_REPLAY_TIMESCALE', "1")
- await arun_command(['sleep', str(1/float(scale))])
-
def render(self):
return {
'write_files': {
'etc_default_keyboard': {
'path': 'etc/default/keyboard',
- 'content': self.setting.render(),
+ 'content': render(self.setting),
'permissions': 0o644,
},
},
diff --git a/subiquity/ui/views/keyboard.py b/subiquity/ui/views/keyboard.py
index 3a2fbfb7..1514ee28 100644
--- a/subiquity/ui/views/keyboard.py
+++ b/subiquity/ui/views/keyboard.py
@@ -44,7 +44,8 @@ from subiquitycore.ui.stretchy import (
from subiquitycore.ui.utils import button_pile, Color, Padding, screen
from subiquitycore.view import BaseView
-from subiquity.models.keyboard import KeyboardSetting
+from subiquity.common.types import KeyboardSetting
+from subiquity.keyboard import latinizable, for_ui
from subiquity.ui.views import pc105
log = logging.getLogger("subiquity.ui.views.keyboard")
@@ -129,8 +130,8 @@ another layout or run the automated detection again.
self.keyboard_detector.keyboard_view.found_layout(self.step.result)
def make_body(self):
- model = self.keyboard_detector.keyboard_view.model
- layout, variant = model.lookup(self.step.result)
+ kl = self.keyboard_detector.keyboard_view.keyboard_list
+ layout, variant = kl.lookup(self.step.result)
var_desc = []
layout_text = _("Layout")
var_text = _("Variant")
@@ -340,9 +341,9 @@ class ToggleQuestion(Stretchy):
self.setting = setting
self.selector = Selector(toggle_options)
self.selector.value = 'alt_shift_toggle'
- if self.parent.model.setting.toggle:
+ if self.parent.initial_setting.toggle:
try:
- self.selector.value = self.parent.model.setting.toggle
+ self.selector.value = self.parent.initial_setting.toggle
except AttributeError:
pass
@@ -386,21 +387,21 @@ class KeyboardView(BaseView):
title = _("Keyboard configuration")
- def __init__(self, model, controller, opts):
- self.model = model
+ def __init__(self, controller, initial_setting):
self.controller = controller
- self.opts = opts
+ self.keyboard_list = controller.keyboard_list
+ self.initial_setting = initial_setting
self.form = KeyboardForm()
opts = []
- for layout, desc in model.layouts.items():
+ for layout, desc in self.keyboard_list.layouts.items():
opts.append(Option((desc, True, layout)))
opts.sort(key=lambda o: o.label.text)
connect_signal(self.form, 'submit', self.done)
connect_signal(self.form, 'cancel', self.cancel)
connect_signal(self.form.layout.widget, "select", self.select_layout)
self.form.layout.widget.options = opts
- setting = model.setting.for_ui()
+ setting = for_ui(initial_setting)
try:
self.form.layout.widget.value = setting.layout
except AttributeError:
@@ -413,7 +414,7 @@ class KeyboardView(BaseView):
# Don't crash on pre-existing invalid config.
pass
- if self.opts.run_on_serial:
+ if self.controller.opts.run_on_serial:
excerpt = _('Please select the layout of the keyboard directly '
'attached to the system, if any.')
else:
@@ -422,7 +423,7 @@ class KeyboardView(BaseView):
'automatically.')
lb_contents = self.form.as_rows()
- if not self.opts.run_on_serial:
+ if not self.controller.opts.run_on_serial:
lb_contents.extend([
Text(""),
button_pile([
@@ -457,17 +458,19 @@ class KeyboardView(BaseView):
if self.form.variant.widget.value is not None:
variant = self.form.variant.widget.value
setting = KeyboardSetting(layout=layout, variant=variant)
- new_setting = setting.latinizable()
+ new_setting = latinizable(setting)
if new_setting != setting:
self.show_stretchy_overlay(ToggleQuestion(self, new_setting))
return
self.really_done(setting)
def really_done(self, setting):
- if setting != self.model.setting:
+ apply = False
+ if setting != self.initial_setting:
+ apply = True
ac = ApplyingConfig(self.controller.app.aio_loop)
self.show_overlay(ac, width=ac.width, min_width=None)
- self.controller.done(setting)
+ self.controller.done(setting, apply=apply)
def cancel(self, result=None):
self.controller.cancel()
@@ -477,7 +480,7 @@ class KeyboardView(BaseView):
log.debug("select_layout %s", layout)
opts = []
default_i = -1
- layout_items = enumerate(self.model.variants[layout].items())
+ layout_items = enumerate(self.keyboard_list.variants[layout].items())
for i, (variant, variant_desc) in layout_items:
if variant == "":
default_i = i