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