Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
This commit is contained in:
		
						commit
						b01684ef27
					
				| @ -71,12 +71,6 @@ class HomeModel(gobject.GObject): | |||||||
|         screen.connect('active-window-changed', |         screen.connect('active-window-changed', | ||||||
|                        self._active_window_changed_cb) |                        self._active_window_changed_cb) | ||||||
| 
 | 
 | ||||||
|         bus = dbus.SessionBus() |  | ||||||
|         bus.add_signal_receiver(self._dbus_name_owner_changed_cb, |  | ||||||
|                                 'NameOwnerChanged',  |  | ||||||
|                                 'org.freedesktop.DBus',  |  | ||||||
|                                 'org.freedesktop.DBus') |  | ||||||
| 
 |  | ||||||
|     def get_current_activity(self): |     def get_current_activity(self): | ||||||
|         return self._current_activity |         return self._current_activity | ||||||
| 
 | 
 | ||||||
| @ -111,7 +105,7 @@ class HomeModel(gobject.GObject): | |||||||
|                 activity = HomeActivity(bundle, activity_id) |                 activity = HomeActivity(bundle, activity_id) | ||||||
|                 self._add_activity(activity) |                 self._add_activity(activity) | ||||||
| 
 | 
 | ||||||
|             service = self._get_activity_service(window.get_xid()) |             service = self._get_activity_service(activity_id) | ||||||
|             activity.set_service(service) |             activity.set_service(service) | ||||||
|             activity.set_window(window) |             activity.set_window(window) | ||||||
| 
 | 
 | ||||||
| @ -125,19 +119,6 @@ class HomeModel(gobject.GObject): | |||||||
|             self.emit('active-activity-changed', None) |             self.emit('active-activity-changed', None) | ||||||
|             self._notify_activity_activation(self._current_activity, None) |             self._notify_activity_activation(self._current_activity, None) | ||||||
| 
 | 
 | ||||||
|     def _dbus_name_owner_changed_cb(self, name, old, new): |  | ||||||
|         """Detect new activity instances on the DBus""" |  | ||||||
|         if name.startswith(_SERVICE_NAME) and new and not old: |  | ||||||
|             try: |  | ||||||
|                 xid = int(name[len(_SERVICE_NAME):]) |  | ||||||
|                 activity = self._get_activity_by_xid(xid) |  | ||||||
|                 if activity and not activity.get_service(): |  | ||||||
|                     service = self._get_activity_service(xid) |  | ||||||
|                     activity.set_service(service) |  | ||||||
|             except ValueError: |  | ||||||
|                 logging.error('Invalid activity service name, ' |  | ||||||
|                               'cannot extract the xid') |  | ||||||
| 
 |  | ||||||
|     def _get_activity_by_xid(self, xid): |     def _get_activity_by_xid(self, xid): | ||||||
|         for activity in self._activities: |         for activity in self._activities: | ||||||
|             if activity.get_xid() == xid: |             if activity.get_xid() == xid: | ||||||
| @ -185,12 +166,12 @@ class HomeModel(gobject.GObject): | |||||||
| 
 | 
 | ||||||
|         self.emit('active-activity-changed', self._current_activity) |         self.emit('active-activity-changed', self._current_activity) | ||||||
| 
 | 
 | ||||||
|     def _get_activity_service(self, xid): |     def _get_activity_service(self, activity_id): | ||||||
|         bus = dbus.SessionBus() |         bus = dbus.SessionBus() | ||||||
|         try: |         try: | ||||||
|             service = dbus.Interface( |             service = dbus.Interface( | ||||||
|                     bus.get_object(_SERVICE_NAME + '%d' % xid, |                     bus.get_object(_SERVICE_NAME + activity_id, | ||||||
|                                    _SERVICE_PATH + "/%s" % xid), |                                    _SERVICE_PATH + "/" + activity_id), | ||||||
|                                    _SERVICE_INTERFACE) |                                    _SERVICE_INTERFACE) | ||||||
|         except dbus.DBusException: |         except dbus.DBusException: | ||||||
|             service = None |             service = None | ||||||
|  | |||||||
| @ -26,10 +26,6 @@ from sugar.presence import presenceservice | |||||||
| from sugar.activity.activityhandle import ActivityHandle | from sugar.activity.activityhandle import ActivityHandle | ||||||
| from sugar import util | from sugar import util | ||||||
| 
 | 
 | ||||||
| _ACTIVITY_SERVICE_NAME = "org.laptop.Activity" |  | ||||||
| _ACTIVITY_SERVICE_PATH = "/org/laptop/Activity" |  | ||||||
| _ACTIVITY_INTERFACE = "org.laptop.Activity" |  | ||||||
| 
 |  | ||||||
| _ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory" | _ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory" | ||||||
| 
 | 
 | ||||||
| def create_activity_id(): | def create_activity_id(): | ||||||
|  | |||||||
| @ -33,24 +33,21 @@ class ActivityService(dbus.service.Object): | |||||||
|     def __init__(self, activity): |     def __init__(self, activity): | ||||||
|         """Initialise the service for the given activity |         """Initialise the service for the given activity | ||||||
|          |          | ||||||
|         activity -- sugar.activity.activity.Activity instance, |         activity -- sugar.activity.activity.Activity instance | ||||||
|             must have already bound it's window (i.e. it must  |  | ||||||
|             have already initialised to the point of having |  | ||||||
|             the X window available). |  | ||||||
|          |          | ||||||
|         Creates dbus services that use the xid of the activity's |         Creates dbus services that use the instance's activity_id | ||||||
|         root window as discriminants among all active services  |         as discriminants among all active services  | ||||||
|         of this type.  That is, the services are all available  |         of this type.  That is, the services are all available  | ||||||
|         as names/paths derived from the xid for the window. |         as names/paths derived from the instance's activity_id. | ||||||
|          |          | ||||||
|         The various methods exposed on dbus are just forwarded |         The various methods exposed on dbus are just forwarded | ||||||
|         to the client Activity object's equally-named methods. |         to the client Activity object's equally-named methods. | ||||||
|         """ |         """ | ||||||
|         activity.realize() |         activity.realize() | ||||||
| 
 | 
 | ||||||
|         xid = activity.window.xid |         activity_id = activity.get_id() | ||||||
|         service_name = _ACTIVITY_SERVICE_NAME + '%d' % xid  |         service_name = _ACTIVITY_SERVICE_NAME + activity_id | ||||||
|         object_path = _ACTIVITY_SERVICE_PATH + "/%s" % xid |         object_path  = _ACTIVITY_SERVICE_PATH + "/" + activity_id | ||||||
| 
 | 
 | ||||||
|         bus = dbus.SessionBus() |         bus = dbus.SessionBus() | ||||||
|         bus_name = dbus.service.BusName(service_name, bus=bus) |         bus_name = dbus.service.BusName(service_name, bus=bus) | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import gtk | |||||||
| from gtk import gdk, keysyms | from gtk import gdk, keysyms | ||||||
| import gobject | import gobject | ||||||
| import time | import time | ||||||
|  | import hippo | ||||||
| 
 | 
 | ||||||
| ALIGNMENT_AUTOMATIC     = 0 | ALIGNMENT_AUTOMATIC     = 0 | ||||||
| ALIGNMENT_BOTTOM_LEFT   = 1 | ALIGNMENT_BOTTOM_LEFT   = 1 | ||||||
| @ -36,7 +37,7 @@ class Palette(gtk.Window): | |||||||
|     __gtype_name__ = 'SugarPalette' |     __gtype_name__ = 'SugarPalette' | ||||||
| 
 | 
 | ||||||
|     __gproperties__ = { |     __gproperties__ = { | ||||||
|         'parent': (object, None, None, gobject.PARAM_READWRITE), |         'invoker': (object, None, None, gobject.PARAM_READWRITE), | ||||||
| 
 | 
 | ||||||
|         'alignment': (gobject.TYPE_INT, None, None, 0, 8, ALIGNMENT_AUTOMATIC, |         'alignment': (gobject.TYPE_INT, None, None, 0, 8, ALIGNMENT_AUTOMATIC, | ||||||
|                     gobject.PARAM_READWRITE), |                     gobject.PARAM_READWRITE), | ||||||
| @ -46,7 +47,6 @@ class Palette(gtk.Window): | |||||||
| 
 | 
 | ||||||
|     _PADDING    = 1 |     _PADDING    = 1 | ||||||
|     _WIN_BORDER = 5 |     _WIN_BORDER = 5 | ||||||
|     _POPUP_PALETTE_DELAY = 0.15 |  | ||||||
| 
 | 
 | ||||||
|     def __init__(self, **kwargs): |     def __init__(self, **kwargs): | ||||||
|         gobject.GObject.__init__(self, type=gtk.WINDOW_POPUP, **kwargs) |         gobject.GObject.__init__(self, type=gtk.WINDOW_POPUP, **kwargs) | ||||||
| @ -85,7 +85,7 @@ class Palette(gtk.Window): | |||||||
|         self.add(vbox) |         self.add(vbox) | ||||||
| 
 | 
 | ||||||
|         # Widget events |         # Widget events | ||||||
|         self.connect('motion-notify-event', self._mouse_over_widget_cb) |         self.connect('enter-notify-event', self._mouse_over_widget_cb) | ||||||
|         self.connect('leave-notify-event', self._mouse_out_widget_cb) |         self.connect('leave-notify-event', self._mouse_out_widget_cb) | ||||||
|         self.connect('button-press-event', self._close_palette_cb) |         self.connect('button-press-event', self._close_palette_cb) | ||||||
|         self.connect('key-press-event', self._on_key_press_event_cb) |         self.connect('key-press-event', self._on_key_press_event_cb) | ||||||
| @ -96,8 +96,8 @@ class Palette(gtk.Window): | |||||||
|         self._scr_height = gtk.gdk.screen_height() |         self._scr_height = gtk.gdk.screen_height() | ||||||
| 
 | 
 | ||||||
|     def do_set_property(self, pspec, value): |     def do_set_property(self, pspec, value): | ||||||
|         if pspec.name == 'parent': |         if pspec.name == 'invoker': | ||||||
|             self._parent_widget = value |             self._invoker = value | ||||||
|         elif pspec.name == 'alignment': |         elif pspec.name == 'alignment': | ||||||
|             self._alignment = value |             self._alignment = value | ||||||
|         elif pspec.name == 'is-tooltip': |         elif pspec.name == 'is-tooltip': | ||||||
| @ -155,41 +155,41 @@ class Palette(gtk.Window): | |||||||
|             return True |             return True | ||||||
| 
 | 
 | ||||||
|     def _calc_position(self, alignment): |     def _calc_position(self, alignment): | ||||||
|         win_x, win_y = self._parent_widget.window.get_origin() |         # Invoker: x, y, width and height | ||||||
|         parent_rectangle = self._parent_widget.get_allocation() |         inv_rect = self._invoker.get_rect() | ||||||
|         palette_rectangle = self.get_allocation() |         palette_rectangle = self.get_allocation() | ||||||
| 
 | 
 | ||||||
|         if alignment == ALIGNMENT_BOTTOM_LEFT: |         if alignment == ALIGNMENT_BOTTOM_LEFT: | ||||||
|             move_x = win_x + parent_rectangle.x |             move_x = inv_rect.x | ||||||
|             move_y = win_y + parent_rectangle.y + parent_rectangle.height |             move_y = inv_rect.y + inv_rect.height | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_BOTTOM_RIGHT: |         elif alignment == ALIGNMENT_BOTTOM_RIGHT: | ||||||
|             move_x = (win_x + parent_rectangle.x + parent_rectangle.width) - self._width |             move_x = (inv_rect.x + inv_rect.width) - self._width | ||||||
|             move_y = win_y + parent_rectangle.y + parent_rectangle.height |             move_y = inv_rect.y + inv_rect.height | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_LEFT_BOTTOM: |         elif alignment == ALIGNMENT_LEFT_BOTTOM: | ||||||
|             move_x = (win_x + parent_rectangle.x) - self._width |             move_x = inv_rect.x - self._width | ||||||
|             move_y = win_y + parent_rectangle.y |             move_y = inv_rect.y | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_LEFT_TOP: |         elif alignment == ALIGNMENT_LEFT_TOP: | ||||||
|             move_x = (win_x + parent_rectangle.x) - self._width |             move_x = inv_rect.x - self._width | ||||||
|             move_y = (win_y + parent_rectangle.y + parent_rectangle.height) - palette_rectangle.height  |             move_y = (inv_rect.y + inv_rect.height) - palette_rectangle.height | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_RIGHT_BOTTOM: |         elif alignment == ALIGNMENT_RIGHT_BOTTOM: | ||||||
|             move_x = win_x + parent_rectangle.x + parent_rectangle.width |             move_x = inv_rect.x + inv_rect.width | ||||||
|             move_y = win_y + parent_rectangle.y |             move_y = inv_rect.y | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_RIGHT_TOP: |         elif alignment == ALIGNMENT_RIGHT_TOP: | ||||||
|             move_x = win_x + parent_rectangle.x + parent_rectangle.width |             move_x = inv_rect.x + inv_rect.width | ||||||
|             move_y = (win_y + parent_rectangle.y + parent_rectangle.height) - palette_rectangle.height |             move_y = (inv_rect.y + inv_rect.height) - palette_rectangle.height | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_TOP_LEFT: |         elif alignment == ALIGNMENT_TOP_LEFT: | ||||||
|             move_x = (win_x + parent_rectangle.x) |             move_x = inv_rect.x | ||||||
|             move_y = (win_y + parent_rectangle.y) - (palette_rectangle.height) |             move_y = inv_rect.y - palette_rectangle.height | ||||||
| 
 | 
 | ||||||
|         elif alignment == ALIGNMENT_TOP_RIGHT: |         elif alignment == ALIGNMENT_TOP_RIGHT: | ||||||
|             move_x = (win_x + parent_rectangle.x + parent_rectangle.width) - self._width |             move_x = (inv_rect.x + inv_rect.width) - self._width | ||||||
|             move_y = (win_y + parent_rectangle.y) - (palette_rectangle.height) |             move_y = inv_rect.y - palette_rectangle.height | ||||||
| 
 | 
 | ||||||
|         return move_x, move_y |         return move_x, move_y | ||||||
| 
 | 
 | ||||||
| @ -219,18 +219,13 @@ class Palette(gtk.Window): | |||||||
| 
 | 
 | ||||||
|     # Display the palette and set the position on the screen |     # Display the palette and set the position on the screen | ||||||
|     def popup(self): |     def popup(self): | ||||||
|         # We need to know if the mouse pointer continue inside |  | ||||||
|         # the parent widget (opener) |  | ||||||
|         pointer_x, pointer_y = self._parent_widget.get_pointer() |  | ||||||
|         self._parent_alloc = self._parent_widget.get_allocation() |  | ||||||
|         pointer_rect = gdk.Rectangle(pointer_x + self._parent_alloc.x, pointer_y + self._parent_alloc.y, 1, 1) |  | ||||||
| 
 |  | ||||||
|         if (self._parent_widget.allocation.intersect(pointer_rect).width == 0): |  | ||||||
|             return |  | ||||||
| 
 |  | ||||||
|         self.realize() |         self.realize() | ||||||
|         self.set_position() |         self.set_position() | ||||||
|         self._pointer_grab() |         self._pointer_ungrab() | ||||||
|  | 
 | ||||||
|  |     def popdown(self): | ||||||
|  |         self._pointer_ungrab() | ||||||
|  |         self.hide() | ||||||
| 
 | 
 | ||||||
|     # PRIVATE METHODS |     # PRIVATE METHODS | ||||||
| 
 | 
 | ||||||
| @ -244,32 +239,29 @@ class Palette(gtk.Window): | |||||||
|         else: |         else: | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|     def _pointer_grab(self): |     def _pointer_ungrab(self): | ||||||
|         gtk.gdk.pointer_grab(self.window, owner_events=False, |         gdk.keyboard_ungrab() | ||||||
|             event_mask=gtk.gdk.BUTTON_PRESS_MASK | |  | ||||||
|             gtk.gdk.BUTTON_RELEASE_MASK | |  | ||||||
|             gtk.gdk.ENTER_NOTIFY_MASK | |  | ||||||
|             gtk.gdk.LEAVE_NOTIFY_MASK | |  | ||||||
|             gtk.gdk.POINTER_MOTION_MASK) |  | ||||||
| 
 | 
 | ||||||
|  |     def _pointer_grab(self): | ||||||
|         gdk.keyboard_grab(self.window, False) |         gdk.keyboard_grab(self.window, False) | ||||||
| 
 | 
 | ||||||
|     # SIGNAL HANDLERS |     # SIGNAL HANDLERS | ||||||
| 
 | 
 | ||||||
|     # Release the GDK pointer and hide the palette |     # Release the GDK pointer and hide the palette | ||||||
|     def _close_palette_cb(self, widget=None, event=None): |     def _close_palette_cb(self, widget=None, event=None): | ||||||
|         gtk.gdk.pointer_ungrab() |         self.popdown() | ||||||
|         self.hide() |  | ||||||
| 
 | 
 | ||||||
|     # Mouse is out of the widget |     # Mouse is out of the widget | ||||||
|     def _mouse_out_widget_cb(self, widget, event): |     def _mouse_out_widget_cb(self, widget, event): | ||||||
|         time.sleep(self._POPUP_PALETTE_DELAY) |  | ||||||
|         if (widget == self) and self._is_mouse_out(widget): |         if (widget == self) and self._is_mouse_out(widget): | ||||||
|             self._close_palette_cb() |             self._close_palette_cb() | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |         self._pointer_grab() | ||||||
| 
 | 
 | ||||||
|     # Mouse inside the widget |     # Mouse inside the widget | ||||||
|     def _mouse_over_widget_cb(self, widget, event): |     def _mouse_over_widget_cb(self, widget, event): | ||||||
|         gtk.gdk.pointer_ungrab() |         self._pointer_ungrab() | ||||||
| 
 | 
 | ||||||
|     # Some key is pressed |     # Some key is pressed | ||||||
|     def _on_key_press_event_cb(self, window, event): |     def _on_key_press_event_cb(self, window, event): | ||||||
| @ -282,3 +274,46 @@ class Palette(gtk.Window): | |||||||
|             ((keyval == keysyms.Up or keyval == keysyms.KP_Up) and |             ((keyval == keysyms.Up or keyval == keysyms.KP_Up) and | ||||||
|              state == gdk.MOD1_MASK)): |              state == gdk.MOD1_MASK)): | ||||||
|             self._close_palette_cb() |             self._close_palette_cb() | ||||||
|  | 
 | ||||||
|  | class WidgetInvoker: | ||||||
|  |     def __init__(self, parent): | ||||||
|  |         self._parent = parent | ||||||
|  | 
 | ||||||
|  |     def get_rect(self): | ||||||
|  |         win_x, win_y = self._parent.window.get_origin() | ||||||
|  |         rectangle = self._parent.get_allocation() | ||||||
|  | 
 | ||||||
|  |         x = win_x + rectangle.x | ||||||
|  |         y = win_y + rectangle.y | ||||||
|  |         width = rectangle.width | ||||||
|  |         height = rectangle.height | ||||||
|  | 
 | ||||||
|  |         return gtk.gdk.Rectangle(x, y, width, height) | ||||||
|  | 
 | ||||||
|  |     # Is mouse over self._parent ? | ||||||
|  |     def is_mouse_over(self): | ||||||
|  |         pointer_x, pointer_y = self._parent.get_pointer() | ||||||
|  |         self._parent_alloc = self._parent.get_allocation() | ||||||
|  | 
 | ||||||
|  |         pointer_rect = gdk.Rectangle(pointer_x + self._parent_alloc.x, \ | ||||||
|  |             pointer_y + self._parent_alloc.y, 1, 1) | ||||||
|  | 
 | ||||||
|  |         if (self._parent.allocation.intersect(pointer_rect).width == 0): | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  | class CanvasInvoker: | ||||||
|  |     def __init__(self, parent): | ||||||
|  |         self._parent = parent | ||||||
|  | 
 | ||||||
|  |     def get_rect(self): | ||||||
|  |         context = self._parent.get_context() | ||||||
|  |         x, y = context.translate_to_screen(self._parent) | ||||||
|  |         width, height = self._parent.get_allocation() | ||||||
|  | 
 | ||||||
|  |         return gtk.gdk.Rectangle(x, y, width, height) | ||||||
|  | 
 | ||||||
|  |     # Is mouse over self._parent ? | ||||||
|  |     def is_mouse_over(self): | ||||||
|  |         return True | ||||||
|  | |||||||
| @ -16,18 +16,23 @@ | |||||||
| # Boston, MA 02111-1307, USA. | # Boston, MA 02111-1307, USA. | ||||||
| 
 | 
 | ||||||
| import gtk | import gtk | ||||||
|  | import gobject | ||||||
| import time | import time | ||||||
| 
 | 
 | ||||||
| from sugar.graphics.icon import Icon | from sugar.graphics.icon import Icon | ||||||
| from sugar.graphics.palette import * | from sugar.graphics.palette import * | ||||||
| 
 | 
 | ||||||
| class ToolButton(gtk.ToolButton): | class ToolButton(gtk.ToolButton): | ||||||
|     _POPUP_PALETTE_DELAY = 0.15 |     _POPUP_PALETTE_DELAY = 100 | ||||||
| 
 | 
 | ||||||
|     def __init__(self, icon_name=None): |     def __init__(self, icon_name=None): | ||||||
|         gtk.ToolButton.__init__(self) |         gtk.ToolButton.__init__(self) | ||||||
|         self._palette = None |         self._palette = None | ||||||
|         self.set_icon(icon_name) |         self.set_icon(icon_name) | ||||||
|  |         self.child.connect('enter-notify-event',self._enter_notify_event_cb) | ||||||
|  |         self.child.connect('leave-notify-event',self._leave_notify_event_cb) | ||||||
|  |         self._enter_tag = None | ||||||
|  |         self._leave_tag = None | ||||||
| 
 | 
 | ||||||
|     def set_icon(self, icon_name): |     def set_icon(self, icon_name): | ||||||
|         icon = Icon(icon_name) |         icon = Icon(icon_name) | ||||||
| @ -36,8 +41,7 @@ class ToolButton(gtk.ToolButton): | |||||||
| 
 | 
 | ||||||
|     def set_palette(self, palette): |     def set_palette(self, palette): | ||||||
|         self._palette = palette |         self._palette = palette | ||||||
|         self._palette.props.parent = self |         self._palette.props.invoker = WidgetInvoker(self) | ||||||
|         self.child.connect('enter-notify-event', self._show_palette_timeout_cb) |  | ||||||
| 
 | 
 | ||||||
|     def set_tooltip(self, text): |     def set_tooltip(self, text): | ||||||
|         if self._palette: |         if self._palette: | ||||||
| @ -45,9 +49,49 @@ class ToolButton(gtk.ToolButton): | |||||||
| 
 | 
 | ||||||
|         self._palette = Palette(is_tooltip=True) |         self._palette = Palette(is_tooltip=True) | ||||||
|         self._palette.set_primary_state(text) |         self._palette.set_primary_state(text) | ||||||
|         self._palette.props.parent = self |         self._palette.props.invoker = WidgetInvoker(self) | ||||||
|         self.child.connect('enter-notify-event', self._show_palette_timeout_cb) |  | ||||||
| 
 | 
 | ||||||
|     def _show_palette_timeout_cb(self, widget, event): |     def _enter_notify_event_cb(self, widget, event): | ||||||
|         time.sleep(self._POPUP_PALETTE_DELAY) |         gtk.gdk.pointer_ungrab() | ||||||
|  | 
 | ||||||
|  |         if self._leave_tag: | ||||||
|  |             gobject.source_remove(self._leave_tag) | ||||||
|  |             self._leave_tag = None | ||||||
|  | 
 | ||||||
|  |         self._enter_tag = gobject.timeout_add(self._POPUP_PALETTE_DELAY, \ | ||||||
|  |             self._show_palette) | ||||||
|  | 
 | ||||||
|  |     def _leave_notify_event_cb(self, widget, event): | ||||||
|  |         if self._enter_tag: | ||||||
|  |             gobject.source_remove(self._enter_tag) | ||||||
|  |             self._enter_tag = None | ||||||
|  | 
 | ||||||
|  |         self._leave_tag = gobject.timeout_add(self._POPUP_PALETTE_DELAY,\ | ||||||
|  |             self._hide_palette) | ||||||
|  | 
 | ||||||
|  |     def _show_palette(self): | ||||||
|         self._palette.popup() |         self._palette.popup() | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def _hide_palette(self): | ||||||
|  |         # Just hide the palette if the mouse pointer is  | ||||||
|  |         # out of the toolbutton and the palette | ||||||
|  |         if self._is_mouse_out(self._palette): | ||||||
|  |             self._palette.popdown() | ||||||
|  |         else: | ||||||
|  |             gtk.gdk.pointer_ungrab() | ||||||
|  |          | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def _pointer_grab(self): | ||||||
|  |         gtk.gdk.pointer_grab(self.window, owner_events=True,\ | ||||||
|  |             event_mask=gtk.gdk.PROPERTY_CHANGE_MASK ) | ||||||
|  | 
 | ||||||
|  |     def _is_mouse_out(self, widget): | ||||||
|  |         mouse_x, mouse_y = widget.get_pointer() | ||||||
|  |         event_rect = gdk.Rectangle(mouse_x, mouse_y, 1, 1) | ||||||
|  | 
 | ||||||
|  |         if (widget.allocation.intersect(event_rect).width==0): | ||||||
|  |             return True | ||||||
|  |         else: | ||||||
|  |             return False | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marco Pesenti Gritti
						Marco Pesenti Gritti