Copy pressed_keys list before sending released/cancelled signal (RHBZ#737396).
This commit is contained in:
@ -229,12 +229,17 @@ eek_gtk_keyboard_real_button_release_event (GtkWidget *self,
|
|||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
{
|
{
|
||||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||||
GList *head;
|
GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||||
|
|
||||||
head = eek_keyboard_get_pressed_keys (priv->keyboard);
|
/* Make a copy of HEAD before sending "released" signal on
|
||||||
for (; head; head = g_list_next (head)) {
|
elements, so that the default handler of
|
||||||
|
EekKeyboard::key-released signal can remove elements from its
|
||||||
|
internal copy */
|
||||||
|
head = g_list_copy (head);
|
||||||
|
for (; head; head = g_list_next (head))
|
||||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
||||||
}
|
g_list_free (head);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,12 +256,20 @@ eek_gtk_keyboard_real_motion_notify_event (GtkWidget *self,
|
|||||||
if (key) {
|
if (key) {
|
||||||
GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
|
GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
/* Make a copy of HEAD before sending "cancelled" signal on
|
||||||
|
elements, so that the default handler of
|
||||||
|
EekKeyboard::key-cancelled signal can remove elements from its
|
||||||
|
internal copy */
|
||||||
|
head = g_list_copy (head);
|
||||||
for (; head; head = g_list_next (head)) {
|
for (; head; head = g_list_next (head)) {
|
||||||
if (head->data == key)
|
if (head->data == key)
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
else
|
else
|
||||||
g_signal_emit_by_name (head->data, "cancelled", priv->keyboard);
|
g_signal_emit_by_name (head->data, "cancelled", priv->keyboard);
|
||||||
}
|
}
|
||||||
|
g_list_free (head);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
g_signal_emit_by_name (key, "pressed", priv->keyboard);
|
g_signal_emit_by_name (key, "pressed", priv->keyboard);
|
||||||
}
|
}
|
||||||
@ -269,12 +282,16 @@ eek_gtk_keyboard_real_unmap (GtkWidget *self)
|
|||||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||||
|
|
||||||
if (priv->keyboard) {
|
if (priv->keyboard) {
|
||||||
GList *head;
|
GList *head = eek_keyboard_get_pressed_keys (priv->keyboard);
|
||||||
|
|
||||||
head = eek_keyboard_get_pressed_keys (priv->keyboard);
|
/* Make a copy of HEAD before sending "released" signal on
|
||||||
for (; head; head = g_list_next (head)) {
|
elements, so that the default handler of
|
||||||
|
EekKeyboard::key-released signal can remove elements from its
|
||||||
|
internal copy */
|
||||||
|
head = g_list_copy (head);
|
||||||
|
for (; head; head = g_list_next (head))
|
||||||
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
g_signal_emit_by_name (head->data, "released", priv->keyboard);
|
||||||
}
|
g_list_free (head);
|
||||||
}
|
}
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->unmap (self);
|
GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->unmap (self);
|
||||||
|
|||||||
@ -331,16 +331,12 @@ eek_keyboard_real_key_cancelled (EekKeyboard *self,
|
|||||||
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
EekKeyboardPrivate *priv = EEK_KEYBOARD_GET_PRIVATE(self);
|
||||||
GList *head;
|
GList *head;
|
||||||
|
|
||||||
for (head = priv->pressed_keys; head; ) {
|
for (head = priv->pressed_keys; head; head = g_list_next (head)) {
|
||||||
EekKey *pressed_key = head->data;
|
if (head->data == key) {
|
||||||
if (pressed_key == key) {
|
priv->pressed_keys = g_list_remove_link (priv->pressed_keys, head);
|
||||||
GList *next = g_list_next (head);
|
|
||||||
priv->pressed_keys =
|
|
||||||
g_list_remove_link (priv->pressed_keys, head);
|
|
||||||
g_list_free1 (head);
|
g_list_free1 (head);
|
||||||
head = next;
|
break;
|
||||||
} else
|
}
|
||||||
head = g_list_next (head);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user