X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Flayout.c;h=48c478e9b0e904a94eeb7e13eddb6c310fbb44a7;hb=7ec377fb843d18ac29cd756b5833d94185706602;hp=95d3e541853f647b4d333d0672d4101404b21a49;hpb=70a2d75e8e35d94bf2b1aef430ac7ed8cd3d96bc;p=src%2Fagl-compositor.git diff --git a/src/layout.c b/src/layout.c index 95d3e54..48c478e 100644 --- a/src/layout.c +++ b/src/layout.c @@ -1,5 +1,5 @@ /* - * Copyright © 2019 Collabora, Ltd. + * Copyright © 2019, 2024 Collabora, Ltd. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -32,7 +32,7 @@ #include #include -#include +#include #include "agl-shell-desktop-server-protocol.h" @@ -54,6 +54,81 @@ static const char *ivi_roles_as_string[] = { bool ivi_surf_in_hidden_layer(struct ivi_compositor *ivi, struct ivi_surface *surface); +void +ivi_layout_save(struct ivi_compositor *ivi, struct ivi_output *output) +{ + struct ivi_output *new_output; + ivi->need_ivi_output_relayout = true; + + new_output = zalloc(sizeof(*new_output)); + + new_output->ivi = ivi; + new_output->background = output->background; + + new_output->top = output->top; + new_output->bottom = output->bottom; + new_output->left = output->left; + new_output->right = output->right; + + new_output->active = output->active; + new_output->previous_active = output->previous_active; + new_output->name = strdup(output->name); + if (output->app_ids) + new_output->app_ids = strdup(output->app_ids); + + new_output->area = output->area; + new_output->area_saved = output->area_saved; + new_output->area_activation = output->area_activation; + + weston_log("saving output layout for output %s\n", new_output->name); + + wl_list_insert(&ivi->saved_outputs, &new_output->link); +} + +void +ivi_layout_restore(struct ivi_compositor *ivi, struct ivi_output *n_output) +{ + struct ivi_output *output = NULL; + struct ivi_output *iter_output; + + if (!ivi->need_ivi_output_relayout) + return; + + ivi->need_ivi_output_relayout = false; + + wl_list_for_each(iter_output, &ivi->saved_outputs, link) { + if (strcmp(n_output->name, iter_output->name) == 0) { + output = iter_output; + break; + } + } + + if (!output) + return; + + weston_log("restoring output layout for output %s\n", output->name); + n_output->background = output->background; + + n_output->top = output->top; + n_output->bottom = output->bottom; + n_output->left = output->left; + n_output->right = output->right; + + n_output->active = output->active; + n_output->previous_active = output->previous_active; + if (output->app_ids) + n_output->app_ids = strdup(output->app_ids); + + n_output->area = output->area; + n_output->area_saved = output->area_saved; + n_output->area_activation = output->area_activation; + + free(output->app_ids); + free(output->name); + wl_list_remove(&output->link); + free(output); +} + const char * ivi_layout_get_surface_role_name(struct ivi_surface *surf) { @@ -69,6 +144,8 @@ ivi_background_init(struct ivi_compositor *ivi, struct ivi_output *output) struct weston_output *woutput = output->output; struct ivi_surface *bg = output->background; struct weston_view *view; + struct weston_surface *wsurface = + weston_desktop_surface_get_surface(bg->dsurface); if (!bg) { weston_log("WARNING: Output does not have a background\n"); @@ -78,17 +155,15 @@ ivi_background_init(struct ivi_compositor *ivi, struct ivi_output *output) assert(bg->role == IVI_SURFACE_ROLE_BACKGROUND); view = bg->view; + weston_surface_map(wsurface); weston_view_set_output(view, woutput); - weston_view_set_position(view, woutput->x, woutput->y); - - weston_log("(background) position view %p, x %d, y %d, on output %s\n", view, - woutput->x, woutput->y, output->name); + weston_view_set_position(view, woutput->pos); - view->is_mapped = true; - view->surface->is_mapped = true; + weston_view_move_to_layer(view, &ivi->background.view_list); + weston_log("(background) position view %p, x %f, y %f, on output %s\n", view, + woutput->pos.c.x, woutput->pos.c.y, output->name); - weston_layer_entry_insert(&ivi->background.view_list, &view->layer_link); } static void @@ -99,8 +174,8 @@ ivi_panel_init(struct ivi_compositor *ivi, struct ivi_output *output, struct weston_desktop_surface *dsurface; struct weston_view *view; struct weston_geometry geom; - int x = woutput->x; - int y = woutput->y; + struct weston_coord_global pos = woutput->pos; + struct weston_surface *wsurface; if (!panel) return; @@ -109,6 +184,7 @@ ivi_panel_init(struct ivi_compositor *ivi, struct ivi_output *output, dsurface = panel->dsurface; view = panel->view; geom = weston_desktop_surface_get_geometry(dsurface); + wsurface = weston_desktop_surface_get_surface(panel->dsurface); weston_log("(panel) geom.width %d, geom.height %d, geom.x %d, geom.y %d\n", geom.width, geom.height, geom.x, geom.y); @@ -119,7 +195,7 @@ ivi_panel_init(struct ivi_compositor *ivi, struct ivi_output *output, output->area.height -= geom.height; break; case AGL_SHELL_EDGE_BOTTOM: - y += woutput->height - geom.height; + pos.c.y += woutput->height - geom.height; output->area.height -= geom.height; break; case AGL_SHELL_EDGE_LEFT: @@ -127,27 +203,25 @@ ivi_panel_init(struct ivi_compositor *ivi, struct ivi_output *output, output->area.width -= geom.width; break; case AGL_SHELL_EDGE_RIGHT: - x += woutput->width - geom.width; + pos.c.x += woutput->width - geom.width; output->area.width -= geom.width; break; } - x -= geom.x; - y -= geom.y; + pos.c.x -= geom.x; + pos.c.y -= geom.y; weston_view_set_output(view, woutput); - weston_view_set_position(view, x, y); + weston_view_set_position(view, pos); - weston_log("(panel) edge %d position view %p, x %d, y %d\n", - panel->panel.edge, view, x, y); + weston_surface_map(wsurface); + weston_view_move_to_layer(view, &ivi->panel.view_list); - view->is_mapped = true; - view->surface->is_mapped = true; + weston_log("(panel) edge %d position view %p, x %f, y %f\n", + panel->panel.edge, view, pos.c.x, pos.c.y); weston_log("panel type %d inited on output %s\n", panel->panel.edge, output->name); - - weston_layer_entry_insert(&ivi->panel.view_list, &view->layer_link); } /* @@ -247,6 +321,7 @@ ivi_layout_activate_complete(struct ivi_output *output, struct ivi_shell_seat *ivi_seat = get_ivi_shell_seat(wseat); const char *app_id = weston_desktop_surface_get_app_id(surf->dsurface); bool update_previous = true; + struct weston_coord_global pos; if (weston_view_is_mapped(view)) { weston_layer_entry_remove(&view->layer_link); @@ -280,13 +355,15 @@ ivi_layout_activate_complete(struct ivi_output *output, /* drop any previous masks set on this view */ weston_view_set_mask_infinite(view); - if (surf->role != IVI_SURFACE_ROLE_BACKGROUND) - weston_view_set_position(view, - woutput->x + output->area.x, - woutput->y + output->area.y); + if (surf->role != IVI_SURFACE_ROLE_BACKGROUND) { + pos.c.x = woutput->pos.c.x + output->area.x; + pos.c.y = woutput->pos.c.y + output->area.y; + weston_view_set_position(view, pos); + } /* reset any previous orientation */ - if (surf->orientation != AGL_SHELL_TILE_ORIENTATION_NONE) { + if (surf->orientation != AGL_SHELL_TILE_ORIENTATION_NONE && + !surf->sticky) { weston_log("%s() resetting itself to none orientation\n", __func__); surf->orientation = AGL_SHELL_TILE_ORIENTATION_NONE; weston_desktop_surface_set_orientation(surf->dsurface, @@ -317,7 +394,9 @@ ivi_layout_activate_complete(struct ivi_output *output, if (output->active) { /* keep the background surface mapped at all times */ - if (output->active->role != IVI_SURFACE_ROLE_BACKGROUND) { + if (output->active->role != IVI_SURFACE_ROLE_BACKGROUND && + !output->active->sticky) { + output->active->view->is_mapped = false; output->active->view->surface->is_mapped = false; @@ -717,7 +796,7 @@ ivi_layout_fullscreen_committed(struct ivi_surface *surface) weston_layer_entry_remove(&view->layer_link); weston_view_set_output(view, woutput); - weston_view_set_position(view, woutput->x, woutput->y); + weston_view_set_position(view, woutput->pos); weston_layer_entry_insert(&ivi->fullscreen.view_list, &view->layer_link); wsurface->is_mapped = true; @@ -749,15 +828,17 @@ ivi_layout_desktop_resize(struct ivi_surface *surface, struct weston_desktop_surface *dsurf = surface->dsurface; struct weston_view *view = surface->view; - int x = area.x; - int y = area.y; + struct weston_coord_global pos; int width = area.width; int height = area.height; + pos.c.x = area.x; + pos.c.y = area.y; + weston_desktop_surface_set_size(dsurf, width, height); - weston_view_set_position(view, x, y); + weston_view_set_position(view, pos); weston_view_geometry_dirty(view); weston_surface_damage(view->surface); @@ -783,12 +864,9 @@ ivi_layout_split_committed(struct ivi_surface *surface) struct weston_view *view = surface->view; struct weston_geometry geom; - int x, y; + struct weston_coord_global pos = woutput->pos; int width, height; - x = woutput->x; - y = woutput->y; - if (policy && policy->api.surface_activate_by_default && !policy->api.surface_activate_by_default(surface, surface->ivi) && !surface->mapped) @@ -810,25 +888,25 @@ ivi_layout_split_committed(struct ivi_surface *surface) case IVI_SURFACE_ROLE_SPLIT_V: geom.width = (output->area.width / 2); - x += woutput->width - geom.width; + pos.c.x += woutput->width - geom.width; output->area.width -= geom.width; - width = woutput->width - x; + width = woutput->width - pos.c.x; height = output->area.height; - y = output->area.y; + pos.c.y = output->area.y; break; case IVI_SURFACE_ROLE_SPLIT_H: geom.height = (output->area.height / 2); - y = output->area.y; + pos.c.y = output->area.y; output->area.y += geom.height; output->area.height -= geom.height; width = output->area.width; height = output->area.height; - x = output->area.x; + pos.c.x = output->area.x; break; default: @@ -844,7 +922,7 @@ ivi_layout_split_committed(struct ivi_surface *surface) ivi_layout_desktop_resize(output->active, output->area); weston_view_set_output(view, woutput); - weston_view_set_position(view, x, y); + weston_view_set_position(view, pos); weston_layer_entry_insert(&ivi->normal.view_list, &view->layer_link); weston_view_geometry_dirty(view); @@ -865,10 +943,10 @@ ivi_layout_split_committed(struct ivi_surface *surface) static void ivi_compute_popup_position(const struct weston_output *output, struct weston_view *view, - int initial_x, int initial_y, int *new_x, int *new_y) + int initial_x, int initial_y, double *new_x, double *new_y) { - *new_x = output->x + initial_x; - *new_y = output->y + initial_y; + *new_x = output->pos.c.x + initial_x; + *new_y = output->pos.c.y + initial_y; } @@ -901,7 +979,7 @@ ivi_layout_popup_committed(struct ivi_surface *surface) weston_desktop_surface_get_surface(dsurface); const char *app_id = weston_desktop_surface_get_app_id(dsurface); - int new_x, new_y; + struct weston_coord_global pos; struct ivi_output *output = surface->popup.output; struct weston_output *woutput = output->output; @@ -928,8 +1006,8 @@ ivi_layout_popup_committed(struct ivi_surface *surface) weston_view_set_output(view, woutput); ivi_compute_popup_position(woutput, view, - surface->popup.x, surface->popup.y, &new_x, &new_y); - weston_view_set_position(view, new_x, new_y); + surface->popup.x, surface->popup.y, &pos.c.x, &pos.c.y); + weston_view_set_position(view, pos); weston_view_update_transform(view); /* only clip the pop-up dialog window if we have a valid @@ -1036,11 +1114,13 @@ void ivi_layout_reset_split_surfaces(struct ivi_compositor *ivi) { struct ivi_surface *ivisurf; + struct ivi_surface *found_ivi_surf = NULL; bool found_split_surface = false; struct ivi_output *output = NULL; wl_list_for_each(ivisurf, &ivi->surfaces, link) { if (ivisurf->orientation != AGL_SHELL_TILE_ORIENTATION_NONE) { + found_ivi_surf = ivisurf; found_split_surface = true; break; } @@ -1049,7 +1129,11 @@ ivi_layout_reset_split_surfaces(struct ivi_compositor *ivi) if (!found_split_surface) return; - output = ivisurf->current_completed_output; + output = found_ivi_surf->current_completed_output; + + if (found_ivi_surf->sticky) + return; + if (output->previous_active && output->background != output->previous_active) { struct weston_view *ev = output->previous_active->view; struct weston_output *woutput = output->output; @@ -1067,16 +1151,16 @@ ivi_layout_reset_split_surfaces(struct ivi_compositor *ivi) weston_layer_entry_insert(&ivi->normal.view_list, &ev->layer_link); - _ivi_set_shell_surface_split(output->previous_active, NULL, - AGL_SHELL_TILE_ORIENTATION_NONE, false); + _ivi_set_shell_surface_split(output->previous_active, NULL, 0, + AGL_SHELL_TILE_ORIENTATION_NONE, false, false); if (output->active == ivisurf) { output->active = output->previous_active; } } - _ivi_set_shell_surface_split(ivisurf, NULL, - AGL_SHELL_TILE_ORIENTATION_NONE, false); + _ivi_set_shell_surface_split(ivisurf, NULL, 0, + AGL_SHELL_TILE_ORIENTATION_NONE, false, false); } void @@ -1128,6 +1212,12 @@ ivi_layout_activate_by_surf(struct ivi_output *output, struct ivi_surface *surf) return; } + if (surf->sticky && surf->role == IVI_SURFACE_ROLE_TILE && output->active == surf) { + weston_log("Application %s is already active on output %s (split role)\n", + app_id, output->output->name); + return; + } + if (ivi_layout_surface_is_split_or_fullscreen(surf)) { weston_log("Application %s is fullscreen or split on output %s\n", app_id, output->output->name); @@ -1164,7 +1254,8 @@ ivi_layout_activate_by_surf(struct ivi_output *output, struct ivi_surface *surf) /* the background surface is already "maximized" so we don't need to * add to the hidden layer */ - if (surf->role == IVI_SURFACE_ROLE_BACKGROUND) { + if (surf->role == IVI_SURFACE_ROLE_BACKGROUND && + output->active->role != IVI_SURFACE_ROLE_TILE) { ivi_layout_activate_complete(output, surf); return; }