Skip to content
Commits on Source (20)
......@@ -565,7 +565,7 @@ get_animation_type(char *animation)
return ANIMATION_NONE;
}
static void
static bool
shell_configuration(struct desktop_shell *shell)
{
struct weston_config_section *section;
......@@ -592,15 +592,28 @@ shell_configuration(struct desktop_shell *shell)
weston_config_section_get_string(section, "close-animation", &s, "fade");
shell->win_close_animation_type = get_animation_type(s);
free(s);
weston_config_section_get_string(section,
"startup-animation", &s, "fade");
shell->startup_animation_type = get_animation_type(s);
if (shell->startup_animation_type == ANIMATION_ZOOM) {
weston_log("invalid startup animation type %s\n", s);
free(s);
return false;
}
free(s);
if (shell->startup_animation_type == ANIMATION_ZOOM)
shell->startup_animation_type = ANIMATION_NONE;
weston_config_section_get_string(section, "focus-animation", &s, "none");
shell->focus_animation_type = get_animation_type(s);
if (shell->focus_animation_type != ANIMATION_NONE &&
shell->focus_animation_type != ANIMATION_DIM_LAYER) {
weston_log("invalid focus animation type %s\n", s);
free(s);
return false;
}
free(s);
return true;
}
static int
......@@ -646,8 +659,6 @@ create_focus_surface(struct weston_compositor *ec,
fsurf->curtain = weston_shell_utils_curtain_create(ec, &curtain_params);
weston_view_set_output(fsurf->curtain->view, output);
/* XXX: can't map view without a layer! */
fsurf->curtain->view->is_mapped = true;
return fsurf;
}
......@@ -667,6 +678,39 @@ focus_animation_done(struct weston_view_animation *animation, void *data)
ws->focus_animation = NULL;
}
static void
animate_focus_change(struct desktop_shell *shell, struct workspace *ws,
struct weston_view *from, struct weston_view *to)
{
struct weston_view *front = ws->fsurf_front->curtain->view;
struct weston_view *back = ws->fsurf_back->curtain->view;
if ((from && from == to) || shell->focus_animation_type == ANIMATION_NONE)
return;
if (ws->focus_animation) {
weston_view_animation_destroy(ws->focus_animation);
ws->focus_animation = NULL;
}
if (to) {
weston_view_move_to_layer(front, &to->layer_link);
if (from)
weston_view_move_to_layer(back, &from->layer_link);
else
weston_view_move_to_layer(back, &ws->layer.view_list);
ws->focus_animation =
weston_stable_fade_run(front, 0.0, back, 0.4,
focus_animation_done, ws);
} else {
weston_view_move_to_layer(front, &ws->layer.view_list);
weston_view_move_to_layer(back, NULL);
ws->focus_animation =
weston_fade_run(front, front->alpha, 0.0, 300,
focus_animation_done, ws);
}
}
static void
focus_state_destroy(struct focus_state *state)
{
......@@ -725,14 +769,9 @@ focus_state_surface_destroy(struct wl_listener *listener, void *data)
activate(state->shell, next, state->seat,
WESTON_ACTIVATE_FLAG_CONFIGURE);
} else {
if (state->shell->focus_animation_type == ANIMATION_DIM_LAYER) {
if (state->ws->focus_animation)
weston_view_animation_destroy(state->ws->focus_animation);
state->ws->focus_animation = weston_fade_run(
state->ws->fsurf_front->curtain->view,
state->ws->fsurf_front->curtain->view->alpha, 0.0, 300,
focus_animation_done, state->ws);
if (state->shell->focus_animation_type != ANIMATION_NONE) {
animate_focus_change(state->shell, state->ws,
get_default_view(main_surface), NULL);
}
wl_list_remove(&state->link);
......@@ -852,71 +891,6 @@ drop_focus_state(struct desktop_shell *shell, struct workspace *ws,
focus_state_set_focus(state, NULL);
}
static void
animate_focus_change(struct desktop_shell *shell, struct workspace *ws,
struct weston_view *from, struct weston_view *to)
{
struct weston_output *output;
bool focus_surface_created = false;
/* FIXME: Only support dim animation using two layers */
if (from == to || shell->focus_animation_type != ANIMATION_DIM_LAYER)
return;
output = weston_shell_utils_get_default_output(shell->compositor);
if (ws->fsurf_front == NULL && (from || to)) {
ws->fsurf_front = create_focus_surface(shell->compositor, output);
if (ws->fsurf_front == NULL)
return;
weston_view_set_alpha(ws->fsurf_front->curtain->view, 0.0);
ws->fsurf_back = create_focus_surface(shell->compositor, output);
if (ws->fsurf_back == NULL) {
focus_surface_destroy(ws->fsurf_front);
return;
}
weston_view_set_alpha(ws->fsurf_back->curtain->view, 0.0);
focus_surface_created = true;
} else {
weston_layer_entry_remove(&ws->fsurf_front->curtain->view->layer_link);
weston_layer_entry_remove(&ws->fsurf_back->curtain->view->layer_link);
}
if (ws->focus_animation) {
weston_view_animation_destroy(ws->focus_animation);
ws->focus_animation = NULL;
}
if (to)
weston_layer_entry_insert(&to->layer_link,
&ws->fsurf_front->curtain->view->layer_link);
else if (from)
weston_layer_entry_insert(&ws->layer.view_list,
&ws->fsurf_front->curtain->view->layer_link);
if (focus_surface_created) {
ws->focus_animation = weston_fade_run(
ws->fsurf_front->curtain->view,
ws->fsurf_front->curtain->view->alpha, 0.4, 300,
focus_animation_done, ws);
} else if (from) {
weston_layer_entry_insert(&from->layer_link,
&ws->fsurf_back->curtain->view->layer_link);
ws->focus_animation = weston_stable_fade_run(
ws->fsurf_front->curtain->view, 0.0,
ws->fsurf_back->curtain->view, 0.4,
focus_animation_done, ws);
} else if (to) {
weston_layer_entry_insert(&ws->layer.view_list,
&ws->fsurf_back->curtain->view->layer_link);
ws->focus_animation = weston_stable_fade_run(
ws->fsurf_front->curtain->view, 0.0,
ws->fsurf_back->curtain->view, 0.4,
focus_animation_done, ws);
}
}
static void
desktop_shell_destroy_layer(struct weston_layer *layer);
......@@ -961,8 +935,21 @@ workspace_create(struct desktop_shell *shell)
wl_list_init(&ws->focus_list);
wl_list_init(&ws->seat_destroyed_listener.link);
ws->seat_destroyed_listener.notify = seat_destroyed;
ws->fsurf_front = NULL;
ws->fsurf_back = NULL;
if (shell->focus_animation_type != ANIMATION_NONE) {
struct weston_output *output =
weston_shell_utils_get_default_output(shell->compositor);
assert(shell->focus_animation_type == ANIMATION_DIM_LAYER);
ws->fsurf_front = create_focus_surface(shell->compositor, output);
assert(ws->fsurf_front);
ws->fsurf_back = create_focus_surface(shell->compositor, output);
assert(ws->fsurf_back);
} else {
ws->fsurf_front = NULL;
ws->fsurf_back = NULL;
}
ws->focus_animation = NULL;
}
......@@ -1852,7 +1839,6 @@ set_minimized(struct weston_surface *surface)
struct shell_surface *shsurf;
struct workspace *current_ws;
struct weston_view *view;
struct weston_subsurface *subsurface;
view = get_default_view(surface);
if (!view)
......@@ -1863,19 +1849,13 @@ set_minimized(struct weston_surface *surface)
shsurf = get_shell_surface(surface);
current_ws = get_current_workspace(shsurf->shell);
weston_layer_entry_remove(&view->layer_link);
weston_layer_entry_insert(&shsurf->shell->minimized_layer.view_list, &view->layer_link);
weston_view_move_to_layer(view,
&shsurf->shell->minimized_layer.view_list);
drop_focus_state(shsurf->shell, current_ws, view->surface);
surface_keyboard_focus_lost(surface);
shell_surface_update_child_surface_layers(shsurf);
weston_view_damage_below(shsurf->view);
wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
wl_list_for_each(view, &subsurface->surface->views, surface_link)
weston_view_damage_below(view);
}
}
......@@ -1932,8 +1912,10 @@ is_black_surface_view(struct weston_view *view, struct weston_view **fs_view)
return false;
}
/* Set the shell surface as the current fullscreen view for its current output,
* centering it with a black background */
static void
shell_ensure_fullscreen_black_view(struct shell_surface *shsurf)
shell_set_view_fullscreen(struct shell_surface *shsurf)
{
struct weston_surface *surface =
weston_desktop_surface_get_surface(shsurf->desktop_surface);
......@@ -1948,59 +1930,23 @@ shell_ensure_fullscreen_black_view(struct shell_surface *shsurf)
.surface_private = shsurf->view,
.capture_input = true,
};
struct weston_view *view;
assert(weston_desktop_surface_get_fullscreen(shsurf->desktop_surface));
weston_view_move_to_layer(shsurf->view,
&shsurf->shell->fullscreen_layer.view_list);
weston_shell_utils_center_on_output(shsurf->view, shsurf->fullscreen_output);
if (!shsurf->fullscreen.black_view) {
shsurf->fullscreen.black_view =
weston_shell_utils_curtain_create(ec, &curtain_params);
}
view = shsurf->fullscreen.black_view->view;
weston_view_set_output(view, output);
weston_view_move_to_layer(view, &shsurf->view->layer_link);
shsurf->state.lowered = false;
}
/* Create black surface and append it to the associated fullscreen surface.
* Handle size dismatch and positioning according to the method. */
static void
shell_configure_fullscreen(struct shell_surface *shsurf)
{
struct weston_surface *surface =
weston_desktop_surface_get_surface(shsurf->desktop_surface);
int32_t surf_x, surf_y, surf_width, surf_height;
/* Reverse the effect of lower_fullscreen_layer() */
weston_layer_entry_remove(&shsurf->view->layer_link);
weston_layer_entry_insert(&shsurf->shell->fullscreen_layer.view_list,
weston_view_set_output(shsurf->fullscreen.black_view->view,
shsurf->fullscreen_output);
weston_view_move_to_layer(shsurf->fullscreen.black_view->view,
&shsurf->view->layer_link);
if (!shsurf->fullscreen_output) {
struct weston_coord_global pos;
/* If there is no output, there's not much we can do.
* Position the window somewhere, whatever. */
pos.c = weston_coord(0, 0);
weston_view_set_position(shsurf->view, pos);
return;
}
shell_ensure_fullscreen_black_view(shsurf);
weston_shell_utils_subsurfaces_boundingbox(surface, &surf_x, &surf_y,
&surf_width, &surf_height);
if (weston_surface_has_content(surface))
weston_shell_utils_center_on_output(shsurf->view, shsurf->fullscreen_output);
}
static void
shell_map_fullscreen(struct shell_surface *shsurf)
{
shell_configure_fullscreen(shsurf);
shsurf->state.lowered = false;
}
static void
......@@ -2357,9 +2303,7 @@ map(struct desktop_shell *shell, struct shell_surface *shsurf)
/* initial positioning, see also configure() */
if (shsurf->state.fullscreen) {
weston_shell_utils_center_on_output(shsurf->view,
shsurf->fullscreen_output);
shell_map_fullscreen(shsurf);
shell_set_view_fullscreen(shsurf);
} else if (shsurf->state.maximized) {
set_maximized_position(shell, shsurf);
} else if (shsurf->xwayland.is_set) {
......@@ -3669,7 +3613,7 @@ rotate_binding(struct weston_pointer *pointer, const struct timespec *time,
/* Move all fullscreen layers down to the current workspace and hide their
* black views. The surfaces' state is set to both fullscreen and lowered,
* and this is reversed when such a surface is re-configured, see
* shell_configure_fullscreen() and shell_ensure_fullscreen_black_view().
* shell_set_view_fullscreen().
*
* lowering_output = NULL - Lower on all outputs, else only lower on the
* specified output.
......@@ -3698,12 +3642,8 @@ lower_fullscreen_layer(struct desktop_shell *shell,
if (lowering_output && (shsurf->fullscreen_output != lowering_output))
continue;
/* We can have a non-fullscreen popup for a fullscreen surface
* in the fullscreen layer. */
if (weston_desktop_surface_get_fullscreen(shsurf->desktop_surface) &&
shsurf->fullscreen.black_view) {
if (shsurf->fullscreen.black_view)
weston_view_move_to_layer(shsurf->fullscreen.black_view->view, NULL);
}
/* Lower the view to the workspace layer */
weston_view_move_to_layer(view, &ws->layer.view_list);
......@@ -3776,13 +3716,14 @@ activate(struct desktop_shell *shell, struct weston_view *view,
if (weston_desktop_surface_get_fullscreen(shsurf->desktop_surface) &&
flags & WESTON_ACTIVATE_FLAG_CONFIGURE)
shell_configure_fullscreen(shsurf);
shell_set_view_fullscreen(shsurf);
/* Update the surface’s layer. This brings it to the top of the stacking
* order as appropriate. */
shell_surface_update_layer(shsurf);
if (shell->focus_animation_type != ANIMATION_NONE) {
assert(shell->focus_animation_type == ANIMATION_DIM_LAYER);
ws = get_current_workspace(shell);
animate_focus_change(shell, ws, get_default_view(old_es), get_default_view(es));
}
......@@ -4390,8 +4331,7 @@ switcher_next(struct switcher *switcher)
struct weston_view *tmp;
struct weston_view **minimized;
wl_list_for_each_safe(view, tmp, &switcher->shell->minimized_layer.view_list.link, layer_link.link) {
weston_layer_entry_remove(&view->layer_link);
weston_layer_entry_insert(&ws->layer.view_list, &view->layer_link);
weston_view_move_to_layer(view, &ws->layer.view_list);
minimized = wl_array_add(&switcher->minimized_array, sizeof *minimized);
*minimized = view;
}
......@@ -4467,11 +4407,10 @@ switcher_destroy(struct switcher *switcher)
struct weston_view **minimized;
wl_array_for_each(minimized, &switcher->minimized_array) {
/* with the exception of the current selected */
if ((*minimized)->surface != switcher->current->surface) {
weston_layer_entry_remove(&(*minimized)->layer_link);
weston_layer_entry_insert(&switcher->shell->minimized_layer.view_list, &(*minimized)->layer_link);
weston_view_damage_below(*minimized);
}
if ((*minimized)->surface == switcher->current->surface)
continue;
weston_view_move_to_layer(*minimized,
&switcher->shell->minimized_layer.view_list);
}
wl_array_release(&switcher->minimized_array);
......@@ -4831,7 +4770,6 @@ setup_output_destroy_handler(struct weston_compositor *ec,
{
struct weston_output *output;
wl_list_init(&shell->output_list);
wl_list_for_each(output, &ec->output_list, link)
create_shell_output(shell, output);
......@@ -5064,18 +5002,27 @@ wet_shell_init(struct weston_compositor *ec,
wl_list_init(&shell->seat_list);
wl_list_init(&shell->shsurf_list);
wl_list_init(&shell->output_list);
wl_list_init(&shell->output_create_listener.link);
wl_list_init(&shell->output_move_listener.link);
wl_list_init(&shell->seat_create_listener.link);
wl_list_init(&shell->resized_listener.link);
wl_list_init(&shell->workspace.focus_list);
wl_list_init(&shell->workspace.seat_destroyed_listener.link);
weston_layer_init(&shell->minimized_layer, ec);
weston_layer_init(&shell->workspace.layer, ec);
if (input_panel_setup(shell) < 0)
return -1;
shell->text_backend = text_backend_init(ec);
shell_configuration(shell);
if (!shell_configuration(shell))
return -1;
workspace_create(shell);
weston_layer_init(&shell->minimized_layer, ec);
shell->desktop = weston_desktop_create(ec, &shell_desktop_api, shell);
if (!shell->desktop)
return -1;
......