From f24f40b500d159bea43f8fa2a6bc02d1ce58aebe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= <manuq@laptop.org>
Date: Fri, 8 Mar 2013 09:25:12 -0300
Subject: [PATCH] Palettes: prevent popup after popdown for a few milliseconds
- SL #2184
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Mail-Followup-To: <sugar-devel@lists.sugarlabs.org>
An inconsistent state can be reached if the user does rapid presses of
mouse buttons or rapid touches in the screen over a palette invoker
widget, leaving the palette black.
As we suspend presses for a few milliseconds, the user interaction is
not affected.
Signed-off-by: Manuel Quiñones <manuq@laptop.org>
---
src/sugar3/graphics/palettewindow.py | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/sugar3/graphics/palettewindow.py b/src/sugar3/graphics/palettewindow.py
index c48ae55..f3893c7 100644
a
|
b
|
import math |
29 | 29 | from gi.repository import Gdk |
30 | 30 | from gi.repository import Gtk |
31 | 31 | from gi.repository import GObject |
| 32 | from gi.repository import GLib |
32 | 33 | |
33 | 34 | from gi.repository import SugarGestures |
34 | 35 | from sugar3.graphics import palettegroup |
35 | 36 | from sugar3.graphics import animator |
36 | 37 | from sugar3.graphics import style |
37 | 38 | |
| 39 | _SUSPEND_PRESSES_TIMEOUT = 300 |
| 40 | |
38 | 41 | |
39 | 42 | def _calculate_gap(a, b): |
40 | 43 | """Helper function to find the gap position and size of widget a""" |
… |
… |
class PaletteWindow(GObject.GObject): |
675 | 678 | def _invoker_toggle_state_cb(self, invoker): |
676 | 679 | if self.is_up() and self._palette_state == self.SECONDARY: |
677 | 680 | self.popdown(immediate=True) |
| 681 | # Suspend presses for a few milliseconds to prevent rapid |
| 682 | # popup after popdown - SL #2184 |
| 683 | self._invoker.temporally_suspend_presses() |
678 | 684 | else: |
679 | 685 | self.popup(immediate=True, state=self.SECONDARY) |
680 | 686 | |
… |
… |
class WidgetInvoker(Invoker): |
1102 | 1108 | self._long_pressed_controller.detach(self._widget) |
1103 | 1109 | self._long_pressed_controller.disconnect(self._long_pressed_hid) |
1104 | 1110 | |
| 1111 | def temporally_suspend_presses(self): |
| 1112 | def reconnect(): |
| 1113 | self._release_hid = self._widget.connect('button-release-event', |
| 1114 | self.__button_release_event_cb) |
| 1115 | if GObject.signal_lookup('clicked', self._widget) != 0: |
| 1116 | self._click_hid = self._widget.connect('clicked', |
| 1117 | self.__click_event_cb) |
| 1118 | |
| 1119 | self._widget.disconnect(self._release_hid) |
| 1120 | if self._click_hid: |
| 1121 | self._widget.disconnect(self._click_hid) |
| 1122 | GLib.timeout_add(_SUSPEND_PRESSES_TIMEOUT, reconnect) |
| 1123 | |
1105 | 1124 | def get_rect(self): |
1106 | 1125 | allocation = self._widget.get_allocation() |
1107 | 1126 | window = self._widget.get_window() |
… |
… |
class CursorInvoker(Invoker): |
1266 | 1285 | self._long_pressed_controller.detach(self._item) |
1267 | 1286 | self._long_pressed_controller.disconnect(self._long_pressed_hid) |
1268 | 1287 | |
| 1288 | def temporally_suspend_presses(self): |
| 1289 | def reconnect(): |
| 1290 | self._release_hid = self._item.connect('button-release-event', |
| 1291 | self.__button_release_event_cb) |
| 1292 | |
| 1293 | self._item.disconnect(self._release_hid) |
| 1294 | GLib.timeout_add(_SUSPEND_PRESSES_TIMEOUT, reconnect) |
| 1295 | |
1269 | 1296 | def get_default_position(self): |
1270 | 1297 | return self.AT_CURSOR |
1271 | 1298 | |