SHELL_SURFACE_NONE,
SHELL_SURFACE_TOPLEVEL,
SHELL_SURFACE_TRANSIENT,
- SHELL_SURFACE_FULLSCREEN,
- SHELL_SURFACE_MAXIMIZED,
SHELL_SURFACE_POPUP,
SHELL_SURFACE_XWAYLAND
};
struct wl_list link;
const struct weston_shell_client *client;
+
+ struct {
+ bool maximized;
+ bool fullscreen;
+ } state, next_state; /* surface states */
+ bool state_changed;
};
struct shell_grab {
if (!shsurf)
return -1;
- if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+ if (shsurf->state.fullscreen)
return 0;
if (shsurf->grabbed)
return 0;
if (shsurf->grabbed)
return 0;
- if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+ if (shsurf->state.fullscreen)
return 0;
move = malloc(sizeof *move);
{
struct weston_resize_grab *resize;
- if (shsurf->type == SHELL_SURFACE_FULLSCREEN ||
- shsurf->type == SHELL_SURFACE_MAXIMIZED)
+ if (shsurf->state.fullscreen || shsurf->state.maximized)
return 0;
if (edges == 0 || edges > 15 ||
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
struct weston_surface *surface;
- if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+ if (shsurf->state.fullscreen)
return;
surface = weston_surface_get_main_surface(seat->pointer->focus->surface);
break;
}
- case SHELL_SURFACE_FULLSCREEN:
- return &shsurf->shell->fullscreen_layer.view_list;
+ case SHELL_SURFACE_TOPLEVEL: {
+ if (shsurf->state.fullscreen)
+ return &shsurf->shell->fullscreen_layer.view_list;
+ break;
+ }
case SHELL_SURFACE_XWAYLAND:
- case SHELL_SURFACE_TOPLEVEL:
- case SHELL_SURFACE_MAXIMIZED:
case SHELL_SURFACE_NONE:
default:
/* Go to the fallback, below. */
}
static void
+surface_clear_next_states(struct shell_surface *shsurf)
+{
+ shsurf->next_state.maximized = false;
+ shsurf->next_state.fullscreen = false;
+
+ if ((shsurf->next_state.maximized != shsurf->state.maximized) ||
+ (shsurf->next_state.fullscreen != shsurf->state.fullscreen))
+ shsurf->state_changed = true;
+}
+
+static void
set_toplevel(struct shell_surface *shsurf)
{
shell_surface_set_parent(shsurf, NULL);
{
struct shell_surface *surface = wl_resource_get_user_data(resource);
+ surface_clear_next_states(surface);
set_toplevel(surface);
}
struct weston_surface *parent =
wl_resource_get_user_data(parent_resource);
+ surface_clear_next_states(shsurf);
set_transient(shsurf, parent, x, y, flags);
}
shell_surface_set_parent(shsurf, NULL);
- shsurf->next_type = SHELL_SURFACE_FULLSCREEN;
+ shsurf->next_type = shsurf->type;
shsurf->client->send_configure(shsurf->surface, 0,
shsurf->output->width,
else
output = NULL;
+ surface_clear_next_states(shsurf);
+ shsurf->next_state.fullscreen = true;
+ shsurf->state_changed = true;
set_fullscreen(shsurf, method, framerate, output);
}
{
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+ surface_clear_next_states(shsurf);
set_popup(shsurf,
wl_resource_get_user_data(parent_resource),
wl_resource_get_user_data(seat_resource),
shell_surface_set_parent(shsurf, NULL);
- shsurf->next_type = SHELL_SURFACE_MAXIMIZED;
+ shsurf->next_type = shsurf->type;
}
static void
else
output = NULL;
+ surface_clear_next_states(shsurf);
+ shsurf->next_state.maximized = true;
+ shsurf->state_changed = true;
set_maximized(shsurf, output);
}
static int
reset_surface_type(struct shell_surface *surface)
{
- switch (surface->type) {
- case SHELL_SURFACE_FULLSCREEN:
+ if (surface->state.fullscreen)
unset_fullscreen(surface);
- break;
- case SHELL_SURFACE_MAXIMIZED:
+ if (surface->state.maximized)
unset_maximized(surface);
- break;
- case SHELL_SURFACE_NONE:
- case SHELL_SURFACE_TOPLEVEL:
- case SHELL_SURFACE_TRANSIENT:
- case SHELL_SURFACE_POPUP:
- case SHELL_SURFACE_XWAYLAND:
- default:
- break;
- }
surface->type = SHELL_SURFACE_NONE;
return 0;
}
static void
+set_full_output(struct shell_surface *shsurf)
+{
+ shsurf->saved_x = shsurf->view->geometry.x;
+ shsurf->saved_y = shsurf->view->geometry.y;
+ shsurf->saved_position_valid = true;
+
+ if (!wl_list_empty(&shsurf->rotation.transform.link)) {
+ wl_list_remove(&shsurf->rotation.transform.link);
+ wl_list_init(&shsurf->rotation.transform.link);
+ weston_view_geometry_dirty(shsurf->view);
+ shsurf->saved_rotation_valid = true;
+ }
+}
+
+static void
set_surface_type(struct shell_surface *shsurf)
{
struct weston_surface *pes = shsurf->parent;
reset_surface_type(shsurf);
shsurf->type = shsurf->next_type;
+ shsurf->state = shsurf->next_state;
shsurf->next_type = SHELL_SURFACE_NONE;
+ shsurf->state_changed = false;
switch (shsurf->type) {
case SHELL_SURFACE_TOPLEVEL:
+ if (shsurf->state.maximized || shsurf->state.fullscreen)
+ set_full_output(shsurf);
break;
case SHELL_SURFACE_TRANSIENT:
if (pev)
pev->geometry.y + shsurf->transient.y);
break;
- case SHELL_SURFACE_MAXIMIZED:
- case SHELL_SURFACE_FULLSCREEN:
- shsurf->saved_x = shsurf->view->geometry.x;
- shsurf->saved_y = shsurf->view->geometry.y;
- shsurf->saved_position_valid = true;
-
- if (!wl_list_empty(&shsurf->rotation.transform.link)) {
- wl_list_remove(&shsurf->rotation.transform.link);
- wl_list_init(&shsurf->rotation.transform.link);
- weston_view_geometry_dirty(shsurf->view);
- shsurf->saved_rotation_valid = true;
- }
- break;
-
case SHELL_SURFACE_XWAYLAND:
weston_view_set_position(shsurf->view, shsurf->transient.x,
shsurf->transient.y);
{
struct weston_output *output = shsurf->fullscreen_output;
- assert(shsurf->type == SHELL_SURFACE_FULLSCREEN);
+ assert(shsurf->state.fullscreen);
if (!shsurf->fullscreen.black_view)
shsurf->fullscreen.black_view =
set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags)
{
/* XXX: using the same fields for transient type */
+ surface_clear_next_states(shsurf);
shsurf->transient.x = x;
shsurf->transient.y = y;
shsurf->transient.flags = flags;
return;
shsurf = get_shell_surface(surface);
- if (shsurf == NULL || shsurf->type == SHELL_SURFACE_FULLSCREEN ||
- shsurf->type == SHELL_SURFACE_MAXIMIZED)
+ if (shsurf == NULL || shsurf->state.fullscreen ||
+ shsurf->state.maximized)
return;
surface_move(shsurf, (struct weston_seat *) seat);
return;
shsurf = get_shell_surface(surface);
- if (shsurf == NULL || shsurf->type == SHELL_SURFACE_FULLSCREEN ||
- shsurf->type == SHELL_SURFACE_MAXIMIZED)
+ if (shsurf == NULL || shsurf->state.fullscreen ||
+ shsurf->state.maximized)
return;
surface_touch_move(shsurf, (struct weston_seat *) seat);
return;
shsurf = get_shell_surface(surface);
- if (!shsurf || shsurf->type == SHELL_SURFACE_FULLSCREEN ||
- shsurf->type == SHELL_SURFACE_MAXIMIZED)
+ if (shsurf == NULL || shsurf->state.fullscreen ||
+ shsurf->state.maximized)
return;
weston_view_from_global(shsurf->view,
return;
surface = get_shell_surface(base_surface);
- if (!surface || surface->type == SHELL_SURFACE_FULLSCREEN ||
- surface->type == SHELL_SURFACE_MAXIMIZED)
+ if (surface == NULL || surface->state.fullscreen ||
+ surface->state.maximized)
return;
surface_rotate(surface, seat);
struct focus_state *state;
struct workspace *ws;
struct weston_surface *old_es;
+ struct shell_surface *shsurf;
main_surface = weston_surface_get_main_surface(es);
wl_list_remove(&state->surface_destroy_listener.link);
wl_signal_add(&es->destroy_signal, &state->surface_destroy_listener);
- switch (get_shell_surface_type(main_surface)) {
- case SHELL_SURFACE_FULLSCREEN:
- /* should on top of panels */
- shell_configure_fullscreen(get_shell_surface(main_surface));
- return;
- case SHELL_SURFACE_TOPLEVEL:
- case SHELL_SURFACE_TRANSIENT:
- case SHELL_SURFACE_MAXIMIZED:
- case SHELL_SURFACE_POPUP:
- case SHELL_SURFACE_XWAYLAND:
- case SHELL_SURFACE_NONE:
- default:
+ shsurf = get_shell_surface(main_surface);
+ if (shsurf->state.fullscreen)
+ shell_configure_fullscreen(shsurf);
+ else
restore_all_output_modes(shell->compositor);
- break;
- }
if (shell->focus_animation_type != ANIMATION_NONE) {
ws = get_current_workspace(shell);
/* initial positioning, see also configure() */
switch (shsurf->type) {
- case SHELL_SURFACE_TOPLEVEL:
- weston_view_set_initial_position(shsurf->view, shell);
- break;
- case SHELL_SURFACE_FULLSCREEN:
- center_on_output(shsurf->view, shsurf->fullscreen_output);
- shell_map_fullscreen(shsurf);
- break;
- case SHELL_SURFACE_MAXIMIZED:
- /* use surface configure to set the geometry */
- panel_height = get_output_panel_height(shell, shsurf->output);
- surface_subsurfaces_boundingbox(shsurf->surface,
- &surf_x, &surf_y, NULL, NULL);
- weston_view_set_position(shsurf->view,
- shsurf->output->x - surf_x,
- shsurf->output->y + panel_height - surf_y);
+ if (shsurf->state.fullscreen) {
+ center_on_output(shsurf->view, shsurf->fullscreen_output);
+ shell_map_fullscreen(shsurf);
+ } else if (shsurf->state.maximized) {
+ /* use surface configure to set the geometry */
+ panel_height = get_output_panel_height(shell, shsurf->output);
+ surface_subsurfaces_boundingbox(shsurf->surface,
+ &surf_x, &surf_y, NULL, NULL);
+ weston_view_set_position(shsurf->view,
+ shsurf->output->x - surf_x,
+ shsurf->output->y +
+ panel_height - surf_y);
+ } else {
+ weston_view_set_initial_position(shsurf->view, shell);
+ }
break;
case SHELL_SURFACE_POPUP:
shell_map_popup(shsurf);
if (shsurf->type != SHELL_SURFACE_NONE) {
weston_view_update_transform(shsurf->view);
- if (shsurf->type == SHELL_SURFACE_MAXIMIZED) {
+ if (shsurf->state.maximized) {
shsurf->surface->output = shsurf->output;
shsurf->view->output = shsurf->output;
}
WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
break;
case SHELL_SURFACE_TOPLEVEL:
- case SHELL_SURFACE_FULLSCREEN:
- case SHELL_SURFACE_MAXIMIZED:
if (!shell->locked) {
wl_list_for_each(seat, &compositor->seat_list, link)
activate(shell, shsurf->surface, seat);
break;
}
- if (shsurf->type == SHELL_SURFACE_TOPLEVEL)
+ if (shsurf->type == SHELL_SURFACE_TOPLEVEL &&
+ !shsurf->state.maximized && !shsurf->state.fullscreen)
{
switch (shell->win_animation_type) {
case ANIMATION_FADE:
configure(struct desktop_shell *shell, struct weston_surface *surface,
float x, float y)
{
- enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
struct shell_surface *shsurf;
struct weston_view *view;
int32_t mx, my, surf_x, surf_y;
shsurf = get_shell_surface(surface);
- if (shsurf)
- surface_type = shsurf->type;
- switch (surface_type) {
- case SHELL_SURFACE_FULLSCREEN:
+ if (shsurf->state.fullscreen)
shell_configure_fullscreen(shsurf);
- break;
- case SHELL_SURFACE_MAXIMIZED:
+ else if (shsurf->state.maximized) {
/* setting x, y and using configure to change that geometry */
surface_subsurfaces_boundingbox(shsurf->surface, &surf_x, &surf_y,
NULL, NULL);
my = shsurf->output->y +
get_output_panel_height(shell,shsurf->output) - surf_y;
weston_view_set_position(shsurf->view, mx, my);
- break;
- case SHELL_SURFACE_TOPLEVEL:
- case SHELL_SURFACE_TRANSIENT:
- case SHELL_SURFACE_POPUP:
- case SHELL_SURFACE_XWAYLAND:
- case SHELL_SURFACE_NONE:
- default:
+ } else {
weston_view_set_position(shsurf->view, x, y);
- break;
}
/* XXX: would a fullscreen surface need the same handling? */
wl_list_for_each(view, &surface->views, surface_link)
weston_view_update_transform(view);
- if (surface_type == SHELL_SURFACE_MAXIMIZED)
+ if (shsurf->state.maximized)
surface->output = shsurf->output;
}
}
if (es->width == 0)
return;
- if (shsurf->next_type != SHELL_SURFACE_NONE &&
- shsurf->type != shsurf->next_type) {
+ if ((shsurf->next_type != SHELL_SURFACE_NONE &&
+ shsurf->type != shsurf->next_type) ||
+ shsurf->state_changed) {
set_surface_type(shsurf);
type_changed = 1;
}
wl_list_for_each(view, &ws->layer.view_list, layer_link) {
switch (get_shell_surface_type(view->surface)) {
case SHELL_SURFACE_TOPLEVEL:
- case SHELL_SURFACE_FULLSCREEN:
- case SHELL_SURFACE_MAXIMIZED:
if (first == NULL)
first = view->surface;
if (prev == switcher->current)
view->alpha = 1.0;
shsurf = get_shell_surface(switcher->current);
- if (shsurf && shsurf->type ==SHELL_SURFACE_FULLSCREEN)
+ if (shsurf && shsurf->state.fullscreen)
shsurf->fullscreen.black_view->alpha = 1.0;
}