Merge pull request #170 from CanonicalLtd/mwhudson/kill-some-signals

remove trivial uses of signals for console-conf
This commit is contained in:
Michael Hudson-Doyle 2016-11-03 09:46:01 +13:00 committed by GitHub
commit 1594ff0f32
20 changed files with 127 additions and 132 deletions

View File

@ -30,12 +30,12 @@ class IdentityController(BaseIdentityController):
footer = "" footer = ""
self.ui.set_header(title, excerpt) self.ui.set_header(title, excerpt)
self.ui.set_footer(footer, 40) self.ui.set_footer(footer, 40)
self.ui.set_body(self.identity_view(self.model, self.signal, self.opts, self.loop)) self.ui.set_body(self.identity_view(self.model, self, self.opts, self.loop))
device_owner = self.get_device_owner() device_owner = self.get_device_owner()
if device_owner is not None: if device_owner is not None:
mark_firstboot_complete() mark_firstboot_complete()
self.model.add_user(device_owner) self.model.add_user(device_owner)
self.signal.emit_signal('identity:login') self.login()
def get_device_owner(self): def get_device_owner(self):
""" Check if device is owned """ """ Check if device is owned """
@ -81,7 +81,12 @@ class IdentityController(BaseIdentityController):
'username': data['username'], 'username': data['username'],
} }
self.model.add_user(result) self.model.add_user(result)
self.signal.emit_signal('identity:login') self.login()
def cancel(self):
# You can only go back if we haven't created a user yet.
if self.model.user is None:
self.signal.emit_signal('prev-screen')
def login(self): def login(self):
title = "Configuration Complete" title = "Configuration Complete"
@ -92,11 +97,7 @@ class IdentityController(BaseIdentityController):
net_model = self.controllers['Network'].model net_model = self.controllers['Network'].model
net_model.probe_network() net_model.probe_network()
configured_ifaces = net_model.get_configured_interfaces() configured_ifaces = net_model.get_configured_interfaces()
login_view = LoginView(self.opts, login_view = LoginView(self.opts, self.model, self, configured_ifaces)
self.model,
self.signal,
self.model.user,
configured_ifaces)
self.ui.set_body(login_view) self.ui.set_body(login_view)

View File

@ -28,5 +28,5 @@ class WelcomeController(WelcomeControllerBase):
"account on this all-snap Ubuntu Core system.") "account on this all-snap Ubuntu Core system.")
self.ui.set_header(title, excerpt) self.ui.set_header(title, excerpt)
self.ui.set_footer("") self.ui.set_footer("")
view = WelcomeView(self.model, self.signal) view = WelcomeView(self.model, self)
self.ui.set_body(view) self.ui.set_body(view)

View File

@ -27,5 +27,4 @@ class ConsoleConf(Application):
"Welcome", "Welcome",
"Network", "Network",
"Identity", "Identity",
"Login",
] ]

View File

@ -60,9 +60,9 @@ class SubmittingEmailEditor(EmailEditor):
class IdentityView(BaseView): class IdentityView(BaseView):
def __init__(self, model, signal, opts, loop): def __init__(self, model, controller, opts, loop):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.opts = opts self.opts = opts
self.loop = loop self.loop = loop
self.items = [] self.items = []
@ -105,10 +105,10 @@ class IdentityView(BaseView):
return Pile(buttons) return Pile(buttons)
def cancel(self, button): def cancel(self, button):
self.signal.emit_signal('prev-screen') self.controller.cancel()
def done(self, button): def done(self, button):
if len(self.email.value) < 1: if len(self.email.value) < 1:
self.error.set_text("Please enter an email address.") self.error.set_text("Please enter an email address.")
return return
self.signal.emit_signal('identity:done', self.email.value) self.controller.identity_done(self.email.value)

View File

@ -28,11 +28,10 @@ log = logging.getLogger("subiquitycore.views.login")
class LoginView(BaseView): class LoginView(BaseView):
def __init__(self, opts, model, signal, user, ifaces): def __init__(self, opts, model, controller, ifaces):
self.opts = opts self.opts = opts
self.model = model self.model = model
self.signal = signal self.controller = controller
self.user = user
self.ifaces = ifaces self.ifaces = ifaces
self.items = [] self.items = []
self.body = [ self.body = [
@ -118,4 +117,4 @@ class LoginView(BaseView):
self.done() self.done()
def done(self, button): def done(self, button):
self.signal.emit_signal('identity:login:done') self.controller.login_done()

View File

@ -34,6 +34,3 @@ class WelcomeView(CoreWelcomeView):
focus_map='button focus'), focus_map='button focus'),
] ]
return Pile(self.buttons) return Pile(self.buttons)
def confirm(self, result):
self.signal.emit_signal('welcome:done')

View File

@ -14,14 +14,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from abc import ABC, abstractmethod
import logging import logging
log = logging.getLogger("subiquitycore.controller") log = logging.getLogger("subiquitycore.controller")
class BaseController: class BaseController(ABC):
"""Base class for controllers.""" """Base class for controllers."""
signals = []
def __init__(self, common): def __init__(self, common):
self.ui = common['ui'] self.ui = common['ui']
self.signal = common['signal'] self.signal = common['signal']
@ -37,5 +40,10 @@ class BaseController:
signals.append((sig, getattr(self, cb))) signals.append((sig, getattr(self, cb)))
self.signal.connect_signals(signals) self.signal.connect_signals(signals)
@abstractmethod
def cancel(self):
pass
@abstractmethod
def default(self): def default(self):
raise NotImplementedError(self.default) pass

View File

@ -17,6 +17,7 @@ import logging
from subiquitycore.controller import BaseController from subiquitycore.controller import BaseController
from subiquitycore.models import IdentityModel from subiquitycore.models import IdentityModel
from subiquitycore.ui.views import LoginView from subiquitycore.ui.views import LoginView
from subiquitycore import utils
log = logging.getLogger('subiquitycore.controllers.identity') log = logging.getLogger('subiquitycore.controllers.identity')
@ -25,12 +26,6 @@ class BaseIdentityController(BaseController):
identity_view = None identity_view = None
signals = [
('identity:done', 'identity_done'),
('identity:login', 'login'),
('identity:login:done', 'login_done'),
]
def __init__(self, common): def __init__(self, common):
super().__init__(common) super().__init__(common)
self.model = IdentityModel(self.opts) self.model = IdentityModel(self.opts)
@ -41,10 +36,13 @@ class BaseIdentityController(BaseController):
footer = "" footer = ""
self.ui.set_header(title, excerpt) self.ui.set_header(title, excerpt)
self.ui.set_footer(footer, 40) self.ui.set_footer(footer, 40)
self.ui.set_body(self.identity_view(self.model, self.signal, self.opts)) self.ui.set_body(self.identity_view(self.model, self, self.opts))
def cancel(self):
self.signal.emit_signal('prev-screen')
def identity_done(self): def identity_done(self):
self.signal.emit_signal('identity:login') self.login()
def login(self): def login(self):
log.debug("Identity login view") log.debug("Identity login view")
@ -55,12 +53,15 @@ class BaseIdentityController(BaseController):
net_model = self.controllers['Network'].model net_model = self.controllers['Network'].model
configured_ifaces = net_model.get_configured_interfaces() configured_ifaces = net_model.get_configured_interfaces()
login_view = LoginView(self.model, login_view = LoginView(self.model, self, configured_ifaces)
self.signal,
self.model.user,
configured_ifaces)
self.ui.set_body(login_view) self.ui.set_body(login_view)
def login_done(self): def login_done(self):
# mark ourselves complete
utils.mark_firstboot_complete()
# disable the UI service restoring getty service
utils.disable_first_boot_service()
self.signal.emit_signal('quit') self.signal.emit_signal('quit')

View File

@ -186,6 +186,14 @@ class TaskSequence:
self.call_from_thread(self.watcher.task_error, self.stage) self.call_from_thread(self.watcher.task_error, self.stage)
def view(func):
n = func.__name__
def f(self, *args, **kw):
m = getattr(self, n)
self.view_stack.append((m, args, kw))
return func(self, *args, **kw)
return f
netplan_path = '/etc/netplan/00-snapd-config.yaml' netplan_path = '/etc/netplan/00-snapd-config.yaml'
def sanitize_config(config): def sanitize_config(config):
@ -200,11 +208,6 @@ def sanitize_config(config):
class NetworkController(BaseController): class NetworkController(BaseController):
signals = [ signals = [
('menu:network:main:start', 'start'),
('network:finish', 'network_finish'),
('menu:network:main:configure-interface', 'network_configure_interface'),
('menu:network:main:configure-ipv4-interface', 'network_configure_ipv4_interface'),
('menu:network:main:configure-wlan-interface', 'network_configure_wlan_interface'),
('menu:network:main:set-default-v4-route', 'set_default_v4_route'), ('menu:network:main:set-default-v4-route', 'set_default_v4_route'),
('menu:network:main:set-default-v6-route', 'set_default_v6_route'), ('menu:network:main:set-default-v6-route', 'set_default_v6_route'),
] ]
@ -212,13 +215,27 @@ class NetworkController(BaseController):
def __init__(self, common): def __init__(self, common):
super().__init__(common) super().__init__(common)
self.model = NetworkModel(self.prober, self.opts) self.model = NetworkModel(self.prober, self.opts)
self.view_stack = []
def prev_view(self):
self.view_stack.pop()
meth, args, kw = self.view_stack.pop()
meth(*args, **kw)
def cancel(self):
if len(self.view_stack) <= 1:
self.signal.emit_signal('prev-screen')
else:
self.prev_view()
def default(self): def default(self):
self.model.reset() self.model.reset()
self.view_stack = []
log.info("probing for network devices") log.info("probing for network devices")
self.model.probe_network() self.model.probe_network()
self.signal.emit_signal('menu:network:main:start') self.start()
@view
def start(self): def start(self):
title = "Network connections" title = "Network connections"
excerpt = ("Configure at least the main interface this server will " excerpt = ("Configure at least the main interface this server will "
@ -226,7 +243,7 @@ class NetworkController(BaseController):
footer = ("Additional networking info here") footer = ("Additional networking info here")
self.ui.set_header(title, excerpt) self.ui.set_header(title, excerpt)
self.ui.set_footer(footer, 20) self.ui.set_footer(footer, 20)
self.ui.set_body(NetworkView(self.model, self.signal)) self.ui.set_body(NetworkView(self.model, self))
def network_finish(self, config): def network_finish(self, config):
log.debug("network config: \n%s", yaml.dump(sanitize_config(config), default_flow_style=False)) log.debug("network config: \n%s", yaml.dump(sanitize_config(config), default_flow_style=False))
@ -286,53 +303,44 @@ class NetworkController(BaseController):
def tasks_finished(self): def tasks_finished(self):
self.signal.emit_signal('next-screen') self.signal.emit_signal('next-screen')
@view
def set_default_v4_route(self): def set_default_v4_route(self):
self.ui.set_header("Default route") self.ui.set_header("Default route")
self.ui.set_body(NetworkSetDefaultRouteView(self.model, self.ui.set_body(NetworkSetDefaultRouteView(self.model, netifaces.AF_INET, self))
netifaces.AF_INET,
self.signal))
@view
def set_default_v6_route(self): def set_default_v6_route(self):
self.ui.set_header("Default route") self.ui.set_header("Default route")
self.ui.set_body(NetworkSetDefaultRouteView(self.model, self.ui.set_body(NetworkSetDefaultRouteView(self.model, netifaces.AF_INET6, self))
netifaces.AF_INET6,
self.signal))
@view
def bond_interfaces(self): def bond_interfaces(self):
self.ui.set_header("Bond interfaces") self.ui.set_header("Bond interfaces")
self.ui.set_body(NetworkBondInterfacesView(self.model, self.ui.set_body(NetworkBondInterfacesView(self.model, self))
self.signal))
@view
def network_configure_interface(self, iface): def network_configure_interface(self, iface):
self.ui.set_header("Network interface {}".format(iface)) self.ui.set_header("Network interface {}".format(iface))
self.ui.set_body(NetworkConfigureInterfaceView(self.model, self.ui.set_body(NetworkConfigureInterfaceView(self.model, self, iface))
self.signal,
iface))
@view
def network_configure_ipv4_interface(self, iface): def network_configure_ipv4_interface(self, iface):
self.model.prev_signal = ('Back to configure interface menu',
'network:configure-interface-menu',
'network_configure_interface')
self.ui.set_header("Network interface {} manual IPv4 " self.ui.set_header("Network interface {} manual IPv4 "
"configuration".format(iface)) "configuration".format(iface))
self.ui.set_body(NetworkConfigureIPv4InterfaceView(self.model, self.ui.set_body(NetworkConfigureIPv4InterfaceView(self.model, self, iface))
self.signal,
iface))
@view
def network_configure_wlan_interface(self, iface): def network_configure_wlan_interface(self, iface):
self.model.prev_signal = ('Back to configure interface menu',
'network:configure-interface-menu',
'network_configure_interface')
self.ui.set_header("Network interface {} manual IPv4 " self.ui.set_header("Network interface {} manual IPv4 "
"configuration".format(iface)) "configuration".format(iface))
self.ui.set_body(NetworkConfigureWLANView(self.model, self.signal, iface)) self.ui.set_body(NetworkConfigureWLANView(self.model, self, iface))
@view
def network_configure_ipv6_interface(self, iface): def network_configure_ipv6_interface(self, iface):
self.model.prev_signal = ('Back to configure interface menu', self.ui.set_body(DummyView(self))
'network:configure-interface-menu',
'network_configure_interface')
self.ui.set_body(DummyView(self.signal))
@view
def install_network_driver(self): def install_network_driver(self):
self.ui.set_body(DummyView(self.signal)) self.ui.set_body(DummyView(self))

View File

@ -21,10 +21,6 @@ from subiquitycore.controller import BaseController
class WelcomeController(BaseController): class WelcomeController(BaseController):
signals = [
('welcome:done', 'done'),
]
def __init__(self, common): def __init__(self, common):
super().__init__(common) super().__init__(common)
self.model = WelcomeModel() self.model = WelcomeModel()
@ -36,8 +32,12 @@ class WelcomeController(BaseController):
"select your language.") "select your language.")
self.ui.set_header(title, excerpt) self.ui.set_header(title, excerpt)
self.ui.set_footer(footer) self.ui.set_footer(footer)
view = WelcomeView(self.model, self.signal) view = WelcomeView(self.model, self)
self.ui.set_body(view) self.ui.set_body(view)
def done(self): def done(self):
self.signal.emit_signal('next-screen') self.signal.emit_signal('next-screen')
def cancel(self):
# Can't go back from here!
pass

View File

@ -61,6 +61,7 @@ class IdentityModel(BaseModel):
def __init__(self, opts): def __init__(self, opts):
self.opts = opts self.opts = opts
self._user = None
def add_user(self, result): def add_user(self, result):
if result: if result:

View File

@ -38,9 +38,10 @@ USERNAME_MAXLEN = 32
class BaseIdentityView(BaseView): class BaseIdentityView(BaseView):
def __init__(self, model, signal, opts): def __init__(self, model, controller, opts):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.signal = controller.signal
self.opts = opts self.opts = opts
self.items = [] self.items = []
self.realname = RealnameEditor(caption="") self.realname = RealnameEditor(caption="")

View File

@ -23,16 +23,14 @@ from urwid import (ListBox, Pile, Text)
from subiquitycore.ui.buttons import finish_btn from subiquitycore.ui.buttons import finish_btn
from subiquitycore.ui.utils import Padding, Color from subiquitycore.ui.utils import Padding, Color
from subiquitycore.view import BaseView from subiquitycore.view import BaseView
from subiquitycore import utils
log = logging.getLogger("subiquitycore.views.login") log = logging.getLogger("subiquitycore.views.login")
class LoginView(BaseView): class LoginView(BaseView):
def __init__(self, model, signal, user, ifaces): def __init__(self, model, controller, ifaces):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.user = user
self.ifaces = ifaces self.ifaces = ifaces
self.items = [] self.items = []
self.body = [ self.body = [
@ -112,14 +110,5 @@ class LoginView(BaseView):
return Pile(sl) return Pile(sl)
def confirm(self, result):
self.done()
def done(self, button): def done(self, button):
# mark ourselves complete self.controller.login_done()
utils.mark_firstboot_complete()
# disable the UI service restoring getty service
utils.disable_first_boot_service()
self.signal.emit_signal('quit')

View File

@ -55,9 +55,9 @@ class ApplyingConfigWidget(WidgetWrap):
class NetworkView(BaseView): class NetworkView(BaseView):
def __init__(self, model, signal): def __init__(self, model, controller):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.items = [] self.items = []
self.error = Text("", align='center') self.error = Text("", align='center')
self.body = [ self.body = [
@ -264,12 +264,11 @@ class NetworkView(BaseView):
return Pile(labels + buttons) return Pile(labels + buttons)
def additional_menu_select(self, result, sig): def additional_menu_select(self, result, sig):
self.signal.emit_signal(sig) self.controller.signal.emit_signal(sig)
def on_net_dev_press(self, result): def on_net_dev_press(self, result):
log.debug("Selected network dev: {}".format(result.label)) log.debug("Selected network dev: {}".format(result.label))
self.signal.emit_signal('menu:network:main:configure-interface', self.controller.network_configure_interface(result.label)
result.label)
def show_network_error(self, action): def show_network_error(self, action):
if action == 'generate': if action == 'generate':
@ -288,7 +287,7 @@ class NetworkView(BaseView):
"please verify your settings.") "please verify your settings.")
def done(self, result): def done(self, result):
self.signal.emit_signal('network:finish', self.model.render()) self.controller.network_finish(self.model.render())
def cancel(self, button): def cancel(self, button):
self.signal.emit_signal('prev-screen') self.controller.cancel()

View File

@ -24,9 +24,9 @@ log = logging.getLogger('subiquitycore.ui.bond_interfaces')
class NetworkBondInterfacesView(BaseView): class NetworkBondInterfacesView(BaseView):
def __init__(self, model, signal): def __init__(self, model, controller):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.bond_iface = None self.bond_iface = None
self.bond_mode = Selector(self.model.bonding_modes.values()) self.bond_mode = Selector(self.model.bonding_modes.values())
self.selected_ifaces = [] self.selected_ifaces = []
@ -128,8 +128,8 @@ class NetworkBondInterfacesView(BaseView):
return return
log.debug('bond: successful bond creation') log.debug('bond: successful bond creation')
self.signal.prev_signal() self.controller.prev_view()
def cancel(self, button): def cancel(self, button):
log.debug('bond: button_cancel') log.debug('bond: button_cancel')
self.signal.prev_signal() self.controller.prev_view()

View File

@ -24,9 +24,9 @@ log = logging.getLogger('subiquitycore.network.network_configure_interface')
class NetworkConfigureInterfaceView(BaseView): class NetworkConfigureInterfaceView(BaseView):
def __init__(self, model, signal, iface): def __init__(self, model, controller, iface):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.iface = iface self.iface = iface
self.iface_obj = self.model.get_interface(iface) self.iface_obj = self.model.get_interface(iface)
self._build_widgets() self._build_widgets()
@ -204,27 +204,24 @@ class NetworkConfigureInterfaceView(BaseView):
self.update_interface() self.update_interface()
def show_wlan_configuration(self, btn): def show_wlan_configuration(self, btn):
self.signal.emit_signal( self.controller.network_configure_wlan_interface(self.iface)
'menu:network:main:configure-wlan-interface', self.iface)
def show_ipv4_configuration(self, btn): def show_ipv4_configuration(self, btn):
self.signal.emit_signal( self.controller.network_configure_ipv4_interface(self.iface)
'menu:network:main:configure-ipv4-interface', self.iface)
def show_ipv6_configuration(self, btn): def show_ipv6_configuration(self, btn):
log.debug("calling menu:network:main:configure-ipv6-interface") log.debug("calling configure-ipv6-interface")
# TODO: implement UI for configuring static IPv6. # TODO: implement UI for configuring static IPv6.
# self.signal.emit_signal( # self.network_configure_ipv6_interface(self.iface)
# 'menu:network:main:configure-ipv6-interface', self.iface)
def done(self, result): def done(self, result):
self.signal.prev_signal() self.controller.prev_view()
class NetworkConfigureWLANView(BaseView): class NetworkConfigureWLANView(BaseView):
def __init__(self, model, signal, iface): def __init__(self, model, controller, iface):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.iface = iface self.iface = iface
self.iface_obj = self.model.get_interface(iface) self.iface_obj = self.model.get_interface(iface)
self.essid_input = StringEditor(caption="") self.essid_input = StringEditor(caption="")
@ -277,7 +274,7 @@ class NetworkConfigureWLANView(BaseView):
else: else:
self.iface_obj.essid = None self.iface_obj.essid = None
self.iface_obj.wpa_psk = self.psk_input.value self.iface_obj.wpa_psk = self.psk_input.value
self.signal.prev_signal() self.controller.prev_view()
def cancel(self, btn): def cancel(self, btn):
self.signal.prev_signal() self.controller.prev_view()

View File

@ -26,9 +26,9 @@ log = logging.getLogger('subiquitycore.network.network_configure_ipv4_interface'
class NetworkConfigureIPv4InterfaceView(BaseView): class NetworkConfigureIPv4InterfaceView(BaseView):
def __init__(self, model, signal, iface): def __init__(self, model, controller, iface):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.ifname = iface self.ifname = iface
self.iface = self.model.get_interface(self.ifname) self.iface = self.model.get_interface(self.ifname)
self.is_gateway = False self.is_gateway = False
@ -182,8 +182,8 @@ class NetworkConfigureIPv4InterfaceView(BaseView):
return return
# return # return
self.signal.prev_signal() self.controller.prev_view()
def cancel(self, button): def cancel(self, button):
self.model.default_gateway = None self.model.default_gateway = None
self.signal.prev_signal() self.controller.prev_view()

View File

@ -25,10 +25,10 @@ log = logging.getLogger('subiquitycore.network.set_default_route')
class NetworkSetDefaultRouteView(BaseView): class NetworkSetDefaultRouteView(BaseView):
def __init__(self, model, family, signal): def __init__(self, model, family, controller):
self.model = model self.model = model
self.family = family self.family = family
self.signal = signal self.controller = controller
self.default_gateway_w = None self.default_gateway_w = None
self.gateway_options = Pile(self._build_default_routes()) self.gateway_options = Pile(self._build_default_routes())
body = [ body = [
@ -113,7 +113,6 @@ class NetworkSetDefaultRouteView(BaseView):
Color.string_input( Color.string_input(
self.default_gateway_w, self.default_gateway_w,
focus_map="string_input focus")), self.gateway_options.options()) focus_map="string_input focus")), self.gateway_options.options())
# self.signal.emit_signal('refresh')
def done(self, result): def done(self, result):
log.debug("changing default gw: {}".format(result)) log.debug("changing default gw: {}".format(result))
@ -141,7 +140,7 @@ class NetworkSetDefaultRouteView(BaseView):
except ValueError: except ValueError:
# FIXME: raise UX error message # FIXME: raise UX error message
pass pass
self.signal.prev_signal() self.controller.prev_view()
def cancel(self, button): def cancel(self, button):
self.signal.prev_signal() self.controller.prev_view()

View File

@ -29,9 +29,9 @@ log = logging.getLogger("subiquitycore.views.welcome")
class CoreWelcomeView(BaseView): class CoreWelcomeView(BaseView):
def __init__(self, model, signal): def __init__(self, model, controller):
self.model = model self.model = model
self.signal = signal self.controller = controller
self.items = [] self.items = []
# Padding.center_50(self._build_model_inputs()), # Padding.center_50(self._build_model_inputs()),
self.body = [ self.body = [
@ -60,8 +60,4 @@ class CoreWelcomeView(BaseView):
def confirm(self, result): def confirm(self, result):
self.model.selected_language = result.label self.model.selected_language = result.label
log.debug('calling installpath') log.debug('calling installpath')
self.signal.emit_signal('welcome:done') self.controller.done()
def cancel(self, button):
raise SystemExit("No language selected, exiting as there are no "
"more previous controllers to render.")

View File

@ -24,9 +24,9 @@ from urwid import WidgetWrap
class BaseView(WidgetWrap): class BaseView(WidgetWrap):
def keypress(self, size, key): def keypress(self, size, key):
if key == 'esc': if key == 'esc':
self.signal.prev_signal() self.controller.cancel()
return None return None
if key in ['ctrl x']: if key in ['ctrl x']:
self.signal.emit_signal('control-x-quit') self.controller.signal.emit_signal('control-x-quit')
return super().keypress(size, key) return super().keypress(size, key)