[PATCH] desktop-shell: Add shortcut support

zhiwen.wu at linux.intel.com zhiwen.wu at linux.intel.com
Wed Jun 20 21:51:47 PDT 2012


From: Alex Wu <zhiwen.wu at linux.intel.com>

The section name in weston.ini is "shortcut" and keys definition
are the same as launcher. The layout of shortcut is hardcoded for
implementation convenience. Since the concept of shortcut is almost
the same as panel_launcher, reused the panel_launcher code.
---
 clients/desktop-shell.c |  240 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 167 insertions(+), 73 deletions(-)

diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 6c73a5c..ea4ec70 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -59,20 +59,19 @@ struct surface {
 			  struct desktop_shell *desktop_shell,
 			  uint32_t edges, struct window *window,
 			  int32_t width, int32_t height);
+	struct window *window;
+	struct widget *widget;
 };
 
 struct panel {
 	struct surface base;
-	struct window *window;
-	struct widget *widget;
 	struct wl_list launcher_list;
 	struct panel_clock *clock;
 };
 
 struct background {
 	struct surface base;
-	struct window *window;
-	struct widget *widget;
+	struct wl_list shortcut_list;
 };
 
 struct output {
@@ -83,9 +82,9 @@ struct output {
 	struct background *background;
 };
 
-struct panel_launcher {
+struct launcher {
 	struct widget *widget;
-	struct panel *panel;
+	struct surface *parent;
 	cairo_surface_t *icon;
 	int focused, pressed;
 	const char *path;
@@ -112,9 +111,12 @@ static char *key_background_image = DATADIR "/weston/pattern.png";
 static char *key_background_type = "tile";
 static uint32_t key_panel_color = 0xaa000000;
 static uint32_t key_background_color = 0xff002244;
-static char *key_launcher_icon;
-static char *key_launcher_path;
-static void launcher_section_done(void *data);
+static char *key_panel_launcher_icon;
+static char *key_panel_launcher_path;
+static char *key_shortcut_icon;
+static char *key_shortcut_path;
+static void panel_launcher_section_done(void *data);
+static void shortcut_section_done(void *data);
 static int key_locking = 1;
 
 static const struct config_key shell_config_keys[] = {
@@ -125,17 +127,25 @@ static const struct config_key shell_config_keys[] = {
 	{ "locking", CONFIG_KEY_BOOLEAN, &key_locking },
 };
 
-static const struct config_key launcher_config_keys[] = {
-	{ "icon", CONFIG_KEY_STRING, &key_launcher_icon },
-	{ "path", CONFIG_KEY_STRING, &key_launcher_path },
+static const struct config_key panel_launcher_config_keys[] = {
+	{ "icon", CONFIG_KEY_STRING, &key_panel_launcher_icon },
+	{ "path", CONFIG_KEY_STRING, &key_panel_launcher_path },
+};
+
+static const struct config_key shortcut_config_keys[] = {
+	{ "icon", CONFIG_KEY_STRING, &key_shortcut_icon },
+	{ "path", CONFIG_KEY_STRING, &key_shortcut_path },
 };
 
 static const struct config_section config_sections[] = {
 	{ "shell",
 	  shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
 	{ "launcher",
-	  launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
-	  launcher_section_done }
+	  panel_launcher_config_keys, ARRAY_LENGTH(panel_launcher_config_keys),
+	  panel_launcher_section_done },
+	{ "shortcut",
+	  shortcut_config_keys, ARRAY_LENGTH(shortcut_config_keys),
+	  shortcut_section_done },
 };
 
 static void
@@ -163,13 +173,13 @@ show_menu(struct panel *panel, struct input *input, uint32_t time)
 	};
 
 	input_get_position(input, &x, &y);
-	window_show_menu(window_get_display(panel->window),
-			 input, time, panel->window,
+	window_show_menu(window_get_display(panel->base.window),
+			 input, time, panel->base.window,
 			 x - 10, y - 10, menu_func, entries, 4);
 }
 
 static void
-panel_launcher_activate(struct panel_launcher *widget)
+launcher_activate(struct launcher *widget)
 {
 	pid_t pid;
 
@@ -189,14 +199,14 @@ panel_launcher_activate(struct panel_launcher *widget)
 }
 
 static void
-panel_launcher_redraw_handler(struct widget *widget, void *data)
+launcher_redraw_handler(struct widget *widget, void *data)
 {
-	struct panel_launcher *launcher = data;
+	struct launcher *launcher = data;
 	cairo_surface_t *surface;
 	struct rectangle allocation;
 	cairo_t *cr;
 
-	surface = window_get_surface(launcher->panel->window);
+	surface = window_get_surface(launcher->parent->window);
 	cr = cairo_create(surface);
 
 	widget_get_allocation(widget, &allocation);
@@ -219,10 +229,10 @@ panel_launcher_redraw_handler(struct widget *widget, void *data)
 }
 
 static int
-panel_launcher_motion_handler(struct widget *widget, struct input *input,
-			      uint32_t time, float x, float y, void *data)
+launcher_motion_handler(struct widget *widget, struct input *input,
+			uint32_t time, float x, float y, void *data)
 {
-	struct panel_launcher *launcher = data;
+	struct launcher *launcher = data;
 
 	widget_set_tooltip(widget, basename((char *)launcher->path), x, y);
 
@@ -246,7 +256,7 @@ panel_redraw_handler(struct widget *widget, void *data)
 	cairo_t *cr;
 	struct panel *panel = data;
 
-	surface = window_get_surface(panel->window);
+	surface = window_get_surface(panel->base.window);
 	cr = cairo_create(surface);
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
 	set_hex_color(cr, key_panel_color);
@@ -257,10 +267,10 @@ panel_redraw_handler(struct widget *widget, void *data)
 }
 
 static int
-panel_launcher_enter_handler(struct widget *widget, struct input *input,
+launcher_enter_handler(struct widget *widget, struct input *input,
 			     float x, float y, void *data)
 {
-	struct panel_launcher *launcher = data;
+	struct launcher *launcher = data;
 
 	launcher->focused = 1;
 	widget_schedule_redraw(widget);
@@ -269,10 +279,10 @@ panel_launcher_enter_handler(struct widget *widget, struct input *input,
 }
 
 static void
-panel_launcher_leave_handler(struct widget *widget,
-			     struct input *input, void *data)
+launcher_leave_handler(struct widget *widget,
+		       struct input *input, void *data)
 {
-	struct panel_launcher *launcher = data;
+	struct launcher *launcher = data;
 
 	launcher->focused = 0;
 	widget_destroy_tooltip(widget);
@@ -280,17 +290,21 @@ panel_launcher_leave_handler(struct widget *widget,
 }
 
 static void
-panel_launcher_button_handler(struct widget *widget,
-			      struct input *input, uint32_t time,
-			      uint32_t button,
-			      enum wl_pointer_button_state state, void *data)
+launcher_button_handler(struct widget *widget,
+			struct input *input, uint32_t time,
+			uint32_t button,
+			enum wl_pointer_button_state state, void *data)
 {
-	struct panel_launcher *launcher;
+	struct launcher *launcher;
 
 	launcher = widget_get_user_data(widget);
 	widget_schedule_redraw(widget);
-	if (state == WL_POINTER_BUTTON_STATE_RELEASED)
-		panel_launcher_activate(launcher);
+	if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
+		launcher->pressed = 0;
+		launcher_activate(launcher);
+	} else if (state == WL_POINTER_BUTTON_STATE_PRESSED)
+		launcher->pressed = 1;
+	
 }
 
 static void
@@ -325,7 +339,7 @@ panel_clock_redraw_handler(struct widget *widget, void *data)
 	if (allocation.width == 0)
 		return;
 
-	surface = window_get_surface(clock->panel->window);
+	surface = window_get_surface(clock->panel->base.window);
 	cr = cairo_create(surface);
 	cairo_select_font_face(cr, "sans",
 			       CAIRO_FONT_SLANT_NORMAL,
@@ -380,11 +394,11 @@ panel_add_clock(struct panel *panel)
 	clock->clock_fd = timerfd;
 
 	clock->clock_task.run = clock_func;
-	display_watch_fd(window_get_display(panel->window), clock->clock_fd,
+	display_watch_fd(window_get_display(panel->base.window), clock->clock_fd,
 			 EPOLLIN, &clock->clock_task);
 	clock_timer_reset(clock);
 
-	clock->widget = widget_add_widget(panel->widget, clock);
+	clock->widget = widget_add_widget(panel->base.widget, clock);
 	widget_set_redraw_handler(clock->widget, panel_clock_redraw_handler);
 }
 
@@ -404,7 +418,7 @@ static void
 panel_resize_handler(struct widget *widget,
 		     int32_t width, int32_t height, void *data)
 {
-	struct panel_launcher *launcher;
+	struct launcher *launcher;
 	struct panel *panel = data;
 	int x, y, w, h;
 	
@@ -434,7 +448,7 @@ panel_configure(void *data,
 	struct surface *surface = window_get_user_data(window);
 	struct panel *panel = container_of(surface, struct panel, base);
 
-	window_schedule_resize(panel->window, width, 32);
+	window_schedule_resize(panel->base.window, width, 32);
 }
 
 static struct panel *
@@ -446,17 +460,17 @@ panel_create(struct display *display)
 	memset(panel, 0, sizeof *panel);
 
 	panel->base.configure = panel_configure;
-	panel->window = window_create(display);
-	panel->widget = window_add_widget(panel->window, panel);
+	panel->base.window = window_create(display);
+	panel->base.widget = window_add_widget(panel->base.window, panel);
 	wl_list_init(&panel->launcher_list);
 
-	window_set_title(panel->window, "panel");
-	window_set_custom(panel->window);
-	window_set_user_data(panel->window, panel);
+	window_set_title(panel->base.window, "panel");
+	window_set_custom(panel->base.window);
+	window_set_user_data(panel->base.window, panel);
 
-	widget_set_redraw_handler(panel->widget, panel_redraw_handler);
-	widget_set_resize_handler(panel->widget, panel_resize_handler);
-	widget_set_button_handler(panel->widget, panel_button_handler);
+	widget_set_redraw_handler(panel->base.widget, panel_redraw_handler);
+	widget_set_resize_handler(panel->base.widget, panel_resize_handler);
+	widget_set_button_handler(panel->base.widget, panel_button_handler);
 	
 	panel_add_clock(panel);
 
@@ -464,28 +478,53 @@ panel_create(struct display *display)
 }
 
 static void
+background_add_shortcut(struct background *background, const char *icon, const char *path)
+{
+	struct launcher *shortcut;
+
+	shortcut = malloc(sizeof *shortcut);
+	memset(shortcut, 0, sizeof *shortcut);
+	shortcut->icon = cairo_image_surface_create_from_png(icon);
+	shortcut->path = strdup(path);
+	shortcut->parent = &background->base;
+	wl_list_insert(background->shortcut_list.prev, &shortcut->link);
+
+	shortcut->widget = widget_add_widget(background->base.widget, shortcut);
+	widget_set_enter_handler(shortcut->widget,
+				 launcher_enter_handler);
+	widget_set_leave_handler(shortcut->widget,
+				 launcher_leave_handler);
+	widget_set_button_handler(shortcut->widget,
+				  launcher_button_handler);
+	widget_set_redraw_handler(shortcut->widget,
+				  launcher_redraw_handler);
+	widget_set_motion_handler(shortcut->widget,
+				  launcher_motion_handler);
+}
+
+static void
 panel_add_launcher(struct panel *panel, const char *icon, const char *path)
 {
-	struct panel_launcher *launcher;
+	struct launcher *launcher;
 
 	launcher = malloc(sizeof *launcher);
 	memset(launcher, 0, sizeof *launcher);
 	launcher->icon = cairo_image_surface_create_from_png(icon);
 	launcher->path = strdup(path);
-	launcher->panel = panel;
+	launcher->parent = &panel->base;
 	wl_list_insert(panel->launcher_list.prev, &launcher->link);
 
-	launcher->widget = widget_add_widget(panel->widget, launcher);
+	launcher->widget = widget_add_widget(panel->base.widget, launcher);
 	widget_set_enter_handler(launcher->widget,
-				 panel_launcher_enter_handler);
+				 launcher_enter_handler);
 	widget_set_leave_handler(launcher->widget,
-				   panel_launcher_leave_handler);
+				 launcher_leave_handler);
 	widget_set_button_handler(launcher->widget,
-				    panel_launcher_button_handler);
+				  launcher_button_handler);
 	widget_set_redraw_handler(launcher->widget,
-				  panel_launcher_redraw_handler);
+				  launcher_redraw_handler);
 	widget_set_motion_handler(launcher->widget,
-				  panel_launcher_motion_handler);
+				  launcher_motion_handler);
 }
 
 enum {
@@ -504,8 +543,11 @@ background_draw(struct widget *widget, void *data)
 	double sx, sy;
 	struct rectangle allocation;
 	int type = -1;
+	struct launcher *shortcut;
+	const int rows = 3, columns = 4, icon_width = 128, icon_height = 128;
+	int x, y, i, width, height, vmargin, hmargin, vpadding, hpadding;
 
-	surface = window_get_surface(background->window);
+	surface = window_get_surface(background->base.window);
 
 	cr = cairo_create(surface);
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
@@ -548,6 +590,34 @@ background_draw(struct widget *widget, void *data)
 	}
 
 	cairo_paint(cr);
+
+	/* draw shortcuts */
+	cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+
+	width = allocation.width - columns * icon_width;
+	hpadding = width / (columns + 1);
+	hmargin = (width - hpadding * (columns - 1)) / 2;
+
+	height = allocation.height - rows * icon_height;
+	vpadding = height / (rows + 1);
+	vmargin = (height - vpadding * (rows - 1)) / 2;
+
+	x = hmargin;
+	y = vmargin;
+	i = 0;
+
+	wl_list_for_each(shortcut, &background->shortcut_list, link) {
+		widget_set_allocation(shortcut->widget,
+				      x, y, icon_width, icon_height);
+		x += icon_width + hpadding;
+		i++;
+		if (i == columns) {
+			x = hmargin;
+			y += icon_height + vpadding;
+			i = 0;
+		}
+	}
+
 	cairo_destroy(cr);
 	cairo_surface_destroy(surface);
 }
@@ -561,7 +631,7 @@ background_configure(void *data,
 	struct background *background =
 		(struct background *) window_get_user_data(window);
 
-	widget_schedule_resize(background->widget, width, height);
+	widget_schedule_resize(background->base.widget, width, height);
 }
 
 static void
@@ -758,11 +828,13 @@ background_create(struct desktop *desktop)
 	memset(background, 0, sizeof *background);
 
 	background->base.configure = background_configure;
-	background->window = window_create(desktop->display);
-	background->widget = window_add_widget(background->window, background);
-	window_set_custom(background->window);
-	window_set_user_data(background->window, background);
-	widget_set_redraw_handler(background->widget, background_draw);
+	background->base.window = window_create(desktop->display);
+	background->base.widget = window_add_widget(background->base.window, background);
+
+	wl_list_init(&background->shortcut_list);
+	window_set_custom(background->base.window);
+	window_set_user_data(background->base.window, background);
+	widget_set_redraw_handler(background->base.widget, background_draw);
 
 	return background;
 }
@@ -824,25 +896,47 @@ global_handler(struct wl_display *display, uint32_t id,
 }
 
 static void
-launcher_section_done(void *data)
+shortcut_section_done(void *data)
+{
+	struct desktop *desktop = data;
+	struct output *output;
+
+	if (key_shortcut_icon == NULL || key_shortcut_path == NULL) {
+		fprintf(stderr, "invalid shortcut section\n");
+		return;
+	}
+
+	wl_list_for_each(output, &desktop->outputs, link) {
+		background_add_shortcut(output->background,
+				        key_shortcut_icon, key_shortcut_path);
+	}
+
+	free(key_shortcut_icon);
+	key_shortcut_icon = NULL;
+	free(key_shortcut_path);
+	key_shortcut_path = NULL;
+}
+
+static void
+panel_launcher_section_done(void *data)
 {
 	struct desktop *desktop = data;
 	struct output *output;
 
-	if (key_launcher_icon == NULL || key_launcher_path == NULL) {
+	if (key_panel_launcher_icon == NULL || key_panel_launcher_path == NULL) {
 		fprintf(stderr, "invalid launcher section\n");
 		return;
 	}
 
 	wl_list_for_each(output, &desktop->outputs, link) {
 		panel_add_launcher(output->panel,
-				   key_launcher_icon, key_launcher_path);
+				   key_panel_launcher_icon, key_panel_launcher_path);
 	}
 
-	free(key_launcher_icon);
-	key_launcher_icon = NULL;
-	free(key_launcher_path);
-	key_launcher_path = NULL;
+	free(key_panel_launcher_icon);
+	key_panel_launcher_icon = NULL;
+	free(key_panel_launcher_path);
+	key_panel_launcher_path = NULL;
 }
 
 static void
@@ -880,11 +974,11 @@ int main(int argc, char *argv[])
 		struct wl_shell_surface *s;
 
 		output->panel = panel_create(desktop.display);
-		s = window_get_wl_shell_surface(output->panel->window);
+		s = window_get_wl_shell_surface(output->panel->base.window);
 		desktop_shell_set_panel(desktop.shell, output->output, s);
 
 		output->background = background_create(&desktop);
-		s = window_get_wl_shell_surface(output->background->window);
+		s = window_get_wl_shell_surface(output->background->base.window);
 		desktop_shell_set_background(desktop.shell, output->output, s);
 	}
 
-- 
1.7.9.5



More information about the wayland-devel mailing list