天天看點

Weston中panel的設定過程

此篇筆記主要介紹wetson shell的桌面工作列(panel)的渲染過程。

基于clients/desktop-shell.c

parse_panel_position從配置檔案中解析出panel-position,注意這裡的want_panel,如果為0,則代表桌面不需要工作列,那麼weston啟動之後就隻有背景layer,沒有panel layer。

static void
parse_panel_position(struct desktop *desktop, struct weston_config_section *s)
{
	char *position;

	desktop->want_panel = 1;

	weston_config_section_get_string(s, "panel-position", &position, "top");
	if (strcmp(position, "top") == 0) {
		desktop->panel_position = WESTON_DESKTOP_SHELL_PANEL_POSITION_TOP;
	} else if (strcmp(position, "bottom") == 0) {
		desktop->panel_position = WESTON_DESKTOP_SHELL_PANEL_POSITION_BOTTOM;
	} else if (strcmp(position, "left") == 0) {
		desktop->panel_position = WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT;
	} else if (strcmp(position, "right") == 0) {
		desktop->panel_position = WESTON_DESKTOP_SHELL_PANEL_POSITION_RIGHT;
	} else {
		/* 'none' is valid here */
		if (strcmp(position, "none") != 0)
			fprintf(stderr, "Wrong panel position: %s\n", position);
		desktop->want_panel = 0;
	}
	free(position);
}
           

display_set_global_handler(desktop.display, global_handler)設定全局對象的handler。其中将綁定client端shell的interface,這個interface定義于server端,用于client端與server的操作。第二部步設定的listener用于監聽server端的操作,server那邊一完成即可回調進client端。

//client
static void
global_handler(struct display *display, uint32_t id,
	       const char *interface, uint32_t version, void *data)
{
	struct desktop *desktop = data;

	if (!strcmp(interface, "weston_desktop_shell")) {
		desktop->shell = display_bind(desktop->display,
					      id,
					      &weston_desktop_shell_interface,
					      1);
		weston_desktop_shell_add_listener(desktop->shell,
						  &listener,
						  desktop);
	} else if (!strcmp(interface, "wl_output")) {
		create_output(desktop, id);
	}
}
           
//server
static const struct weston_desktop_shell_interface desktop_shell_implementation = {
	desktop_shell_set_background,
	desktop_shell_set_panel,
	desktop_shell_set_lock_surface,
	desktop_shell_unlock,
	desktop_shell_set_grab_surface,
	desktop_shell_desktop_ready,
	desktop_shell_set_panel_position
};
           
//client
static const struct weston_desktop_shell_listener listener = {
	desktop_shell_configure,
	desktop_shell_prepare_lock_surface,
	desktop_shell_grab_cursor
};
           

handler配置完,然後在main函數裡初始化desktop的界面。建立panel并傳給ouput,設定panel;建立background并傳給output,設定background。

output_init(output, &desktop);
           
static void
output_init(struct output *output, struct desktop *desktop)
{
	struct wl_surface *surface;

	if (desktop->want_panel) {
		output->panel = panel_create(desktop, output);
		surface = window_get_wl_surface(output->panel->window);
		weston_desktop_shell_set_panel(desktop->shell,
					       output->output, surface);
	}

	output->background = background_create(desktop, output);
	surface = window_get_wl_surface(output->background->window);
	weston_desktop_shell_set_background(desktop->shell,
					    output->output, surface);
}

           

panel_create函數和background_create的過程類似,主要來看panel_create。

1.panel_configure

這個函數就是用來設定不同位置panel的width/height參數,如果是TOP/BOTTOM,則預設的panel 的高度為32個像素值。

switch (desktop->panel_position) {
	case WESTON_DESKTOP_SHELL_PANEL_POSITION_TOP:
	case WESTON_DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
		height = 32;
		break;
	case WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT:
	case WESTON_DESKTOP_SHELL_PANEL_POSITION_RIGHT:
		switch (desktop->clock_format) {
		case CLOCK_FORMAT_NONE:
			width = 32;
			break;
		case CLOCK_FORMAT_MINUTES:
			width = 150;
			break;
		case CLOCK_FORMAT_SECONDS:
			width = 170;
			break;
		}
		break;
	}
           

預設顯示效果:

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-hVVhjYlC-1634438246411)(…/imgs/weston.png)]

修改height為100:

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-x82IiGLD-1634438246414)(…/imgs/weston2.png)]

可以看到,工作列的高度變化了,但是其中的時間顯示及程式入口圖示大小并沒有變化。

2.window_create_custom(desktop->display)

調用compositor建立一個panel->window->surface

surface = surface_create(window)
  	-->wl_compositor_create_surface(display->compositor)
           

3.window_add_widget(panel->window, panel)

建立完panel->window->surface,會建立一個widget并添加進剛才的window。

panel_redraw_handler是widget重繪的處理函數,使用的是cairo。panel_resize_handler是widget在resize時的處理函數。可以了解為panel是底部,在上面添加了一個surface,在surface裡添加了widget元件,這個widget元件可以是應用程式launcher的入口。

4.panel_add_launchers(panel, desktop)

讀取config中配置的launcher入口,包括圖示和bin檔案位置。具體的解析過程有機會再看。

panel_add_launcher
  -->panel_launcher_enter_handler
  -->panel_launcher_leave_handler
  -->panel_launcher_button_handler
  -->panel_launcher_touch_down_handler
  -->panel_launcher_touch_up_handler
  -->panel_launcher_redraw_handler
  -->panel_launcher_motion_handler
           

如果按下launcher圖示并釋放會觸發panel_launcher_activate函數,fork一個pid然後啟動launcher。

panel_launcher_redraw_handler使用cairo重繪launcher。