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