diff --git a/data/GtkGreeterSettingsWindow.ui b/data/GtkGreeterSettingsWindow.ui index 8e95946..7899558 100644 --- a/data/GtkGreeterSettingsWindow.ui +++ b/data/GtkGreeterSettingsWindow.ui @@ -60,7 +60,7 @@ lightdm-gtk-greeter-settings - + True False 8 @@ -753,6 +753,9 @@ True False + %H %I - hours, %M - minutes, %S - seconds +%d - day, %m - month, %y %Y - year +%a %A - day of the week, %b %B - month name 24 True <preview> @@ -763,26 +766,6 @@ 0 2 - 2 - - - - - True - False - start - 24 - True - %H %I - hours, %M - minutes, %S - seconds -%d - day, %m - month, %y %Y - year -%a %A - day of the week, %b %B - month name - - - - - - 0 - 3 2 @@ -1791,7 +1774,6 @@ - True True False warning @@ -1815,10 +1797,10 @@ False 8 - - True - False - You don't have permissions to change greeter configuration + + True + False + label center True diff --git a/lightdm-gtk-greeter-settings.desktop.in b/lightdm-gtk-greeter-settings.desktop.in index dd8f508..13ad205 100644 --- a/lightdm-gtk-greeter-settings.desktop.in +++ b/lightdm-gtk-greeter-settings.desktop.in @@ -1,6 +1,7 @@ [Desktop Entry] _Name=LightDM GTK+ Greeter settings -Categories=GNOME;GTK;Settings;System;Utility;X-XFCE-SettingsDialog; +_Comment=Configure LightDM GTK+ Greeter +Categories=GNOME;GTK;Settings;System;Utility;X-XFCE-SettingsDialog;X-XFCE-SystemSettings; Keywords=Configuration;Utility; Exec=lightdm-gtk-greeter-settings-pkexec Icon=lightdm-gtk-greeter-settings diff --git a/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py b/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py index d04ea53..ee3235e 100644 --- a/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py +++ b/lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py @@ -41,12 +41,20 @@ from lightdm_gtk_greeter_settings.helpers import ( C_, string2bool, + SimpleEnum, WidgetsEnum) from lightdm_gtk_greeter_settings.MonitorsGroup import MonitorsGroup from lightdm_gtk_greeter_settings.OptionGroup import SimpleGroup -__all__ = ['GtkGreeterSettingsWindow'] +__all__ = ['GtkGreeterSettingsWindow', + 'WindowMode'] + + +class WindowMode(SimpleEnum): + Default = 'default' + Embedded = 'embedded' + GtkHeader = 'gtk-header' InitialValue = collections.namedtuple('InitialValue', ('value', 'enabled')) @@ -58,18 +66,25 @@ class Widgets(WidgetsEnum): apply = 'apply_button' + reload = 'reset_button' + close = 'close_button' + buttons = 'dialog_buttons' + content = 'content_box' infobar = 'infobar' - - def __new__(cls): + infobar_label = 'infobar_label' + + def __new__(cls, mode=WindowMode.Default): builder = Gtk.Builder() builder.add_from_file(helpers.get_data_path('%s.ui' % cls.__name__)) window = builder.get_object('settings_window') window.builder = builder + window.mode = mode builder.connect_signals(window) window.init_window() return window builder = None + mode = WindowMode.Default entries_setup = { ('greeter', 'allow-debugging'): ('changed',), @@ -122,17 +137,39 @@ self._config_path = helpers.get_config_path() self._allow_edit = self._has_access_to_write(self._config_path) - self._widgets.infobar.props.visible = not self._allow_edit self._widgets.apply.props.visible = self._allow_edit if not self._allow_edit: - helpers.show_message( - text=_('No permissions to save configuration'), - secondary_text=_( - 'It seems that you don\'t have permissions to write to ' - 'file:\n{path}\n\nTry to run this program using "sudo" ' - 'or "pkexec"').format(path=self._config_path), - message_type=Gtk.MessageType.WARNING) + self._set_message(_('You don\'t have permissions to change greeter configuration'), + Gtk.MessageType.WARNING) + if self.mode != WindowMode.Embedded: + helpers.show_message( + text=_('No permissions to save configuration'), + secondary_text=_( + 'It seems that you don\'t have permissions to write to ' + 'file:\n{path}\n\nTry to run this program using "sudo" ' + 'or "pkexec"').format(path=self._config_path), + message_type=Gtk.MessageType.WARNING) + + if self.mode == WindowMode.Embedded: + self._widgets.buttons.hide() + self.on_entry_changed = self.on_entry_changed_embedded + self._widgets.content.reorder_child(self._widgets.infobar, 0) + elif self.mode == WindowMode.GtkHeader: + self._widgets.buttons.remove(self._widgets.apply) + self._widgets.buttons.remove(self._widgets.reload) + self._widgets.buttons.hide() + self._widgets.apply.set_label('') + self._widgets.reload.set_label('') + + header = Gtk.HeaderBar() + header.set_show_close_button(True) + header.props.title = self.get_title() + header.pack_start(self._widgets.reload) + header.pack_start(self._widgets.apply) + header.show_all() + + self.set_titlebar(header) self._config = configparser.RawConfigParser(strict=False) self._read() @@ -142,12 +179,20 @@ return True return os.access(os.path.dirname(self._config_path), os.W_OK | os.X_OK) + def _set_message(self, message, type_=Gtk.MessageType.INFO): + if not message: + self._widgets.infobar.hide() + + self._widgets.infobar.props.message_type = type_ + self._widgets.infobar_label.props.label = message + self._widgets.infobar.show() + def _read(self): self._config.clear() try: - if not self._config.read(self._config_path): - helpers.show_message(text=_('Failed to read configuration ' - 'file: {path}') + if not self._config.read(self._config_path) and \ + self.mode != WindowMode.Embedded: + helpers.show_message(text=_('Failed to read configuration file: {path}') .format(path=self._config_path), message_type=Gtk.MessageType.ERROR) except (configparser.DuplicateSectionError, @@ -168,11 +213,12 @@ for group in self._groups: group.write(self._config) - for entry in self._changed_entries: - self._initial_values[entry] = InitialValue(entry.value, entry.enabled) - - self._changed_entries.clear() - self._widgets.apply.props.sensitive = False + if self.mode != WindowMode.Embedded: + for entry in self._changed_entries: + self._initial_values[entry] = InitialValue(entry.value, entry.enabled) + + self._changed_entries.clear() + self._widgets.apply.props.sensitive = False try: with open(self._config_path, 'w') as file: @@ -220,6 +266,20 @@ self._changed_entries.discard(entry) self._widgets.apply.props.sensitive = self._allow_edit and self._changed_entries + + def on_entry_changed_embedded(self, entry, force=False): + if self._changed_entries is None: + return + + initial = self._initial_values[entry] + if force or entry.enabled != initial.enabled or \ + (entry.enabled and entry.value != initial.value): + self._changed_entries.add(entry) + else: + self._changed_entries.discard(entry) + + if self._allow_edit: + self._write() def on_entry_reset_clicked(self, item): entry, value, enabled = item._reset_entry_data diff --git a/lightdm_gtk_greeter_settings/__init__.py b/lightdm_gtk_greeter_settings/__init__.py index 470a8cb..794aac1 100644 --- a/lightdm_gtk_greeter_settings/__init__.py +++ b/lightdm_gtk_greeter_settings/__init__.py @@ -18,14 +18,40 @@ def main(): from gi.repository import Gtk + from lightdm_gtk_greeter_settings import helpers from lightdm_gtk_greeter_settings import GtkGreeterSettingsWindow + from lightdm_gtk_greeter_settings.GtkGreeterSettingsWindow import WindowMode + import argparse import locale locale.textdomain('lightdm-gtk-greeter-settings') - window = GtkGreeterSettingsWindow.GtkGreeterSettingsWindow() - window.show() - Gtk.main() + parser = argparse.ArgumentParser(description='LightDM Gtk+ Greeter settings editor') + parser.add_argument('-s', '--socket-id', action='store', help='Settings manager socket') + parser.add_argument('--use-gtk-header', action='store_const', const=True, + help='Use GtkHeaderBar') + args = parser.parse_args() + + try: + socket_id = int(args.socket_id or '') + except ValueError: + socket_id = None + + if socket_id: + window = GtkGreeterSettingsWindow.GtkGreeterSettingsWindow(WindowMode.Embedded) + plug = Gtk.Plug.new(socket_id) + plug.connect('delete-event', Gtk.main_quit) + plug.show() + content = window.builder.get_object('content_box') + content.reparent(plug) + Gtk.main() + else: + if args.use_gtk_header: + window = GtkGreeterSettingsWindow.GtkGreeterSettingsWindow(mode=WindowMode.GtkHeader) + else: + window = GtkGreeterSettingsWindow.GtkGreeterSettingsWindow() + window.show() + Gtk.main() if __name__ == '__main__':