Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeuvizoso.net>2008-11-04 16:31:44 (GMT)
committer Tomeu Vizoso <tomeu@tomeuvizoso.net>2008-11-04 16:31:44 (GMT)
commita45e7239135c6bc143e8ba5efbdb05eb69155372 (patch)
tree804f144b532741afb7112900b6e11d786530a5f4 /src
parent2d8a5024676f908cdf38493cbb73bebcd4d22d2e (diff)
Initial implementation of activity notifications
Diffstat (limited to 'src')
-rw-r--r--src/jarabe/frame/frame.py45
-rw-r--r--src/jarabe/model/Makefile.am1
-rw-r--r--src/jarabe/model/notifications.py95
3 files changed, 138 insertions, 3 deletions
diff --git a/src/jarabe/frame/frame.py b/src/jarabe/frame/frame.py
index a1daced..6ba8814 100644
--- a/src/jarabe/frame/frame.py
+++ b/src/jarabe/frame/frame.py
@@ -23,6 +23,7 @@ import hippo
from sugar.graphics import animator
from sugar.graphics import style
from sugar.graphics import palettegroup
+from sugar import profile
from jarabe.frame.eventarea import EventArea
from jarabe.frame.activitiestray import ActivitiesTray
@@ -32,6 +33,7 @@ from jarabe.frame.devicestray import DevicesTray
from jarabe.frame.framewindow import FrameWindow
from jarabe.frame.clipboardpanelwindow import ClipboardPanelWindow
from jarabe.frame.notification import NotificationIcon, NotificationWindow
+from jarabe.model import notifications
TOP_RIGHT = 0
TOP_LEFT = 1
@@ -125,9 +127,17 @@ class Frame(object):
self._notif_by_icon = {}
+ notification_service = notifications.get_service()
+ notification_service.notification_received.connect(
+ self.__notification_received_cb)
+ notification_service.notification_cancelled.connect(
+ self.__notification_cancelled_cb)
+
def is_visible(self):
return self.current_position != 0.0
+ visible = property(is_visible, None)
+
def hide(self):
if self._animator:
self._animator.stop()
@@ -276,7 +286,9 @@ class Frame(object):
def notify_key_press(self):
self._key_listener.key_press()
- def add_notification(self, icon, corner=gtk.CORNER_TOP_LEFT):
+ def add_notification(self, icon, corner=gtk.CORNER_TOP_LEFT,
+ duration=_NOTIFICATION_DURATION):
+
if not isinstance(icon, NotificationIcon):
raise TypeError('icon must be a NotificationIcon.')
@@ -301,7 +313,7 @@ class Frame(object):
self._notif_by_icon[icon] = window
- gobject.timeout_add(_NOTIFICATION_DURATION,
+ gobject.timeout_add(duration,
lambda: self.remove_notification(icon))
def remove_notification(self, icon):
@@ -316,4 +328,31 @@ class Frame(object):
window.destroy()
del self._notif_by_icon[icon]
- visible = property(is_visible, None)
+ def __notification_received_cb(self, **kwargs):
+ logging.debug('__notification_received_cb %r' % kwargs)
+ icon = NotificationIcon()
+
+ hints = kwargs['hints']
+
+ icon_file_name = hints.get('x-sugar-icon-file-name', '')
+ if icon_file_name:
+ icon.props.icon_filename = icon_file_name
+ else:
+ icon.props.icon_name = 'application-octet-stream'
+
+ icon_colors = hints.get('x-sugar-icon-colors', '')
+ if not icon_colors:
+ icon_colors = profile.get_color()
+ icon.props.xo_color = icon_colors
+
+ duration = kwargs.get('expire_timeout', -1)
+ if duration == -1:
+ duration = _NOTIFICATION_DURATION
+
+ self.add_notification(icon, gtk.CORNER_TOP_RIGHT, duration)
+
+ def __notification_cancelled_cb(self, **kwargs):
+ # Do nothing for now. Our notification UI is so simple, there's no
+ # point yet.
+ pass
+
diff --git a/src/jarabe/model/Makefile.am b/src/jarabe/model/Makefile.am
index 9ab6779..71ba988 100644
--- a/src/jarabe/model/Makefile.am
+++ b/src/jarabe/model/Makefile.am
@@ -8,6 +8,7 @@ sugar_PYTHON = \
owner.py \
neighborhood.py \
network.py \
+ notifications.py \
shell.py \
screen.py \
session.py \
diff --git a/src/jarabe/model/notifications.py b/src/jarabe/model/notifications.py
new file mode 100644
index 0000000..da5c590
--- /dev/null
+++ b/src/jarabe/model/notifications.py
@@ -0,0 +1,95 @@
+# Copyright (C) 2008 One Laptop Per Child
+#
+# 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 sys
+import logging
+
+import dbus
+
+from sugar import dispatch
+
+from jarabe import config
+
+_DBUS_SERVICE = "org.freedesktop.Notifications"
+_DBUS_IFACE = "org.freedesktop.Notifications"
+_DBUS_PATH = "/org/freedesktop/Notifications"
+
+class NotificationService(dbus.service.Object):
+ def __init__(self):
+ bus = dbus.SessionBus()
+ bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus)
+ dbus.service.Object.__init__(self, bus_name, _DBUS_PATH)
+
+ self._notification_counter = 0
+ self.notification_received = dispatch.Signal()
+ self.notification_cancelled = dispatch.Signal()
+
+ @dbus.service.method(_DBUS_IFACE,
+ in_signature='susssava{sv}i', out_signature='u')
+ def Notify(self, app_name, replaces_id, app_icon, summary, body, actions,
+ hints, expire_timeout):
+
+ logging.debug('Received notification: %r' % ([app_name, replaces_id,
+ app_icon, summary, body, actions, hints, expire_timeout]))
+
+ if replaces_id > 0:
+ notification_id = replaces_id
+ else:
+ if self._notification_counter == sys.maxint:
+ self._notification_counter = 1
+ else:
+ self._notification_counter += 1
+ notification_id = self._notification_counter
+
+ self.notification_received.send(self, app_name=app_name,
+ replaces_id=replaces_id, app_icon=app_icon, summary=summary,
+ body=body, actions=actions, hints=hints,
+ expire_timeout=expire_timeout)
+
+ return notification_id
+
+ @dbus.service.method(_DBUS_IFACE, in_signature='u', out_signature='')
+ def CloseNotification(self, notification_id):
+ self.notification_cancelled.send(self, notification_id=notification_id)
+
+ @dbus.service.method(_DBUS_IFACE, in_signature='', out_signature='as')
+ def GetCapabilities(self):
+ return []
+
+ @dbus.service.method(_DBUS_IFACE, in_signature='', out_signature='sss')
+ def GetServerInformation(self, name, vendor, version):
+ return 'Sugar Shell', 'Sugar', config.version
+
+
+ @dbus.service.signal(_DBUS_IFACE, signature="uu")
+ def NotificationClosed(self, notification_id, reason):
+ pass
+
+ @dbus.service.signal(_DBUS_IFACE, signature="us")
+ def ActionInvoked(self, notification_id, action_key):
+ pass
+
+_instance = None
+
+def get_service():
+ global _instance
+ if not _instance:
+ _instance = NotificationService()
+ return _instance
+
+def init():
+ get_service()
+