[PATCH 1/2] desktop-shell: Add shortcut on background and can be activated.

tecton69 at gmail.com tecton69 at gmail.com
Mon Jul 9 19:58:10 PDT 2012


From: Wu, Zhiwen <zhiwen.wu at 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.

Signed-off-by: Wu Zhiwen <zhiwen.wu at intel.com>

---
 clients/desktop-shell.c | 245 +++++++++++++++++++++++++++++++++---------------
 weston.ini              |  18 ++++
 2 files changed, 188 insertions(+), 75 deletions(-)

diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index fbc0604..81ff1b4 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -31,7 +31,7 @@
 #include <cairo.h>
 #include <sys/wait.h>
 #include <sys/timerfd.h>
-#include <sys/epoll.h> 
+#include <sys/epoll.h>
 #include <linux/input.h>
 #include <libgen.h>
 #include <time.h>
@@ -61,20 +61,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 {
@@ -85,9 +84,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;
@@ -114,9 +113,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[] = {
@@ -127,17 +129,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
@@ -165,13 +175,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;
 
@@ -191,14 +201,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);
@@ -221,10 +231,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);
 
@@ -234,7 +244,7 @@ panel_launcher_motion_handler(struct widget *widget, struct input *input,
 static void
 set_hex_color(cairo_t *cr, uint32_t color)
 {
-	cairo_set_source_rgba(cr, 
+	cairo_set_source_rgba(cr,
 			      ((color >> 16) & 0xff) / 255.0,
 			      ((color >>  8) & 0xff) / 255.0,
 			      ((color >>  0) & 0xff) / 255.0,
@@ -248,7 +258,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);
@@ -259,10 +269,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);
@@ -271,10 +281,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);
@@ -282,17 +292,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
@@ -328,7 +342,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,
@@ -383,11 +397,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);
 }
 
@@ -407,10 +421,10 @@ 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;
-	
+
 	x = 10;
 	y = 16;
 	wl_list_for_each(launcher, &panel->launcher_list, link) {
@@ -437,7 +451,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 *
@@ -449,45 +463,71 @@ panel_create(struct display *display)
 	memset(panel, 0, sizeof *panel);
 
 	panel->base.configure = panel_configure;
-	panel->window = window_create_custom(display);
-	panel->widget = window_add_widget(panel->window, panel);
+
+	panel->base.window = window_create_custom(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_user_data(panel->window, panel);
+	window_set_title(panel->base.window, "panel");
+	window_set_user_data(panel->base.window, panel);
+
+	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);
 
-	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);
-	
 	panel_add_clock(panel);
 
 	return panel;
 }
 
 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 {
@@ -506,8 +546,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);
@@ -550,6 +593,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);
 }
@@ -563,7 +634,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
@@ -804,10 +875,12 @@ background_create(struct desktop *desktop)
 	memset(background, 0, sizeof *background);
 
 	background->base.configure = background_configure;
-	background->window = window_create_custom(desktop->display);
-	background->widget = window_add_widget(background->window, background);
-	window_set_user_data(background->window, background);
-	widget_set_redraw_handler(background->widget, background_draw);
+	background->base.window = window_create_custom(desktop->display);
+	background->base.widget = window_add_widget(background->base.window, background);
+
+	wl_list_init(&background->shortcut_list);
+	window_set_user_data(background->base.window, background);
+	widget_set_redraw_handler(background->base.widget, background_draw);
 
 	return background;
 }
@@ -873,25 +946,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
@@ -929,12 +1024,12 @@ int main(int argc, char *argv[])
 		struct wl_surface *surface;
 
 		output->panel = panel_create(desktop.display);
-		surface = window_get_wl_surface(output->panel->window);
+		surface = window_get_wl_surface(output->panel->base.window);
 		desktop_shell_set_panel(desktop.shell,
 					output->output, surface);
 
 		output->background = background_create(&desktop);
-		surface = window_get_wl_surface(output->background->window);
+		surface = window_get_wl_surface(output->background->base.window);
 		desktop_shell_set_background(desktop.shell,
 					     output->output, surface);
 	}
diff --git a/weston.ini b/weston.ini
index f0736df..26b6587 100644
--- a/weston.ini
+++ b/weston.ini
@@ -27,6 +27,24 @@ path=/usr/bin/google-chrome
 icon=/usr/share/icons/gnome/24x24/apps/arts.png
 path=./clients/flower
 
+[shortcut]
+icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png
+path=/usr/bin/weston-terminal
+
+[shortcut]
+icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png
+path=/usr/bin/weston-terminal
+
+#==============================================================================
+
+[shortcut]
+icon=/usr/share/icons/hicolor/24x24/apps/google-chrome.png
+path=/usr/bin/google-chrome
+
+[shortcut]
+icon=/usr/share/icons/hicolor/24x24/apps/google-chrome.png
+path=/usr/bin/google-chrome
+
 [screensaver]
 # Uncomment path to disable screensaver
 path=/usr/libexec/weston-screensaver
-- 
1.7.11.1



More information about the wayland-devel mailing list