From 4bf936360d42fb5b96a44fd17028ae66fc462362 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 19 Mar 2018 23:11:37 -0400 Subject: Arrange & render layer surfaces --- rootston/output.c | 57 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 13 deletions(-) (limited to 'rootston/output.c') diff --git a/rootston/output.c b/rootston/output.c index 52ece54d..71497608 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -13,6 +13,7 @@ #include #include #include "rootston/config.h" +#include "rootston/layers.h" #include "rootston/output.h" #include "rootston/server.h" @@ -417,6 +418,21 @@ static void surface_send_frame_done(struct wlr_surface *surface, double lx, wlr_surface_send_frame_done(surface, when); } +static void render_layer( + struct roots_output *output, + const struct wlr_box *output_layout_box, + struct render_data *data, + struct wl_list *layer) { + struct roots_layer_surface *roots_surface; + wl_list_for_each(roots_surface, layer, link) { + struct wlr_layer_surface *layer = roots_surface->layer_surface; + render_surface(layer->surface, + roots_surface->geo.x + output_layout_box->x, + roots_surface->geo.y + output_layout_box->y, + 0, data); + } +} + static void render_output(struct roots_output *output) { struct wlr_output *wlr_output = output->wlr_output; struct roots_desktop *desktop = output->desktop; @@ -433,14 +449,15 @@ static void render_output(struct roots_output *output) { float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f}; + const struct wlr_box *output_box = + wlr_output_layout_get_box(desktop->layout, wlr_output); + // Check if we can delegate the fullscreen surface to the output if (output->fullscreen_view != NULL && output->fullscreen_view->wlr_surface != NULL) { struct roots_view *view = output->fullscreen_view; // Make sure the view is centered on screen - const struct wlr_box *output_box = - wlr_output_layout_get_box(desktop->layout, wlr_output); struct wlr_box view_box; view_get_box(view, &view_box); double view_x = (double)(output_box->width - view_box.width) / 2 + @@ -498,6 +515,11 @@ static void render_output(struct roots_output *output) { wlr_renderer_clear(renderer, clear_color); } + render_layer(output, output_box, &data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]); + render_layer(output, output_box, &data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); + // If a view is fullscreen on this output, render it if (output->fullscreen_view != NULL) { struct roots_view *view = output->fullscreen_view; @@ -520,20 +542,23 @@ static void render_output(struct roots_output *output) { render_surface, &data); } #endif - - goto renderer_end; - } - - // Render all views - struct roots_view *view; - wl_list_for_each_reverse(view, &desktop->views, link) { - render_view(view, &data); + } else { + // Render all views + struct roots_view *view; + wl_list_for_each_reverse(view, &desktop->views, link) { + render_view(view, &data); + } } // Render drag icons data.alpha = 1.0; drag_icons_for_each_surface(server->input, render_surface, &data); + render_layer(output, output_box, &data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); + render_layer(output, output_box, &data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); + renderer_end: wlr_renderer_scissor(renderer, NULL); wlr_renderer_end(renderer); @@ -603,7 +628,7 @@ static bool view_accept_damage(struct roots_output *output, return false; } -static void damage_whole_surface(struct wlr_surface *surface, +void output_damage_whole_surface(struct wlr_surface *surface, double lx, double ly, float rotation, void *data) { struct roots_output *output = data; @@ -647,13 +672,13 @@ void output_damage_whole_view(struct roots_output *output, } damage_whole_decoration(view, output); - view_for_each_surface(view, damage_whole_surface, output); + view_for_each_surface(view, output_damage_whole_surface, output); } void output_damage_whole_drag_icon(struct roots_output *output, struct roots_drag_icon *icon) { surface_for_each_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, 0, - damage_whole_surface, output); + output_damage_whole_surface, output); } static void damage_from_surface(struct wlr_surface *surface, @@ -781,6 +806,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { clock_gettime(CLOCK_MONOTONIC, &output->last_frame); output->desktop = desktop; output->wlr_output = wlr_output; + wlr_output->data = output; wl_list_insert(&desktop->outputs, &output->link); output->damage = wlr_output_damage_create(wlr_output); @@ -792,6 +818,11 @@ void handle_new_output(struct wl_listener *listener, void *data) { output->damage_destroy.notify = output_damage_handle_destroy; wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); + size_t len = sizeof(output->layers) / sizeof(output->layers[0]); + for (size_t i = 0; i < len; ++i) { + wl_list_init(&output->layers[i]); + } + struct roots_output_config *output_config = roots_config_get_output(config, wlr_output); if (output_config) { -- cgit v1.2.3 From f444a0d14c046b7df5a63f34a6f958cb175eb851 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 20 Mar 2018 21:13:39 -0400 Subject: Implement layer surface damage --- examples/layer-shell.c | 36 +++++++++++++++++++++++++++++------- include/rootston/output.h | 4 ++-- render/egl.c | 2 +- rootston/layer_shell.c | 32 ++++++++++++++++++++++++++------ rootston/output.c | 27 ++++++++++++++++++++++++--- 5 files changed, 82 insertions(+), 19 deletions(-) (limited to 'rootston/output.c') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index b5542f7a..91c509f6 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -1,8 +1,9 @@ -#define _POSIX_C_SOURCE 2 +#define _POSIX_C_SOURCE 199309L #include #include #include #include +#include #include #include #include @@ -25,6 +26,12 @@ static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; static int32_t width = 256, height = 256; +static struct { + struct timespec last_frame; + float color[3]; + int dec; +} demo; + static void draw(void); static void surface_frame_callback( @@ -40,17 +47,33 @@ static struct wl_callback_listener frame_listener = { static void draw(void) { eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); - wlr_log(L_DEBUG, "Drawing frame"); - float color[] = {1.0, 0.0, 0.0, 1.0}; + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + long ms = (ts.tv_sec - demo.last_frame.tv_sec) * 1000 + + (ts.tv_nsec - demo.last_frame.tv_nsec) / 1000000; + int inc = (demo.dec + 1) % 3; + + demo.color[inc] += ms / 2000.0f; + demo.color[demo.dec] -= ms / 2000.0f; + + if (demo.color[demo.dec] < 0.0f) { + demo.color[inc] = 1.0f; + demo.color[demo.dec] = 0.0f; + demo.dec = inc; + } + glViewport(0, 0, width, height); - glClearColor(color[0], color[1], color[2], 1.0); + glClearColor(demo.color[0], demo.color[1], demo.color[2], 1.0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); - frame_callback = wl_surface_frame(wl_surface); wl_callback_add_listener(frame_callback, &frame_listener, NULL); + + eglSwapBuffers(egl.display, egl_surface); + + demo.last_frame = ts; } static void layer_surface_configure(void *data, @@ -196,7 +219,6 @@ int main(int argc, char **argv) { &layer_surface_listener, layer_surface); // TODO: margin, interactivity, exclusive zone wl_surface_commit(wl_surface); - wl_display_dispatch(display); wl_display_roundtrip(display); wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, NULL, diff --git a/include/rootston/output.h b/include/rootston/output.h index 5545d76a..5cdbcb32 100644 --- a/include/rootston/output.h +++ b/include/rootston/output.h @@ -36,7 +36,7 @@ void output_damage_from_view(struct roots_output *output, struct roots_view *view); void output_damage_whole_drag_icon(struct roots_output *output, struct roots_drag_icon *icon); -void output_damage_whole_surface(struct wlr_surface *surface, - double lx, double ly, float rotation, void *data); +void output_damage_from_local_surface(struct roots_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation); #endif diff --git a/render/egl.c b/render/egl.c index d230f589..315eb098 100644 --- a/render/egl.c +++ b/render/egl.c @@ -95,7 +95,7 @@ static void print_dmabuf_formats(struct wlr_egl *egl) { for (int i = 0; i < num; i++) { snprintf(&str_formats[i*5], (num - i) * 5 + 1, "%.4s ", (char*)&formats[i]); } - wlr_log(L_INFO, "Supported dmabuf buffer formats: %s", str_formats); + wlr_log(L_DEBUG, "Supported dmabuf buffer formats: %s", str_formats); free(formats); } diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index 25e683fe..73addb7a 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -114,12 +114,32 @@ static void arrange_layers(struct wlr_output *_output) { } } +static void unmap(struct wlr_layer_surface *layer_surface) { + struct roots_layer_surface *layer = layer_surface->data; + wl_list_remove(&layer->link); + + struct wlr_output *wlr_output = layer_surface->output; + struct roots_output *output = wlr_output->data; + wlr_output_damage_add_box(output->damage, &layer->geo); +} + static void handle_destroy(struct wl_listener *listener, void *data) { - // TODO + struct roots_layer_surface *layer = wl_container_of( + listener, layer, destroy); + if (layer->layer_surface->mapped) { + unmap(layer->layer_surface); + } + free(layer); } static void handle_surface_commit(struct wl_listener *listener, void *data) { - // TODO + struct roots_layer_surface *layer = + wl_container_of(listener, layer, surface_commit); + struct wlr_layer_surface *layer_surface = layer->layer_surface; + struct wlr_output *wlr_output = layer_surface->output; + struct roots_output *output = wlr_output->data; + output_damage_from_local_surface(output, layer_surface->surface, + layer->geo.x, layer->geo.y, 0); } static void handle_map(struct wl_listener *listener, void *data) { @@ -127,13 +147,13 @@ static void handle_map(struct wl_listener *listener, void *data) { struct roots_layer_surface *layer = layer_surface->data; struct wlr_output *wlr_output = layer_surface->output; struct roots_output *output = wlr_output->data; - // TODO: This doesn't play right with output layouts and is also stupid - output_damage_whole_surface(layer_surface->surface, layer->geo.x, - layer->geo.y, 0, output); + wlr_output_damage_add_box(output->damage, &layer->geo); } static void handle_unmap(struct wl_listener *listener, void *data) { - // TODO + struct roots_layer_surface *layer = wl_container_of( + listener, layer, unmap); + unmap(layer->layer_surface); } void handle_layer_shell_surface(struct wl_listener *listener, void *data) { diff --git a/rootston/output.c b/rootston/output.c index 71497608..7c2c6d44 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -433,6 +433,18 @@ static void render_layer( } } +static void layers_send_done( + struct roots_output *output, struct timespec *when) { + size_t len = sizeof(output->layers) / sizeof(output->layers[0]); + for (size_t i = 0; i < len; ++i) { + struct roots_layer_surface *roots_surface; + wl_list_for_each(roots_surface, &output->layers[i], link) { + struct wlr_layer_surface *layer = roots_surface->layer_surface; + wlr_surface_send_frame_done(layer->surface, when); + } + } +} + static void render_output(struct roots_output *output) { struct wlr_output *wlr_output = output->wlr_output; struct roots_desktop *desktop = output->desktop; @@ -595,6 +607,7 @@ damage_finish: drag_icons_for_each_surface(server->input, surface_send_frame_done, &data); } + layers_send_done(output, data.when); } void output_damage_whole(struct roots_output *output) { @@ -628,7 +641,7 @@ static bool view_accept_damage(struct roots_output *output, return false; } -void output_damage_whole_surface(struct wlr_surface *surface, +static void damage_whole_surface(struct wlr_surface *surface, double lx, double ly, float rotation, void *data) { struct roots_output *output = data; @@ -672,13 +685,13 @@ void output_damage_whole_view(struct roots_output *output, } damage_whole_decoration(view, output); - view_for_each_surface(view, output_damage_whole_surface, output); + view_for_each_surface(view, damage_whole_surface, output); } void output_damage_whole_drag_icon(struct roots_output *output, struct roots_drag_icon *icon) { surface_for_each_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, 0, - output_damage_whole_surface, output); + damage_whole_surface, output); } static void damage_from_surface(struct wlr_surface *surface, @@ -716,6 +729,14 @@ static void damage_from_surface(struct wlr_surface *surface, pixman_region32_fini(&damage); } +void output_damage_from_local_surface(struct roots_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation) { + struct wlr_output_layout_output *layout = wlr_output_layout_get( + output->desktop->layout, output->wlr_output); + damage_from_surface(surface, ox + layout->x, oy + layout->y, + rotation, output); +} + void output_damage_from_view(struct roots_output *output, struct roots_view *view) { if (!view_accept_damage(output, view)) { -- cgit v1.2.3 From 776b81d499ae4430c0ebe5421b119c6b3355a1ce Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 26 Mar 2018 23:13:09 -0400 Subject: Fix surface layer damage tracking --- examples/layer-shell.c | 1 - include/rootston/output.h | 4 +++- rootston/layer_shell.c | 16 ++++++++++------ rootston/output.c | 8 ++++++++ 4 files changed, 21 insertions(+), 8 deletions(-) (limited to 'rootston/output.c') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 4c501d3d..e559121e 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -76,7 +76,6 @@ static void draw(void) { int32_t old_top = margin_top; margin_top = -(20 - ((int)frame % 20)); if (old_top != margin_top) { - wlr_log(L_DEBUG, "setting margin to %d", margin_top); zwlr_layer_surface_v1_set_margin(layer_surface, margin_top, 0, 0, 0); wl_surface_commit(wl_surface); diff --git a/include/rootston/output.h b/include/rootston/output.h index 535c07d8..e40ad776 100644 --- a/include/rootston/output.h +++ b/include/rootston/output.h @@ -40,6 +40,8 @@ void output_damage_from_view(struct roots_output *output, void output_damage_whole_drag_icon(struct roots_output *output, struct roots_drag_icon *icon); void output_damage_from_local_surface(struct roots_output *output, - struct wlr_surface *surface, double ox, double oy, float rotation); + struct wlr_surface *surface, double ox, double oy, float rotation); +void output_damage_whole_local_surface(struct roots_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation); #endif diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index 35896228..5efdf3c9 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -149,8 +149,6 @@ static void arrange_layer(struct wlr_output *output, struct wl_list *list, apply_exclusive(usable_area, state->anchor, state->exclusive_zone, state->margin.top, state->margin.right, state->margin.bottom, state->margin.left); - wlr_log(L_DEBUG, "arranged layer at %dx%d@%d,%d", - box.width, box.height, box.x, box.y); wlr_layer_surface_configure(layer, box.width, box.height); } } @@ -221,11 +219,17 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = layer_surface->output; if (wlr_output != NULL) { struct roots_output *output = wlr_output->data; - output_damage_from_local_surface(output, layer_surface->surface, - layer->geo.x, layer->geo.y, 0); + struct wlr_box old_geo = layer->geo; arrange_layers(wlr_output); - output_damage_from_local_surface(output, layer_surface->surface, - layer->geo.x, layer->geo.y, 0); + if (memcmp(&old_geo, &layer->geo, sizeof(struct wlr_box)) != 0) { + output_damage_whole_local_surface(output, layer_surface->surface, + old_geo.x, old_geo.y, 0); + output_damage_whole_local_surface(output, layer_surface->surface, + layer->geo.x, layer->geo.y, 0); + } else { + output_damage_from_local_surface(output, layer_surface->surface, + layer->geo.x, layer->geo.y, 0); + } } } diff --git a/rootston/output.c b/rootston/output.c index 7c2c6d44..aa74c8d7 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -664,6 +664,14 @@ static void damage_whole_surface(struct wlr_surface *surface, wlr_output_damage_add_box(output->damage, &box); } +void output_damage_whole_local_surface(struct roots_output *output, + struct wlr_surface *surface, double ox, double oy, float rotation) { + struct wlr_output_layout_output *layout = wlr_output_layout_get( + output->desktop->layout, output->wlr_output); + damage_whole_surface(surface, ox + layout->x, oy + layout->y, + rotation, output); +} + static void damage_whole_decoration(struct roots_view *view, struct roots_output *output) { if (!view->decorated || view->wlr_surface == NULL) { -- cgit v1.2.3 From a1d5d20914b25ef2d9820f04d885f22d6488d5e1 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 27 Mar 2018 17:36:35 -0400 Subject: Address some more feedback --- rootston/layer_shell.c | 7 +++++++ rootston/output.c | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'rootston/output.c') diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index 809ddbf3..d6428c51 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -138,6 +138,11 @@ static void arrange_layer(struct wlr_output *output, struct wl_list *list, } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { box.y -= state->margin.bottom; } + if (box.width < 0 || box.height < 0) { + // TODO: Bubble up a protocol error? + wlr_layer_surface_close(layer); + continue; + } // Apply roots_surface->geo = box; apply_exclusive(usable_area, state->anchor, state->exclusive_zone, @@ -177,6 +182,7 @@ static void arrange_layers(struct wlr_output *_output) { } // Arrange non-exlusive surfaces from top->bottom + usable_area.x = usable_area.y = 0; wlr_output_effective_resolution(output->wlr_output, &usable_area.width, &usable_area.height); arrange_layer(output->wlr_output, @@ -313,6 +319,7 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { wl_signal_add(&layer_surface->events.map, &roots_surface->map); roots_surface->unmap.notify = handle_unmap; wl_signal_add(&layer_surface->events.unmap, &roots_surface->unmap); + // TODO: Listen for subsurfaces roots_surface->layer_surface = layer_surface; layer_surface->data = roots_surface; diff --git a/rootston/output.c b/rootston/output.c index aa74c8d7..d903963e 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -560,14 +560,15 @@ static void render_output(struct roots_output *output) { wl_list_for_each_reverse(view, &desktop->views, link) { render_view(view, &data); } + // Render top layer above shell views + render_layer(output, output_box, &data, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); } // Render drag icons data.alpha = 1.0; drag_icons_for_each_surface(server->input, render_surface, &data); - render_layer(output, output_box, &data, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); render_layer(output, output_box, &data, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); @@ -670,6 +671,7 @@ void output_damage_whole_local_surface(struct roots_output *output, output->desktop->layout, output->wlr_output); damage_whole_surface(surface, ox + layout->x, oy + layout->y, rotation, output); + // TODO: subsurfaces } static void damage_whole_decoration(struct roots_view *view, @@ -743,6 +745,7 @@ void output_damage_from_local_surface(struct roots_output *output, output->desktop->layout, output->wlr_output); damage_from_surface(surface, ox + layout->x, oy + layout->y, rotation, output); + // TODO: Subsurfaces } void output_damage_from_view(struct roots_output *output, -- cgit v1.2.3 From b887af9a6013ea0466b6152e74f69659d7d45711 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 12:18:13 -0400 Subject: Fix maximized windows interaction with layer shell If there were no layer surfaces the usable area of the output would be an empty box. --- include/rootston/layers.h | 6 +++--- include/rootston/output.h | 2 ++ rootston/layer_shell.c | 31 +++++-------------------------- rootston/output.c | 18 ++++++++++++++++++ 4 files changed, 28 insertions(+), 29 deletions(-) (limited to 'rootston/output.c') diff --git a/include/rootston/layers.h b/include/rootston/layers.h index 35f5399e..0e5164bb 100644 --- a/include/rootston/layers.h +++ b/include/rootston/layers.h @@ -1,7 +1,6 @@ #ifndef ROOTSTON_LAYERS_H #define ROOTSTON_LAYERS_H #include -#include #include #include #include @@ -15,11 +14,12 @@ struct roots_layer_surface { struct wl_listener unmap; struct wl_listener surface_commit; struct wl_listener output_destroy; - struct wl_listener output_mode; - struct wl_listener output_transform; bool configured; struct wlr_box geo; }; +struct roots_output; +void arrange_layers(struct roots_output *output); + #endif diff --git a/include/rootston/output.h b/include/rootston/output.h index e40ad776..bf152038 100644 --- a/include/rootston/output.h +++ b/include/rootston/output.h @@ -23,6 +23,8 @@ struct roots_output { struct wlr_box usable_area; struct wl_listener destroy; + struct wl_listener mode; + struct wl_listener transform; struct wl_listener damage_frame; struct wl_listener damage_destroy; }; diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index 06ab15c3..edfaf5ea 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -82,7 +82,7 @@ static void arrange_layer(struct wlr_output *output, struct wl_list *list, wl_list_for_each(roots_surface, list, link) { struct wlr_layer_surface *layer = roots_surface->layer_surface; struct wlr_layer_surface_state *state = &layer->current; - if (exclusive != (state->exclusive_zone >0)) { + if (exclusive != (state->exclusive_zone > 0)) { continue; } struct wlr_box bounds; @@ -152,9 +152,7 @@ static void arrange_layer(struct wlr_output *output, struct wl_list *list, } } -static void arrange_layers(struct wlr_output *_output) { - struct roots_output *output = _output->data; - +void arrange_layers(struct roots_output *output) { struct wlr_box usable_area = { 0 }; wlr_output_effective_resolution(output->wlr_output, &usable_area.width, &usable_area.height); @@ -204,18 +202,9 @@ static void handle_output_destroy(struct wl_listener *listener, void *data) { wl_container_of(listener, layer, output_destroy); layer->layer_surface->output = NULL; wl_list_remove(&layer->output_destroy.link); - wl_list_remove(&layer->output_mode.link); wlr_layer_surface_close(layer->layer_surface); } -static void handle_output_mode(struct wl_listener *listener, void *data) { - arrange_layers((struct wlr_output *)data); -} - -static void handle_output_transform(struct wl_listener *listener, void *data) { - arrange_layers((struct wlr_output *)data); -} - static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_layer_surface *layer = wl_container_of(listener, layer, surface_commit); @@ -224,7 +213,7 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { if (wlr_output != NULL) { struct roots_output *output = wlr_output->data; struct wlr_box old_geo = layer->geo; - arrange_layers(wlr_output); + arrange_layers(output); if (memcmp(&old_geo, &layer->geo, sizeof(struct wlr_box)) != 0) { output_damage_whole_local_surface(output, layer_surface->surface, old_geo.x, old_geo.y, 0); @@ -258,9 +247,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&layer->unmap.link); wl_list_remove(&layer->surface_commit.link); wl_list_remove(&layer->output_destroy.link); - wl_list_remove(&layer->output_mode.link); - wl_list_remove(&layer->output_transform.link); - arrange_layers(layer->layer_surface->output); + arrange_layers((struct roots_output *)layer->layer_surface->output->data); free(layer); } @@ -306,14 +293,6 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { wl_signal_add(&layer_surface->output->events.destroy, &roots_surface->output_destroy); - roots_surface->output_mode.notify = handle_output_mode; - wl_signal_add(&layer_surface->output->events.mode, - &roots_surface->output_mode); - - roots_surface->output_transform.notify = handle_output_transform; - wl_signal_add(&layer_surface->output->events.transform, - &roots_surface->output_transform); - roots_surface->destroy.notify = handle_destroy; wl_signal_add(&layer_surface->events.destroy, &roots_surface->destroy); roots_surface->map.notify = handle_map; @@ -333,7 +312,7 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { struct wlr_layer_surface_state old_state = layer_surface->current; layer_surface->current = layer_surface->client_pending; - arrange_layers(output->wlr_output); + arrange_layers(output); layer_surface->current = old_state; } diff --git a/rootston/output.c b/rootston/output.c index d903963e..bf2bbdc2 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -816,6 +816,18 @@ static void output_damage_handle_destroy(struct wl_listener *listener, output_destroy(output); } +static void output_handle_mode(struct wl_listener *listener, void *data) { + struct roots_output *output = + wl_container_of(listener, output, mode); + arrange_layers(output); +} + +static void output_handle_transform(struct wl_listener *listener, void *data) { + struct roots_output *output = + wl_container_of(listener, output, transform); + arrange_layers(output); +} + void handle_new_output(struct wl_listener *listener, void *data) { struct roots_desktop *desktop = wl_container_of(listener, desktop, new_output); @@ -845,6 +857,11 @@ void handle_new_output(struct wl_listener *listener, void *data) { output->destroy.notify = output_handle_destroy; wl_signal_add(&wlr_output->events.destroy, &output->destroy); + output->mode.notify = output_handle_mode; + wl_signal_add(&wlr_output->events.mode, &output->mode); + output->transform.notify = output_handle_transform; + wl_signal_add(&wlr_output->events.transform, &output->transform); + output->damage_frame.notify = output_damage_handle_frame; wl_signal_add(&output->damage->events.frame, &output->damage_frame); output->damage_destroy.notify = output_damage_handle_destroy; @@ -879,5 +896,6 @@ void handle_new_output(struct wl_listener *listener, void *data) { roots_seat_configure_xcursor(seat); } + arrange_layers(output); output_damage_whole(output); } -- cgit v1.2.3