此篇笔记主要介绍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。
到这里panel_create的工作基本完成。
weston_desktop_shell_set_panel将设置的panel传给server。这里会进入server端的desktop_shell_set_panel。下一节再分析渲染过程。
欢迎关注【求密勒实验室】