commit 8187fc8

Michael Forney  ·  2014-02-24 22:27:51 +0000 UTC
parent 8a03536
input_focus: Keep track of view instead of surface

If we ever want to have a surface visible in multiple views, it is the
focused view that matters, not the surface (so we can correctly
calculate coordinates for wl_pointer motion events).
13 files changed,  +81, -82
+6, -3
 1@@ -486,6 +486,7 @@ struct compositor_view * swc_compositor_create_view
 2     view_initialize(&view->base, &view_impl);
 3     view->surface = surface;
 4     view->buffer = NULL;
 5+    view->window = NULL;
 6     view->parent = NULL;
 7     view->visible = false;
 8     view->extents.x1 = 0;
 9@@ -497,6 +498,7 @@ struct compositor_view * swc_compositor_create_view
10     view->border.damaged = false;
11     pixman_region32_init(&view->clip);
12     wl_list_init(&view->children);
13+    wl_signal_init(&view->destroy_signal);
14     swc_surface_set_view(surface, &view->base);
15 
16     return view;
17@@ -504,6 +506,7 @@ struct compositor_view * swc_compositor_create_view
18 
19 void compositor_view_destroy(struct compositor_view * view)
20 {
21+    wl_signal_emit(&view->destroy_signal, NULL);
22     compositor_view_hide(view);
23     swc_surface_set_view(view->surface, NULL);
24     view_finalize(&view->base);
25@@ -732,7 +735,7 @@ bool handle_motion(struct pointer_handler * handler, uint32_t time,
26                    wl_fixed_t fx, wl_fixed_t fy)
27 {
28     struct compositor_view * view;
29-    struct swc_surface * surface = NULL;
30+    bool found = false;
31     int32_t x, y;
32 
33     wl_list_for_each(view, &compositor.views, link)
34@@ -745,12 +748,12 @@ bool handle_motion(struct pointer_handler * handler, uint32_t time,
35                                               x - view->base.geometry.x,
36                                               y - view->base.geometry.y, NULL))
37         {
38-            surface = view->surface;
39+            found = true;
40             break;
41         }
42     }
43 
44-    pointer_set_focus(swc.seat->pointer, surface);
45+    pointer_set_focus(swc.seat->pointer, found ? view : NULL);
46 
47     return false;
48 }
+2, -0
 1@@ -42,6 +42,7 @@ struct compositor_view
 2     struct view base;
 3     struct swc_surface * surface;
 4     struct wld_buffer * buffer;
 5+    struct window * window;
 6     struct compositor_view * parent;
 7 
 8     /* Whether or not the view is visible (mapped). */
 9@@ -62,6 +63,7 @@ struct compositor_view
10     } border;
11 
12     struct wl_list link, children, child_link;
13+    struct wl_signal destroy_signal;
14 };
15 
16 struct compositor_view * swc_compositor_create_view
+39, -45
  1@@ -22,56 +22,62 @@
  2  */
  3 
  4 #include "input_focus.h"
  5+#include "compositor.h"
  6 #include "event.h"
  7 #include "surface.h"
  8 #include "util.h"
  9 
 10 static inline void focus(struct input_focus * input_focus,
 11-                         struct swc_surface * surface,
 12-                         struct wl_resource * resource)
 13+                         struct compositor_view * view)
 14 {
 15-    if (surface)
 16+    struct wl_resource * resource = NULL;
 17+
 18+    if (view)
 19     {
 20-        wl_resource_add_destroy_listener
 21-            (surface->resource, &input_focus->surface_destroy_listener);
 22-    }
 23+        struct wl_client * client;
 24+
 25+        client = wl_resource_get_client(view->surface->resource);
 26+        resource = wl_resource_find_for_client(&input_focus->resources, client);
 27 
 28-    if (resource)
 29-        input_focus->handler->enter(input_focus->handler, resource, surface);
 30+        wl_signal_add(&view->destroy_signal,
 31+                      &input_focus->view_destroy_listener);
 32 
 33-    input_focus->surface = surface;
 34+        if (resource)
 35+            input_focus->handler->enter(input_focus->handler, resource, view);
 36+    }
 37+
 38+    input_focus->view = view;
 39     input_focus->resource = resource;
 40 }
 41 
 42 static inline void unfocus(struct input_focus * input_focus)
 43 {
 44-    if (input_focus->surface)
 45-        wl_list_remove(&input_focus->surface_destroy_listener.link);
 46+    if (input_focus->view)
 47+        wl_list_remove(&input_focus->view_destroy_listener.link);
 48 
 49     if (input_focus->resource)
 50     {
 51         input_focus->handler->leave(input_focus->handler, input_focus->resource,
 52-                                    input_focus->surface);
 53+                                    input_focus->view);
 54     }
 55 }
 56 
 57-static void handle_focus_surface_destroy(struct wl_listener * listener,
 58-                                         void * data)
 59+static void handle_focus_view_destroy(struct wl_listener * listener,
 60+                                      void * data)
 61 {
 62-    struct input_focus * input_focus = CONTAINER_OF
 63-        (listener, typeof(*input_focus), surface_destroy_listener);
 64+    struct input_focus * input_focus
 65+        = CONTAINER_OF(listener, typeof(*input_focus), view_destroy_listener);
 66 
 67-    input_focus->surface = NULL;
 68     input_focus->resource = NULL;
 69+    input_focus->view = NULL;
 70 }
 71 
 72 bool input_focus_initialize(struct input_focus * input_focus,
 73                             struct input_focus_handler * handler)
 74 {
 75     input_focus->resource = NULL;
 76-    input_focus->surface = NULL;
 77-    input_focus->surface_destroy_listener.notify
 78-        = &handle_focus_surface_destroy;
 79+    input_focus->view = NULL;
 80+    input_focus->view_destroy_listener.notify = &handle_focus_view_destroy;
 81     input_focus->handler = handler;
 82 
 83     wl_list_init(&input_focus->resources);
 84@@ -90,17 +96,19 @@ void input_focus_add_resource(struct input_focus * input_focus,
 85 {
 86     /* If this new input resource corresponds to our focus, set it as our
 87      * focus. */
 88-    if (input_focus->surface)
 89+    if (input_focus->view)
 90     {
 91         struct wl_client * client, * surface_client;
 92 
 93         client = wl_resource_get_client(resource);
 94-        surface_client = wl_resource_get_client(input_focus->surface->resource);
 95+        surface_client = wl_resource_get_client
 96+            (input_focus->view->surface->resource);
 97 
 98         if (client == surface_client)
 99         {
100-            unfocus(input_focus);
101-            focus(input_focus, input_focus->surface, resource);
102+            input_focus->handler->enter(input_focus->handler, resource,
103+                                        input_focus->view);
104+            input_focus->resource = resource;
105         }
106     }
107 
108@@ -117,35 +125,21 @@ void input_focus_remove_resource(struct input_focus * input_focus,
109 }
110 
111 void input_focus_set(struct input_focus * input_focus,
112-                     struct swc_surface * surface)
113+                     struct compositor_view * view)
114 {
115-    struct wl_client * client;
116-    struct wl_resource * resource;
117     struct input_focus_event_data data;
118 
119-    if (surface == input_focus->surface)
120+    if (view == input_focus->view)
121         return;
122 
123-    data.old = input_focus->surface;
124+    data.old = input_focus->view;
125+    data.new = view;
126 
127-    /* Unfocus previously focused surface. */
128+    /* Unfocus previously focused view. */
129     unfocus(input_focus);
130 
131-    /* Focus new surface, if given. */
132-    if (surface)
133-    {
134-        client = wl_resource_get_client(surface->resource);
135-        resource = wl_resource_find_for_client(&input_focus->resources, client);
136-
137-        focus(input_focus, surface, resource);
138-    }
139-    else
140-    {
141-        input_focus->surface = NULL;
142-        input_focus->resource = NULL;
143-    }
144-
145-    data.new = input_focus->surface;
146+    /* Focus new view, if given. */
147+    focus(input_focus, view);
148 
149     swc_send_event(&input_focus->event_signal, INPUT_FOCUS_EVENT_CHANGED,
150                    &data);
+6, -6
 1@@ -34,24 +34,24 @@ enum
 2 
 3 struct input_focus_event_data
 4 {
 5-    struct swc_surface * old, * new;
 6+    struct compositor_view * old, * new;
 7 };
 8 
 9 struct input_focus_handler
10 {
11     void (* enter)(struct input_focus_handler * handler,
12                    struct wl_resource * resource,
13-                   struct swc_surface * surface);
14+                   struct compositor_view * view);
15     void (* leave)(struct input_focus_handler * handler,
16                    struct wl_resource * resource,
17-                   struct swc_surface * surface);
18+                   struct compositor_view * view);
19 };
20 
21 struct input_focus
22 {
23     struct wl_resource * resource;
24-    struct swc_surface * surface;
25-    struct wl_listener surface_destroy_listener;
26+    struct compositor_view * view;
27+    struct wl_listener view_destroy_listener;
28 
29     struct input_focus_handler * handler;
30     struct wl_list resources;
31@@ -71,7 +71,7 @@ void input_focus_remove_resource(struct input_focus * input_focus,
32                                  struct wl_resource * resource);
33 
34 void input_focus_set(struct input_focus * input_focus,
35-                     struct swc_surface * surface);
36+                     struct compositor_view * view);
37 
38 #endif
39 
+7, -6
 1@@ -26,6 +26,7 @@
 2  */
 3 
 4 #include "swc.h"
 5+#include "compositor.h"
 6 #include "keyboard.h"
 7 #include "util.h"
 8 
 9@@ -33,7 +34,7 @@
10 #include <string.h>
11 
12 static void enter(struct input_focus_handler * handler,
13-                  struct wl_resource * resource, struct swc_surface * surface)
14+                  struct wl_resource * resource, struct compositor_view * view)
15 {
16     struct keyboard * keyboard;
17     struct wl_client * client;
18@@ -45,12 +46,12 @@ static void enter(struct input_focus_handler * handler,
19     display = wl_client_get_display(client);
20     serial = wl_display_next_serial(display);
21 
22-    wl_keyboard_send_enter(resource, serial, surface->resource,
23+    wl_keyboard_send_enter(resource, serial, view->surface->resource,
24                            &keyboard->client_handler.keys);
25 }
26 
27 static void leave(struct input_focus_handler * handler,
28-                  struct wl_resource * resource, struct swc_surface * surface)
29+                  struct wl_resource * resource, struct compositor_view * view)
30 {
31     struct wl_client * client;
32     struct wl_display * display;
33@@ -60,7 +61,7 @@ static void leave(struct input_focus_handler * handler,
34     display = wl_client_get_display(client);
35     serial = wl_display_next_serial(display);
36 
37-    wl_keyboard_send_leave(resource, serial, surface->resource);
38+    wl_keyboard_send_leave(resource, serial, view->surface->resource);
39 }
40 
41 static bool client_handle_key(struct keyboard * keyboard, uint32_t time,
42@@ -141,9 +142,9 @@ void keyboard_finalize(struct keyboard * keyboard)
43  * Sets the focus of the keyboard to the specified surface.
44  */
45 void keyboard_set_focus(struct keyboard * keyboard,
46-                            struct swc_surface * surface)
47+                        struct compositor_view * view)
48 {
49-    input_focus_set(&keyboard->focus, surface);
50+    input_focus_set(&keyboard->focus, view);
51 }
52 
53 static void unbind(struct wl_resource * resource)
+1, -1
1@@ -68,7 +68,7 @@ struct keyboard
2 bool keyboard_initialize(struct keyboard * keyboard);
3 void keyboard_finalize(struct keyboard * keyboard);
4 void keyboard_set_focus(struct keyboard * keyboard,
5-                        struct swc_surface * surface);
6+                        struct compositor_view * view);
7 struct wl_resource * keyboard_bind(struct keyboard * keyboard,
8                                    struct wl_client * client, uint32_t id);
9 void keyboard_handle_key(struct keyboard * keyboard, uint32_t time,
+1, -1
1@@ -132,7 +132,7 @@ static void dock(struct wl_client * client, struct wl_resource * resource,
2     wl_list_insert(&screen->modifiers, &panel->modifier.link);
3 
4     if (focus)
5-        keyboard_set_focus(swc.seat->keyboard, panel->surface);
6+        keyboard_set_focus(swc.seat->keyboard, panel->view);
7 
8     swc_panel_send_docked(resource, length);
9 }
+11, -10
 1@@ -22,6 +22,7 @@
 2  */
 3 
 4 #include "pointer.h"
 5+#include "compositor.h"
 6 #include "event.h"
 7 #include "internal.h"
 8 #include "screen.h"
 9@@ -34,7 +35,7 @@
10 #include <wld/wld.h>
11 
12 static void enter(struct input_focus_handler * handler,
13-                  struct wl_resource * resource, struct swc_surface * surface)
14+                  struct wl_resource * resource, struct compositor_view * view)
15 {
16     struct pointer * pointer;
17     struct wl_client * client;
18@@ -47,15 +48,15 @@ static void enter(struct input_focus_handler * handler,
19     display = wl_client_get_display(client);
20     serial = wl_display_next_serial(display);
21 
22-    surface_x = pointer->x - wl_fixed_from_int(surface->view->geometry.x);
23-    surface_y = pointer->y - wl_fixed_from_int(surface->view->geometry.y);
24+    surface_x = pointer->x - wl_fixed_from_int(view->base.geometry.x);
25+    surface_y = pointer->y - wl_fixed_from_int(view->base.geometry.y);
26 
27-    wl_pointer_send_enter(resource, serial, surface->resource,
28+    wl_pointer_send_enter(resource, serial, view->surface->resource,
29                           surface_x, surface_y);
30 }
31 
32 static void leave(struct input_focus_handler * handler,
33-                  struct wl_resource * resource, struct swc_surface * surface)
34+                  struct wl_resource * resource, struct compositor_view * view)
35 {
36     struct wl_client * client;
37     struct wl_display * display;
38@@ -65,7 +66,7 @@ static void leave(struct input_focus_handler * handler,
39     display = wl_client_get_display(client);
40     serial = wl_display_next_serial(display);
41 
42-    wl_pointer_send_leave(resource, serial, surface->resource);
43+    wl_pointer_send_leave(resource, serial, view->surface->resource);
44 }
45 
46 static void handle_cursor_surface_destroy(struct wl_listener * listener,
47@@ -203,8 +204,8 @@ static bool client_handle_motion(struct pointer_handler * handler,
48 
49     wl_pointer_send_motion
50         (pointer->focus.resource, time,
51-         x - wl_fixed_from_int(pointer->focus.surface->view->geometry.x),
52-         y - wl_fixed_from_int(pointer->focus.surface->view->geometry.y));
53+         x - wl_fixed_from_int(pointer->focus.view->base.geometry.x),
54+         y - wl_fixed_from_int(pointer->focus.view->base.geometry.y));
55 
56     return true;
57 }
58@@ -256,9 +257,9 @@ void pointer_finalize(struct pointer * pointer)
59     pixman_region32_fini(&pointer->region);
60 }
61 
62-void pointer_set_focus(struct pointer * pointer, struct swc_surface * surface)
63+void pointer_set_focus(struct pointer * pointer, struct compositor_view * view)
64 {
65-    input_focus_set(&pointer->focus, surface);
66+    input_focus_set(&pointer->focus, view);
67 }
68 
69 static void clip_position(struct pointer * pointer,
+1, -1
1@@ -81,7 +81,7 @@ struct pointer
2 
3 bool pointer_initialize(struct pointer * pointer);
4 void pointer_finalize(struct pointer * pointer);
5-void pointer_set_focus(struct pointer * pointer, struct swc_surface * surface);
6+void pointer_set_focus(struct pointer * pointer, struct compositor_view * view);
7 void pointer_set_region(struct pointer * pointer, pixman_region32_t * region);
8 void pointer_set_cursor(struct pointer * pointer, uint32_t id);
9 
+3, -2
 1@@ -22,6 +22,7 @@
 2  */
 3 
 4 #include "seat.h"
 5+#include "compositor.h"
 6 #include "data_device.h"
 7 #include "evdev_device.h"
 8 #include "event.h"
 9@@ -103,8 +104,8 @@ static void handle_keyboard_focus_event(struct wl_listener * listener,
10         case INPUT_FOCUS_EVENT_CHANGED:
11             if (event_data->new)
12             {
13-                struct wl_client * client
14-                    = wl_resource_get_client(event_data->new->resource);
15+                struct wl_client * client = wl_resource_get_client
16+                    (event_data->new->surface->resource);
17 
18                 /* Offer the selection to the new focus. */
19                 swc_data_device_offer_selection(&seat.data_device, client);
+0, -1
1@@ -373,7 +373,6 @@ struct swc_surface * swc_surface_new(struct wl_client * client,
2 
3     /* Initialize the surface. */
4     surface->pending.commit = 0;
5-    surface->window = NULL;
6     surface->view = NULL;
7     surface->view_listener.notify = &handle_view_event;
8 
+0, -1
1@@ -68,7 +68,6 @@ struct swc_surface
2         int32_t x, y;
3     } pending;
4 
5-    struct window * window;
6     struct view * view;
7     struct wl_listener view_listener;
8 };
+4, -5
 1@@ -71,8 +71,8 @@ EXPORT
 2 void swc_window_focus(struct swc_window * base)
 3 {
 4     struct window * window = INTERNAL(base);
 5-    struct swc_surface * new_focus = window ? window->surface : NULL,
 6-                       * old_focus = swc.seat->keyboard->focus.surface;
 7+    struct compositor_view * new_focus = window ? window->view : NULL,
 8+                           * old_focus = swc.seat->keyboard->focus.view;
 9 
10     /* If the keyboard already has a focused window, and we are changing the
11      * focus to either NULL, or a window with a different implementation, set
12@@ -239,6 +239,7 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
13 
14     window->surface = surface;
15     window->impl = impl;
16+    window->view->window = window;
17     window->move.interaction.handler = (struct pointer_handler) {
18         .motion = &move_motion,
19         .button = &handle_button
20@@ -248,8 +249,6 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
21         .button = &handle_button
22     };
23 
24-    surface->window = window;
25-
26     swc.manager->new_window(&window->base);
27 
28     return true;
29@@ -261,7 +260,7 @@ void window_finalize(struct window * window)
30 
31     swc_send_event(&window->base.event_signal, SWC_WINDOW_DESTROYED, NULL);
32     compositor_view_destroy(window->view);
33-    window->surface->window = NULL;
34+    window->view->window = NULL;
35     free(window->base.title);
36     free(window->base.class);
37 }