diff options
author | Daniel Narvaez <dwnarvaez@gmail.com> | 2012-12-10 16:21:28 (GMT) |
---|---|---|
committer | Simon Schampijer <simon@laptop.org> | 2013-01-22 09:14:00 (GMT) |
commit | 7a3c6568835a40e0d322175a14fa1d79bc0cd27d (patch) | |
tree | e13d34ad45f6858e724cd759b074c91994e6b3b6 /src | |
parent | 668ba9a910a53740b4c84eadfddbfca04d105d72 (diff) |
Move the sugar-session code inside jarabe
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.
Acked-by: Simon Schampijer <simon@laptop.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/jarabe/Makefile.am | 3 | ||||
-rwxr-xr-x | src/jarabe/main.py | 351 |
2 files changed, 353 insertions, 1 deletions
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() |