diff --git a/data/GtkGreeterSettingsWindow.ui b/data/GtkGreeterSettingsWindow.ui index 3f3fec6..952424c 100644 --- a/data/GtkGreeterSettingsWindow.ui +++ b/data/GtkGreeterSettingsWindow.ui @@ -1378,12 +1378,43 @@ 8 - Keyboard True True False 0 True + + + True + False + + + True + False + Keyboard + + + False + True + 0 + + + + + False + 0 + 12 + dialog-warning + 1 + + + False + True + 1 + + + + 0 @@ -1392,12 +1423,43 @@ - Reader True True False 0 True + + + True + False + + + True + False + Reader + + + False + True + 0 + + + + + False + 0 + 12 + dialog-warning + 1 + + + False + True + 1 + + + + 0 diff --git a/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py b/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py index 4a1f0f9..08a5ed7 100644 --- a/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py +++ b/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py @@ -19,6 +19,7 @@ import collections import configparser import os +import shlex import sys from glob import iglob from itertools import chain @@ -72,7 +73,9 @@ ('greeter', 'default-user-image'): ('changed',), ('greeter', 'screensaver-timeout'): ('setup', 'get', 'set'), ('greeter', 'theme-name'): ('setup', 'changed'), - ('greeter', 'icon-theme-name'): ('setup', 'changed')} + ('greeter', 'icon-theme-name'): ('setup', 'changed'), + ('greeter', 'keyboard'): ('changed',), + ('greeter', 'reader'): ('changed',)} def init_window(self): self._widgets = self.Widgets(builder=self.builder) @@ -84,8 +87,8 @@ self._groups = ( SimpleGroup('greeter', self.builder, { # Appearance - 'theme-name': (OptionEntry.StringEntry, None), - 'icon-theme-name': (OptionEntry.StringEntry, None), + 'theme-name': (OptionEntry.StringEntry, ''), + 'icon-theme-name': (OptionEntry.StringEntry, ''), 'font-name': (OptionEntry.FontEntry, 'Sans 10'), 'xft-antialias': (OptionEntry.BooleanEntry, 'false'), 'xft-dpi': (OptionEntry.StringEntry, None), @@ -105,7 +108,7 @@ 'screensaver-timeout': (OptionEntry.AdjustmentEntry, 60), 'keyboard': (OptionEntry.StringPathEntry, None), 'reader': (OptionEntry.StringPathEntry, None), - 'a11y-states': (OptionEntry.AccessibilityStatesEntry, None), + 'a11y-states': (OptionEntry.AccessibilityStatesEntry, ''), 'allow-debugging': (OptionEntry.BooleanEntry, 'false'), }), MonitorsGroup(WidgetsWrapper(self.builder))) @@ -224,13 +227,21 @@ adjustment) def on_entry_get_greeter_screensaver_timeout(self, entry=None, value=None): - value = int(float(value)) + try: + value = int(float(value)) + except ValueError: + value = 60 + if value > 60: return (value - 59) * 60 return value def on_entry_set_greeter_screensaver_timeout(self, entry=None, value=None): - value = int(float(value)) + try: + value = int(float(value)) + except ValueError: + value = 60 + if value > 60: return value // 60 + 59 return value @@ -292,6 +303,21 @@ else: entry.error = helpers.check_path_accessibility(value) + # [greeter] keyboard + def on_entry_changed_greeter_keyboard(self, entry): + error = None + if entry.enabled: + value = entry.value + if os.path.isabs(value): + argv = shlex.split(value) + error = helpers.check_path_accessibility(argv[0], executable=True) + elif not value: + error = _('Do not leave this field empty') + entry.error = error + + # [greeter] reader + on_entry_changed_greeter_reader = on_entry_changed_greeter_keyboard + def on_destroy(self, *unused): Gtk.main_quit() diff --git a/lightdm_gtk_greeter_settings/IndicatorsEntry.py b/lightdm_gtk_greeter_settings/IndicatorsEntry.py index 2746c0e..5776ab7 100644 --- a/lightdm_gtk_greeter_settings/IndicatorsEntry.py +++ b/lightdm_gtk_greeter_settings/IndicatorsEntry.py @@ -231,8 +231,6 @@ # text, image, layout=image-text -> text, image if options.get(Option.Layout) == {LayoutSet.Text, LayoutSet.Image}: del options[Option.Layout] - # defaults.pop(Option.Image, None) - # defaults.pop(Option.Text, None) for k in defaults.keys() & options.keys(): if defaults[k] == options[k]: diff --git a/lightdm_gtk_greeter_settings/OptionEntry.py b/lightdm_gtk_greeter_settings/OptionEntry.py index 7ab2c6e..9c8ad5b 100644 --- a/lightdm_gtk_greeter_settings/OptionEntry.py +++ b/lightdm_gtk_greeter_settings/OptionEntry.py @@ -481,7 +481,7 @@ class AccessibilityStatesEntry(BaseEntry): - Options = {'keyboard', 'reader', 'contrast', 'font'} + Options = ('keyboard', 'reader', 'contrast', 'font') def __init__(self, widgets): super().__init__(widgets) diff --git a/lightdm_gtk_greeter_settings/helpers.py b/lightdm_gtk_greeter_settings/helpers.py index 5577d9e..25173f1 100644 --- a/lightdm_gtk_greeter_settings/helpers.py +++ b/lightdm_gtk_greeter_settings/helpers.py @@ -129,7 +129,7 @@ return pixbuf -def check_path_accessibility(path): +def check_path_accessibility(path, file=True, executable=False): """Return None if file is readable by greeter and error message otherwise""" if not os.path.exists(path): @@ -171,7 +171,23 @@ _('LighDM do not have permissions to read path: {path}'.format(path=p)) errors = (check(p) for p in accumulate(parts, os.path.join)) - return next((error for error in errors if error), None) + error = next((error for error in errors if error), None) + + if not error and file and not os.path.isfile(path): + return _('Path is not a regular file: {path}'.format(path=path)) + + if not error and executable: + st = os.stat(path) + if st.st_uid == uid: + if not st.st_mode & stat.S_IXUSR: + return _('LighDM do not have permissions to execute file: {path}'.format(path=path)) + elif st.st_gid in gids: + if not st.st_mode & stat.S_IXGRP: + return _('LighDM do not have permissions to execute file: {path}'.format(path=path)) + elif not st.st_mode & stat.S_IXOTH: + return _('LighDM do not have permissions to execute file: {path}'.format(path=path)) + + return error def get_markup_error(markup):