此篇筆記主要介紹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。