clients/desktop-shell: preserve background/panel in clone mode
In shared-CRTC clone mode there are several wl_output globals for one weston_output. Only one panel and background is needed per weston_output, so the extra wl_outputs do not get their own panel and background. When a head is unplugged, the corresponding wl_output is removed. If that was the wl_output associated with the background and panel surfaces, we must transfer the ownership to a remaining wl_output that was a clone to avoid losing the background and panel completely. The transfer relies on desktop-shell.so implementation to register background and panel surfaces with the weston_output, not the weston_head, so it does not actually matter the wl_output used to bind the surfaces is going away. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
1a0239e40f
commit
c1bcce6a25
@ -128,6 +128,8 @@ struct output {
|
|||||||
uint32_t server_output_id;
|
uint32_t server_output_id;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
struct panel *panel;
|
struct panel *panel;
|
||||||
struct background *background;
|
struct background *background;
|
||||||
};
|
};
|
||||||
@ -1245,6 +1247,9 @@ output_handle_geometry(void *data,
|
|||||||
{
|
{
|
||||||
struct output *output = data;
|
struct output *output = data;
|
||||||
|
|
||||||
|
output->x = x;
|
||||||
|
output->y = y;
|
||||||
|
|
||||||
if (output->panel)
|
if (output->panel)
|
||||||
window_set_buffer_transform(output->panel->window, transform);
|
window_set_buffer_transform(output->panel->window, transform);
|
||||||
if (output->background)
|
if (output->background)
|
||||||
@ -1328,6 +1333,49 @@ create_output(struct desktop *desktop, uint32_t id)
|
|||||||
output_init(output, desktop);
|
output_init(output, desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_remove(struct desktop *desktop, struct output *output)
|
||||||
|
{
|
||||||
|
struct output *cur;
|
||||||
|
struct output *rep = NULL;
|
||||||
|
|
||||||
|
if (!output->background) {
|
||||||
|
output_destroy(output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find a wl_output that is a clone of the removed wl_output.
|
||||||
|
* We don't want to leave the clone without a background or panel. */
|
||||||
|
wl_list_for_each(cur, &desktop->outputs, link) {
|
||||||
|
if (cur == output)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* XXX: Assumes size matches. */
|
||||||
|
if (cur->x == output->x && cur->y == output->y) {
|
||||||
|
rep = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rep) {
|
||||||
|
/* If found, hand over the background and panel so they don't
|
||||||
|
* get destroyed. */
|
||||||
|
assert(!rep->background);
|
||||||
|
assert(!rep->panel);
|
||||||
|
|
||||||
|
rep->background = output->background;
|
||||||
|
output->background = NULL;
|
||||||
|
rep->background->owner = rep;
|
||||||
|
|
||||||
|
rep->panel = output->panel;
|
||||||
|
output->panel = NULL;
|
||||||
|
if (rep->panel)
|
||||||
|
rep->panel->owner = rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
output_destroy(output);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
global_handler(struct display *display, uint32_t id,
|
global_handler(struct display *display, uint32_t id,
|
||||||
const char *interface, uint32_t version, void *data)
|
const char *interface, uint32_t version, void *data)
|
||||||
@ -1357,7 +1405,7 @@ global_handler_remove(struct display *display, uint32_t id,
|
|||||||
if (!strcmp(interface, "wl_output")) {
|
if (!strcmp(interface, "wl_output")) {
|
||||||
wl_list_for_each(output, &desktop->outputs, link) {
|
wl_list_for_each(output, &desktop->outputs, link) {
|
||||||
if (output->server_output_id == id) {
|
if (output->server_output_id == id) {
|
||||||
output_destroy(output);
|
output_remove(desktop, output);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user