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端具體角色的具體功能的接口