compositor: Ensure views are visible if their output was unplugged
Use the output destroy signal to move the views in the event the output was unplugged. Signed-off-by: Zhang, Xiong Y <xiong.y.zhang@intel.com> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
f301241d1a
commit
010d0b1695
+57
-2
@@ -365,6 +365,52 @@ weston_view_output_move_handler(struct wl_listener *listener,
|
|||||||
ev->geometry.y + output->move_y);
|
ev->geometry.y + output->move_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
weston_view_output_destroy_handler(struct wl_listener *listener,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct weston_view *ev;
|
||||||
|
struct weston_compositor *ec;
|
||||||
|
struct weston_output *output, *first_output;
|
||||||
|
float x, y;
|
||||||
|
int visible;
|
||||||
|
|
||||||
|
ev = container_of(listener, struct weston_view,
|
||||||
|
output_destroy_listener);
|
||||||
|
|
||||||
|
ec = ev->surface->compositor;
|
||||||
|
|
||||||
|
/* the child window's view->geometry is a relative coordinate to
|
||||||
|
* parent view, no need to move child_view. */
|
||||||
|
if (ev->geometry.parent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
x = ev->geometry.x;
|
||||||
|
y = ev->geometry.y;
|
||||||
|
|
||||||
|
/* At this point the destroyed output is not in the list anymore.
|
||||||
|
* If the view is still visible somewhere, we leave where it is,
|
||||||
|
* otherwise, move it to the first output. */
|
||||||
|
visible = 0;
|
||||||
|
wl_list_for_each(output, &ec->output_list, link) {
|
||||||
|
if (pixman_region32_contains_point(&output->region,
|
||||||
|
x, y, NULL)) {
|
||||||
|
visible = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
first_output = container_of(ec->output_list.next,
|
||||||
|
struct weston_output, link);
|
||||||
|
|
||||||
|
x = first_output->x + first_output->width / 4;
|
||||||
|
y = first_output->y + first_output->height / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
weston_view_set_position(ev, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
WL_EXPORT struct weston_view *
|
WL_EXPORT struct weston_view *
|
||||||
weston_view_create(struct weston_surface *surface)
|
weston_view_create(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
@@ -401,6 +447,8 @@ weston_view_create(struct weston_surface *surface)
|
|||||||
view->output = NULL;
|
view->output = NULL;
|
||||||
|
|
||||||
view->output_move_listener.notify = weston_view_output_move_handler;
|
view->output_move_listener.notify = weston_view_output_move_handler;
|
||||||
|
view->output_destroy_listener.notify =
|
||||||
|
weston_view_output_destroy_handler;
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@@ -816,12 +864,17 @@ weston_view_assign_output(struct weston_view *ev)
|
|||||||
}
|
}
|
||||||
pixman_region32_fini(®ion);
|
pixman_region32_fini(®ion);
|
||||||
|
|
||||||
if (ev->output_mask != 0)
|
if (ev->output_mask != 0) {
|
||||||
wl_list_remove(&ev->output_move_listener.link);
|
wl_list_remove(&ev->output_move_listener.link);
|
||||||
|
wl_list_remove(&ev->output_destroy_listener.link);
|
||||||
|
}
|
||||||
|
|
||||||
if (mask != 0)
|
if (mask != 0) {
|
||||||
wl_signal_add(&new_output->move_signal,
|
wl_signal_add(&new_output->move_signal,
|
||||||
&ev->output_move_listener);
|
&ev->output_move_listener);
|
||||||
|
wl_signal_add(&new_output->destroy_signal,
|
||||||
|
&ev->output_destroy_listener);
|
||||||
|
}
|
||||||
|
|
||||||
ev->output = new_output;
|
ev->output = new_output;
|
||||||
ev->output_mask = mask;
|
ev->output_mask = mask;
|
||||||
@@ -1265,6 +1318,8 @@ weston_view_unmap(struct weston_view *view)
|
|||||||
wl_list_init(&view->link);
|
wl_list_init(&view->link);
|
||||||
wl_list_remove(&view->output_move_listener.link);
|
wl_list_remove(&view->output_move_listener.link);
|
||||||
wl_list_init(&view->output_move_listener.link);
|
wl_list_init(&view->output_move_listener.link);
|
||||||
|
wl_list_remove(&view->output_destroy_listener.link);
|
||||||
|
wl_list_init(&view->output_destroy_listener.link);
|
||||||
view->output_mask = 0;
|
view->output_mask = 0;
|
||||||
weston_surface_assign_output(view->surface);
|
weston_surface_assign_output(view->surface);
|
||||||
|
|
||||||
|
|||||||
@@ -807,6 +807,7 @@ struct weston_view {
|
|||||||
uint32_t output_mask;
|
uint32_t output_mask;
|
||||||
|
|
||||||
struct wl_listener output_move_listener;
|
struct wl_listener output_move_listener;
|
||||||
|
struct wl_listener output_destroy_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_surface {
|
struct weston_surface {
|
||||||
|
|||||||
Reference in New Issue
Block a user