desktop shell强相关的一共分如下几部分:
1.client/desktop-shell.c + window.c
2.desktop-shell目录
3.libweston-desktop部分\
1是desktop客户端的实现,因为桌面本身也是一个负责和weston交互的客户端。
2是负责大多数desktop-shell.c里面的实现,如创建鼠标,键盘,窗口布局,窗口效果。
3则是xdg一些独立于desktop的实现,在任何窗口都有可能需要用到。
一句话来说,desktop-shell目录是一些具体的特殊的情况,而libweston-desktop则是一些普遍的实现
desktop-shell.c
main
...
config相关,如panel位置(就是显示时间那一行),显示的时间格式等等
...
###########display_create
desktop.display = display_create(&argc, argv);
d->display = wl_display_connect(NULL);//Connect to the Wayland display named \c name.
If \c name is \c NULL,its value will be replaced with the WAYLAND_DISPLAY
environment variable if it is set, otherwise display "wayland-0" will be used.
如果有多个监听的节点(可能是多个server,或者单一server但是监听多个节点),这个时候就可以决定对应的客户端与那个socket节点通信。
d->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);//键盘输入相关
https://wayland-book.com/seat/xkb.html
//epoll, handle_display_data是对应的处理事件,
主要是wl_display_dispatch和wl_display_flush
d->epoll_fd = os_epoll_create_cloexec();
d->display_fd = wl_display_get_fd(d->display);
d->display_task.run = handle_display_data;
display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP,
&d->display_task);
wl_list_init(&d->deferred_list);
wl_list_init(&d->input_list);
wl_list_init(&d->output_list);//这个对应实际的屏幕,output
wl_list_init(&d->global_list);//这个是gloabel object的列表,如下会全部保存一份
//注册绑定对应的global服务
d->registry = wl_display_get_registry(d->display);
wl_registry_add_listener(d->registry, ®istry_listener, d);
//registry_handle_global里面把所有的global interface全部装在之前创建的 global_list里面:
global = xmalloc(sizeof *global);
global->name = id;
global->interface = strdup(interface);
global->version = version;
wl_list_insert(d->global_list.prev, &global->link);
#ifdef HAVE_CAIRO_EGL //init_egl
if (init_egl(d) < 0)
create_cursors(d); //鼠标 https://invisible-island.net/xterm/xcursor/xcursor.html
d->theme = theme_create(); //主要是和窗口主题相关内容,比方说,窗口背后阴影
窗口的帮助栏大小等等。比较复杂,目前不理解
wl_list_init(&d->window_list);
init_dummy_surface(d); //貌似和weston桌面鼠标停留左上角terminal的info有关
##########
//初始化desktop.display对象的data,global_handler和globale_handler_remove
display_set_user_data(desktop.display, &desktop);
display_set_global_handler(desktop.display, global_handler);//此处会注册绑定
weston_desktop_shell和wl_output接口,这里面很有意思,先来的信号是wl_output
//因为先来的是wl_output,那么create_output里面的if(desktop->shell)就不会成功,
也就不会在这里创建panel和background
global_handler
...
} else if (!strcmp(interface, "wl_output")) {
create_output(desktop, id);
if (desktop->shell) {
output_init(output, desktop);
...
display_set_global_handler_remove(desktop.display, global_handler_remove);
##########创建background和panel的地方
weston_desktop_shell_set_panel_position(desktop.shell, desktop.panel_position); //对应
desktop-shell文件夹里面实现的weston_desktop_shell_interface->desktop_shell_set_panel_position
wl_list_for_each(output, &desktop.outputs, link)
if (!output->panel)
output_init(output, &desktop);
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);
##########
grab_surface_create(&desktop); //应该是用鼠标设置窗口大小时候的那个手一样的surface
由下面的desktop_shell_set_grab_surface支持
display_run(desktop.display);
整个desktop client不使用xdg-shell相关。
参考weston目录下的weston-desktop-shell.xml;
client在绑定desktop-shell的时候,实现了会从server那边收到的三个消息:configure,prepare_lock_surface,grab_cursor。
并在绑定wl_output的时候实现了create_output,这是显而易见的,因为我们可以从wl_output_protocol里面获取屏幕大小等用来创建全局窗口的有用信息。
desktop-shell里面的接口:
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
};
xdg-shell里面有几套接口,分别是:
static const struct xdg_wm_base_interface weston_desktop_xdg_shell_implementation = {
.destroy = weston_desktop_destroy_request,
.create_positioner = weston_desktop_xdg_shell_protocol_create_positioner,
.get_xdg_surface = weston_desktop_xdg_shell_protocol_get_xdg_surface,
.pong = weston_desktop_xdg_shell_protocol_pong,
};
在client 端bind wm_base以后提供的接口,可以通过wl_surface获取xdg_surface。
static const struct xdg_surface_interface weston_desktop_xdg_surface_implementation = {
.destroy = weston_desktop_destroy_request,
.get_toplevel = weston_desktop_xdg_surface_protocol_get_toplevel,
.get_popup = weston_desktop_xdg_surface_protocol_get_popup,
.set_window_geometry = weston_desktop_xdg_surface_protocol_set_window_geometry,
.ack_configure = weston_desktop_xdg_surface_protocol_ack_configure,
};
在获取xdg_surface以后,可以通过上述接口获得具体的角色,toplevel或者popup。
static const struct weston_desktop_surface_implementation weston_desktop_xdg_surface_internal_implementation = {
/* These are used for toplevel only */
.set_maximized = weston_desktop_xdg_toplevel_set_maximized,
.set_fullscreen = weston_desktop_xdg_toplevel_set_fullscreen,
.set_resizing = weston_desktop_xdg_toplevel_set_resizing,
.set_activated = weston_desktop_xdg_toplevel_set_activated,
.set_size = weston_desktop_xdg_toplevel_set_size,
.get_maximized = weston_desktop_xdg_toplevel_get_maximized,
.get_fullscreen = weston_desktop_xdg_toplevel_get_fullscreen,
.get_resizing = weston_desktop_xdg_toplevel_get_resizing,
.get_activated = weston_desktop_xdg_toplevel_get_activated,
/* These are used for popup only */
.update_position = weston_desktop_xdg_popup_update_position,
/* Common API */
.committed = weston_desktop_xdg_surface_committed,
.ping = weston_desktop_xdg_surface_ping,
.close = weston_desktop_xdg_surface_close,
.destroy = weston_desktop_xdg_surface_destroy,
};
这一部分是内部用的,并不是暴露给client的,而是用来和weston\desktop-shell目录所生成的desktop-shell.so对接,是desktop-shell.so里面功能的实现。
static const struct xdg_popup_interface weston_desktop_xdg_popup_implementation = {
.destroy = weston_desktop_destroy_request,
.grab = weston_desktop_xdg_popup_protocol_grab,
};
static const struct xdg_toplevel_interface weston_desktop_xdg_toplevel_implementation = {
.destroy = weston_desktop_destroy_request,
.set_parent = weston_desktop_xdg_toplevel_protocol_set_parent,
.set_title = weston_desktop_xdg_toplevel_protocol_set_title,
.set_app_id = weston_desktop_xdg_toplevel_protocol_set_app_id,
.show_window_menu = weston_desktop_xdg_toplevel_protocol_show_window_menu,
.move = weston_desktop_xdg_toplevel_protocol_move,
.resize = weston_desktop_xdg_toplevel_protocol_resize,
.set_min_size = weston_desktop_xdg_toplevel_protocol_set_min_size,
.set_max_size = weston_desktop_xdg_toplevel_protocol_set_max_size,
.set_maximized = weston_desktop_xdg_toplevel_protocol_set_maximized,
.unset_maximized = weston_desktop_xdg_toplevel_protocol_unset_maximized,
.set_fullscreen = weston_desktop_xdg_toplevel_protocol_set_fullscreen,
.unset_fullscreen = weston_desktop_xdg_toplevel_protocol_unset_fullscreen,
.set_minimized = weston_desktop_xdg_toplevel_protocol_set_minimized,
};
这两部分是给client使用的,对接client端具体角色的具体功能的接口