commit 28f049f

Michael Forney  ·  2014-08-14 05:16:21 +0000 UTC
parent 210f524
Replace window and screen event signals with handler structures
11 files changed,  +173, -142
+42, -55
  1@@ -30,7 +30,6 @@
  2 struct screen
  3 {
  4     struct swc_screen * swc;
  5-    struct wl_listener event_listener;
  6     struct wl_list windows;
  7     unsigned num_windows;
  8 };
  9@@ -38,7 +37,6 @@ struct screen
 10 struct window
 11 {
 12     struct swc_window * swc;
 13-    struct wl_listener event_listener;
 14     struct screen * screen;
 15     struct wl_list link;
 16 };
 17@@ -129,61 +127,57 @@ static void focus(struct window * window)
 18     focused_window = window;
 19 }
 20 
 21-static void window_event(struct wl_listener * listener, void * data)
 22+static void screen_usable_geometry_changed(void * data)
 23 {
 24-    struct swc_event * event = data;
 25-    struct window * window = NULL, * next_focus;
 26+    struct screen * screen = data;
 27 
 28-    window = wl_container_of(listener, window, event_listener);
 29+    /* If the usable geometry of the screen changes, for example when a panel is
 30+     * docked to the edge of the screen, we need to rearrange the windows to
 31+     * ensure they are all within the new usable geometry. */
 32+    arrange(screen);
 33+}
 34+
 35+static const struct swc_screen_handler screen_handler = {
 36+    .usable_geometry_changed = &screen_usable_geometry_changed,
 37+};
 38+
 39+static void window_destroy(void * data)
 40+{
 41+    struct window * window = data, * next_focus;
 42 
 43-    switch (event->type)
 44+    if (focused_window == window)
 45     {
 46-        case SWC_WINDOW_DESTROYED:
 47-            if (focused_window == window)
 48-            {
 49-                /* Try to find a new focus nearby the old one. */
 50-                next_focus = wl_container_of(window->link.next, window, link);
 51-
 52-                if (&next_focus->link == &window->screen->windows)
 53-                {
 54-                    next_focus = wl_container_of(window->link.prev,
 55-                                                 window, link);
 56-
 57-                    if (&next_focus->link == &window->screen->windows)
 58-                        next_focus = NULL;
 59-                }
 60-
 61-                focus(next_focus);
 62-            }
 63-
 64-            screen_remove_window(window->screen, window);
 65-            free(window);
 66-            break;
 67-        case SWC_WINDOW_ENTERED:
 68-            focus(window);
 69-            break;
 70+        /* Try to find a new focus nearby the old one. */
 71+        next_focus = wl_container_of(window->link.next, window, link);
 72+
 73+        if (&next_focus->link == &window->screen->windows)
 74+        {
 75+            next_focus = wl_container_of(window->link.prev,
 76+                                         window, link);
 77+
 78+            if (&next_focus->link == &window->screen->windows)
 79+                next_focus = NULL;
 80+        }
 81+
 82+        focus(next_focus);
 83     }
 84+
 85+    screen_remove_window(window->screen, window);
 86+    free(window);
 87 }
 88 
 89-static void screen_event(struct wl_listener * listener, void * data)
 90+static void window_entered(void * data)
 91 {
 92-    struct swc_event * event = data;
 93-    struct screen * screen = NULL;
 94-
 95-    screen = wl_container_of(listener, screen, event_listener);
 96+    struct window * window = data;
 97 
 98-    switch (event->type)
 99-    {
100-        case SWC_SCREEN_USABLE_GEOMETRY_CHANGED:
101-            /* If the usable geometry of the screen changes, for example when a
102-             * panel is docked to the edge of the screen, we need to rearrange
103-             * the windows to ensure they are all within the new usable
104-             * geometry. */
105-            arrange(screen);
106-            break;
107-    }
108+    focus(window);
109 }
110 
111+static const struct swc_window_handler window_handler = {
112+    .destroy = &window_destroy,
113+    .entered = &window_entered,
114+};
115+
116 static void new_screen(struct swc_screen * swc)
117 {
118     struct screen * screen;
119@@ -194,12 +188,9 @@ static void new_screen(struct swc_screen * swc)
120         return;
121 
122     screen->swc = swc;
123-    screen->event_listener.notify = &screen_event;
124     screen->num_windows = 0;
125     wl_list_init(&screen->windows);
126-
127-    /* Register a listener for the screen's event signal. */
128-    wl_signal_add(&swc->event_signal, &screen->event_listener);
129+    swc_screen_set_handler(swc, &screen_handler, screen);
130     active_screen = screen;
131 }
132 
133@@ -213,12 +204,8 @@ static void new_window(struct swc_window * swc)
134         return;
135 
136     window->swc = swc;
137-    window->event_listener.notify = &window_event;
138     window->screen = NULL;
139-
140-    /* Register a listener for the window's event signal. */
141-    wl_signal_add(&swc->event_signal, &window->event_listener);
142-
143+    swc_window_set_handler(swc, &window_handler, window);
144     screen_add_window(active_screen, window);
145     focus(window);
146 }
+12, -15
 1@@ -31,6 +31,7 @@
 2 #include "compositor.h"
 3 #include "data_device_manager.h"
 4 #include "drm.h"
 5+#include "event.h"
 6 #include "internal.h"
 7 #include "launch.h"
 8 #include "output.h"
 9@@ -59,7 +60,7 @@ struct target
10     struct wl_listener view_listener;
11     uint32_t mask;
12 
13-    struct wl_listener screen_listener;
14+    struct wl_listener screen_destroy_listener;
15 };
16 
17 static bool handle_motion(struct pointer_handler * handler, uint32_t time,
18@@ -92,27 +93,23 @@ struct swc_compositor swc_compositor = {
19     .pointer_handler = &pointer_handler
20 };
21 
22-static void handle_screen_event(struct wl_listener * listener, void * data)
23+static void handle_screen_destroy(struct wl_listener * listener, void * data)
24 {
25-    struct swc_event * event = data;
26-
27-    if (event->type == SWC_SCREEN_DESTROYED)
28-    {
29-        struct target * target
30-            = wl_container_of(listener, target, screen_listener);
31+    struct target * target
32+        = wl_container_of(listener, target, screen_destroy_listener);
33 
34-        wld_destroy_surface(target->surface);
35-        free(target);
36-    }
37+    wld_destroy_surface(target->surface);
38+    free(target);
39 }
40 
41 static struct target * target_get(struct screen * screen)
42 {
43     struct wl_listener * listener
44-        = wl_signal_get(&screen->base.event_signal, &handle_screen_event);
45+        = wl_signal_get(&screen->destroy_signal, &handle_screen_destroy);
46     struct target * target;
47 
48-    return listener ? wl_container_of(listener, target, screen_listener) : NULL;
49+    return listener ? wl_container_of(listener, target, screen_destroy_listener)
50+                    : NULL;
51 }
52 
53 static void handle_screen_view_event(struct wl_listener * listener, void * data)
54@@ -178,8 +175,8 @@ static struct target * target_new(struct screen * screen)
55     target->mask = screen_mask(screen);
56     target_swap_buffers(target);
57 
58-    target->screen_listener.notify = &handle_screen_event;
59-    wl_signal_add(&screen->base.event_signal, &target->screen_listener);
60+    target->screen_destroy_listener.notify = &handle_screen_destroy;
61+    wl_signal_add(&screen->destroy_signal, &target->screen_destroy_listener);
62 
63     return target;
64 
+1, -0
1@@ -23,6 +23,7 @@
2 
3 #include "cursor_plane.h"
4 #include "drm.h"
5+#include "event.h"
6 #include "internal.h"
7 #include "launch.h"
8 #include "screen.h"
+23, -0
 1@@ -6,6 +6,29 @@
 2 #include <stdint.h>
 3 #include <wayland-server.h>
 4 
 5+/**
 6+ * An event is the data passed to the listeners of the event_signals of various
 7+ * objects.
 8+ */
 9+struct swc_event
10+{
11+    /**
12+     * The type of event that was sent.
13+     *
14+     * The meaning of this field depends on the type of object containing the
15+     * event_signal that passed this event.
16+     */
17+    uint32_t type;
18+
19+    /**
20+     * Data specific to the event type.
21+     *
22+     * Unless explicitly stated in the description of the event type, this
23+     * value is undefined.
24+     */
25+    void * data;
26+};
27+
28 static inline void swc_send_event(struct wl_signal * signal, uint32_t type,
29                                   void * event_data)
30 {
+1, -0
1@@ -23,6 +23,7 @@
2 
3 #include "framebuffer_plane.h"
4 #include "drm.h"
5+#include "event.h"
6 #include "internal.h"
7 #include "launch.h"
8 #include "util.h"
+1, -0
1@@ -23,6 +23,7 @@
2 
3 #include "panel.h"
4 #include "compositor.h"
5+#include "event.h"
6 #include "internal.h"
7 #include "keyboard.h"
8 #include "output.h"
+20, -4
 1@@ -35,6 +35,19 @@
 2 
 3 #define INTERNAL(s) ((struct screen *) (s))
 4 
 5+static const struct swc_screen_handler null_handler;
 6+
 7+EXPORT
 8+void swc_screen_set_handler(struct swc_screen * base,
 9+                            const struct swc_screen_handler * handler,
10+                            void * data)
11+{
12+    struct screen * screen = INTERNAL(base);
13+
14+    screen->handler = handler;
15+    screen->handler_data = data;
16+}
17+
18 bool screens_initialize()
19 {
20     wl_list_init(&swc.screens);
21@@ -114,7 +127,8 @@ struct screen * screen_new(uint32_t crtc, struct swc_output * output)
22         goto error3;
23     }
24 
25-    wl_signal_init(&screen->base.event_signal);
26+    screen->handler = &null_handler;
27+    wl_signal_init(&screen->destroy_signal);
28     wl_list_init(&screen->resources);
29     wl_list_init(&screen->outputs);
30     wl_list_insert(&screen->outputs, &output->link);
31@@ -142,7 +156,9 @@ void screen_destroy(struct screen * screen)
32 {
33     struct swc_output * output, * next;
34 
35-    swc_send_event(&screen->base.event_signal, SWC_SCREEN_DESTROYED, NULL);
36+    if (screen->handler->destroy)
37+        screen->handler->destroy(screen->handler_data);
38+    wl_signal_emit(&screen->destroy_signal, NULL);
39     wl_list_for_each_safe(output, next, &screen->outputs, link)
40         swc_output_destroy(output);
41     framebuffer_plane_finalize(&screen->planes.framebuffer);
42@@ -182,8 +198,8 @@ void screen_update_usable_geometry(struct screen * screen)
43         screen->base.usable_geometry.width = extents->x2 - extents->x1;
44         screen->base.usable_geometry.height = extents->y2 - extents->y1;
45 
46-        swc_send_event(&screen->base.event_signal,
47-                       SWC_SCREEN_USABLE_GEOMETRY_CHANGED, NULL);
48+        if (screen->handler->usable_geometry_changed)
49+            screen->handler->usable_geometry_changed(screen->handler_data);
50     }
51 }
52 
+3, -0
 1@@ -49,7 +49,10 @@ struct screen_modifier
 2 struct screen
 3 {
 4     struct swc_screen base;
 5+    const struct swc_screen_handler * handler;
 6+    void * handler_data;
 7 
 8+    struct wl_signal destroy_signal;
 9     uint8_t id;
10 
11     struct
+40, -62
  1@@ -40,34 +40,32 @@ struct swc_rectangle
  2 
  3 /* Screens {{{ */
  4 
  5-enum
  6+struct swc_screen_handler
  7 {
  8     /**
  9-     * Sent when the screen is about to be destroyed.
 10+     * Called when the screen is about to be destroyed.
 11      *
 12-     * After this event is sent, the screen is not longer valid.
 13+     * After this is called, the screen is no longer valid.
 14      */
 15-    SWC_SCREEN_DESTROYED,
 16+    void (* destroy)(void * data);
 17 
 18     /**
 19-     * Sent when the total area of the screen is changed.
 20+     * Called when the total area of the screen has changed.
 21      */
 22-    SWC_SCREEN_GEOMETRY_CHANGED,
 23+    void (* geometry_changed)(void * data);
 24 
 25     /**
 26-     * Sent when the geometry of the screen available for laying out windows is
 27-     * changed.
 28+     * Called when the geometry of the screen available for laying out windows
 29+     * has changed.
 30      *
 31-     * Display servers should respond to this event by making sure all visible
 32-     * windows are within this area.
 33+     * A window manager should respond by making sure all visible windows are
 34+     * within this area.
 35      */
 36-    SWC_SCREEN_USABLE_GEOMETRY_CHANGED
 37+    void (* usable_geometry_changed)(void * data);
 38 };
 39 
 40 struct swc_screen
 41 {
 42-    struct wl_signal event_signal;
 43-
 44     /**
 45      * The total area of the screen.
 46      */
 47@@ -79,58 +77,65 @@ struct swc_screen
 48     struct swc_rectangle usable_geometry;
 49 };
 50 
 51+/**
 52+ * Set the handler associated with this screen.
 53+ */
 54+void swc_screen_set_handler(struct swc_screen * screen,
 55+                            const struct swc_screen_handler * handler,
 56+                            void * data);
 57+
 58 /* }}} */
 59 
 60 /* Windows {{{ */
 61 
 62-enum
 63+struct swc_window_handler
 64 {
 65     /**
 66-     * Sent when the window is about to be destroyed.
 67+     * Called when the window is about to be destroyed.
 68      *
 69-     * After this event is sent, the window is not longer valid.
 70+     * After this is called, the window is no longer valid.
 71      */
 72-    SWC_WINDOW_DESTROYED,
 73+    void (* destroy)(void * data);
 74 
 75     /**
 76-     * Sent when the window's title changes.
 77+     * Called when the window's title changes.
 78      */
 79-    SWC_WINDOW_TITLE_CHANGED,
 80+    void (* title_changed)(void * data);
 81 
 82     /**
 83-     * Sent when the window's class changes.
 84+     * Called when the window's class changes.
 85      */
 86-    SWC_WINDOW_CLASS_CHANGED,
 87+    void (* class_changed)(void * data);
 88 
 89     /**
 90-     * Sent when the pointer enters the window.
 91-     */
 92-    SWC_WINDOW_ENTERED,
 93-
 94-    /**
 95-     * Sent when the window's size has changed.
 96+     * Called when the window's parent changes.
 97+     *
 98+     * This can occur when the window becomes a transient for another window, or
 99+     * becomes a toplevel window.
100      */
101-    SWC_WINDOW_RESIZED,
102+    void (* parent_changed)(void * data);
103 
104     /**
105-     * Sent when the window's parent changes.
106-     *
107-     * This can occur when the window becomes a transient for another window,
108-     * or becomes a toplevel window.
109+     * Called when the pointer enters the window.
110      */
111-    SWC_WINDOW_PARENT_CHANGED
112+    void (* entered)(void * data);
113 };
114 
115 struct swc_window
116 {
117-    struct wl_signal event_signal;
118-
119     char * title;
120     char * class;
121 
122     struct swc_window * parent;
123 };
124 
125+/**
126+ * Set the handler associated with this window.
127+ */
128+void swc_window_set_handler(struct swc_window * window,
129+                            const struct swc_window_handler * handler,
130+                            void * data);
131+
132 /**
133  * Request that the specified window close.
134  */
135@@ -250,33 +255,6 @@ int swc_add_binding(enum swc_binding_type type,
136 
137 /* }}} */
138 
139-/* Events {{{ */
140-
141-/**
142- * An event is the data passed to the listeners of the event_signals of various
143- * objects.
144- */
145-struct swc_event
146-{
147-    /**
148-     * The type of event that was sent.
149-     *
150-     * The meaning of this field depends on the type of object containing the
151-     * event_signal that passed this event.
152-     */
153-    uint32_t type;
154-
155-    /**
156-     * Data specific to the event type.
157-     *
158-     * Unless explicitly stated in the description of the event type, this
159-     * value is undefined.
160-     */
161-    void * data;
162-};
163-
164-/* }}} */
165-
166 /**
167  * This is a user-provided structure that swc will use to notify the display
168  * server of new windows and screens.
+28, -6
 1@@ -36,6 +36,8 @@
 2 
 3 #define INTERNAL(w) ((struct window *) (w))
 4 
 5+static const struct swc_window_handler null_handler;
 6+
 7 static void handle_window_enter(struct wl_listener * listener, void * data)
 8 {
 9     struct swc_event * event = data;
10@@ -48,13 +50,25 @@ static void handle_window_enter(struct wl_listener * listener, void * data)
11     if (!event_data->new || !(window = event_data->new->window))
12         return;
13 
14-    swc_send_event(&window->base.event_signal, SWC_WINDOW_ENTERED, NULL);
15+    if (window->handler->entered)
16+        window->handler->entered(window->handler_data);
17 }
18 
19 struct wl_listener window_enter_listener = {
20     .notify = &handle_window_enter
21 };
22 
23+EXPORT
24+void swc_window_set_handler(struct swc_window * base,
25+                            const struct swc_window_handler * handler,
26+                            void * data)
27+{
28+    struct window * window = INTERNAL(base);
29+
30+    window->handler = handler;
31+    window->handler_data = data;
32+}
33+
34 EXPORT
35 void swc_window_close(struct swc_window * base)
36 {
37@@ -256,12 +270,12 @@ bool window_initialize(struct window * window, const struct window_impl * impl,
38     window->base.title = NULL;
39     window->base.class = NULL;
40     window->base.parent = NULL;
41-    wl_signal_init(&window->base.event_signal);
42 
43     if (!(window->view = swc_compositor_create_view(surface)))
44         return false;
45 
46     window->impl = impl;
47+    window->handler = &null_handler;
48     window->view->window = window;
49     window->managed = false;
50     window->move.interaction.handler = (struct pointer_handler) {
51@@ -301,7 +315,9 @@ void window_unmanage(struct window * window)
52     if (!window->managed)
53         return;
54 
55-    swc_send_event(&window->base.event_signal, SWC_WINDOW_DESTROYED, NULL);
56+    if (window->handler->destroy)
57+        window->handler->destroy(window->handler_data);
58+    window->handler = &null_handler;
59     window->managed = false;
60 }
61 
62@@ -309,14 +325,18 @@ void window_set_title(struct window * window, const char * title, size_t length)
63 {
64     free(window->base.title);
65     window->base.title = strndup(title, length);
66-    swc_send_event(&window->base.event_signal, SWC_WINDOW_TITLE_CHANGED, NULL);
67+
68+    if (window->handler->title_changed)
69+        window->handler->title_changed(window->handler_data);
70 }
71 
72 void window_set_class(struct window * window, const char * class)
73 {
74     free(window->base.class);
75     window->base.class = strdup(class);
76-    swc_send_event(&window->base.event_signal, SWC_WINDOW_CLASS_CHANGED, NULL);
77+
78+    if (window->handler->class_changed)
79+        window->handler->class_changed(window->handler_data);
80 }
81 
82 void window_set_parent(struct window * window, struct window * parent)
83@@ -326,6 +346,8 @@ void window_set_parent(struct window * window, struct window * parent)
84 
85     compositor_view_set_parent(window->view, parent->view);
86     window->base.parent = &parent->base;
87-    swc_send_event(&window->base.event_signal, SWC_WINDOW_PARENT_CHANGED, NULL);
88+
89+    if (window->handler->parent_changed)
90+        window->handler->parent_changed(window->handler_data);
91 }
92 
+2, -0
1@@ -39,6 +39,8 @@ struct window
2 {
3     struct swc_window base;
4     const struct window_impl * impl;
5+    const struct swc_window_handler * handler;
6+    void * handler_data;
7 
8     struct compositor_view * view;
9     bool managed;