window: Drop the window widget

It was just a temporary convenience for moving things over.
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 92b5f20..8cb85be 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -59,7 +59,9 @@
 struct panel {
 	struct surface base;
 	struct window *window;
+	struct widget *widget;
 	struct window *menu;
+	struct wl_list launcher_list;
 };
 
 struct background {
@@ -81,10 +83,12 @@
 	cairo_surface_t *icon;
 	int pressed;
 	const char *path;
+	struct wl_list link;
 };
 
 struct unlock_dialog {
 	struct window *window;
+	struct widget *widget;
 	struct widget *button;
 	int closing;
 
@@ -164,19 +168,17 @@
 }
 
 static void
-panel_draw_launcher(struct widget *widget, void *data)
+panel_draw_launcher(struct panel_launcher *launcher, void *data)
 {
 	cairo_t *cr = data;
-	struct panel_launcher *pi;
 	int x, y, width, height;
 	double dx, dy;
 
-	pi = widget_get_user_data(widget);
-	width = cairo_image_surface_get_width(pi->icon);
-	height = cairo_image_surface_get_height(pi->icon);
+	width = cairo_image_surface_get_width(launcher->icon);
+	height = cairo_image_surface_get_height(launcher->icon);
 	x = 0;
 	y = -height / 2;
-	if (pi->pressed) {
+	if (launcher->pressed) {
 		x++;
 		y++;
 	}
@@ -184,14 +186,15 @@
 	dx = x;
 	dy = y;
 	cairo_user_to_device(cr, &dx, &dy);
-	widget_set_allocation(widget, dx, dy, width, height);
+	widget_set_allocation(launcher->widget, dx, dy, width, height);
 
-	cairo_set_source_surface(cr, pi->icon, x, y);
+	cairo_set_source_surface(cr, launcher->icon, x, y);
 	cairo_paint(cr);
 
-	if (window_get_focus_widget(pi->panel->window) == widget) {
+	if (window_get_focus_widget(launcher->panel->window) ==
+	    launcher->widget) {
 		cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4);
-		cairo_mask_surface(cr, pi->icon, x, y);
+		cairo_mask_surface(cr, launcher->icon, x, y);
 	}
 
 	cairo_translate(cr, width + 10, 0);
@@ -212,8 +215,9 @@
 {
 	cairo_surface_t *surface;
 	cairo_t *cr;
+	struct panel_launcher *launcher;
+	struct panel *panel = window_get_user_data(window);
 
-	window_draw(window);
 	surface = window_get_surface(window);
 	cr = cairo_create(surface);
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
@@ -222,11 +226,11 @@
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
 	cairo_translate(cr, 10, 32 / 2);
-	window_for_each_widget(window, panel_draw_launcher, cr);
+	wl_list_for_each(launcher, &panel->launcher_list, link)
+		panel_draw_launcher(launcher, cr);
 
 	cairo_destroy(cr);
 	cairo_surface_destroy(surface);
-	window_flush(window);
 }
 
 static int
@@ -291,6 +295,7 @@
 
 	panel->base.configure = panel_configure;
 	panel->window = window_create(display, 0, 0);
+	panel->widget = window_add_widget(panel->window, panel);
 
 	window_set_title(panel->window, "panel");
 	window_set_decoration(panel->window, 0);
@@ -298,8 +303,8 @@
 	window_set_custom(panel->window);
 	window_set_user_data(panel->window, panel);
 
-	widget_set_button_handler(window_get_widget(panel->window),
-				  panel_button_handler);
+	widget_set_button_handler(panel->widget, panel_button_handler);
+	wl_list_init(&panel->launcher_list);
 
 	return panel;
 }
@@ -315,6 +320,8 @@
 	launcher->path = strdup(path);
 	launcher->panel = panel;
 
+	wl_list_insert(panel->launcher_list.prev, &launcher->link);
+
 	launcher->widget = window_add_widget(panel->window, launcher);
 	widget_set_enter_handler(launcher->widget,
 				 panel_launcher_enter_handler);
@@ -485,6 +492,7 @@
 	memset(dialog, 0, sizeof *dialog);
 
 	dialog->window = window_create(display, 260, 230);
+	dialog->widget = window_add_widget(dialog->window, dialog);
 	window_set_title(dialog->window, "Unlock your desktop");
 	window_set_custom(dialog->window);
 
diff --git a/clients/dnd.c b/clients/dnd.c
index febb1cc..e1c057d 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -38,6 +38,7 @@
 
 struct dnd {
 	struct window *window;
+	struct widget *widget;
 	struct display *display;
 	uint32_t key;
 	struct item *items[16];
@@ -365,8 +366,7 @@
 		   struct input *input, uint32_t time,
 		   int button, int state, void *data)
 {
-	struct window *window = data;
-	struct dnd *dnd = window_get_user_data(window);
+	struct dnd *dnd = data;
 	int32_t x, y;
 	struct item *item;
 	struct rectangle allocation;
@@ -406,7 +406,7 @@
 				     "text/plain; charset=utf-8");
 		wl_data_device_start_drag(input_get_data_device(input),
 					  dnd_drag->data_source,
-					  window_get_wl_surface(window),
+					  window_get_wl_surface(dnd->window),
 					  time);
 
 		input_set_pointer_image(input, time, POINTER_DRAGGING);
@@ -437,10 +437,7 @@
 		  struct input *input, uint32_t time,
 		  int32_t x, int32_t y, void *data)
 {
-	struct window *window = data;
-	struct dnd *dnd = window_get_user_data(window);
-
-	return lookup_cursor(dnd, x, y);
+	return lookup_cursor(data, x, y);
 }
 
 static int
@@ -448,10 +445,7 @@
 		   struct input *input, uint32_t time,
 		   int32_t x, int32_t y, void *data)
 {
-	struct window *window = data;
-	struct dnd *dnd = window_get_user_data(window);
-
-	return lookup_cursor(dnd, x, y);
+	return lookup_cursor(data, x, y);
 }
 
 static void
@@ -516,7 +510,6 @@
 	struct dnd *dnd;
 	int i, x, y;
 	int32_t width, height;
-	struct widget *widget;
 
 	dnd = malloc(sizeof *dnd);
 	if (dnd == NULL)
@@ -524,6 +517,7 @@
 	memset(dnd, 0, sizeof *dnd);
 
 	dnd->window = window_create(display, 400, 400);
+	dnd->widget = window_add_widget(dnd->window, dnd);
 	window_set_title(dnd->window, "Wayland Drag and Drop Demo");
 
 	dnd->display = display;
@@ -545,10 +539,9 @@
 	window_set_data_handler(dnd->window, dnd_data_handler);
 	window_set_drop_handler(dnd->window, dnd_drop_handler);
 
-	widget = window_get_widget(dnd->window);
-	widget_set_enter_handler(widget, dnd_enter_handler);
-	widget_set_motion_handler(widget, dnd_motion_handler);
-	widget_set_button_handler(widget, dnd_button_handler);
+	widget_set_enter_handler(dnd->widget, dnd_enter_handler);
+	widget_set_motion_handler(dnd->widget, dnd_motion_handler);
+	widget_set_button_handler(dnd->widget, dnd_button_handler);
 
 	width = 4 * (item_width + item_padding) + item_padding;
 	height = 4 * (item_height + item_padding) + item_padding;
diff --git a/clients/eventdemo.c b/clients/eventdemo.c
index 54daf77..928cfdd 100644
--- a/clients/eventdemo.c
+++ b/clients/eventdemo.c
@@ -83,6 +83,7 @@
  */
 struct eventdemo {
 	struct window *window;
+	struct widget *widget;
 	struct display *display;
 
 	unsigned int x, y, w, h;
@@ -285,6 +286,7 @@
 	 *			      int32_t width, int32_t height);
 	 */
 	e->window = window_create(d, width, height);
+	e->widget = window_add_widget(e->window, e);
 	window_set_title(e->window, title);
 	e->display = d;
 
@@ -314,12 +316,10 @@
 	window_set_key_handler(e->window, key_handler);
 
 	/* Set the callback button handler for the window */
-	widget_set_button_handler(window_get_widget(e->window),
-				  button_handler);
+	widget_set_button_handler(e->widget, button_handler);
 
 	/* Set the callback motion handler for the window */
-	widget_set_motion_handler(window_get_widget(e->window),
-				  motion_handler);
+	widget_set_motion_handler(e->widget, motion_handler);
 
 	/* Demonstrate how to create a borderless window.
 	   Move windows with META + left mouse button.
diff --git a/clients/flower.c b/clients/flower.c
index 18e2015..cac470d 100644
--- a/clients/flower.c
+++ b/clients/flower.c
@@ -36,6 +36,13 @@
 #include <wayland-client.h>
 #include "window.h"
 
+struct flower {
+	struct display *display;
+	struct window *window;
+	struct widget *widget;
+	int width, height;
+};
+
 static void
 set_random_color(cairo_t *cr)
 {
@@ -109,18 +116,12 @@
 	       struct input *input, uint32_t time,
 	       int button, int state, void *data)
 {
-	struct window *window = data;
+	struct flower *flower = data;
 
 	if (state)
-		window_move(window, input, time);
+		window_move(flower->window, input, time);
 }
 
-struct flower {
-	struct display *display;
-	struct window *window;
-	int width, height;
-};
-
 int main(int argc, char *argv[])
 {
 	cairo_surface_t *s;
@@ -141,6 +142,7 @@
 	flower.height = 200;
 	flower.display = d;
 	flower.window = window_create(d, flower.width, flower.height);
+	flower.widget = window_add_widget(flower.window, &flower);
 
 	window_set_title(flower.window, "flower");
 	window_set_decoration(flower.window, 0);
@@ -156,10 +158,8 @@
 	cairo_surface_destroy(s);
 	window_flush(flower.window);
 
-	widget_set_motion_handler(window_get_widget(flower.window),
-				  motion_handler);
-	widget_set_button_handler(window_get_widget(flower.window),
-				  button_handler);
+	widget_set_motion_handler(flower.widget, motion_handler);
+	widget_set_button_handler(flower.widget, button_handler);
 	window_set_user_data(flower.window, &flower);
 	display_run(d);
 
diff --git a/clients/resizor.c b/clients/resizor.c
index 2818e26..8f70d53 100644
--- a/clients/resizor.c
+++ b/clients/resizor.c
@@ -38,6 +38,7 @@
 struct resizor {
 	struct display *display;
 	struct window *window;
+	struct widget *widget;
 	struct window *menu;
 	int32_t width;
 
@@ -194,8 +195,7 @@
 	       struct input *input, uint32_t time,
 	       int button, int state, void *data)
 {
-	struct window *window = data;
-	struct resizor *resizor = window_get_user_data(window);
+	struct resizor *resizor = data;
 
 	switch (button) {
 	case BTN_RIGHT:
@@ -217,6 +217,7 @@
 	memset(resizor, 0, sizeof *resizor);
 
 	resizor->window = window_create(display, 500, 400);
+	resizor->widget = window_add_widget(resizor->window, resizor);
 	window_set_title(resizor->window, "Wayland Resizor");
 	resizor->display = display;
 
@@ -233,8 +234,7 @@
 	height = resizor->height.current + 0.5;
 
 	window_set_child_size(resizor->window, resizor->width, height);
-	widget_set_button_handler(window_get_widget(resizor->window),
-				  button_handler);
+	widget_set_button_handler(resizor->widget, button_handler);
 
 	resizor_draw(resizor);
 
diff --git a/clients/smoke.c b/clients/smoke.c
index 47f9ca5..2624deb 100644
--- a/clients/smoke.c
+++ b/clients/smoke.c
@@ -38,6 +38,7 @@
 struct smoke {
 	struct display *display;
 	struct window *window;
+	struct widget *widget;
 	cairo_surface_t *surface;
 	int x, y, width, height;
 	int offset, current;
@@ -267,6 +268,7 @@
 	smoke.height = 200;
 	smoke.display = d;
 	smoke.window = window_create(d, smoke.width, smoke.height);
+	smoke.widget = window_add_widget(smoke.window, &smoke);
 	window_set_title(smoke.window, "smoke");
 
 	window_set_buffer_type(smoke.window, WINDOW_BUFFER_TYPE_SHM);
@@ -289,8 +291,7 @@
 
 	window_flush(smoke.window);
 
-	widget_set_motion_handler(window_get_widget(smoke.window),
-				  smoke_motion_handler);
+	widget_set_motion_handler(smoke.widget, smoke_motion_handler);
 
 	window_set_user_data(smoke.window, &smoke);
 	frame_callback(&smoke, NULL, 0);
diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
index 479aa88..cdb38b4 100644
--- a/clients/tablet-shell.c
+++ b/clients/tablet-shell.c
@@ -220,8 +220,6 @@
 	window_set_user_data(shell->lockscreen, shell);
 	window_set_decoration(shell->lockscreen, 0);
 	window_set_custom(shell->lockscreen);
-	widget_set_button_handler(window_get_widget(shell->lockscreen),
-				  lockscreen_button_handler);
 
 	tablet_shell_set_lockscreen(shell->tablet_shell,
 				    window_get_wl_surface(shell->lockscreen));
diff --git a/clients/terminal.c b/clients/terminal.c
index 9ec8190..b507ab6 100644
--- a/clients/terminal.c
+++ b/clients/terminal.c
@@ -356,6 +356,7 @@
 
 struct terminal {
 	struct window *window;
+	struct widget *widget;
 	struct display *display;
 	union utf8_char *data;
 	struct task io_task;
@@ -2228,8 +2229,7 @@
 	       struct input *input, uint32_t time,
 	       int button, int state, void *data)
 {
-	struct window *window = data;
-	struct terminal *terminal = window_get_user_data(window);
+	struct terminal *terminal = data;
 
 	switch (button) {
 	case 272:
@@ -2240,7 +2240,7 @@
 					   &terminal->selection_start_y);
 			terminal->selection_end_x = terminal->selection_start_x;
 			terminal->selection_end_y = terminal->selection_start_y;
-			window_schedule_redraw(window);
+			widget_schedule_redraw(widget);
 		} else {
 			terminal->dragging = 0;
 		}
@@ -2253,8 +2253,7 @@
 	       struct input *input, uint32_t time,
 	       int32_t x, int32_t y, void *data)
 {
-	struct window *window = data;
-	struct terminal *terminal = window_get_user_data(window);
+	struct terminal *terminal = data;
 
 	if (terminal->dragging) {
 		input_get_position(input,
@@ -2284,6 +2283,7 @@
 	terminal->margin_top = 0;
 	terminal->margin_bottom = -1;
 	terminal->window = window_create(display, 500, 400);
+	terminal->widget = window_add_widget(terminal->window, terminal);
 	window_set_title(terminal->window, "Wayland Terminal");
 
 	init_state_machine(&terminal->state_machine);
@@ -2299,11 +2299,8 @@
 	window_set_key_handler(terminal->window, key_handler);
 	window_set_keyboard_focus_handler(terminal->window,
 					  keyboard_focus_handler);
-	widget_set_button_handler(window_get_widget(terminal->window),
-				  button_handler);
-
-	widget_set_motion_handler(window_get_widget(terminal->window),
-				  motion_handler);
+	widget_set_button_handler(terminal->widget, button_handler);
+	widget_set_motion_handler(terminal->widget, motion_handler);
 
 	surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
 	cr = cairo_create(surface);
diff --git a/clients/window.c b/clients/window.c
index 4da418d..998afb6 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -107,7 +107,6 @@
 struct window {
 	struct display *display;
 	struct window *parent;
-	struct widget *widget;
 	struct wl_surface *surface;
 	struct wl_shell_surface *shell_surface;
 	char *title;
@@ -183,6 +182,7 @@
 
 struct menu {
 	struct window *window;
+	struct widget *widget;
 	const char **entries;
 	uint32_t time;
 	int current;
@@ -918,12 +918,6 @@
 	return window->display;
 }
 
-struct widget *
-window_get_widget(struct window *window)
-{
-	return window->widget;
-}
-
 void
 window_create_surface(struct window *window)
 {
@@ -1065,6 +1059,7 @@
 	memset(widget, 0, sizeof *widget);
 	widget->window = window;
 	widget->user_data = data;
+	widget->allocation = window->allocation;
 	wl_list_insert(&window->widget_list, &widget->link);
 
 	return widget;
@@ -1879,6 +1874,7 @@
 		 int32_t width, int32_t height)
 {
 	struct window *window = data;
+	struct widget *widget;
 	int32_t child_width, child_height;
 
 	/* FIXME: this is probably the wrong place to check for width
@@ -1903,6 +1899,9 @@
 		if (window->redraw_handler)
 			window_schedule_redraw(window);
 	}
+
+	wl_list_for_each(widget, &window->widget_list, link)
+		widget->allocation = window->allocation;
 }
 
 static void
@@ -1959,8 +1958,6 @@
 		window->allocation.width = width;
 		window->allocation.height = height;
 	}
-
-	window->widget->allocation = window->allocation;
 }
 
 static void
@@ -2146,7 +2143,6 @@
 	window->transparent = 1;
 
 	wl_list_init(&window->widget_list);
-	window->widget = window_add_widget(window, window);
 
 	if (display->dpy)
 #ifdef HAVE_CAIRO_EGL
@@ -2208,7 +2204,7 @@
 	next = (sy - 8) / 20;
 	if (menu->current != next) {
 		menu->current = next;
-		widget_schedule_redraw(menu->window->widget);
+		widget_schedule_redraw(menu->widget);
 	}
 
 	return POINTER_LEFT_PTR;
@@ -2219,10 +2215,7 @@
 		    struct input *input, uint32_t time,
 		    int32_t x, int32_t y, void *data)
 {
-	struct window *window = data;
-	struct menu *menu = window_get_user_data(window);
-
-	return menu_set_item(menu, y);
+	return menu_set_item(data, y);
 }
 
 static int
@@ -2230,21 +2223,13 @@
 		   struct input *input, uint32_t time,
 		   int32_t x, int32_t y, void *data)
 {
-	struct window *window = data;
-	struct menu *menu = window_get_user_data(window);
-
-	menu_set_item(menu, y);
-
-	return POINTER_LEFT_PTR;
+	return menu_set_item(data, y);
 }
 
 static void
 menu_leave_handler(struct widget *widget, struct input *input, void *data)
 {
-	struct window *window = data;
-	struct menu *menu = window_get_user_data(window);
-
-	menu_set_item(menu, -200);
+	menu_set_item(data, -200);
 }
 
 static void
@@ -2253,14 +2238,13 @@
 		    int button, int state, void *data)
 
 {
-	struct window *window = data;
-	struct menu *menu = window_get_user_data(window);
+	struct menu *menu = data;
 
 	/* Either relase after press-drag-release or click-motion-click. */
 	if (state == 0 && time - menu->time > 500) {
-		menu->func(window->parent, 
-			   menu->current, window->parent->user_data);
-		window_destroy(window);
+		menu->func(menu->window->parent, 
+			   menu->current, menu->window->parent->user_data);
+		window_destroy(widget->window);
 	}
 }
 
@@ -2272,9 +2256,6 @@
 	struct menu *menu = data;
 	int32_t width, height, i;
 
-	width = 200;
-	height = menu->count * 20 + margin * 2;
-	window_set_child_size(window, width, height);
 	window_create_surface(window);
 
 	cr = cairo_create(window->cairo_surface);
@@ -2317,16 +2298,19 @@
 {
 	struct window *window;
 	struct menu *menu;
+	const int32_t margin = 3;
 
 	menu = malloc(sizeof *menu);
 	if (!menu)
 		return NULL;
 
-	window = window_create_internal(parent->display, parent, 0, 0);
+	window = window_create_internal(parent->display, parent,
+					200, count * 20 + margin * 2);
 	if (!window)
 		return NULL;
 
 	menu->window = window;
+	menu->widget = window_add_widget(menu->window, menu);
 	menu->entries = entries;
 	menu->count = count;
 	menu->time = time;
@@ -2344,10 +2328,10 @@
 	window_set_redraw_handler(window, menu_redraw_handler);
 	window_set_user_data(window, menu);
 
-	widget_set_enter_handler(window->widget, menu_enter_handler);
-	widget_set_leave_handler(window->widget, menu_leave_handler);
-	widget_set_motion_handler(window->widget, menu_motion_handler);
-	widget_set_button_handler(window->widget, menu_button_handler);
+	widget_set_enter_handler(menu->widget, menu_enter_handler);
+	widget_set_leave_handler(menu->widget, menu_leave_handler);
+	widget_set_motion_handler(menu->widget, menu_motion_handler);
+	widget_set_button_handler(menu->widget, menu_button_handler);
 
 	return window;
 }