From 7457d84226083870469e11cb0d5ed450cc031b45 Mon Sep 17 00:00:00 2001 From: Sophia Gong Date: Fri, 21 Feb 2025 10:24:55 +0800 Subject: [PATCH] desktop-shell: enable app-ids for output Signed-off-by: Sophia Gong --- desktop-shell/shell.c | 120 +++++++++++++++++++++++++++++++++++++++++- desktop-shell/shell.h | 3 ++ 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 644062f27..52a2b680a 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -1740,6 +1740,85 @@ shell_set_view_fullscreen(struct shell_surface *shsurf) shsurf->state.lowered = false; } +/* parse app_id in weston.ini section output. it's like + * app_id=org.freedesktop.weston.simple-egl + */ +static bool +shell_output_parse_appid(struct shell_surface *shsurf, char *cur, + char *comma, const char *app_id) +{ + char *str = NULL; + size_t len; + + if (app_id == NULL) + return false; + + if (comma != NULL) + str = strndup(cur, comma-cur); + else + str = strdup(cur); + + if (str == NULL) + return false; + + len = strlen(app_id); + if (strncmp(str, app_id, len) == 0) { + free(str); + return true; + } + + free(str); + return false; +} + +static bool +shell_output_has_app_id(struct shell_output *shell_output, + struct shell_surface *shsurf, const char *app_id) +{ + char *cur, *comma = NULL; + bool has_app_id = false; + + if (!shell_output->app_ids) + return false; + + cur = shell_output->app_ids; + + while ((cur = strstr(cur, app_id))) { + comma = strchr(cur, ','); + has_app_id = shell_output_parse_appid(shsurf, cur, comma, app_id); + if (has_app_id) + return true; + + if (comma != NULL) + cur = comma; + else + break; + } + + return false; +} + +static struct weston_output * +shell_surface_find_assign_output(struct shell_surface *shsurf) +{ + struct shell_output *shell_output; + const char *app_id; + + /* Check if we have a designated output for this app. */ + app_id = weston_desktop_surface_get_app_id(shsurf->desktop_surface); + if (app_id) { + wl_list_for_each(shell_output, &shsurf->shell->output_list, link) { + if (shell_output_has_app_id(shell_output, shsurf, app_id)) { + shsurf->appid_output_assigned = true; + weston_log("%s app-id %s at output %s\n", __func__, app_id, shell_output->output->name); + return shell_output->output; + } + } + } + + return NULL; +} + static void desktop_shell_destroy_seat(struct shell_seat *shseat) { @@ -1927,6 +2006,7 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface, struct wl_client *wl_client = weston_desktop_client_get_client(client); struct weston_view *view; + struct weston_output *output = NULL; struct shell_surface *shsurf; struct weston_surface *surface = weston_desktop_surface_get_surface(desktop_surface); @@ -1953,9 +2033,12 @@ desktop_surface_added(struct weston_desktop_surface *desktop_surface, shsurf->desktop_surface = desktop_surface; shsurf->view = view; shsurf->fullscreen.black_view = NULL; + shsurf->appid_output_assigned = false; - shell_surface_set_output( - shsurf, weston_shell_utils_get_default_output(shsurf->shell->compositor)); + output = shell_surface_find_assign_output(shsurf); + if (!output) + output = weston_shell_utils_get_default_output(shsurf->shell->compositor); + shell_surface_set_output(shsurf, output); wl_signal_init(&shsurf->destroy_signal); @@ -2148,6 +2231,8 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface, weston_desktop_surface_get_user_data(desktop_surface); struct weston_surface *surface = weston_desktop_surface_get_surface(desktop_surface); + const char *app_id = + weston_desktop_surface_get_app_id(desktop_surface); struct weston_view *view = shsurf->view; struct desktop_shell *shell = data; bool was_fullscreen; @@ -2164,6 +2249,19 @@ desktop_surface_committed(struct weston_desktop_surface *desktop_surface, return; } + if (!shsurf->appid_output_assigned && app_id) { + struct weston_output *output = NULL; + + /* reset previous output being set in _added() as the output is + * being cached */ + output = shell_surface_find_assign_output(shsurf); + if (output) { + shsurf->output = NULL; + shell_surface_set_output(shsurf, output); + } + shsurf->appid_output_assigned = true; + } + was_fullscreen = shsurf->state.fullscreen; was_maximized = shsurf->state.maximized; @@ -4429,6 +4527,7 @@ shell_output_destroy(struct shell_output *shell_output) } wl_list_remove(&shell_output->destroy_listener.link); wl_list_remove(&shell_output->link); + free(shell_output->app_ids); free(shell_output); } @@ -4501,6 +4600,21 @@ desktop_shell_temporary_curtain_get_label(struct weston_surface *surface, return snprintf(buf, len, "desktop shell background placeholder"); } +static void +desktop_shell_output_config(struct shell_output *shell_output) +{ + struct weston_config *wc = wet_get_config(shell_output->shell->compositor); + struct weston_config_section *section = + weston_config_get_section(wc, "output", "name", shell_output->output->name); + + assert(shell_output->app_ids == NULL); + + if (section) { + weston_config_section_get_string(section, "app-ids", + &shell_output->app_ids, NULL); + } +} + static void create_shell_output(struct desktop_shell *shell, struct weston_output *output) @@ -4519,6 +4633,8 @@ create_shell_output(struct desktop_shell *shell, &shell_output->destroy_listener); wl_list_insert(shell->output_list.prev, &shell_output->link); + desktop_shell_output_config(shell_output); + if (!shell->disallow_output_changed_move && wl_list_length(&shell->output_list) == 1) shell_for_each_layer(shell, shell_output_changed_move_layer, NULL); diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index 836925ede..1bd9b7418 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -128,6 +128,8 @@ struct shell_surface { struct weston_coord_global pos; } xwayland; + bool appid_output_assigned; + int focus_count; bool destroying; @@ -232,6 +234,7 @@ struct shell_output { struct wl_listener destroy_listener; struct wl_list link; + char *app_ids; struct weston_surface *panel_surface; struct weston_view *panel_view; struct wl_listener panel_surface_listener;