mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-06-29 06:15:29 +00:00
kiosk-shell, xwayland: Add a new weston_xwayland_surface_api function
Such that shells can retrieve Xwayland's surface WM_CLASS/WM_NAME and use it to place the corresponding Xwayland surface on the appropriate output, similar to what xdg_shell::set_app_id does. Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
parent
f2486c8b96
commit
619578f62f
|
@ -38,7 +38,12 @@ struct weston_compositor;
|
|||
struct weston_xwayland;
|
||||
|
||||
#define WESTON_XWAYLAND_API_NAME "weston_xwayland_v3"
|
||||
#define WESTON_XWAYLAND_SURFACE_API_NAME "weston_xwayland_surface_v1"
|
||||
#define WESTON_XWAYLAND_SURFACE_API_NAME "weston_xwayland_surface_v2"
|
||||
|
||||
enum window_atom_type {
|
||||
WM_NAME,
|
||||
WM_CLASS,
|
||||
};
|
||||
|
||||
typedef struct wl_client *
|
||||
(*weston_xwayland_spawn_xserver_func_t)(
|
||||
|
@ -146,6 +151,16 @@ struct weston_xwayland_surface_api {
|
|||
*/
|
||||
void
|
||||
(*send_position)(struct weston_surface *surface, int32_t x, int32_t y);
|
||||
|
||||
/** Grab the window's name using enume window_atom_type
|
||||
*
|
||||
*
|
||||
* \param surface The Xwayland surface.
|
||||
* \param atype the type of the atom, either WM_NAME or WM_CLASS
|
||||
* \returns the net_wm_name, as a string.
|
||||
*/
|
||||
const char *
|
||||
(*get_xwayland_window_name)(struct weston_surface *surface, enum window_atom_type atype);
|
||||
};
|
||||
|
||||
/** Retrieve the API object for the libweston Xwayland surface.
|
||||
|
|
|
@ -112,6 +112,25 @@ transform_handler(struct wl_listener *listener, void *data)
|
|||
shsurf->view->geometry.pos_offset.y);
|
||||
}
|
||||
|
||||
static const char *
|
||||
xwayland_get_xwayland_name(struct kiosk_shell_surface *shsurf, enum window_atom_type type)
|
||||
{
|
||||
const struct weston_xwayland_surface_api *api;
|
||||
struct weston_surface *surface;
|
||||
|
||||
api = shsurf->shell->xwayland_surface_api;
|
||||
if (!api) {
|
||||
api = weston_xwayland_surface_get_api(shsurf->shell->compositor);
|
||||
shsurf->shell->xwayland_surface_api = api;
|
||||
}
|
||||
|
||||
surface = weston_desktop_surface_get_surface(shsurf->desktop_surface);
|
||||
if (!api || !api->is_xwayland_surface(surface))
|
||||
return NULL;
|
||||
|
||||
return api->get_xwayland_window_name(surface, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* kiosk_shell_surface
|
||||
*/
|
||||
|
@ -162,8 +181,7 @@ kiosk_shell_surface_get_parent_root(struct kiosk_shell_surface *shsurf)
|
|||
}
|
||||
|
||||
static bool
|
||||
kiosk_shell_output_has_app_id(struct kiosk_shell_output *shoutput,
|
||||
const char *app_id);
|
||||
kiosk_shell_output_has_app_id(char *config_app_ids, const char *app_id);
|
||||
|
||||
static struct weston_output *
|
||||
kiosk_shell_surface_find_best_output(struct kiosk_shell_surface *shsurf)
|
||||
|
@ -181,7 +199,27 @@ kiosk_shell_surface_find_best_output(struct kiosk_shell_surface *shsurf)
|
|||
app_id = weston_desktop_surface_get_app_id(shsurf->desktop_surface);
|
||||
if (app_id) {
|
||||
wl_list_for_each(shoutput, &shsurf->shell->output_list, link) {
|
||||
if (kiosk_shell_output_has_app_id(shoutput, app_id)) {
|
||||
if (kiosk_shell_output_has_app_id(shoutput->app_ids, app_id)) {
|
||||
shsurf->appid_output_assigned = true;
|
||||
return shoutput->output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app_id = xwayland_get_xwayland_name(shsurf, WM_NAME);
|
||||
if (app_id) {
|
||||
wl_list_for_each(shoutput, &shsurf->shell->output_list, link) {
|
||||
if (kiosk_shell_output_has_app_id(shoutput->x11_wm_name_app_ids, app_id)) {
|
||||
shsurf->appid_output_assigned = true;
|
||||
return shoutput->output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app_id = xwayland_get_xwayland_name(shsurf, WM_CLASS);
|
||||
if (app_id) {
|
||||
wl_list_for_each(shoutput, &shsurf->shell->output_list, link) {
|
||||
if (kiosk_shell_output_has_app_id(shoutput->x11_wm_class_app_ids, app_id)) {
|
||||
shsurf->appid_output_assigned = true;
|
||||
return shoutput->output;
|
||||
}
|
||||
|
@ -669,27 +707,28 @@ kiosk_shell_output_destroy(struct kiosk_shell_output *shoutput)
|
|||
wl_list_remove(&shoutput->link);
|
||||
|
||||
free(shoutput->app_ids);
|
||||
free(shoutput->x11_wm_name_app_ids);
|
||||
free(shoutput->x11_wm_class_app_ids);
|
||||
|
||||
free(shoutput);
|
||||
}
|
||||
|
||||
static bool
|
||||
kiosk_shell_output_has_app_id(struct kiosk_shell_output *shoutput,
|
||||
const char *app_id)
|
||||
kiosk_shell_output_has_app_id(char *config_app_ids, const char *app_id)
|
||||
{
|
||||
char *cur;
|
||||
size_t app_id_len;
|
||||
|
||||
if (!shoutput->app_ids)
|
||||
if (!config_app_ids)
|
||||
return false;
|
||||
|
||||
cur = shoutput->app_ids;
|
||||
cur = config_app_ids;
|
||||
app_id_len = strlen(app_id);
|
||||
|
||||
while ((cur = strstr(cur, app_id))) {
|
||||
/* Check whether we have found a complete match of app_id. */
|
||||
if ((cur[app_id_len] == ',' || cur[app_id_len] == '\0') &&
|
||||
(cur == shoutput->app_ids || cur[-1] == ','))
|
||||
(cur == config_app_ids || cur[-1] == ','))
|
||||
return true;
|
||||
cur++;
|
||||
}
|
||||
|
@ -705,10 +744,16 @@ kiosk_shell_output_configure(struct kiosk_shell_output *shoutput)
|
|||
weston_config_get_section(wc, "output", "name", shoutput->output->name);
|
||||
|
||||
assert(shoutput->app_ids == NULL);
|
||||
assert(shoutput->x11_wm_name_app_ids == NULL);
|
||||
assert(shoutput->x11_wm_class_app_ids == NULL);
|
||||
|
||||
if (section) {
|
||||
weston_config_section_get_string(section, "app-ids",
|
||||
&shoutput->app_ids, NULL);
|
||||
weston_config_section_get_string(section, "x11-wm-name",
|
||||
&shoutput->x11_wm_name_app_ids, NULL);
|
||||
weston_config_section_get_string(section, "x11-wm-class",
|
||||
&shoutput->x11_wm_class_app_ids, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,8 @@ struct kiosk_shell_output {
|
|||
struct wl_list link;
|
||||
|
||||
char *app_ids;
|
||||
char *x11_wm_name_app_ids;
|
||||
char *x11_wm_class_app_ids;
|
||||
|
||||
struct wl_list *active_surface_tree;
|
||||
};
|
||||
|
|
|
@ -2986,6 +2986,25 @@ is_wm_window(struct weston_surface *surface)
|
|||
return get_wm_window(surface) != NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_xwayland_window_name(struct weston_surface *surface, enum window_atom_type atype)
|
||||
{
|
||||
struct weston_wm_window *window = get_wm_window(surface);
|
||||
|
||||
switch (atype) {
|
||||
case WM_NAME:
|
||||
return window->name;
|
||||
break;
|
||||
case WM_CLASS:
|
||||
return window->class;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
weston_wm_window_configure(void *data)
|
||||
{
|
||||
|
@ -3354,4 +3373,5 @@ xserver_map_shell_surface(struct weston_wm_window *window,
|
|||
const struct weston_xwayland_surface_api surface_api = {
|
||||
is_wm_window,
|
||||
send_position,
|
||||
get_xwayland_window_name,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user