commit b0ef818

Michael Forney  ·  2014-04-23 03:34:11 +0000 UTC
parent 740bae3
xwm: Use two lists of windows instead of an array of window entries
1 files changed,  +40, -48
+40, -48
  1@@ -1,6 +1,6 @@
  2 /* swc: libswc/xwm.c
  3  *
  4- * Copyright (c) 2013 Michael Forney
  5+ * Copyright (c) 2013, 2014 Michael Forney
  6  *
  7  * Permission is hereby granted, free of charge, to any person obtaining a copy
  8  * of this software and associated documentation files (the "Software"), to deal
  9@@ -35,17 +35,16 @@
 10 #include <xcb/xcb_ewmh.h>
 11 
 12 struct xwl_window
 13-{
 14-    xcb_window_t id;
 15-    struct window window;
 16-    struct wl_listener surface_destroy_listener;
 17-};
 18-
 19-struct xwl_window_entry
 20 {
 21     xcb_window_t id;
 22     bool override_redirect;
 23-    struct xwl_window * xwl_window;
 24+    struct wl_list link;
 25+
 26+    /* Only used for paired windows. */
 27+    struct {
 28+        struct window window;
 29+        struct wl_listener surface_destroy_listener;
 30+    };
 31 };
 32 
 33 static struct
 34@@ -54,7 +53,7 @@ static struct
 35     xcb_ewmh_connection_t ewmh;
 36     xcb_screen_t * screen;
 37     struct wl_event_source * source;
 38-    struct wl_array windows;
 39+    struct wl_list windows, unpaired_windows;
 40 } xwm;
 41 
 42 static void update_name(struct xwl_window * xwl_window)
 43@@ -72,14 +71,14 @@ static void update_name(struct xwl_window * xwl_window)
 44     xcb_ewmh_get_utf8_strings_reply_wipe(&wm_name_reply);
 45 }
 46 
 47-static struct xwl_window_entry * find_window(xcb_window_t id)
 48+static struct xwl_window * find_window(struct wl_list * list, xcb_window_t id)
 49 {
 50-    struct xwl_window_entry * entry;
 51+    struct xwl_window * window;
 52 
 53-    wl_array_for_each(entry, &xwm.windows)
 54+    wl_list_for_each(window, list, link)
 55     {
 56-        if (entry->id == id)
 57-            return entry;
 58+        if (window->id == id)
 59+            return window;
 60     }
 61 
 62     return NULL;
 63@@ -88,24 +87,30 @@ static struct xwl_window_entry * find_window(xcb_window_t id)
 64 /* X event handlers */
 65 void create_notify(xcb_create_notify_event_t * event)
 66 {
 67-    struct xwl_window_entry * entry;
 68+    struct xwl_window * xwl_window;
 69 
 70-    if (!(entry = wl_array_add(&xwm.windows, sizeof *entry)))
 71+    if (!(xwl_window = malloc(sizeof *xwl_window)))
 72         return;
 73 
 74-    entry->id = event->window;
 75-    entry->override_redirect = event->override_redirect;
 76-    entry->xwl_window = NULL;
 77+    xwl_window->id = event->window;
 78+    xwl_window->override_redirect = event->override_redirect;
 79+    wl_list_insert(&xwm.unpaired_windows, &xwl_window->link);
 80 }
 81 
 82 void destroy_notify(xcb_destroy_notify_event_t * event)
 83 {
 84-    struct xwl_window_entry * entry;
 85+    struct xwl_window * xwl_window;
 86 
 87-    if (!(entry = find_window(event->window)))
 88+    if ((xwl_window = find_window(&xwm.windows, event->window)))
 89+    {
 90+        wl_list_remove(&xwl_window->surface_destroy_listener.link);
 91+        window_finalize(&xwl_window->window);
 92+    }
 93+    else if (!(xwl_window = find_window(&xwm.unpaired_windows, event->window)))
 94         return;
 95 
 96-    swc_array_remove(&xwm.windows, entry, sizeof *entry);
 97+    wl_list_remove(&xwl_window->link);
 98+    free(xwl_window);
 99 }
100 
101 void map_request(xcb_map_request_event_t * event)
102@@ -119,15 +124,15 @@ void configure_request(xcb_configure_request_event_t * event)
103 
104 void property_notify(xcb_property_notify_event_t * event)
105 {
106-    struct xwl_window_entry * entry;
107+    struct xwl_window * xwl_window;
108 
109-    if (!(entry = find_window(event->window)) || !entry->xwl_window)
110+    if (!(xwl_window = find_window(&xwm.windows, event->window)))
111         return;
112 
113     if (event->atom == xwm.ewmh._NET_WM_NAME
114         && event->state == XCB_PROPERTY_NEW_VALUE)
115     {
116-        update_name(entry->xwl_window);
117+        update_name(xwl_window);
118     }
119 }
120 
121@@ -206,7 +211,8 @@ bool swc_xwm_initialize(int fd)
122 
123     xwm.source = wl_event_loop_add_fd(swc.event_loop, fd, WL_EVENT_READABLE,
124                                       &connection_data, NULL);
125-    wl_array_init(&xwm.windows);
126+    wl_list_init(&xwm.windows);
127+    wl_list_init(&xwm.unpaired_windows);
128 
129     if (!xwm.source)
130     {
131@@ -259,7 +265,6 @@ bool swc_xwm_initialize(int fd)
132 
133 void swc_xwm_finalize()
134 {
135-    wl_array_release(&xwm.windows);
136     wl_event_source_remove(xwm.source);
137     xcb_ewmh_connection_wipe(&xwm.ewmh);
138     xcb_disconnect(xwm.connection);
139@@ -301,46 +306,30 @@ static const struct window_impl xwl_window_handler = {
140 
141 static void handle_surface_destroy(struct wl_listener * listener, void * data)
142 {
143-    struct xwl_window_entry * entry;
144     struct xwl_window * xwl_window
145         = CONTAINER_OF(listener, typeof(*xwl_window), surface_destroy_listener);
146 
147     window_finalize(&xwl_window->window);
148-    free(xwl_window);
149-
150-    wl_array_for_each(entry, &xwm.windows)
151-    {
152-        if (entry->xwl_window == xwl_window)
153-        {
154-            entry->xwl_window = NULL;
155-            break;
156-        }
157-    }
158+    wl_list_remove(&xwl_window->link);
159+    wl_list_insert(&xwm.unpaired_windows, &xwl_window->link);
160 }
161 
162 void swc_xwm_manage_window(xcb_window_t id, struct swc_surface * surface)
163 {
164-    struct xwl_window_entry * entry;
165     struct xwl_window * xwl_window;
166     xcb_get_geometry_cookie_t geometry_cookie;
167     xcb_get_geometry_reply_t * geometry_reply;
168 
169-    if (!(entry = find_window(id)))
170-        return;
171-
172-    if (!(xwl_window = malloc(sizeof *xwl_window)))
173+    if (!(xwl_window = find_window(&xwm.unpaired_windows, id)))
174         return;
175 
176     geometry_cookie = xcb_get_geometry(xwm.connection, id);
177 
178     window_initialize(&xwl_window->window, &xwl_window_handler, surface);
179-    xwl_window->id = id;
180     xwl_window->surface_destroy_listener.notify = &handle_surface_destroy;
181     wl_resource_add_destroy_listener(surface->resource,
182                                      &xwl_window->surface_destroy_listener);
183 
184-    entry->xwl_window = xwl_window;
185-
186     if ((geometry_reply = xcb_get_geometry_reply(xwm.connection,
187                                                  geometry_cookie, NULL)))
188     {
189@@ -348,7 +337,7 @@ void swc_xwm_manage_window(xcb_window_t id, struct swc_surface * surface)
190         free(geometry_reply);
191     }
192 
193-    if (entry->override_redirect)
194+    if (xwl_window->override_redirect)
195         compositor_view_show(xwl_window->window.view);
196     else
197     {
198@@ -364,5 +353,8 @@ void swc_xwm_manage_window(xcb_window_t id, struct swc_surface * surface)
199 
200         window_set_state(&xwl_window->window, SWC_WINDOW_STATE_NORMAL);
201     }
202+
203+    wl_list_remove(&xwl_window->link);
204+    wl_list_insert(&xwm.windows, &xwl_window->link);
205 }
206