Skip to content
Commits on Source (19)
......@@ -89,6 +89,9 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
struct weston_surface *focus;
struct weston_coord_global pos;
if (!weston_surface_is_mapped(ipsurf->surface))
return;
wl_list_for_each(seat, &shell->compositor->seat_list, link) {
struct weston_keyboard *keyboard =
weston_seat_get_keyboard(seat);
......@@ -105,13 +108,8 @@ show_input_panel_surface(struct input_panel_surface *ipsurf)
weston_view_set_position(ipsurf->view, pos);
}
weston_layer_entry_insert(&shell->input_panel_layer.view_list,
&ipsurf->view->layer_link);
weston_view_geometry_dirty(ipsurf->view);
weston_view_update_transform(ipsurf->view);
ipsurf->view->is_mapped = true;
weston_surface_map(ipsurf->surface);
weston_surface_damage(ipsurf->surface);
weston_view_move_to_layer(ipsurf->view,
&shell->input_panel_layer.view_list);
if (ipsurf->anim)
weston_view_animation_destroy(ipsurf->anim);
......@@ -143,9 +141,6 @@ show_input_panels(struct wl_listener *listener, void *data)
wl_list_for_each_safe(ipsurf, next,
&shell->input_panel.surfaces, link) {
if (ipsurf->surface->width == 0)
continue;
show_input_panel_surface(ipsurf);
}
}
......@@ -169,7 +164,7 @@ hide_input_panels(struct wl_listener *listener, void *data)
wl_list_for_each_safe(view, next,
&shell->input_panel_layer.view_list.link,
layer_link.link)
weston_view_unmap(view);
weston_view_move_to_layer(view, NULL);
}
static void
......@@ -196,16 +191,20 @@ input_panel_committed(struct weston_surface *surface,
struct desktop_shell *shell = ip_surface->shell;
struct weston_coord_global pos;
if (surface->width == 0)
if (!weston_surface_has_content(surface))
return;
if (calc_input_panel_position(ip_surface, &pos))
return;
weston_view_set_position(ip_surface->view, pos);
if (!weston_surface_is_mapped(surface)) {
weston_surface_map(surface);
if (shell->showing_input_panels)
show_input_panel_surface(ip_surface);
}
if (!weston_surface_is_mapped(surface) && shell->showing_input_panels)
show_input_panel_surface(ip_surface);
weston_view_set_position(ip_surface->view, pos);
}
static void
......
......@@ -229,17 +229,26 @@ shell_fade(struct desktop_shell *shell, enum fade_type type);
static struct shell_seat *
get_shell_seat(struct weston_seat *seat);
static void
get_output_panel_size(struct desktop_shell *shell,
struct weston_output *output,
int *width, int *height);
static void
shell_surface_update_child_surface_layers(struct shell_surface *shsurf);
static void
get_maximized_size(struct shell_surface *shsurf, int32_t *width, int32_t *height);
static struct shell_output *
find_shell_output_from_weston_output(struct desktop_shell *shell,
struct weston_output *output)
{
struct shell_output *shell_output;
wl_list_for_each(shell_output, &shell->output_list, link) {
if (shell_output->output == output)
return shell_output;
}
return NULL;
}
static bool
shsurf_is_max_or_fullscreen(struct shell_surface *shsurf)
{
......@@ -359,90 +368,49 @@ shell_grab_start(struct shell_grab *grab,
}
}
static void
get_panel_size(struct desktop_shell *shell,
struct weston_view *view,
int *width,
int *height)
{
struct weston_coord_global a, b;
struct weston_coord_surface tmp_s;
tmp_s = weston_coord_surface(0, 0, view->surface);
a = weston_coord_surface_to_global(view, tmp_s);
tmp_s = weston_coord_surface(view->surface->width,
view->surface->height,
view->surface);
b = weston_coord_surface_to_global(view, tmp_s);
a = weston_coord_global_sub(b, a);
*width = a.c.x;
*height = a.c.y;
}
static void
get_output_panel_size(struct desktop_shell *shell,
struct weston_output *output,
int *width,
int *height)
{
struct weston_view *view;
*width = 0;
*height = 0;
if (!output)
return;
wl_list_for_each(view, &shell->panel_layer.view_list.link, layer_link.link) {
if (view->surface->output == output) {
weston_view_update_transform(view);
get_panel_size(shell, view, width, height);
return;
}
}
/* the correct view wasn't found */
}
void
get_output_work_area(struct desktop_shell *shell,
struct weston_output *output,
pixman_rectangle32_t *area)
{
int32_t panel_width = 0, panel_height = 0;
struct shell_output *sh_output;
if (!output) {
area->x = 0;
area->y = 0;
area->width = 0;
area->height = 0;
area->x = 0;
area->y = 0;
area->width = 0;
area->height = 0;
if (!output)
return;
}
sh_output = find_shell_output_from_weston_output(shell, output);
assert(sh_output);
area->x = output->pos.c.x;
area->y = output->pos.c.y;
area->width = output->width;
area->height = output->height;
if (!sh_output->panel_view ||
!weston_view_is_mapped(sh_output->panel_view)) {
return;
}
get_output_panel_size(shell, output, &panel_width, &panel_height);
switch (shell->panel_position) {
case WESTON_DESKTOP_SHELL_PANEL_POSITION_TOP:
default:
area->y += panel_height;
area->y += sh_output->panel_surface->height;
/* fallthrough */
case WESTON_DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
area->width = output->width;
area->height = output->height - panel_height;
area->height -= sh_output->panel_surface->height;
break;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT:
area->x += panel_width;
area->x += sh_output->panel_surface->width;
/* fallthrough */
case WESTON_DESKTOP_SHELL_PANEL_POSITION_RIGHT:
area->width = output->width - panel_width;
area->height = output->height;
area->width -= sh_output->panel_surface->width;
break;
default:
unreachable("unknown panel position");
}
}
......@@ -2796,47 +2764,6 @@ static const struct weston_desktop_api shell_desktop_api = {
/* ************************ *
* end of libweston-desktop *
* ************************ */
static void
configure_static_view(struct weston_view *ev, struct weston_layer *layer,
struct weston_coord_global offset_on_output)
{
struct weston_coord_global pos;
struct weston_view *v, *next;
if (!ev->output)
return;
wl_list_for_each_safe(v, next, &layer->view_list.link, layer_link.link) {
if (v->output == ev->output && v != ev) {
weston_view_unmap(v);
v->surface->committed = NULL;
weston_surface_set_label_func(v->surface, NULL);
}
}
pos = weston_coord_global_add(ev->output->pos, offset_on_output);
weston_view_set_position(ev, pos);
weston_surface_map(ev->surface);
if (wl_list_empty(&ev->layer_link.link))
weston_view_move_to_layer(ev, &layer->view_list);
}
static struct shell_output *
find_shell_output_from_weston_output(struct desktop_shell *shell,
struct weston_output *output)
{
struct shell_output *shell_output;
wl_list_for_each(shell_output, &shell->output_list, link) {
if (shell_output->output == output)
return shell_output;
}
return NULL;
}
static int
background_get_label(struct weston_surface *surface, char *buf, size_t len)
{
......@@ -2848,14 +2775,23 @@ static void
background_committed(struct weston_surface *es,
struct weston_coord_surface new_origin)
{
struct desktop_shell *shell = es->committed_private;
struct weston_view *view;
struct weston_coord_global tmp;
struct shell_output *sh_output = es->committed_private;
struct desktop_shell *shell = sh_output->shell;
tmp.c = weston_coord(0, 0);
view = container_of(es->views.next, struct weston_view, surface_link);
if (!weston_surface_has_content(es))
return;
configure_static_view(view, &shell->background_layer, tmp);
if (!weston_surface_is_mapped(es)) {
weston_surface_map(es);
assert(wl_list_empty(&es->views));
sh_output->background_view = weston_view_create(es);
}
assert(sh_output->background_view);
weston_view_set_position(sh_output->background_view,
sh_output->output->pos);
weston_view_move_to_layer(sh_output->background_view,
&shell->background_layer.view_list);
}
static void
......@@ -2864,9 +2800,9 @@ handle_background_surface_destroy(struct wl_listener *listener, void *data)
struct shell_output *output =
container_of(listener, struct shell_output, background_surface_listener);
weston_log("background surface gone\n");
wl_list_remove(&output->background_surface_listener.link);
output->background_surface = NULL;
output->background_view = NULL;
}
static void
......@@ -2879,7 +2815,6 @@ desktop_shell_set_background(struct wl_client *client,
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
struct shell_output *sh_output;
struct weston_view *view, *next;
struct weston_head *head = weston_head_from_resource(output_resource);
if (surface->committed) {
......@@ -2892,36 +2827,30 @@ desktop_shell_set_background(struct wl_client *client,
if (!head)
return;
wl_list_for_each_safe(view, next, &surface->views, surface_link)
weston_view_destroy(view);
view = weston_view_create(surface);
surface->output = head->output;
sh_output = find_shell_output_from_weston_output(shell, surface->output);
if (sh_output->background_surface) {
wl_resource_post_error(surface_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"output already has a background surface");
return;
}
surface->committed = background_committed;
surface->committed_private = shell;
surface->committed_private = sh_output;
weston_surface_set_label_func(surface, background_get_label);
surface->output = head->output;
weston_view_set_output(view, surface->output);
sh_output = find_shell_output_from_weston_output(shell, surface->output);
if (sh_output->background_surface) {
/* The output already has a background, tell our helper
* there is no need for another one. */
weston_desktop_shell_send_configure(resource, 0,
surface_resource,
0, 0);
} else {
weston_desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
surface->output->height);
weston_desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
surface->output->height);
sh_output->background_surface = surface;
sh_output->background_surface = surface;
sh_output->background_surface_listener.notify =
handle_background_surface_destroy;
wl_signal_add(&surface->destroy_signal,
&sh_output->background_surface_listener);
}
sh_output->background_surface_listener.notify =
handle_background_surface_destroy;
wl_signal_add(&surface->destroy_signal,
&sh_output->background_surface_listener);
}
static int
......@@ -2935,35 +2864,43 @@ static void
panel_committed(struct weston_surface *es,
struct weston_coord_surface new_origin)
{
struct desktop_shell *shell = es->committed_private;
struct weston_view *view;
int width, height;
int x = 0, y = 0;
struct weston_coord_global tmp;
struct shell_output *sh_output = es->committed_private;
struct weston_output *output = sh_output->output;
struct weston_coord_global pos = output->pos;
struct desktop_shell *shell = sh_output->shell;
view = container_of(es->views.next, struct weston_view, surface_link);
/* XXX delete me eventually - it would be better if we didn't get here
* with a dirty transform at all, but for now just make sure the
* transform is updated here. */
weston_view_update_transform(view);
if (!weston_surface_has_content(es))
return;
get_panel_size(shell, view, &width, &height);
switch (shell->panel_position) {
case WESTON_DESKTOP_SHELL_PANEL_POSITION_TOP:
case WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT:
sh_output->panel_offset.c = weston_coord(0, 0);
break;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
y = view->output->height - height;
break;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT:
sh_output->panel_offset.c =
weston_coord(0, output->height - es->height);
break;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_RIGHT:
x = view->output->width - width;
sh_output->panel_offset.c =
weston_coord(output->width - es->width, 0);
break;
default:
unreachable("unknown panel position");
break;
}
tmp.c = weston_coord(x, y);
configure_static_view(view, &shell->panel_layer, tmp);
if (!weston_surface_is_mapped(es)) {
weston_surface_map(es);
assert(wl_list_empty(&es->views));
sh_output->panel_view = weston_view_create(es);
}
assert(sh_output->panel_view);
pos = weston_coord_global_add(output->pos, sh_output->panel_offset);
weston_view_set_position(sh_output->panel_view, pos);
weston_view_move_to_layer(sh_output->panel_view,
&shell->panel_layer.view_list);
}
static void
......@@ -2972,9 +2909,9 @@ handle_panel_surface_destroy(struct wl_listener *listener, void *data)
struct shell_output *output =
container_of(listener, struct shell_output, panel_surface_listener);
weston_log("panel surface gone\n");
wl_list_remove(&output->panel_surface_listener.link);
output->panel_surface = NULL;
output->panel_view = NULL;
}
......@@ -2987,7 +2924,6 @@ desktop_shell_set_panel(struct wl_client *client,
struct desktop_shell *shell = wl_resource_get_user_data(resource);
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
struct weston_view *view, *next;
struct shell_output *sh_output;
struct weston_head *head = weston_head_from_resource(output_resource);
......@@ -3001,34 +2937,29 @@ desktop_shell_set_panel(struct wl_client *client,
if (!head)
return;
wl_list_for_each_safe(view, next, &surface->views, surface_link)
weston_view_destroy(view);
view = weston_view_create(surface);
surface->output = head->output;
sh_output = find_shell_output_from_weston_output(shell, surface->output);
if (sh_output->panel_surface) {
wl_resource_post_error(surface_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"output already has a panel surface");
return;
}
surface->committed = panel_committed;
surface->committed_private = shell;
surface->committed_private = sh_output;
weston_surface_set_label_func(surface, panel_get_label);
surface->output = head->output;
weston_view_set_output(view, surface->output);
sh_output = find_shell_output_from_weston_output(shell, surface->output);
if (sh_output->panel_surface) {
/* The output already has a panel, tell our helper
* there is no need for another one. */
weston_desktop_shell_send_configure(resource, 0,
surface_resource,
0, 0);
} else {
weston_desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
surface->output->height);
weston_desktop_shell_send_configure(resource, 0,
surface_resource,
surface->output->width,
surface->output->height);
sh_output->panel_surface = surface;
sh_output->panel_surface = surface;
sh_output->panel_surface_listener.notify = handle_panel_surface_destroy;
wl_signal_add(&surface->destroy_signal, &sh_output->panel_surface_listener);
}
sh_output->panel_surface_listener.notify = handle_panel_surface_destroy;
wl_signal_add(&surface->destroy_signal, &sh_output->panel_surface_listener);
}
static int
......@@ -3042,20 +2973,21 @@ lock_surface_committed(struct weston_surface *surface,
struct weston_coord_surface new_origin)
{
struct desktop_shell *shell = surface->committed_private;
struct weston_view *view;
view = container_of(surface->views.next, struct weston_view, surface_link);
if (surface->width == 0)
if (!weston_surface_has_content(surface))
return;
if (weston_surface_is_mapped(surface))
return;
weston_surface_map(surface);
weston_view_move_to_layer(view, &shell->lock_layer.view_list);
weston_shell_utils_center_on_output(view,
assert(!shell->lock_view);
shell->lock_view = weston_view_create(surface);
weston_shell_utils_center_on_output(shell->lock_view,
weston_shell_utils_get_default_output(shell->compositor));
weston_view_move_to_layer(shell->lock_view,
&shell->lock_layer.view_list);
shell_fade(shell, FADE_IN);
}
......@@ -3065,8 +2997,8 @@ handle_lock_surface_destroy(struct wl_listener *listener, void *data)
struct desktop_shell *shell =
container_of(listener, struct desktop_shell, lock_surface_listener);
weston_log("lock surface gone\n");
shell->lock_surface = NULL;
shell->lock_view = NULL;
}
static void
......@@ -3083,16 +3015,21 @@ desktop_shell_set_lock_surface(struct wl_client *client,
if (!shell->locked)
return;
shell->lock_surface = surface;
shell->lock_surface_listener.notify = handle_lock_surface_destroy;
wl_signal_add(&surface->destroy_signal,
&shell->lock_surface_listener);
if (shell->lock_surface) {
wl_resource_post_error(surface_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"already have a lock surface");
return;
}
weston_view_create(surface);
surface->committed = lock_surface_committed;
surface->committed_private = shell;
weston_surface_set_label_func(surface, lock_surface_get_label);
shell->lock_surface = surface;
shell->lock_surface_listener.notify = handle_lock_surface_destroy;
wl_signal_add(&surface->destroy_signal,
&shell->lock_surface_listener);
}
static void
......
......@@ -67,9 +67,12 @@ struct shell_output {
struct wl_list link;
struct weston_surface *panel_surface;
struct weston_view *panel_view;
struct wl_listener panel_surface_listener;
struct weston_coord_global panel_offset;
struct weston_surface *background_surface;
struct weston_view *background_view;
struct wl_listener background_surface_listener;
};
......@@ -119,6 +122,7 @@ struct desktop_shell {
struct weston_surface *lock_surface;
struct wl_listener lock_surface_listener;
struct weston_view *lock_view;
struct workspace workspace;
......
......@@ -1927,7 +1927,7 @@ struct weston_surface {
*/
const char *role_name;
bool is_mapped, is_unmapping;
bool is_mapped, is_unmapping, is_mapping;
bool is_opaque;
/* An list of per seat pointer constraints. */
......@@ -2244,6 +2244,9 @@ weston_view_schedule_repaint(struct weston_view *view);
bool
weston_surface_is_mapped(struct weston_surface *surface);
bool
weston_surface_is_mapping(struct weston_surface *surface);
bool
weston_surface_is_unmapping(struct weston_surface *surface);
......
......@@ -798,7 +798,7 @@ find_focus_successor(struct kiosk_shell_surface *shsurf,
struct kiosk_shell_surface *view_shsurf;
struct kiosk_shell_surface *root;
if (!view->is_mapped || view == shsurf->view)
if (view == shsurf->view)
continue;
/* pick views only on the same output */
......
......@@ -2136,7 +2136,34 @@ weston_view_find_paint_node(struct weston_view *view,
WL_EXPORT bool
weston_surface_is_mapped(struct weston_surface *surface)
{
return surface->is_mapped;
struct weston_subsurface *sub = weston_surface_to_subsurface(surface);
/* This surface isn't mapped. */
if (!surface->is_mapped)
return false;
/* This surface is mapped, and has no parents to refer to. */
if (!sub || sub->parent == surface)
return true;
/* This subsurface's parent has since vanished. */
if (!sub->parent)
return false;
/* Check recursively up its parent tree. */
return weston_surface_is_mapped(sub->parent);
}
/** Check if the weston_surface is emitting an mapping commit
*
* @param surface The weston_surface.
*
* Returns true if the surface is emitting an mapping commit.
*/
WL_EXPORT bool
weston_surface_is_mapping(struct weston_surface *surface)
{
return surface->is_mapping;
}
/** Check if the weston_surface is emitting an unmapping commit
......@@ -2359,6 +2386,10 @@ weston_view_unmap(struct weston_view *view)
WL_EXPORT void
weston_surface_map(struct weston_surface *surface)
{
if (weston_surface_is_mapped(surface))
return;
surface->is_mapping = true;
surface->is_mapped = true;
surface->compositor->view_list_needs_rebuild = true;
weston_signal_emit_mutable(&surface->map_signal, surface);
......@@ -4478,8 +4509,9 @@ weston_surface_commit_state(struct weston_surface *surface,
wl_signal_emit(&surface->commit_signal, surface);
/* Surface is fully unmapped now */
/* Surface is now quiescent */
surface->is_unmapping = false;
surface->is_mapping = false;
state->status = WESTON_SURFACE_CLEAN;
return status;
......