[PATCH weston 06/11] shell: Organize workspace containers by output

Jonas Ådahl jadahl at gmail.com
Sat Jan 26 06:33:36 PST 2013


Instead of having one global workspace container, have one container per
output. This means that every output will have its own set of workspaces
with its own workspace state.

New surfaces are added to the current workspace on the container of the
output the surface was positioned at.

The workspace manager interface is currently limited to only represent
the container of the first output. All events and requests are handleded
as if there was only one container.

The keyboard bindings for changing workspaces are updated to change the
state of the container of the output where the pointer is on. If no
pointer exists, the workspace changing bindings are no-ops.

Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
---
 src/shell.c |  367 +++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 266 insertions(+), 101 deletions(-)

diff --git a/src/shell.c b/src/shell.c
index c5bb9c4..45e70f0 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -36,6 +36,7 @@
 #include "compositor.h"
 #include "desktop-shell-server-protocol.h"
 #include "workspaces-server-protocol.h"
+#include "../shared/hash.h"
 #include "../shared/config-parser.h"
 
 #define DEFAULT_NUM_WORKSPACES 1
@@ -62,6 +63,8 @@ struct workspace_container {
 	unsigned int current;
 	unsigned int num;
 
+	struct weston_output *output;
+
 	struct weston_animation animation;
 	struct wl_list anim_sticky_list;
 	int anim_dir;
@@ -120,7 +123,7 @@ struct desktop_shell {
 	struct wl_listener lock_surface_listener;
 
 	struct {
-		struct workspace_container container;
+		struct hash_table *table;
 		unsigned int default_num;
 
 		struct wl_list client_list;
@@ -234,9 +237,6 @@ static void
 activate(struct desktop_shell *shell, struct weston_surface *es,
 	 struct weston_seat *seat);
 
-static struct workspace *
-get_current_workspace(struct desktop_shell *shell);
-
 static struct shell_surface *
 get_shell_surface(struct weston_surface *surface);
 
@@ -576,50 +576,98 @@ workspace_restack_surface(struct workspace *ws, struct shell_surface *shsurf)
 }
 
 static struct workspace *
-get_workspace(struct desktop_shell *shell, unsigned int index)
+workspace_container_get(struct workspace_container *container,
+			unsigned int index)
 {
-	struct workspace **pws = shell->workspaces.container.workspaces.data;
-	assert(index < shell->workspaces.container.num);
-	pws += index;
-	return *pws;
+	struct workspace **pws = container->workspaces.data;
+	return *(pws + index);
 }
 
 static struct workspace *
-get_current_workspace(struct desktop_shell *shell)
+workspace_container_get_current(struct workspace_container *container)
 {
-	return get_workspace(shell, shell->workspaces.container.current);
+	return workspace_container_get(container, container->current);
 }
 
-static void
-activate_workspace(struct desktop_shell *shell, unsigned int index)
+static struct workspace_container *
+find_first_workspace_container(struct desktop_shell *shell)
 {
-	struct workspace *ws;
+	struct weston_output *output;
+	struct workspace_container *container;
 
-	ws = get_workspace(shell, index);
-	wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
+	output = container_of(shell->compositor->output_list.next,
+			      struct weston_output, link);
+	container = hash_table_lookup(shell->workspaces.table, output->id);
+
+	return container;
+}
+
+static struct workspace_container *
+find_focused_workspace_container(struct desktop_shell *shell,
+				 struct wl_seat *seat)
+{
+	int x, y;
+	struct weston_output *output;
+
+	if (seat->pointer == NULL)
+		return NULL;
+
+	x = wl_fixed_to_int(seat->pointer->x);
+	y = wl_fixed_to_int(seat->pointer->y);
+	wl_list_for_each(output, &shell->compositor->output_list, link)
+		if (pixman_region32_contains_point(&output->region,
+						   x, y, NULL))
+			return hash_table_lookup(shell->workspaces.table,
+						 output->id);
 
-	shell->workspaces.container.current = index;
+	return NULL;
+}
+
+static struct workspace_container *
+get_workspace_container(struct desktop_shell *shell, uint32_t container_id)
+{
+	return hash_table_lookup(shell->workspaces.table, container_id);
+}
+
+static struct workspace *
+find_workspace_for(struct desktop_shell *shell, struct weston_surface *surface)
+{
+	struct workspace_container *container;
+
+	if (surface->output)
+		container = get_workspace_container(shell, surface->output->id);
+	else
+		container = find_first_workspace_container(shell);
+	return workspace_container_get_current(container);
 }
 
 static void
-workspace_container_release(struct workspace_container *container)
+workspace_container_destroy(struct workspace_container *container)
 {
 	struct workspace **pws;
 
 	wl_array_for_each(pws, &container->workspaces)
 		workspace_destroy(*pws);
 	wl_array_release(&container->workspaces);
+	free(container);
 }
 
-static int
-workspace_container_init(struct workspace_container *container,
-			 struct desktop_shell *shell)
+static struct workspace_container *
+workspace_container_create(struct desktop_shell *shell,
+			   struct weston_output *output,
+			   unsigned int num)
 {
+	struct workspace_container *container;
 	struct workspace **pws;
 	unsigned int i;
 
+	container = malloc(sizeof *container);
+	if (container == NULL)
+		return NULL;
+
+	container->output = output;
 	container->current = 0;
-	container->num = shell->workspaces.default_num;
+	container->num = num;
 	wl_array_init(&container->workspaces);
 
 	container->anim_to = NULL;
@@ -627,20 +675,19 @@ workspace_container_init(struct workspace_container *container,
 
 	for (i = 0; i < container->num; i++) {
 		pws = wl_array_add(&container->workspaces, sizeof *pws);
-		if (pws == NULL) {
+		if (pws == NULL)
 			goto err;
-		}
 
 		*pws = workspace_create(container);
 		if (*pws == NULL)
 			goto err;
 	}
 
-	return 0;
+	return container;
 
 err:
-	workspace_container_release(container);
-	return -1;
+	workspace_container_destroy(container);
+	return NULL;
 }
 
 static unsigned int
@@ -704,7 +751,8 @@ static void
 broadcast_current_workspace_state(struct desktop_shell *shell)
 {
 	struct wl_resource *resource;
-	struct workspace_container *container = &shell->workspaces.container;
+	struct workspace_container *container =
+		find_first_workspace_container(shell);
 
 	wl_list_for_each(resource, &shell->workspaces.client_list, link)
 		workspace_manager_send_state(resource,
@@ -822,8 +870,6 @@ animate_workspace_change(struct desktop_shell *shell,
 			 struct workspace *from,
 			 struct workspace *to)
 {
-	struct weston_output *output;
-
 	int dir;
 
 	if (index > container->current)
@@ -840,9 +886,7 @@ animate_workspace_change(struct desktop_shell *shell,
 	container->anim_timestamp = 0;
 	container->animation.frame = animate_workspace_change_frame;
 
-	output = container_of(shell->compositor->output_list.next,
-			      struct weston_output, link);
-	wl_list_insert(&output->animation_list,
+	wl_list_insert(&container->output->animation_list,
 		       &container->animation.link);
 
 	wl_list_insert(from->layer.link.prev, &to->layer.link);
@@ -866,9 +910,10 @@ update_workspace(struct workspace_container *container,
 }
 
 static void
-change_workspace(struct desktop_shell *shell, unsigned int index)
+change_workspace(struct desktop_shell *shell,
+		 struct workspace_container *container,
+		 unsigned int index)
 {
-	struct workspace_container *container = &shell->workspaces.container;
 	struct workspace *from;
 	struct workspace *to;
 
@@ -879,8 +924,8 @@ change_workspace(struct desktop_shell *shell, unsigned int index)
 	if (!wl_list_empty(&shell->fullscreen_layer.surface_list))
 		return;
 
-	from = get_current_workspace(shell);
-	to = get_workspace(shell, index);
+	from = workspace_container_get_current(container);
+	to = workspace_container_get(container, index);
 
 	if (container->anim_from == to &&
 	    container->anim_to == from) {
@@ -926,9 +971,9 @@ workspace_has_only(struct workspace *ws, struct weston_surface *surface)
 static void
 move_surface_to_workspace(struct desktop_shell *shell,
 			  struct weston_surface *surface,
+			  struct workspace_container *container,
 			  uint32_t workspace)
 {
-	struct workspace_container *container = &shell->workspaces.container;
 	struct workspace *from;
 	struct workspace *to;
 	struct shell_surface *shsurf = get_shell_surface(surface);
@@ -940,7 +985,7 @@ move_surface_to_workspace(struct desktop_shell *shell,
 		return;
 
 	from = shsurf->workspace;
-	to = get_workspace(shell, workspace);
+	to = workspace_container_get(container, workspace);
 
 	workspace_restack_surface(to, shsurf);
 
@@ -956,9 +1001,9 @@ move_surface_to_workspace(struct desktop_shell *shell,
 static void
 take_surface_to_workspace_by_seat(struct desktop_shell *shell,
 				  struct wl_seat *wl_seat,
+				  struct workspace_container *container,
 				  unsigned int index)
 {
-	struct workspace_container *container = &shell->workspaces.container;
 	struct weston_seat *seat = (struct weston_seat *) wl_seat;
 	struct weston_surface *surface =
 		(struct weston_surface *) wl_seat->keyboard->focus;
@@ -973,9 +1018,9 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell,
 
 	shsurf = get_shell_surface(surface);
 	from = shsurf->workspace;
-	to = get_workspace(shell, index);
+	to = workspace_container_get(container, index);
 
-	if (get_current_workspace(shell) != from)
+	if (workspace_container_get_current(container) != from)
 		return;
 
 	workspace_restack_surface(to, shsurf);
@@ -1027,8 +1072,10 @@ workspace_manager_move_surface(struct wl_client *client,
 	struct desktop_shell *shell = resource->data;
 	struct weston_surface *surface =
 		(struct weston_surface *) surface_resource;
+	struct workspace_container *container =
+		find_first_workspace_container(shell);
 
-	move_surface_to_workspace(shell, surface, workspace);
+	move_surface_to_workspace(shell, surface, container, workspace);
 }
 
 static const struct workspace_manager_interface workspace_manager_implementation = {
@@ -1047,6 +1094,7 @@ bind_workspace_manager(struct wl_client *client,
 		       void *data, uint32_t version, uint32_t id)
 {
 	struct desktop_shell *shell = data;
+	struct workspace_container *container;
 	struct wl_resource *resource;
 
 	resource = wl_client_add_object(client, &workspace_manager_interface,
@@ -1061,9 +1109,10 @@ bind_workspace_manager(struct wl_client *client,
 	resource->destroy = unbind_resource;
 	wl_list_insert(&shell->workspaces.client_list, &resource->link);
 
+	container = find_first_workspace_container(shell);
 	workspace_manager_send_state(resource,
-				     shell->workspaces.container.current,
-				     shell->workspaces.container.num);
+				     container->current,
+				     container->num);
 }
 
 static void
@@ -1533,7 +1582,7 @@ shell_unset_fullscreen(struct shell_surface *shsurf)
 		shsurf->saved_rotation_valid = false;
 	}
 
-	ws = get_current_workspace(shsurf->shell);
+	ws = find_workspace_for(shsurf->shell, shsurf->surface);
 	workspace_restack_surface(ws, shsurf);
 }
 
@@ -2339,9 +2388,21 @@ desktop_shell_set_lock_surface(struct wl_client *client,
 }
 
 static void
+restore_current_focus_state(void *element, void *data)
+{
+	struct workspace_container *container = element;
+	struct desktop_shell *shell = data;
+	struct workspace *ws = workspace_container_get_current(container);
+
+	restore_focus_state(shell, ws);
+}
+
+static void
 resume_desktop(struct desktop_shell *shell)
 {
-	struct workspace *ws = get_current_workspace(shell);
+	struct weston_output *output;
+	struct workspace_container *container;
+	struct workspace *ws;
 
 	terminate_screensaver(shell);
 
@@ -2350,16 +2411,19 @@ resume_desktop(struct desktop_shell *shell)
 		       &shell->fullscreen_layer.link);
 	wl_list_insert(&shell->fullscreen_layer.link,
 		       &shell->panel_layer.link);
-	if (shell->showing_input_panels) {
+
+	wl_list_for_each(output, &shell->compositor->output_list, link) {
+		container = get_workspace_container(shell, output->id);
+		ws = workspace_container_get_current(container);
+		wl_list_insert(shell->panel_layer.link.prev, &ws->layer.link);
+	}
+
+	if (shell->showing_input_panels)
 		wl_list_insert(&shell->panel_layer.link,
 			       &shell->input_panel_layer.link);
-		wl_list_insert(&shell->input_panel_layer.link,
-			       &ws->layer.link);
-	} else {
-		wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
-	}
 
-	restore_focus_state(shell, get_current_workspace(shell));
+	hash_table_for_each(shell->workspaces.table,
+			    restore_current_focus_state, shell);
 
 	shell->locked = false;
 	shell->compositor->idle_time = shell->compositor->option_idle_time;
@@ -2712,10 +2776,10 @@ lower_fullscreen_layer(struct desktop_shell *shell)
 	struct weston_surface *surface, *prev;
 	struct shell_surface *shsurf;
 
-	ws = get_current_workspace(shell);
 	wl_list_for_each_reverse_safe(surface, prev,
 				      &shell->fullscreen_layer.surface_list,
 				      layer_link) {
+		ws = find_workspace_for(shell, surface);
 		shsurf = get_shell_surface(surface);
 		if (shsurf)
 			workspace_restack_surface(ws, shsurf);
@@ -2735,7 +2799,7 @@ activate(struct desktop_shell *shell, struct weston_surface *es,
 
 	weston_surface_activate(es, seat);
 
-	ws = get_current_workspace(shell);
+	ws = find_workspace_for(shell, es);
 	state = ensure_focus_state(shell, ws, seat);
 	if (state == NULL)
 		return;
@@ -2798,12 +2862,20 @@ click_to_activate_binding(struct wl_seat *seat, uint32_t time, uint32_t button,
 }
 
 static void
+unlink_current_workspace(void *element, void *data)
+{
+	struct workspace_container *container = element;
+	struct workspace *ws = workspace_container_get_current(container);
+
+	wl_list_remove(&ws->layer.link);
+}
+
+static void
 lock(struct wl_listener *listener, void *data)
 {
 	struct desktop_shell *shell =
 		container_of(listener, struct desktop_shell, lock_listener);
 	struct weston_output *output;
-	struct workspace *ws = get_current_workspace(shell);
 
 	if (shell->locked) {
 		wl_list_for_each(output, &shell->compositor->output_list, link)
@@ -2823,7 +2895,8 @@ lock(struct wl_listener *listener, void *data)
 	wl_list_remove(&shell->fullscreen_layer.link);
 	if (shell->showing_input_panels)
 		wl_list_remove(&shell->input_panel_layer.link);
-	wl_list_remove(&ws->layer.link);
+	hash_table_for_each(shell->workspaces.table,
+			    unlink_current_workspace, NULL);
 	wl_list_insert(&shell->compositor->cursor_layer.link,
 		       &shell->lock_layer.link);
 
@@ -2987,6 +3060,7 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
 	enum shell_surface_type surface_type = shsurf->type;
 	struct weston_surface *parent;
 	struct weston_seat *seat;
+	struct workspace_container *container;
 	struct workspace *ws;
 	int panel_height = 0;
 
@@ -3032,7 +3106,9 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
 	case SHELL_SURFACE_NONE:
 		break;
 	default:
-		ws = get_current_workspace(shell);
+		weston_surface_update_transform(surface);
+		container = get_workspace_container(shell, surface->output->id);
+		ws = workspace_container_get_current(container);
 		workspace_stack_surface(ws, shsurf);
 		break;
 	}
@@ -3416,33 +3492,41 @@ struct switcher {
 static void
 switcher_next(struct switcher *switcher)
 {
+	struct desktop_shell *shell = switcher->shell;
+	struct weston_output *output;
+	struct workspace_container *container;
+	struct workspace *ws;
 	struct weston_surface *surface;
 	struct weston_surface *first = NULL, *prev = NULL, *next = NULL;
 	struct shell_surface *shsurf;
-	struct workspace *ws = get_current_workspace(switcher->shell);
 
-	wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
-		switch (get_shell_surface_type(surface)) {
-		case SHELL_SURFACE_TOPLEVEL:
-		case SHELL_SURFACE_FULLSCREEN:
-		case SHELL_SURFACE_MAXIMIZED:
-			if (first == NULL)
-				first = surface;
-			if (prev == switcher->current)
-				next = surface;
-			prev = surface;
-			surface->alpha = 0.25;
-			surface->geometry.dirty = 1;
-			weston_surface_damage(surface);
-			break;
-		default:
-			break;
-		}
+	wl_list_for_each(output, &shell->compositor->output_list, link) {
+		container = get_workspace_container(shell, output->id);
+		ws = workspace_container_get_current(container);
+
+		wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
+			switch (get_shell_surface_type(surface)) {
+			case SHELL_SURFACE_TOPLEVEL:
+			case SHELL_SURFACE_FULLSCREEN:
+			case SHELL_SURFACE_MAXIMIZED:
+				if (first == NULL)
+					first = surface;
+				if (prev == switcher->current)
+					next = surface;
+				prev = surface;
+				surface->alpha = 0.25;
+				surface->geometry.dirty = 1;
+				weston_surface_damage(surface);
+				break;
+			default:
+				break;
+			}
 
-		if (is_black_surface(surface, NULL)) {
-			surface->alpha = 0.25;
-			surface->geometry.dirty = 1;
-			weston_surface_damage(surface);
+			if (is_black_surface(surface, NULL)) {
+				surface->alpha = 0.25;
+				surface->geometry.dirty = 1;
+				weston_surface_damage(surface);
+			}
 		}
 	}
 
@@ -3476,13 +3560,21 @@ switcher_handle_surface_destroy(struct wl_listener *listener, void *data)
 static void
 switcher_destroy(struct switcher *switcher)
 {
+	struct desktop_shell *shell = switcher->shell;
 	struct weston_surface *surface;
 	struct wl_keyboard *keyboard = switcher->grab.keyboard;
-	struct workspace *ws = get_current_workspace(switcher->shell);
+	struct weston_output *output;
+	struct workspace_container *container;
+	struct workspace *ws;
 
-	wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
-		surface->alpha = 1.0;
-		weston_surface_damage(surface);
+	wl_list_for_each(output, &shell->compositor->output_list, link) {
+		container = get_workspace_container(shell, output->id);
+		ws = workspace_container_get_current(container);
+
+		wl_list_for_each(surface, &ws->layer.surface_list, layer_link) {
+			surface->alpha = 1.0;
+			weston_surface_damage(surface);
+		}
 	}
 
 	if (switcher->current)
@@ -3732,14 +3824,21 @@ workspace_up_binding(struct wl_seat *seat, uint32_t time,
 		     uint32_t key, void *data)
 {
 	struct desktop_shell *shell = data;
-	unsigned int new_index = shell->workspaces.container.current;
+	struct workspace_container *container;
+	unsigned int new_index;
 
 	if (shell->locked)
 		return;
+
+	container = find_focused_workspace_container(shell, seat);
+	if (container == NULL)
+		return;
+
+	new_index = container->current;
 	if (new_index != 0)
 		new_index--;
 
-	change_workspace(shell, new_index);
+	change_workspace(shell, container, new_index);
 }
 
 static void
@@ -3747,14 +3846,21 @@ workspace_down_binding(struct wl_seat *seat, uint32_t time,
 		       uint32_t key, void *data)
 {
 	struct desktop_shell *shell = data;
-	unsigned int new_index = shell->workspaces.container.current;
+	struct workspace_container *container;
+	unsigned int new_index;
 
 	if (shell->locked)
 		return;
-	if (new_index < shell->workspaces.container.num - 1)
+
+	container = find_focused_workspace_container(shell, seat);
+	if (container == NULL)
+		return;
+
+	new_index = container->current;
+	if (new_index < container->num - 1)
 		new_index++;
 
-	change_workspace(shell, new_index);
+	change_workspace(shell, container, new_index);
 }
 
 static void
@@ -3762,15 +3868,30 @@ workspace_f_binding(struct wl_seat *seat, uint32_t time,
 		    uint32_t key, void *data)
 {
 	struct desktop_shell *shell = data;
+	struct workspace_container *container;
 	unsigned int new_index;
 
 	if (shell->locked)
 		return;
+
+	container = find_focused_workspace_container(shell, seat);
+	if (container == NULL)
+		return;
+
 	new_index = key - KEY_F1;
-	if (new_index >= shell->workspaces.container.num)
-		new_index = shell->workspaces.container.num - 1;
+	if (new_index >= container->num)
+		return;
 
-	change_workspace(shell, new_index);
+	change_workspace(shell, container, new_index);
+}
+
+static struct workspace_container *
+get_container_by_seat(struct wl_seat *seat)
+{
+	struct weston_surface *surface =
+		(struct weston_surface *) seat->keyboard->focus;
+	struct shell_surface *shsurf = get_shell_surface(surface);
+	return shsurf->workspace->container;
 }
 
 static void
@@ -3778,7 +3899,8 @@ workspace_move_surface_up_binding(struct wl_seat *seat, uint32_t time,
 				  uint32_t key, void *data)
 {
 	struct desktop_shell *shell = data;
-	unsigned int new_index = shell->workspaces.container.current;
+	struct workspace_container *container = get_container_by_seat(seat);
+	unsigned int new_index = container->current;
 
 	if (shell->locked)
 		return;
@@ -3786,7 +3908,7 @@ workspace_move_surface_up_binding(struct wl_seat *seat, uint32_t time,
 	if (new_index != 0)
 		new_index--;
 
-	take_surface_to_workspace_by_seat(shell, seat, new_index);
+	take_surface_to_workspace_by_seat(shell, seat, container, new_index);
 }
 
 static void
@@ -3794,15 +3916,48 @@ workspace_move_surface_down_binding(struct wl_seat *seat, uint32_t time,
 				    uint32_t key, void *data)
 {
 	struct desktop_shell *shell = data;
-	unsigned int new_index = shell->workspaces.container.current;
+	struct workspace_container *container = get_container_by_seat(seat);
+	unsigned int new_index = container->current;
 
 	if (shell->locked)
 		return;
 
-	if (new_index < shell->workspaces.container.num - 1)
+	if (new_index < container->num - 1)
 		new_index++;
 
-	take_surface_to_workspace_by_seat(shell, seat, new_index);
+	take_surface_to_workspace_by_seat(shell, seat, container, new_index);
+}
+
+static int
+init_output_workspaces(struct desktop_shell *shell,
+		       struct weston_output *output)
+{
+	struct workspace_container *container;
+	struct workspace *ws;
+
+	container = workspace_container_create(shell,
+					       output,
+					       shell->workspaces.default_num);
+	if (container == NULL)
+		return -1;
+
+	if (hash_table_insert(shell->workspaces.table,
+			      output->id, container) != 0) {
+		workspace_container_destroy(container);
+		return -1;
+	}
+
+	ws = workspace_container_get_current(container);
+	wl_list_insert(&shell->panel_layer.link, &ws->layer.link);
+
+	return 0;
+}
+static void
+destroy_workspace_container(void *element, void *data)
+{
+	struct workspace_container *container = element;
+
+	workspace_container_destroy(container);
 }
 
 static void
@@ -3819,7 +3974,9 @@ shell_destroy(struct wl_listener *listener, void *data)
 	wl_list_remove(&shell->show_input_panel_listener.link);
 	wl_list_remove(&shell->hide_input_panel_listener.link);
 
-	workspace_container_release(&shell->workspaces.container);
+	hash_table_for_each(shell->workspaces.table,
+			    destroy_workspace_container,
+			    NULL);
 
 	free(shell->screensaver.path);
 	free(shell);
@@ -3898,6 +4055,7 @@ module_init(struct weston_compositor *ec)
 {
 	struct weston_seat *seat;
 	struct desktop_shell *shell;
+	struct weston_output *output;
 	struct wl_event_loop *loop;
 
 	shell = malloc(sizeof *shell);
@@ -3907,6 +4065,12 @@ module_init(struct weston_compositor *ec)
 	memset(shell, 0, sizeof *shell);
 	shell->compositor = ec;
 
+	shell->workspaces.table = hash_table_create();
+	if (shell->workspaces.table == NULL) {
+		free(shell);
+		return -1;
+	}
+
 	shell->destroy_listener.notify = shell_destroy;
 	wl_signal_add(&ec->destroy_signal, &shell->destroy_listener);
 	shell->lock_listener.notify = lock;
@@ -3937,8 +4101,9 @@ module_init(struct weston_compositor *ec)
 
 	shell_configuration(shell);
 
-	workspace_container_init(&shell->workspaces.container, shell);
-	activate_workspace(shell, 0);
+	wl_list_for_each(output, &ec->output_list, link)
+		if (init_output_workspaces(shell, output) != 0)
+			return -1;
 
 	if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
 				  shell, bind_shell) == NULL)
-- 
1.7.10.4



More information about the wayland-devel mailing list