From 8bcdb8f3dd25ab31da3ce4c76c477c3017f2f712 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 19 Jun 2006 22:39:57 -0400 Subject: [PATCH 1/3] Implement session shutdown. For now we are forcefully killing activities. We will need to implement some sort of shutdown notification system but... for now this works. --- sugar/session/session.py | 78 ++++++++++++++++++++++++---------------- sugar/shell/shell.py | 49 +++++++++++++++---------- sugar/sugar | 3 +- 3 files changed, 81 insertions(+), 49 deletions(-) diff --git a/sugar/session/session.py b/sugar/session/session.py index 76bd9a3e..ea232c01 100644 --- a/sugar/session/session.py +++ b/sugar/session/session.py @@ -1,41 +1,59 @@ import os +import signal from ConfigParser import ConfigParser import pygtk pygtk.require('2.0') import gtk -from sugar.shell import shell +from sugar.shell.shell import Shell from sugar import env -def start(): - shell.main() +class Session: + def __init__(self): + self._activity_processes = {} - activities = [] + def start(self): + shell = Shell() + shell.connect('close', self._shell_close_cb) + shell.start() + + activities = [] + activities_dirs = [] + + for data_dir in env.get_data_dirs(): + act_dir = os.path.join(data_dir, env.get_activities_dir()) + activities_dirs.append(act_dir) + + activities_dirs.append(os.path.join(env.get_user_dir(), 'activities')) + + for activities_dir in activities_dirs: + if os.path.isdir(activities_dir): + for filename in os.listdir(activities_dir): + if filename.endswith(".activity"): + path = os.path.join(activities_dir, filename) + cp = ConfigParser() + cp.read([path]) + python_class = cp.get('Activity', "python_class") + activities.append(python_class) + + for activity in activities: + args = [ 'python', '-m', activity ] + pid = os.spawnvp(os.P_NOWAIT, 'python', args) + self._activity_processes[activity] = pid + + try: + gtk.main() + except KeyboardInterrupt: + print 'Ctrl+C pressed, exiting...' + self.shutdown() + + def _shell_close_cb(self, shell): + self.shutdown() - activities_dirs = [] - - for data_dir in env.get_data_dirs(): - act_dir = os.path.join(data_dir, env.get_activities_dir()) - activities_dirs.append(act_dir) - - activities_dirs.append(os.path.join(env.get_user_dir(), 'activities')) - - for activities_dir in activities_dirs: - if os.path.isdir(activities_dir): - for filename in os.listdir(activities_dir): - if filename.endswith(".activity"): - path = os.path.join(activities_dir, filename) - cp = ConfigParser() - cp.read([path]) - python_class = cp.get('Activity', "python_class") - activities.append(python_class) - - for activity in activities: - args = [ 'python', '-m', activity ] - os.spawnvp(os.P_NOWAIT, 'python', args) - - try: - gtk.main() - except KeyboardInterrupt: - print 'Ctrl+C pressed, exiting...' + def shutdown(self): + # FIXME Obviously we want to notify the activities to + # shutt down rather then killing them down forcefully. + for name in self._activity_processes.keys(): + print 'Shutting down %s' % (name) + os.kill(self._activity_processes[name], signal.SIGTERM) diff --git a/sugar/shell/shell.py b/sugar/shell/shell.py index 2b1f6a3b..3e5450cc 100755 --- a/sugar/shell/shell.py +++ b/sugar/shell/shell.py @@ -472,31 +472,44 @@ class ConsoleLogger(dbus.service.Object): buf = console.get_buffer() buf.insert(buf.get_end_iter(), message) -def main(): - console = ConsoleLogger() +class Shell(gobject.GObject): + __gsignals__ = { + 'close': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([])), + } - log_writer = LogWriter("Shell", False) - log_writer.start() + def __init__(self): + gobject.GObject.__init__(self) - session_bus = dbus.SessionBus() - service = dbus.service.BusName("com.redhat.Sugar.Shell", bus=session_bus) + def start(self): + console = ConsoleLogger() - activity_container = ActivityContainer(service, session_bus) - activity_container.show() + log_writer = LogWriter("Shell", False) + log_writer.start() - wm = WindowManager(activity_container.window) - wm.set_width(640, WindowManager.ABSOLUTE) - wm.set_height(480, WindowManager.ABSOLUTE) - wm.set_position(WindowManager.CENTER) - wm.show() - wm.manage() - - console.set_parent_window(activity_container.window) + session_bus = dbus.SessionBus() + service = dbus.service.BusName("com.redhat.Sugar.Shell", bus=session_bus) + + activity_container = ActivityContainer(service, session_bus) + activity_container.window.connect('destroy', self.__activity_container_destroy_cb) + activity_container.show() + + wm = WindowManager(activity_container.window) + wm.set_width(640, WindowManager.ABSOLUTE) + wm.set_height(480, WindowManager.ABSOLUTE) + wm.set_position(WindowManager.CENTER) + wm.show() + wm.manage() + + console.set_parent_window(activity_container.window) + + def __activity_container_destroy_cb(self, activity_container): + self.emit('close') if __name__ == "__main__": - main() + shell = Shell() + shell.start() try: gtk.main() except KeyboardInterrupt: print 'Ctrl+c pressed, exiting...' - pass diff --git a/sugar/sugar b/sugar/sugar index 259e9b65..28544fce 100755 --- a/sugar/sugar +++ b/sugar/sugar @@ -81,8 +81,9 @@ if console: os.environ['SUGAR_USE_CONSOLE'] = 'yes' print 'Redirecting output to the console, press ctrl+d to open it.' -from sugar.session import session +from sugar.session.session import Session +session = Session() session.start() if dbus_daemon_pid: From 758d9fba4350d7f5eb48a3ebe6fbd3cba4a7fcf0 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 19 Jun 2006 23:04:53 -0400 Subject: [PATCH 2/3] Always enable console --- sugar/session/LogWriter.py | 2 +- sugar/sugar | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/sugar/session/LogWriter.py b/sugar/session/LogWriter.py index be9e5fb2..1368e5d1 100644 --- a/sugar/session/LogWriter.py +++ b/sugar/session/LogWriter.py @@ -16,7 +16,7 @@ class LogWriter: self._logger = dbus.Interface(proxy_obj, 'com.redhat.Sugar.Logger') def start(self): - if os.environ.has_key('SUGAR_USE_CONSOLE') and self._use_console: + if self._use_console: sys.stdout = self sys.stderr = self diff --git a/sugar/sugar b/sugar/sugar index 28544fce..1ec9a6a9 100755 --- a/sugar/sugar +++ b/sugar/sugar @@ -62,8 +62,6 @@ if curdir == '.': else: basedir = os.path.dirname(curdir) -console = False - if os.path.isfile(os.path.join(curdir, '__uninstalled__.py')): if basedir == '': print 'Running sugar from current directory...' @@ -71,15 +69,12 @@ if os.path.isfile(os.path.join(curdir, '__uninstalled__.py')): print 'Running sugar from ' + basedir + ' ...' add_to_python_path(basedir) add_to_python_path(os.path.join(basedir, 'cut-n-paste')) - console = True else: print 'Running the installed sugar...' add_to_python_path(os.path.expanduser('~/.sugar/activities')) -if console: - os.environ['SUGAR_USE_CONSOLE'] = 'yes' - print 'Redirecting output to the console, press ctrl+d to open it.' +print 'Redirecting output to the console, press ctrl+d to open it.' from sugar.session.session import Session From 8212ce759543ae7fee15c48040256dd2bedd8ee0 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Mon, 19 Jun 2006 23:05:25 -0400 Subject: [PATCH 3/3] Ensure to not do unnecessary move when sliding --- sugar/shell/WindowManager.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/sugar/shell/WindowManager.py b/sugar/shell/WindowManager.py index 7e9a2fe6..776b991b 100644 --- a/sugar/shell/WindowManager.py +++ b/sugar/shell/WindowManager.py @@ -54,7 +54,7 @@ class WindowManager: def set_position(self, position): self._position = position - def _update_size_and_position(self): + def _calc_size_and_position(self): screen_width = self._window.get_screen().get_width() screen_height = self._window.get_screen().get_height() @@ -69,27 +69,37 @@ class WindowManager: height = int(screen_height * self._height) if self._position is WindowManager.CENTER: - x = int((screen_width - width) / 2) - y = int((screen_height - height) / 2) + self._x = int((screen_width - width) / 2) + self._y = int((screen_height - height) / 2) elif self._position is WindowManager.LEFT: - x = - int((1.0 - self._sliding_pos) * width) - y = int((screen_height - height) / 2) + self._x = - int((1.0 - self._sliding_pos) * width) + self._y = int((screen_height - height) / 2) elif self._position is WindowManager.TOP: - x = int((screen_width - width) / 2) - y = - int((1.0 - self._sliding_pos) * height) - - self._window.move(x, y) - self._window.resize(width, height) + self._x = int((screen_width - width) / 2) + self._y = - int((1.0 - self._sliding_pos) * height) + + self._real_width = width + self._real_height = height + + def _update_size_and_position(self): + self._calc_size_and_position() + self._window.move(self._x, self._y) + self._window.resize(self._real_width, self._real_height) + + def _update_position(self): + self._calc_size_and_position() + self._window.move(self._x, self._y) def __slide_in_timeout_cb(self): - self._window.show() + if self._sliding_pos == 0: + self._window.show() self._sliding_pos += 0.05 if self._sliding_pos > 1.0: self._sliding_pos = 1.0 - self._update_size_and_position() + self._update_position() if self._sliding_pos == 1.0: return False @@ -104,7 +114,7 @@ class WindowManager: if self._sliding_pos < 0: self._sliding_pos = 0 - self._update_size_and_position() + self._update_position() if self._sliding_pos == 0: self._window.hide()