compositor.c: xdg-surface layout position

Add data structures to compositor.c xdg-surface implementation that allows them
to be rendered in the correct position in the layout, spanning outputs if
necessary.
This commit is contained in:
Tony Crisci 2017-09-19 14:47:28 -04:00
parent 9fa822c666
commit b01909ae15
1 changed files with 33 additions and 6 deletions

View File

@ -63,6 +63,11 @@ struct sample_state {
struct example_xdg_surface_v6 { struct example_xdg_surface_v6 {
struct wlr_xdg_surface_v6 *surface; struct wlr_xdg_surface_v6 *surface;
struct {
int lx;
int ly;
} position;
struct wl_listener destroy_listener; struct wl_listener destroy_listener;
struct wl_listener ping_timeout_listener; struct wl_listener ping_timeout_listener;
struct wl_listener request_minimize_listener; struct wl_listener request_minimize_listener;
@ -80,13 +85,13 @@ static inline int64_t timespec_to_msec(const struct timespec *a) {
static void output_frame_handle_surface(struct sample_state *sample, static void output_frame_handle_surface(struct sample_state *sample,
struct wlr_output *wlr_output, struct timespec *ts, struct wlr_output *wlr_output, struct timespec *ts,
struct wl_resource *_res) { struct wl_resource *_res, int ox, int oy) {
struct wlr_surface *surface = wl_resource_get_user_data(_res); struct wlr_surface *surface = wl_resource_get_user_data(_res);
float matrix[16]; float matrix[16];
float transform[16]; float transform[16];
wlr_surface_flush_damage(surface); wlr_surface_flush_damage(surface);
if (surface->texture->valid) { if (surface->texture->valid) {
wlr_matrix_translate(&transform, 200, 200, 0); wlr_matrix_translate(&transform, ox, oy, 0);
wlr_surface_get_matrix(surface, &matrix, wlr_surface_get_matrix(surface, &matrix,
&wlr_output->transform_matrix, &transform); &wlr_output->transform_matrix, &transform);
wlr_render_with_matrix(sample->renderer, surface->texture, &matrix); wlr_render_with_matrix(sample->renderer, surface->texture, &matrix);
@ -167,6 +172,10 @@ static void handle_new_xdg_surface_v6(struct wl_listener *listener,
} }
esurface->surface = surface; esurface->surface = surface;
// TODO sensible default position
esurface->position.lx = 300;
esurface->position.ly = 300;
surface->data = esurface;
wl_signal_add(&surface->events.destroy, &esurface->destroy_listener); wl_signal_add(&surface->events.destroy, &esurface->destroy_listener);
esurface->destroy_listener.notify = handle_xdg_surface_v6_destroy; esurface->destroy_listener.notify = handle_xdg_surface_v6_destroy;
@ -207,20 +216,38 @@ static void handle_output_frame(struct output_state *output,
struct wlr_wl_shell_surface *wl_shell_surface; struct wlr_wl_shell_surface *wl_shell_surface;
wl_list_for_each(wl_shell_surface, &sample->wl_shell->surfaces, link) { wl_list_for_each(wl_shell_surface, &sample->wl_shell->surfaces, link) {
output_frame_handle_surface(sample, wlr_output, ts, output_frame_handle_surface(sample, wlr_output, ts,
wl_shell_surface->surface); wl_shell_surface->surface, 200, 200);
} }
struct wlr_xdg_surface_v6 *xdg_surface; struct wlr_xdg_surface_v6 *xdg_surface;
struct wlr_xdg_client_v6 *xdg_client; struct wlr_xdg_client_v6 *xdg_client;
wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) { wl_list_for_each(xdg_client, &sample->xdg_shell->clients, link) {
wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) { wl_list_for_each(xdg_surface, &xdg_client->surfaces, link) {
output_frame_handle_surface(sample, wlr_output, ts, if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_NONE) {
xdg_surface->surface->resource); continue;
}
struct example_xdg_surface_v6 *esurface = xdg_surface->data;
int width = xdg_surface->surface->current.buffer_width;
int height = xdg_surface->surface->current.buffer_height;
bool intersects_output = wlr_output_layout_intersects(
sample->layout, wlr_output,
esurface->position.lx, esurface->position.ly,
esurface->position.lx + width, esurface->position.ly + height);
if (intersects_output) {
double ox = esurface->position.lx, oy = esurface->position.ly;
wlr_output_layout_output_coords(sample->layout, wlr_output,
&ox, &oy);
output_frame_handle_surface(sample, wlr_output, ts,
xdg_surface->surface->resource, ox, oy);
}
} }
} }
struct wlr_x11_window *x11_window; struct wlr_x11_window *x11_window;
wl_list_for_each(x11_window, &sample->xwayland->displayable_windows, link) { wl_list_for_each(x11_window, &sample->xwayland->displayable_windows, link) {
output_frame_handle_surface(sample, wlr_output, ts, output_frame_handle_surface(sample, wlr_output, ts,
x11_window->surface); x11_window->surface, 200, 200);
} }
wlr_renderer_end(sample->renderer); wlr_renderer_end(sample->renderer);