From: Daniel Narvaez <dwnarv...@gmail.com> It's quite unexpected to find a large amount of code outside the package. Also it's not really much of a "session", it starts a couple of other processes maybe, but it mostly setups stuff and initialize the UI. --- bin/Makefile.am | 3 +- bin/sugar-session | 352 ------------------------------------------------ bin/sugar.in | 2 +- src/jarabe/Makefile.am | 3 +- src/jarabe/main.py | 351 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 355 insertions(+), 356 deletions(-) delete mode 100755 bin/sugar-session create mode 100755 src/jarabe/main.py
diff --git a/bin/Makefile.am b/bin/Makefile.am index 845816c..cb671da 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -2,8 +2,7 @@ python_scripts = \ sugar-control-panel \ sugar-emulator \ sugar-install-bundle \ - sugar-launch \ - sugar-session + sugar-launch bin_SCRIPTS = \ sugar \ diff --git a/bin/sugar-session b/bin/sugar-session deleted file mode 100755 index 3c86f3e..0000000 --- a/bin/sugar-session +++ /dev/null @@ -1,352 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2006, Red Hat, Inc. -# Copyright (C) 2009, One Laptop Per Child Association Inc -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import os -import sys -import time -import subprocess -import shutil - -# Change the default encoding to avoid UnicodeDecodeError -# http://lists.sugarlabs.org/archive/sugar-devel/2012-August/038928.html -reload(sys) -sys.setdefaultencoding('utf-8') - -if os.environ.get('SUGAR_LOGGER_LEVEL', '') == 'debug': - print '%r STARTUP: Starting the shell' % time.time() - sys.stdout.flush() - -import gettext -import logging -import sys - -from gi.repository import GLib -from gi.repository import GConf -from gi.repository import Gtk -from gi.repository import Gdk -from gi.repository import GdkX11 -from gi.repository import GObject -from gi.repository import Gst -import dbus.glib -from gi.repository import Wnck - -_USE_XKL = False -try: - from gi.repository import Xkl - _USE_XKL = True -except ImportError: - logging.debug('Could not load xklavier for keyboard configuration') - -GLib.threads_init() -Gdk.threads_init() -dbus.glib.threads_init() - -Gst.init(sys.argv) - -def cleanup_logs(logs_dir): - """Clean up the log directory, moving old logs into a numbered backup - directory. We only keep `_MAX_BACKUP_DIRS` of these backup directories - around; the rest are removed.""" - if not os.path.isdir(logs_dir): - os.makedirs(logs_dir) - - backup_logs = [] - backup_dirs = [] - for f in os.listdir(logs_dir): - path = os.path.join(logs_dir, f) - if os.path.isfile(path): - backup_logs.append(f) - elif os.path.isdir(path): - backup_dirs.append(path) - - if len(backup_dirs) > 3: - backup_dirs.sort() - root = backup_dirs[0] - for f in os.listdir(root): - os.remove(os.path.join(root, f)) - os.rmdir(root) - - if len(backup_logs) > 0: - name = str(int(time.time())) - backup_dir = os.path.join(logs_dir, name) - os.mkdir(backup_dir) - for log in backup_logs: - source_path = os.path.join(logs_dir, log) - dest_path = os.path.join(backup_dir, log) - os.rename(source_path, dest_path) - -def start_ui_service(): - from jarabe.view.service import UIService - - ui_service = UIService() - -def start_session_manager(): - from jarabe.model.session import get_session_manager - - session_manager = get_session_manager() - session_manager.start() - -def unfreeze_dcon_cb(): - logging.debug('STARTUP: unfreeze_dcon_cb') - from jarabe.model import screen - - screen.set_dcon_freeze(0) - -def setup_frame_cb(): - logging.debug('STARTUP: setup_frame_cb') - from jarabe import frame - frame.get_view() - -def setup_keyhandler_cb(): - logging.debug('STARTUP: setup_keyhandler_cb') - from jarabe.view import keyhandler - from jarabe import frame - keyhandler.setup(frame.get_view()) - -def setup_gesturehandler_cb(): - logging.debug('STARTUP: setup_gesturehandler_cb') - from jarabe.view import gesturehandler - from jarabe import frame - gesturehandler.setup(frame.get_view()) - -def setup_cursortracker_cb(): - logging.debug('STARTUP: setup_cursortracker_cb') - from jarabe.view import cursortracker - cursortracker.setup() - -def setup_journal_cb(): - logging.debug('STARTUP: setup_journal_cb') - from jarabe.journal import journalactivity - journalactivity.start() - -def show_software_updates_cb(): - logging.debug('STARTUP: show_software_updates_cb') - if os.path.isfile(os.path.expanduser('~/.sugar-update')): - from jarabe.desktop import homewindow - home_window = homewindow.get_instance() - home_window.get_home_box().show_software_updates_alert() - -def setup_notification_service_cb(): - from jarabe.model import notifications - notifications.init() - -def setup_file_transfer_cb(): - from jarabe.model import filetransfer - filetransfer.init() - -def setup_keyboard_cb(): - logging.debug('STARTUP: setup_keyboard_cb') - - gconf_client = GConf.Client.get_default() - have_config = False - - try: - display = GdkX11.x11_get_default_xdisplay() - if display is not None: - engine = Xkl.Engine.get_instance(display) - else: - logging.debug('setup_keyboard_cb: Could not get default display.') - return - - configrec = Xkl.ConfigRec() - configrec.get_from_server(engine) - - # FIXME, gconf_client_get_list not introspectable #681433 - layouts_from_gconf = gconf_client.get( - '/desktop/sugar/peripherals/keyboard/layouts') - layouts_list = [] - variants_list = [] - if layouts_from_gconf: - for gval in layouts_from_gconf.get_list(): - layout = gval.get_string() - layouts_list.append(layout.split('(')[0]) - variants_list.append(layout.split('(')[1][:-1]) - - if layouts_list and variants_list: - have_config = True - configrec.set_layouts(layouts_list) - configrec.set_variants(variants_list) - - model = gconf_client.get_string(\ - '/desktop/sugar/peripherals/keyboard/model') - if model: - have_config = True - configrec.set_model(model) - - options = [] - # FIXME, gconf_client_get_list not introspectable #681433 - options_from_gconf = gconf_client.get(\ - '/desktop/sugar/peripherals/keyboard/options') - if options_from_gconf: - for gval in options_from_gconf.get_list(): - option = gval.get_string() - options.append(option) - if options: - have_config = True - configrec.set_options(options) - - if have_config: - configrec.activate(engine) - except Exception: - logging.exception('Error during keyboard configuration') - -def setup_window_manager(): - logging.debug('STARTUP: window_manager') - - # have to reset cursor(metacity sets it on startup) - if subprocess.call('echo $DISPLAY; xsetroot -cursor_name left_ptr', shell=True): - logging.warning('Can not reset cursor') - - if subprocess.call('metacity-message disable-keybindings', - shell=True): - logging.warning('Can not disable metacity keybindings') - - if subprocess.call('metacity-message disable-mouse-button-modifiers', - shell=True): - logging.warning('Can not disable metacity mouse button modifiers') - -def bootstrap(): - setup_window_manager() - - from jarabe.view import launcher - launcher.setup() - - GObject.idle_add(setup_frame_cb) - GObject.idle_add(setup_keyhandler_cb) - GObject.idle_add(setup_gesturehandler_cb) - GObject.idle_add(setup_journal_cb) - GObject.idle_add(setup_notification_service_cb) - GObject.idle_add(setup_file_transfer_cb) - GObject.idle_add(show_software_updates_cb) - - if _USE_XKL: - GObject.idle_add(setup_keyboard_cb) - -def set_fonts(): - client = GConf.Client.get_default() - face = client.get_string('/desktop/sugar/font/default_face') - size = client.get_float('/desktop/sugar/font/default_size') - settings = Gtk.Settings.get_default() - settings.set_property("gtk-font-name", "%s %f" % (face, size)) - -def set_theme(): - settings = Gtk.Settings.get_default() - sugar_theme = 'sugar-72' - if 'SUGAR_SCALING' in os.environ: - if os.environ['SUGAR_SCALING'] == '100': - sugar_theme = 'sugar-100' - settings.set_property('gtk-theme-name', sugar_theme) - settings.set_property('gtk-icon-theme-name', 'sugar') - -def start_home(): - from jarabe.desktop import homewindow - - start_ui_service() - start_session_manager() - - # open homewindow before window_manager to let desktop appear fast - home_window = homewindow.get_instance() - home_window.show() - - screen = Wnck.Screen.get_default() - screen.connect('window-manager-changed', __window_manager_changed_cb) - _check_for_window_manager(screen) - -def intro_window_done_cb(window): - start_home() - -def main(): - try: - from sugar3 import env - # Remove temporary files. See http://bugs.sugarlabs.org/ticket/1876 - data_dir = os.path.join(env.get_profile_path(), 'data') - shutil.rmtree(data_dir, ignore_errors=True) - os.makedirs(data_dir) - cleanup_logs(env.get_logs_path()) - except OSError, e: - # logs cleanup is not critical; it should not prevent sugar from - # starting if (for example) the disk is full or read-only. - print 'logs cleanup failed: %s' % e - - from sugar3 import logger - # NOTE: This needs to happen so early because some modules register translatable - # strings in the module scope. - from jarabe import config - gettext.bindtextdomain('sugar', config.locale_path) - gettext.bindtextdomain('sugar-toolkit', config.locale_path) - gettext.textdomain('sugar') - - from jarabe.model import sound - from jarabe import intro - from jarabe.intro.window import IntroWindow - - logger.start('shell') - - client = GConf.Client.get_default() - client.set_string('/apps/metacity/general/mouse_button_modifier', - '<Super>') - - timezone = client.get_string('/desktop/sugar/date/timezone') - if timezone is not None and timezone: - os.environ['TZ'] = timezone - - set_fonts() - set_theme() - - # this must be added early, so that it executes and unfreezes the screen - # even when we initially get blocked on the intro screen - GObject.idle_add(unfreeze_dcon_cb) - - GObject.idle_add(setup_cursortracker_cb) - # make sure we have the correct cursor in the intro screen - # TODO #3204 - if subprocess.call('echo $DISPLAY; xsetroot -cursor_name left_ptr', shell=True): - logging.warning('Can not reset cursor') - - sound.restore() - - sys.path.append(config.ext_path) - - icons_path = os.path.join(config.data_path, 'icons') - Gtk.IconTheme.get_default().append_search_path(icons_path) - - if not intro.check_profile(): - win = IntroWindow() - win.connect("done", intro_window_done_cb) - win.show_all() - else: - start_home() - - try: - Gtk.main() - except KeyboardInterrupt: - print 'Ctrl+C pressed, exiting...' - - -def __window_manager_changed_cb(screen): - _check_for_window_manager(screen) - - -def _check_for_window_manager(screen): - wm_name = screen.get_window_manager_name() - if wm_name is not None: - screen.disconnect_by_func(__window_manager_changed_cb) - bootstrap() - - -main() diff --git a/bin/sugar.in b/bin/sugar.in index e7cb068..a2cee51 100644 --- a/bin/sugar.in +++ b/bin/sugar.in @@ -83,4 +83,4 @@ fi echo Xcursor.theme: sugar | xrdb -merge metacity --no-force-fullscreen -d $DISPLAY & -exec sugar-session +exec python -m jarabe.main diff --git a/src/jarabe/Makefile.am b/src/jarabe/Makefile.am index 84bb213..d926d9f 100644 --- a/src/jarabe/Makefile.am +++ b/src/jarabe/Makefile.am @@ -10,7 +10,8 @@ SUBDIRS = \ sugardir = $(pythondir)/jarabe sugar_PYTHON = \ - __init__.py + __init__.py \ + main.py nodist_sugar_PYTHON = config.py diff --git a/src/jarabe/main.py b/src/jarabe/main.py new file mode 100755 index 0000000..0b18320 --- /dev/null +++ b/src/jarabe/main.py @@ -0,0 +1,351 @@ +# Copyright (C) 2006, Red Hat, Inc. +# Copyright (C) 2009, One Laptop Per Child Association Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import sys +import time +import subprocess +import shutil + +# Change the default encoding to avoid UnicodeDecodeError +# http://lists.sugarlabs.org/archive/sugar-devel/2012-August/038928.html +reload(sys) +sys.setdefaultencoding('utf-8') + +if os.environ.get('SUGAR_LOGGER_LEVEL', '') == 'debug': + print '%r STARTUP: Starting the shell' % time.time() + sys.stdout.flush() + +import gettext +import logging +import sys + +from gi.repository import GLib +from gi.repository import GConf +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GdkX11 +from gi.repository import GObject +from gi.repository import Gst +import dbus.glib +from gi.repository import Wnck + +_USE_XKL = False +try: + from gi.repository import Xkl + _USE_XKL = True +except ImportError: + logging.debug('Could not load xklavier for keyboard configuration') + +GLib.threads_init() +Gdk.threads_init() +dbus.glib.threads_init() + +Gst.init(sys.argv) + +def cleanup_logs(logs_dir): + """Clean up the log directory, moving old logs into a numbered backup + directory. We only keep `_MAX_BACKUP_DIRS` of these backup directories + around; the rest are removed.""" + if not os.path.isdir(logs_dir): + os.makedirs(logs_dir) + + backup_logs = [] + backup_dirs = [] + for f in os.listdir(logs_dir): + path = os.path.join(logs_dir, f) + if os.path.isfile(path): + backup_logs.append(f) + elif os.path.isdir(path): + backup_dirs.append(path) + + if len(backup_dirs) > 3: + backup_dirs.sort() + root = backup_dirs[0] + for f in os.listdir(root): + os.remove(os.path.join(root, f)) + os.rmdir(root) + + if len(backup_logs) > 0: + name = str(int(time.time())) + backup_dir = os.path.join(logs_dir, name) + os.mkdir(backup_dir) + for log in backup_logs: + source_path = os.path.join(logs_dir, log) + dest_path = os.path.join(backup_dir, log) + os.rename(source_path, dest_path) + +def start_ui_service(): + from jarabe.view.service import UIService + + ui_service = UIService() + +def start_session_manager(): + from jarabe.model.session import get_session_manager + + session_manager = get_session_manager() + session_manager.start() + +def unfreeze_dcon_cb(): + logging.debug('STARTUP: unfreeze_dcon_cb') + from jarabe.model import screen + + screen.set_dcon_freeze(0) + +def setup_frame_cb(): + logging.debug('STARTUP: setup_frame_cb') + from jarabe import frame + frame.get_view() + +def setup_keyhandler_cb(): + logging.debug('STARTUP: setup_keyhandler_cb') + from jarabe.view import keyhandler + from jarabe import frame + keyhandler.setup(frame.get_view()) + +def setup_gesturehandler_cb(): + logging.debug('STARTUP: setup_gesturehandler_cb') + from jarabe.view import gesturehandler + from jarabe import frame + gesturehandler.setup(frame.get_view()) + +def setup_cursortracker_cb(): + logging.debug('STARTUP: setup_cursortracker_cb') + from jarabe.view import cursortracker + cursortracker.setup() + +def setup_journal_cb(): + logging.debug('STARTUP: setup_journal_cb') + from jarabe.journal import journalactivity + journalactivity.start() + +def show_software_updates_cb(): + logging.debug('STARTUP: show_software_updates_cb') + if os.path.isfile(os.path.expanduser('~/.sugar-update')): + from jarabe.desktop import homewindow + home_window = homewindow.get_instance() + home_window.get_home_box().show_software_updates_alert() + +def setup_notification_service_cb(): + from jarabe.model import notifications + notifications.init() + +def setup_file_transfer_cb(): + from jarabe.model import filetransfer + filetransfer.init() + +def setup_keyboard_cb(): + logging.debug('STARTUP: setup_keyboard_cb') + + gconf_client = GConf.Client.get_default() + have_config = False + + try: + display = GdkX11.x11_get_default_xdisplay() + if display is not None: + engine = Xkl.Engine.get_instance(display) + else: + logging.debug('setup_keyboard_cb: Could not get default display.') + return + + configrec = Xkl.ConfigRec() + configrec.get_from_server(engine) + + # FIXME, gconf_client_get_list not introspectable #681433 + layouts_from_gconf = gconf_client.get( + '/desktop/sugar/peripherals/keyboard/layouts') + layouts_list = [] + variants_list = [] + if layouts_from_gconf: + for gval in layouts_from_gconf.get_list(): + layout = gval.get_string() + layouts_list.append(layout.split('(')[0]) + variants_list.append(layout.split('(')[1][:-1]) + + if layouts_list and variants_list: + have_config = True + configrec.set_layouts(layouts_list) + configrec.set_variants(variants_list) + + model = gconf_client.get_string(\ + '/desktop/sugar/peripherals/keyboard/model') + if model: + have_config = True + configrec.set_model(model) + + options = [] + # FIXME, gconf_client_get_list not introspectable #681433 + options_from_gconf = gconf_client.get(\ + '/desktop/sugar/peripherals/keyboard/options') + if options_from_gconf: + for gval in options_from_gconf.get_list(): + option = gval.get_string() + options.append(option) + if options: + have_config = True + configrec.set_options(options) + + if have_config: + configrec.activate(engine) + except Exception: + logging.exception('Error during keyboard configuration') + +def setup_window_manager(): + logging.debug('STARTUP: window_manager') + + # have to reset cursor(metacity sets it on startup) + if subprocess.call('echo $DISPLAY; xsetroot -cursor_name left_ptr', shell=True): + logging.warning('Can not reset cursor') + + if subprocess.call('metacity-message disable-keybindings', + shell=True): + logging.warning('Can not disable metacity keybindings') + + if subprocess.call('metacity-message disable-mouse-button-modifiers', + shell=True): + logging.warning('Can not disable metacity mouse button modifiers') + +def bootstrap(): + setup_window_manager() + + from jarabe.view import launcher + launcher.setup() + + GObject.idle_add(setup_frame_cb) + GObject.idle_add(setup_keyhandler_cb) + GObject.idle_add(setup_gesturehandler_cb) + GObject.idle_add(setup_journal_cb) + GObject.idle_add(setup_notification_service_cb) + GObject.idle_add(setup_file_transfer_cb) + GObject.idle_add(show_software_updates_cb) + + if _USE_XKL: + GObject.idle_add(setup_keyboard_cb) + +def set_fonts(): + client = GConf.Client.get_default() + face = client.get_string('/desktop/sugar/font/default_face') + size = client.get_float('/desktop/sugar/font/default_size') + settings = Gtk.Settings.get_default() + settings.set_property("gtk-font-name", "%s %f" % (face, size)) + +def set_theme(): + settings = Gtk.Settings.get_default() + sugar_theme = 'sugar-72' + if 'SUGAR_SCALING' in os.environ: + if os.environ['SUGAR_SCALING'] == '100': + sugar_theme = 'sugar-100' + settings.set_property('gtk-theme-name', sugar_theme) + settings.set_property('gtk-icon-theme-name', 'sugar') + +def start_home(): + from jarabe.desktop import homewindow + + start_ui_service() + start_session_manager() + + # open homewindow before window_manager to let desktop appear fast + home_window = homewindow.get_instance() + home_window.show() + + screen = Wnck.Screen.get_default() + screen.connect('window-manager-changed', __window_manager_changed_cb) + _check_for_window_manager(screen) + +def intro_window_done_cb(window): + start_home() + +def main(): + try: + from sugar3 import env + # Remove temporary files. See http://bugs.sugarlabs.org/ticket/1876 + data_dir = os.path.join(env.get_profile_path(), 'data') + shutil.rmtree(data_dir, ignore_errors=True) + os.makedirs(data_dir) + cleanup_logs(env.get_logs_path()) + except OSError, e: + # logs cleanup is not critical; it should not prevent sugar from + # starting if (for example) the disk is full or read-only. + print 'logs cleanup failed: %s' % e + + from sugar3 import logger + # NOTE: This needs to happen so early because some modules register translatable + # strings in the module scope. + from jarabe import config + gettext.bindtextdomain('sugar', config.locale_path) + gettext.bindtextdomain('sugar-toolkit', config.locale_path) + gettext.textdomain('sugar') + + from jarabe.model import sound + from jarabe import intro + from jarabe.intro.window import IntroWindow + + logger.start('shell') + + client = GConf.Client.get_default() + client.set_string('/apps/metacity/general/mouse_button_modifier', + '<Super>') + + timezone = client.get_string('/desktop/sugar/date/timezone') + if timezone is not None and timezone: + os.environ['TZ'] = timezone + + set_fonts() + set_theme() + + # this must be added early, so that it executes and unfreezes the screen + # even when we initially get blocked on the intro screen + GObject.idle_add(unfreeze_dcon_cb) + + GObject.idle_add(setup_cursortracker_cb) + # make sure we have the correct cursor in the intro screen + # TODO #3204 + if subprocess.call('echo $DISPLAY; xsetroot -cursor_name left_ptr', shell=True): + logging.warning('Can not reset cursor') + + sound.restore() + + sys.path.append(config.ext_path) + + icons_path = os.path.join(config.data_path, 'icons') + Gtk.IconTheme.get_default().append_search_path(icons_path) + + if not intro.check_profile(): + win = IntroWindow() + win.connect("done", intro_window_done_cb) + win.show_all() + else: + start_home() + + try: + Gtk.main() + except KeyboardInterrupt: + print 'Ctrl+C pressed, exiting...' + + +def __window_manager_changed_cb(screen): + _check_for_window_manager(screen) + + +def _check_for_window_manager(screen): + wm_name = screen.get_window_manager_name() + if wm_name is not None: + screen.disconnect_by_func(__window_manager_changed_cb) + bootstrap() + + +main() -- 1.7.10.4 _______________________________________________ Sugar-devel mailing list Sugar-devel@lists.sugarlabs.org http://lists.sugarlabs.org/listinfo/sugar-devel