diff options
author | emersion <contact@emersion.fr> | 2017-12-31 12:49:06 +0100 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2017-12-31 12:49:06 +0100 |
commit | 1fe1d640425d87b104038ee23416e60bd9b9b2fc (patch) | |
tree | 4cbd4ef5a221a72dcbf635aa1f78c8086976a4e5 /rootston | |
parent | 80ed4d4d20807f021c473b77d44ce6b464afc0c7 (diff) |
Fix views outside output layout
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/desktop.c | 40 | ||||
-rw-r--r-- | rootston/output.c | 150 |
2 files changed, 114 insertions, 76 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c index 69dcf4a9..b74e2cb1 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -38,12 +38,9 @@ static void view_update_output(const struct roots_view *view, view_get_box(view, &box); wl_list_for_each(output, &desktop->outputs, link) { bool intersected = before != NULL && wlr_output_layout_intersects( - desktop->layout, output->wlr_output, - before->x, before->y, before->x + before->width, - before->y + before->height); - bool intersects = wlr_output_layout_intersects( - desktop->layout, output->wlr_output, - view->x, view->y, view->x + box.width, view->y + box.height); + desktop->layout, output->wlr_output, before); + bool intersects = wlr_output_layout_intersects(desktop->layout, + output->wlr_output, &box); if (intersected && !intersects) { wlr_surface_send_leave(view->wlr_surface, output->wlr_output); } @@ -386,6 +383,34 @@ struct roots_view *desktop_view_at(struct roots_desktop *desktop, double lx, return NULL; } +static void handle_layout_change(struct wl_listener *listener, void *data) { + struct roots_desktop *desktop = + wl_container_of(listener, desktop, layout_change); + + struct wlr_output *center_output = + wlr_output_layout_get_center_output(desktop->layout); + if (center_output == NULL) { + return; + } + + struct wlr_box *center_output_box = + wlr_output_layout_get_box(desktop->layout, center_output); + double center_x = center_output_box->x + center_output_box->width/2; + double center_y = center_output_box->y + center_output_box->height/2; + + struct roots_view *view; + wl_list_for_each(view, &desktop->views, link) { + struct wlr_box box; + view_get_box(view, &box); + + if (wlr_output_layout_intersects(desktop->layout, NULL, &box)) { + continue; + } + + view_move(view, center_x - box.width/2, center_y - box.height/2); + } +} + struct roots_desktop *desktop_create(struct roots_server *server, struct roots_config *config) { wlr_log(L_DEBUG, "Initializing roots desktop"); @@ -428,6 +453,9 @@ struct roots_desktop *desktop_create(struct roots_server *server, } desktop->layout = wlr_output_layout_create(); + desktop->layout_change.notify = handle_layout_change; + wl_signal_add(&desktop->layout->events.change, &desktop->layout_change); + desktop->compositor = wlr_compositor_create(server->wl_display, server->renderer); diff --git a/rootston/output.c b/rootston/output.c index e510be71..10450df3 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -34,79 +34,84 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { - if (wlr_surface_has_buffer(surface)) { - int width = surface->current->width; - int height = surface->current->height; - int render_width = width * wlr_output->scale; - int render_height = height * wlr_output->scale; - double ox = lx, oy = ly; - wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); - ox *= wlr_output->scale; - oy *= wlr_output->scale; - - if (wlr_output_layout_intersects(desktop->layout, wlr_output, - lx, ly, lx + render_width, ly + render_height)) { - float matrix[16]; - - float translate_center[16]; - wlr_matrix_translate(&translate_center, - (int)ox + render_width / 2, (int)oy + render_height / 2, 0); - - float rotate[16]; - wlr_matrix_rotate(&rotate, rotation); - - float translate_origin[16]; - wlr_matrix_translate(&translate_origin, -render_width / 2, - -render_height / 2, 0); - - float scale[16]; - wlr_matrix_scale(&scale, render_width, render_height, 1); - - float transform[16]; - wlr_matrix_mul(&translate_center, &rotate, &transform); - wlr_matrix_mul(&transform, &translate_origin, &transform); - wlr_matrix_mul(&transform, &scale, &transform); - - if (surface->current->transform != WL_OUTPUT_TRANSFORM_NORMAL) { - float surface_translate_center[16]; - wlr_matrix_translate(&surface_translate_center, 0.5, 0.5, 0); - - float surface_transform[16]; - wlr_matrix_transform(surface_transform, - wlr_output_transform_invert(surface->current->transform)); - - float surface_translate_origin[16]; - wlr_matrix_translate(&surface_translate_origin, -0.5, -0.5, 0); - - wlr_matrix_mul(&transform, &surface_translate_center, - &transform); - wlr_matrix_mul(&transform, &surface_transform, &transform); - wlr_matrix_mul(&transform, &surface_translate_origin, - &transform); - } + if (!wlr_surface_has_buffer(surface)) { + return; + } - wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix); + int width = surface->current->width; + int height = surface->current->height; + int render_width = width * wlr_output->scale; + int render_height = height * wlr_output->scale; + double ox = lx, oy = ly; + wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); + ox *= wlr_output->scale; + oy *= wlr_output->scale; + + struct wlr_box render_box = { + .x = lx, .y = ly, + .width = render_width, .height = render_height, + }; + if (wlr_output_layout_intersects(desktop->layout, wlr_output, &render_box)) { + float matrix[16]; + + float translate_center[16]; + wlr_matrix_translate(&translate_center, + (int)ox + render_width / 2, (int)oy + render_height / 2, 0); + + float rotate[16]; + wlr_matrix_rotate(&rotate, rotation); + + float translate_origin[16]; + wlr_matrix_translate(&translate_origin, -render_width / 2, + -render_height / 2, 0); + + float scale[16]; + wlr_matrix_scale(&scale, render_width, render_height, 1); + + float transform[16]; + wlr_matrix_mul(&translate_center, &rotate, &transform); + wlr_matrix_mul(&transform, &translate_origin, &transform); + wlr_matrix_mul(&transform, &scale, &transform); + + if (surface->current->transform != WL_OUTPUT_TRANSFORM_NORMAL) { + float surface_translate_center[16]; + wlr_matrix_translate(&surface_translate_center, 0.5, 0.5, 0); + + float surface_transform[16]; + wlr_matrix_transform(surface_transform, + wlr_output_transform_invert(surface->current->transform)); + + float surface_translate_origin[16]; + wlr_matrix_translate(&surface_translate_origin, -0.5, -0.5, 0); + + wlr_matrix_mul(&transform, &surface_translate_center, + &transform); + wlr_matrix_mul(&transform, &surface_transform, &transform); + wlr_matrix_mul(&transform, &surface_translate_origin, + &transform); + } - wlr_render_with_matrix(desktop->server->renderer, surface->texture, - &matrix); + wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix); - wlr_surface_send_frame_done(surface, when); - } + wlr_render_with_matrix(desktop->server->renderer, surface->texture, + &matrix); - struct wlr_subsurface *subsurface; - wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { - struct wlr_surface_state *state = subsurface->surface->current; - double sx = state->subsurface_position.x; - double sy = state->subsurface_position.y; - double sw = state->buffer_width / state->scale; - double sh = state->buffer_height / state->scale; - rotate_child_position(&sx, &sy, sw, sh, width, height, rotation); - - render_surface(subsurface->surface, desktop, wlr_output, when, - lx + sx, - ly + sy, - rotation); - } + wlr_surface_send_frame_done(surface, when); + } + + struct wlr_subsurface *subsurface; + wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { + struct wlr_surface_state *state = subsurface->surface->current; + double sx = state->subsurface_position.x; + double sy = state->subsurface_position.y; + double sw = state->buffer_width / state->scale; + double sh = state->buffer_height / state->scale; + rotate_child_position(&sx, &sy, sw, sh, width, height, rotation); + + render_surface(subsurface->surface, desktop, wlr_output, when, + lx + sx, + ly + sy, + rotation); } } @@ -356,7 +361,9 @@ void output_add_notify(struct wl_listener *listener, void *data) { void output_remove_notify(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = data; - struct roots_desktop *desktop = wl_container_of(listener, desktop, output_remove); + struct roots_desktop *desktop = + wl_container_of(listener, desktop, output_remove); + struct roots_output *output = NULL, *_output; wl_list_for_each(_output, &desktop->outputs, link) { if (_output->wlr_output == wlr_output) { @@ -367,10 +374,13 @@ void output_remove_notify(struct wl_listener *listener, void *data) { if (!output) { return; // We are unfamiliar with this output } + wlr_output_layout_remove(desktop->layout, output->wlr_output); + // TODO: cursor //example_config_configure_cursor(sample->config, sample->cursor, // sample->compositor); + wl_list_remove(&output->link); wl_list_remove(&output->frame.link); free(output); |