commit 4d1e769

Michael Forney  ·  2014-11-29 19:11:09 +0000 UTC
parent e025cb5
window: Use button given in handler when calling the original handler

When a button is released normalling during a client-initiated resize or
move, we can't (and shouldn't because we already have the button passed
as an argument) look up the button by serial, because this changes to
the serial used for the release event.

Instead, add an extra button parameter to end_interaction, and only look
up the button by serial when it is NULL (when we end the interactions
prematurely).

This fixes a crash for client-initiated moves/resizes.
1 files changed,  +18, -10
+18, -10
 1@@ -76,21 +76,31 @@ static void begin_interaction(struct window_pointer_interaction * interaction,
 2     wl_list_insert(&swc.seat->pointer->handlers, &interaction->handler.link);
 3 }
 4 
 5-static void end_interaction(struct window_pointer_interaction * interaction)
 6+static void end_interaction(struct window_pointer_interaction * interaction,
 7+                            struct button * button)
 8 {
 9     if (!interaction->active)
10         return;
11 
12     if (interaction->original_handler)
13     {
14-        struct button * button;
15+        if (!button)
16+        {
17+            button = pointer_get_button(swc.seat->pointer, interaction->serial);
18+
19+            if (!button)
20+            {
21+                WARNING("No button with serial %u\n", interaction->serial);
22+                goto remove;
23+            }
24+        }
25 
26-        button = pointer_get_button(swc.seat->pointer, interaction->serial);
27         interaction->original_handler->button(interaction->original_handler,
28                                               swc_time(), button,
29                                               WL_POINTER_BUTTON_STATE_RELEASED);
30     }
31 
32+  remove:
33     interaction->active = false;
34     wl_list_remove(&interaction->handler.link);
35 }
36@@ -179,8 +189,8 @@ void swc_window_set_tiled(struct swc_window * base)
37 {
38     struct window * window = INTERNAL(base);
39 
40-    end_interaction(&window->move.interaction);
41-    end_interaction(&window->resize.interaction);
42+    end_interaction(&window->move.interaction, NULL);
43+    end_interaction(&window->resize.interaction, NULL);
44     if (window->impl->set_mode)
45         window->impl->set_mode(window, WINDOW_MODE_TILED);
46     window->mode = WINDOW_MODE_TILED;
47@@ -273,7 +283,7 @@ void swc_window_begin_move(struct swc_window * window)
48 EXPORT
49 void swc_window_end_move(struct swc_window * window)
50 {
51-    end_interaction(&INTERNAL(window)->move.interaction);
52+    end_interaction(&INTERNAL(window)->move.interaction, NULL);
53 }
54 
55 EXPORT
56@@ -285,7 +295,7 @@ void swc_window_begin_resize(struct swc_window * window, uint32_t edges)
57 EXPORT
58 void swc_window_end_resize(struct swc_window * window)
59 {
60-    end_interaction(&INTERNAL(window)->resize.interaction);
61+    end_interaction(&INTERNAL(window)->resize.interaction, NULL);
62 }
63 
64 static bool move_motion(struct pointer_handler * handler, uint32_t time,
65@@ -335,9 +345,7 @@ static bool handle_button(struct pointer_handler * handler, uint32_t time,
66         return false;
67     }
68 
69-    end_interaction(interaction);
70-    interaction->original_handler->button(interaction->original_handler, time,
71-                                          button, state);
72+    end_interaction(interaction, button);
73     return true;
74 }
75